From 792e9997dd755582bfa9f7907cb5290fba6516db Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 13 Apr 2026 17:44:51 +0200 Subject: [PATCH 001/186] chore(tooling): ignore `.mypy_cache` (symlink) and `.python-version` (#2661) --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 3769738d037..5d4e44aa209 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ # Cache cached_downloads/ .cache +.mypy_cache .mypy_cache/ .ruff_cache/ __pycache__/ @@ -47,6 +48,8 @@ MANIFEST # Python virtual environment .venv/ venv/ +# User config; not imposed +.python-version # pycharm .idea/ From 62161905c15ad8f210e699f0237ae15b4f09ea5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:54:57 +0800 Subject: [PATCH 002/186] feat(test-benchmark): add cache strategy to storage benchmark (#2628) --- .../plugins/execute/pre_alloc.py | 11 ++ .../plugins/filler/pre_alloc.py | 20 ++- .../plugins/shared/pre_alloc.py | 15 ++- .../stateful/bloatnet/test_single_opcode.py | 116 +++++++++++++----- 4 files changed, 119 insertions(+), 43 deletions(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py index 64c4b1a6fc1..65d9e100ca6 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py @@ -44,6 +44,7 @@ from execution_testing.vm import Bytecode, Op from ..shared.address_stubs import AddressStubs +from ..shared.execute_fill import stub_eoas_key from ..shared.pre_alloc import Alloc as SharedAlloc from ..shared.pre_alloc import AllocFlags from .contracts import ( @@ -108,6 +109,14 @@ def address_stubs( return address_stubs +@pytest.fixture(scope="session") +def stub_eoas( + request: pytest.FixtureRequest, +) -> Dict[str, EOA]: + """Return stub EOAs pre-populated during configuration.""" + return request.config.stash.get(stub_eoas_key, {}) + + @pytest.fixture(scope="session") def skip_cleanup(request: pytest.FixtureRequest) -> bool: """Return whether to skip cleanup phase after each test.""" @@ -973,6 +982,7 @@ def pre( eth_rpc: EthRPC, chain_config: ChainConfig, address_stubs: AddressStubs | None, + stub_eoas: Dict[str, EOA], skip_cleanup: bool, max_fee_per_gas: int, max_priority_fee_per_gas: int, @@ -994,6 +1004,7 @@ def pre( pre = Alloc( fork=actual_fork, flags=alloc_flags, + stub_eoas=stub_eoas, sender=worker_key, eth_rpc=eth_rpc, eoa_iterator=eoa_iterator, diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/pre_alloc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/pre_alloc.py index ae4f77a723a..c3b76bf9d90 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/pre_alloc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/pre_alloc.py @@ -69,7 +69,6 @@ class Alloc(SharedAlloc): _eoa_fund_amount_default: int = PrivateAttr(10**21) _account_salt: Dict[Hash, int] = PrivateAttr(default_factory=dict) _stub_accounts: Dict[str, Account] = PrivateAttr(default_factory=dict) - _stub_eoas: Dict[str, EOA] = PrivateAttr(default_factory=dict) def __init__( self, @@ -81,20 +80,15 @@ def __init__( **kwargs: Any, ) -> None: """Initialize the pre-alloc.""" - super().__init__(*args, fork=fork, flags=flags, **kwargs) + super().__init__( + *args, + fork=fork, + flags=flags, + stub_eoas=stub_eoas, + **kwargs, + ) if stub_accounts is not None: self._stub_accounts = stub_accounts - if stub_eoas is not None: - self._stub_eoas = stub_eoas - - def stub_eoa(self, label: str) -> EOA: - """Return the EOA for a key-bearing stub.""" - if label not in self._stub_eoas: - raise ValueError( - f"Stub EOA '{label}' not found. " - "Provide --address-stubs with a pkey entry." - ) - return self._stub_eoas[label] def get_next_account_salt(self, account_hash: Hash) -> int: """Retrieve the next salt for this account.""" diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/pre_alloc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/pre_alloc.py index bec3b9241b0..5076bf2fa52 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/pre_alloc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/pre_alloc.py @@ -1,7 +1,7 @@ """Shared pre-alloc functionality.""" from enum import IntFlag, auto -from typing import Any, Literal, Set +from typing import Any, Dict, Literal, Set from pydantic import PrivateAttr @@ -43,6 +43,7 @@ class Alloc(BaseAlloc): _hardcoded_addresses_deployed_to: Set[Address] = PrivateAttr( default_factory=set ) + _stub_eoas: Dict[str, EOA] = PrivateAttr(default_factory=dict) def is_mutable(self) -> bool: """Return whether the pre-alloc is mutable.""" @@ -62,12 +63,24 @@ def __init__( *args: Any, fork: Fork, flags: AllocFlags, + stub_eoas: Dict[str, EOA] | None = None, **kwargs: Any, ) -> None: """Initialize allocation with the given properties.""" super().__init__(*args, **kwargs) self._fork = fork self._flags = flags + if stub_eoas is not None: + self._stub_eoas = stub_eoas + + def stub_eoa(self, label: str) -> EOA: + """Return the EOA for a key-bearing stub.""" + if label not in self._stub_eoas: + raise ValueError( + f"Stub EOA '{label}' not found. " + "Provide --address-stubs with a pkey entry." + ) + return self._stub_eoas[label].copy() def __setitem__( self, diff --git a/tests/benchmark/stateful/bloatnet/test_single_opcode.py b/tests/benchmark/stateful/bloatnet/test_single_opcode.py index 8ecab079140..4256db613e0 100644 --- a/tests/benchmark/stateful/bloatnet/test_single_opcode.py +++ b/tests/benchmark/stateful/bloatnet/test_single_opcode.py @@ -99,6 +99,7 @@ def run_bloated_eoa_benchmark( authority: EOA, existing_slots: bool, runtime_code: Bytecode, + cache_strategy: CacheStrategy, ) -> None: """ Run a bloated-EOA benchmark with the given runtime delegation code. @@ -125,17 +126,32 @@ def run_bloated_eoa_benchmark( sender = pre.fund_eoa() txs: list[Transaction] = [] - while gas_available >= intrinsic_gas: - tx_gas = min(gas_available, tx_gas_limit) - txs.append( - Transaction( - gas_limit=tx_gas, - to=authority, - sender=sender, + with TestPhaseManager.execution(): + while gas_available >= intrinsic_gas: + tx_gas = min(gas_available, tx_gas_limit) + txs.append( + Transaction( + gas_limit=tx_gas, + to=authority, + sender=sender, + ) ) - ) - gas_available -= tx_gas - blocks.append(Block(txs=txs)) + gas_available -= tx_gas + + cache_txs: list[Transaction] = [] + if cache_strategy == CacheStrategy.CACHE_PREVIOUS_BLOCK: + with TestPhaseManager.setup(): + cache_sender = pre.fund_eoa() + for tx in txs: + cache_txs.append( + Transaction( + gas_limit=tx.gas_limit, + to=authority, + sender=cache_sender, + ) + ) + + blocks += build_cache_strategy_blocks(cache_strategy, txs, cache_txs) benchmark_test( pre=pre, @@ -148,6 +164,7 @@ def run_bloated_eoa_benchmark( @pytest.mark.repricing @pytest.mark.stub_parametrize("token_name", "bloated_eoa_") @pytest.mark.parametrize("existing_slots", [False, True]) +@pytest.mark.parametrize("cache_strategy", list(CacheStrategy)) def test_sload_bloated( benchmark_test: BenchmarkTestFiller, pre: Alloc, @@ -156,6 +173,7 @@ def test_sload_bloated( tx_gas_limit: int, token_name: str, existing_slots: bool, + cache_strategy: CacheStrategy, ) -> None: """ Benchmark SLOAD opcodes targeting an EOA with storage bloated. @@ -165,14 +183,28 @@ def test_sload_bloated( storage layout of the target account, then the existing_slots parameter will not be correct. """ + slot_access = ( + Op.DUP1 # [index, index] + + Op.SLOAD # [s[index], index] + + Op.POP # [index] + ) + # CACHE_TX: access each slot twice so the second hit is uncached + if cache_strategy == CacheStrategy.CACHE_TX: + slot_access *= 2 + runtime_code = ( - Op.SLOAD(Op.PUSH0) + Op.PUSH0 # [0] + + Op.SLOAD # [index], s[0] = index + While( - body=(Op.DUP1 + Op.SLOAD + Op.POP + Op.PUSH1(1) + Op.ADD), + body=( + slot_access + + Op.PUSH1(1) # [1, index] + + Op.ADD # [index+1] + ), condition=Op.GT(Op.GAS, 0xFFFF), ) - + Op.PUSH0 - + Op.SSTORE + + Op.PUSH0 # [0, index+1] + + Op.SSTORE # s[0] = index+1 ) run_bloated_eoa_benchmark( @@ -184,6 +216,7 @@ def test_sload_bloated( authority=pre.stub_eoa(token_name), existing_slots=existing_slots, runtime_code=runtime_code, + cache_strategy=cache_strategy, ) @@ -191,6 +224,7 @@ def test_sload_bloated( @pytest.mark.stub_parametrize("token_name", "bloated_eoa_") @pytest.mark.parametrize("write_new_value", [False, True]) @pytest.mark.parametrize("existing_slots", [True, False]) +@pytest.mark.parametrize("cache_strategy", list(CacheStrategy)) def test_sstore_bloated( benchmark_test: BenchmarkTestFiller, pre: Alloc, @@ -200,6 +234,7 @@ def test_sstore_bloated( token_name: str, write_new_value: bool, existing_slots: bool, + cache_strategy: CacheStrategy, ) -> None: """ Benchmark SSTORE opcodes targeting an EOA with storage bloated. @@ -213,29 +248,51 @@ def test_sstore_bloated( test what they claim to do. For instance, for `write_new_value` set to False we need to know the current value of the slots. """ - stack_init = Op.DUP1 + ( - Op.PUSH1(1) + Op.ADD + Op.SWAP1 if write_new_value else Bytecode() + setup = ( + Op.PUSH0 # [0] + + Op.SLOAD # [key], s[0] = key + + Op.DUP1 # [key, key] ) + if write_new_value: + setup += ( + Op.PUSH1(1) # [1, key, key] + + Op.ADD # [key+1, key] + + Op.SWAP1 # [key, key+1] + ) + + # After setup phase, the stack element represents + # [slot, value], slot to write and value to write + + cache_op = Bytecode() + if cache_strategy == CacheStrategy.CACHE_TX: + cache_op = ( + Op.DUP1 # [slot, slot, value] + + Op.SLOAD # [s[slot], slot, value] + + Op.POP # [slot, value] + ) + + # The cache mechanism touches the slot before SSTORE + runtime_code = ( - Op.SLOAD(Op.PUSH0) - + stack_init + setup + While( body=( - Op.DUP2 - + Op.DUP2 - + Op.SSTORE - + Op.PUSH1(1) - + Op.ADD - + Op.SWAP1 - + Op.PUSH1(1) - + Op.ADD - + Op.SWAP1 + cache_op # [slot, value] + + Op.DUP2 # [value, slot, value] + + Op.DUP2 # [slot, value, slot, value] + + Op.SSTORE # [slot, value], s[slot] = value + + Op.PUSH1(1) # [1, slot, value] + + Op.ADD # [slot+1, value] + + Op.SWAP1 # [value, slot+1] + + Op.PUSH1(1) # [1, value, slot+1] + + Op.ADD # [value+1, slot+1] + + Op.SWAP1 # [slot+1, value+1] ), condition=Op.GT(Op.GAS, 0xFFFF), ) - + Op.PUSH0 - + Op.SSTORE + + Op.PUSH0 # [0, slot+1, value+1] + + Op.SSTORE # s[0] = slot+1 ) run_bloated_eoa_benchmark( @@ -247,6 +304,7 @@ def test_sstore_bloated( authority=pre.stub_eoa(token_name), existing_slots=existing_slots, runtime_code=runtime_code, + cache_strategy=cache_strategy, ) From ec74da478720ffd55a0ac93169e48db0ffcae86b Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 13 Apr 2026 23:02:29 +0200 Subject: [PATCH 003/186] fix(test-fill): resolve checklist path for EIPs referenced via `eip=[N]` kwarg (#2665) `@pytest.mark.eip_checklist(..., eip=[N])` is the documented escape hatch for a test that covers EIP N but lives outside a `tests/**/eipN_*/` directory (introduced in ethereum/execution-spec-tests#2088). The collector's `get_eip(N)` stores such EIPs with `path=None`, relying on a later pass over items inside the EIP's own directory to back-fill the path. When those primary tests aren't collected (e.g. deselected by a `-m` filter or `--until`), the path stays `None` and `--checklist-doc-gen` aborts at an `assert eip.path is not None`. Add a filesystem fallback that scans `tests/` for the canonical `eip_*` directory after item collection, and downgrade the assert to a warning-plus-skip so a genuinely missing directory no longer crashes checklist doc generation. The fix is exercised by running `docs/scripts/gen_test_case_reference.py` with `tests/benchmark` included, where `tests/benchmark/compute/precompile/test_p256verify.py` references EIP 7951 via the kwarg. --- .../plugins/filler/eip_checklist.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/eip_checklist.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/eip_checklist.py index ade7ec83288..11129083b82 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/eip_checklist.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/eip_checklist.py @@ -392,6 +392,21 @@ def generate_filled_checklist(self, output_dir: Path) -> Path: return output_dir +def _find_eip_dir(tests_root: Path, eip_number: int) -> Path | None: + """ + Return the first `eip_*` directory under `tests_root`, if any. + + Used as a fallback when an EIP is referenced from a test outside its + own `eipNNNN/` directory via the `eip=[N]` kwarg of `eip_checklist`, + so the checklist doc can still be attached to the EIP's canonical + location even when none of its primary tests were collected. + """ + for match in tests_root.rglob(f"eip{eip_number}_*"): + if match.is_dir(): + return match + return None + + class EIPChecklistCollector: """Collects and manages EIP checklist items from test markers.""" @@ -497,6 +512,14 @@ def pytest_collection_modifyitems( continue self.collect_from_item(item, eip) + # Back-fill the canonical `eipNNNN_*` directory for any EIP added + # via the `eip=[N]` kwarg of `eip_checklist` whose primary tests + # weren't collected (e.g. because of a `-m` filter or `--until`). + tests_root = Path(config.rootpath) / "tests" + for eip in self.eips.values(): + if eip.path is None: + eip.path = _find_eip_dir(tests_root, eip.number) + # Check which mode we are in checklist_doc_gen = config.getoption("checklist_doc_gen", False) checklist_output = config.getoption( @@ -512,7 +535,14 @@ def pytest_collection_modifyitems( continue if checklist_doc_gen: - assert eip.path is not None + if eip.path is None: + logger.warning( + f"EIP-{eip.number} was referenced via the `eip` " + "kwarg of `eip_checklist` but no `eip" + f"{eip.number}_*` directory was found under " + "tests/; skipping checklist doc generation for it." + ) + continue checklist_path = eip.path / "checklist.md" checklist_props[checklist_path] = EipChecklistPageProps( title=f"EIP-{eip.number} Test Checklist", From f059c48836f23dba0ad48d367faf2b74f86c1624 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 13 Apr 2026 23:57:59 +0200 Subject: [PATCH 004/186] feat(tooling): add docs-serve just recipes and tidy docs env handling (#2660) * chore(tooling): add docs-serve and docs-serve-fast just recipes * chore(tooling): only set DYLD_FALLBACK_LIBRARY_PATH no macOS --- Justfile | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Justfile b/Justfile index 89218b3826a..e19ba3ae476 100644 --- a/Justfile +++ b/Justfile @@ -265,6 +265,9 @@ bench-opcode-config *args: # --- Docs --- +export GEN_TEST_DOC_VERSION := "local" +export DYLD_FALLBACK_LIBRARY_PATH := if os() == "macos" { "/opt/homebrew/lib" } else { "" } + # Generate documentation for EELS using docc [group('docs')] docs-spec: @@ -273,13 +276,23 @@ docs-spec: # Build HTML site documentation with mkdocs [group('docs')] -docs: - GEN_TEST_DOC_VERSION="local" DYLD_FALLBACK_LIBRARY_PATH="/opt/homebrew/lib" uv run mkdocs build --strict -d "{{ output_dir }}/docs/site" +docs *args: + uv run mkdocs build --strict -d "{{ output_dir }}/docs/site" "$@" # Build HTML site documentation with mkdocs (skip test case reference) [group('docs')] -docs-fast: - FAST_DOCS=True GEN_TEST_DOC_VERSION="local" DYLD_FALLBACK_LIBRARY_PATH="/opt/homebrew/lib" uv run mkdocs build --strict -d "{{ output_dir }}/docs/site" +docs-fast *args: + FAST_DOCS=True uv run mkdocs build --strict -d "{{ output_dir }}/docs/site" "$@" + +# Serve site documentation locally with mkdocs (live reload) +[group('docs')] +docs-serve *args: + uv run mkdocs serve "$@" + +# Serve site documentation locally with mkdocs (skip test case reference) +[group('docs')] +docs-serve-fast *args: + FAST_DOCS=True uv run mkdocs serve "$@" # Validate docs/CHANGELOG.md entries [group('docs')] From 47782b3d5b1d24e435752878954e01e978681b98 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Mon, 13 Apr 2026 19:11:56 -0400 Subject: [PATCH 005/186] chore(doc): add skill for generating docstrings (#2669) --- .claude/commands/write-docstring.md | 287 +++++++++++++++++++++++ CLAUDE.md | 2 + src/ethereum/forks/amsterdam/requests.py | 165 +++++++++++-- src/ethereum/forks/bpo1/requests.py | 165 +++++++++++-- src/ethereum/forks/bpo2/requests.py | 165 +++++++++++-- src/ethereum/forks/bpo3/requests.py | 165 +++++++++++-- src/ethereum/forks/bpo4/requests.py | 165 +++++++++++-- src/ethereum/forks/bpo5/requests.py | 165 +++++++++++-- src/ethereum/forks/osaka/requests.py | 165 +++++++++++-- src/ethereum/forks/prague/requests.py | 165 +++++++++++-- 10 files changed, 1417 insertions(+), 192 deletions(-) create mode 100644 .claude/commands/write-docstring.md diff --git a/.claude/commands/write-docstring.md b/.claude/commands/write-docstring.md new file mode 100644 index 00000000000..ea98505e779 --- /dev/null +++ b/.claude/commands/write-docstring.md @@ -0,0 +1,287 @@ +# Write Docstring + +Conventions for writing docstrings in `src/ethereum/`. Docstrings are the primary prose of the specification — they read as a narrative explaining how Ethereum works, not as traditional Python API documentation. They are rendered into HTML by docc, which parses them as **Markdown** (via mistletoe). Run this skill before writing or modifying docstrings. + +## General Rules + +- **Markdown only** — no reStructuredText (`.. directives::`, `:param:`, RST section underlines) +- 79-character line limit (same as code) +- Imperative mood for summaries ("Obtain" not "Obtains", "Return" not "Returns") +- Summary on the line after opening `"""` +- Blank line after the summary for multi-line docstrings +- For multi-line docstrings, the closing `"""` should be on its own line +- No `__init__` docstrings (D107 is disabled), only the class itself is documented +- Reference link definitions go at the end of the docstring, after a blank line +- Do not include constants/numeric values in the docstring (values in docstrings can easily desync with the code, and no tool will detect it) +- Avoid restating what the code is doing (the code should speak for itself) +- Avoid mentioning the current fork unnecessarily (creates noisy diffs between forks) + +## Module Docstrings + +Module docstrings introduce the concepts in the module. They should read as narrative prose — imagine a textbook chapter opening. + +Start with a one-line summary, then expand with paragraphs that explain what the module contains and why. Use cross-references to link to the key types and functions defined in the module. + +```python +""" +Ethash is a proof-of-work algorithm designed to be [ASIC] resistant through +[memory hardness][mem-hard]. + +To achieve memory hardness, computing Ethash requires access to subsets of a +large structure. The particular subsets chosen are based on the nonce and block +header, while the set itself is changed every [`epoch`]. + +At a high level, the Ethash algorithm is as follows: + +1. Create a **seed** value, generated with [`generate_seed`] and based on the + preceding block numbers. +1. From the seed, compute a pseudorandom **cache** with [`generate_cache`]. +1. From the cache, generate a **dataset** with [`generate_dataset`]. The + dataset grows over time based on [`DATASET_EPOCH_GROWTH_SIZE`]. +1. Miners hash slices of the dataset together, which is where the memory + hardness is introduced. Verification of the proof-of-work only requires the + cache to be able to recompute a much smaller subset of the full dataset. + +[`DATASET_EPOCH_GROWTH_SIZE`]: ref:ethereum.ethash.DATASET_EPOCH_GROWTH_SIZE +[`generate_dataset`]: ref:ethereum.ethash.generate_dataset +[`generate_cache`]: ref:ethereum.ethash.generate_cache +[`generate_seed`]: ref:ethereum.ethash.generate_seed +[`epoch`]: ref:ethereum.ethash.epoch +[ASIC]: https://en.wikipedia.org/wiki/Application-specific_integrated_circuit +[mem-hard]: https://en.wikipedia.org/wiki/Memory-hard_function +""" +``` + +Short modules that need no narrative can use a single-line summary: + +```python +""" +Utility functions used in this specification. +""" +``` + +## Function Docstrings + +Function docstrings describe what the function does and why, as part of the specification narrative. Reference parameters inline with backticks — do **not** use formal `Parameters`, `Returns`, or `Raises` sections. + +### Short (summary only) + +```python +def convert(balance: str) -> U256: + """ + Convert a string in either hexadecimal or base-10 to a `U256`. + """ +``` + +### Multi-paragraph (with context) + +```python +def add_genesis_block( + hardfork: GenesisFork, chain: Any, genesis: GenesisConfiguration +) -> None: + """ + Add the genesis block to an empty blockchain. + + The genesis block is an entirely sui generis block (unique) that is not + governed by the general rules applying to all other Ethereum blocks. + Instead, the only consensus requirement is that it must be identical to + the block added by this function. + + The initial state is populated with balances based on the Ethereum presale + that happened on the Bitcoin blockchain. Additional ether worth 1.98% of + the presale was given to the foundation. + + The `nonce` field is `0x42` referencing Douglas Adams' "HitchHiker's Guide + to the Galaxy". + + On testnets the genesis configuration usually allocates 1 wei to addresses + `0x00` to `0xFF` to avoid edge cases around precompiles being created or + cleared (by [EIP-161]). + + [EIP-161]: https://eips.ethereum.org/EIPS/eip-161 + """ +``` + +### With cross-references + +```python +def cache_size(block_number: Uint) -> Uint: + """ + Obtain the cache size (in bytes) of the epoch to which `block_number` + belongs. + + See [`INITIAL_CACHE_SIZE`] and [`CACHE_EPOCH_GROWTH_SIZE`] for the initial + size and linear growth rate, respectively. The cache is generated in + [`generate_cache`]. + + The actual cache size is smaller than simply multiplying + `CACHE_EPOCH_GROWTH_SIZE` by the epoch number to minimize the risk of + unintended cyclic behavior. It is defined as the highest prime number below + what linear growth would calculate. + + [`INITIAL_CACHE_SIZE`]: ref:ethereum.ethash.INITIAL_CACHE_SIZE + [`CACHE_EPOCH_GROWTH_SIZE`]: ref:ethereum.ethash.CACHE_EPOCH_GROWTH_SIZE + [`generate_cache`]: ref:ethereum.ethash.generate_cache + """ +``` + +## Class Docstrings + +Brief summary of what the class represents, with optional narrative and cross-references. + +```python +class GenesisConfiguration: + """ + Configuration for the first block of an Ethereum chain. + + Specifies the allocation of ether set out in the pre-sale, and some of + the fields of the genesis block. + """ +``` + +```python +class EvmTracer(Protocol): + """ + [`Protocol`] that describes tracer functions. + + See [`ethereum.trace`] for details about tracing in general, and + [`__call__`] for more on how to implement a tracer. + + [`Protocol`]: https://docs.python.org/3/library/typing.html#typing.Protocol + [`ethereum.trace`]: ref:ethereum.trace + [`__call__`]: ref:ethereum.trace.EvmTracer.__call__ + """ +``` + +## Attribute Docstrings + +docc documents any assignment that is followed by a bare string literal. This is non-standard Python — normally only modules, classes, and functions can have docstrings. Place a triple-quoted string immediately after the assignment. + +This works for **constants**, **class fields**, **module-level variables**, and **type aliases**. + +### Constants + +```python +EPOCH_SIZE = Uint(30000) +""" +Number of blocks before a dataset needs to be regenerated (known as an +"epoch".) See [`epoch`]. + +[`epoch`]: ref:ethereum.ethash.epoch +""" +``` + +### Class fields + +```python +class Example: + chain_id: U64 + """ + Discriminant between diverged blockchains; `1` for Ethereum's main network. + """ +``` + +### Module-level variables + +```python +_evm_trace: EvmTracer = discard_evm_trace +""" +Active [`EvmTracer`] that is used for generating traces. + +[`EvmTracer`]: ref:ethereum.trace.EvmTracer +""" +``` + +### Type aliases + +```python +TraceEvent = ( + TransactionStart + | TransactionEnd + | PrecompileStart + | PrecompileEnd + | OpStart + | OpEnd + | OpException + | EvmStop + | GasAndRefund +) +""" +All possible types of events that an [`EvmTracer`] is expected to handle. + +[`EvmTracer`]: ref:ethereum.trace.EvmTracer +""" +``` + +## Cross-References + +docc resolves Markdown reference links with the `ref:` scheme into hyperlinks in the generated documentation. + +### Internal (to other Python objects) + +Use backtick-wrapped names as the link text, with `ref:` pointing to the fully-qualified path: + +``` +[`ForkCriteria`]: ref:ethereum.fork_criteria.ForkCriteria +[`generate_cache`]: ref:ethereum.ethash.generate_cache +``` + +Short aliases work when the full name is unwieldy: + +``` +[ds]: ref:ethereum.ethash.DATASET_EPOCH_GROWTH_SIZE +``` + +### External URLs + +Standard Markdown reference links: + +``` +[ASIC]: https://en.wikipedia.org/wiki/Application-specific_integrated_circuit +[EIP-3155]: https://eips.ethereum.org/EIPS/eip-3155 +``` + +Bare URLs in angle brackets for inline use: + +``` +Available at . +``` + +### Usage in text + +Reference links are used inline with brackets: + +``` +For these intentional forks to succeed, all participants need to agree on +exactly when to switch rules. The agreed upon criteria are represented by +subclasses of [`ForkCriteria`], like [`ByBlockNumber`] and [`ByTimestamp`]. +``` + +## Markdown Formatting + +- `_italic_` to introduce domain terms: `_Genesis_ is the term for...` +- `**bold**` to highlight key concepts: `Create a **seed** value` +- Backticks for code references: `` `block_number` ``, `` `0x42` `` +- Numbered lists (`1.`) for sequential steps +- Bullet lists (`-`) for unordered items +- Markdown headings are rarely needed inside docstrings; use paragraphs instead + +## Anti-Patterns + +- **No RST directives**: `.. contents::`, `.. note::`, `:param:`, `:returns:` — these are outdated +- **No NumPy/Google sections**: no `Parameters\n----------` or `Args:` blocks +- **No RST section underlines**: `Introduction\n------------` is RST, not Markdown +- **No type repetition in docstrings**: types come from annotations, not prose +- **No empty boilerplate**: don't write `"""Ethereum Specification."""` with a `.. contents::` block — write real narrative or a concise summary +- **Don't skip attribute docstrings**: constants and fields deserve explanations + +## Reference Files + +For examples of well-written docstrings, see: + +- `src/ethereum/ethash.py` — narrative module + function docstrings +- `src/ethereum/genesis.py` — class, attribute, and multi-paragraph function docstrings +- `src/ethereum/trace.py` — class, attribute, and protocol docstrings +- `src/ethereum/fork_criteria.py` — narrative module docstring with Markdown formatting + +If these files no longer exist or are no longer good examples, abort with an appropriate error message. diff --git a/CLAUDE.md b/CLAUDE.md index 243d6704a96..c2aeb8fb7df 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -49,6 +49,7 @@ When reviewing PRs that implement or test EIPs: - Assessing EIP complexity or scope → run `/assess-eip` - Working on EIP test coverage or checklists → run `/eip-checklist` first - Checking if config/skills are stale → run `/audit-config` +- Writing or modifying docstrings in `src/ethereum/` → run `/write-docstring` first - Done with changes and ready to lint → run `/lint` ## Available Skills @@ -62,4 +63,5 @@ When reviewing PRs that implement or test EIPs: - `/eip-checklist` — EIP testing checklist system for tracking coverage - `/lint` — full static analysis suite with auto-fix workflow - `/audit-config` — verify CLAUDE.md and skills are still accurate +- `/write-docstring` — narrative Markdown docstring conventions for the spec - `/grammar-check` — audit grammar in documentation and code comments diff --git a/src/ethereum/forks/amsterdam/requests.py b/src/ethereum/forks/amsterdam/requests.py index 542c9264d37..317b5121b3f 100644 --- a/src/ethereum/forks/amsterdam/requests.py +++ b/src/ethereum/forks/amsterdam/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.amsterdam.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.amsterdam.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.amsterdam.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.amsterdam.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.amsterdam.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.amsterdam.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.amsterdam.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.amsterdam.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.amsterdam.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.amsterdam.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.amsterdam.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/bpo1/requests.py b/src/ethereum/forks/bpo1/requests.py index 542c9264d37..1c1924ef3f7 100644 --- a/src/ethereum/forks/bpo1/requests.py +++ b/src/ethereum/forks/bpo1/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.bpo1.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.bpo1.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.bpo1.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.bpo1.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.bpo1.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.bpo1.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.bpo1.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.bpo1.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.bpo1.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.bpo1.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.bpo1.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/bpo2/requests.py b/src/ethereum/forks/bpo2/requests.py index 542c9264d37..38ca79f7009 100644 --- a/src/ethereum/forks/bpo2/requests.py +++ b/src/ethereum/forks/bpo2/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.bpo2.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.bpo2.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.bpo2.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.bpo2.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.bpo2.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.bpo2.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.bpo2.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.bpo2.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.bpo2.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.bpo2.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.bpo2.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/bpo3/requests.py b/src/ethereum/forks/bpo3/requests.py index 542c9264d37..7aa0bae522d 100644 --- a/src/ethereum/forks/bpo3/requests.py +++ b/src/ethereum/forks/bpo3/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.bpo3.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.bpo3.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.bpo3.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.bpo3.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.bpo3.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.bpo3.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.bpo3.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.bpo3.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.bpo3.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.bpo3.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.bpo3.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/bpo4/requests.py b/src/ethereum/forks/bpo4/requests.py index 542c9264d37..c6f6f099646 100644 --- a/src/ethereum/forks/bpo4/requests.py +++ b/src/ethereum/forks/bpo4/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.bpo4.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.bpo4.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.bpo4.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.bpo4.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.bpo4.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.bpo4.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.bpo4.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.bpo4.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.bpo4.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.bpo4.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.bpo4.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/bpo5/requests.py b/src/ethereum/forks/bpo5/requests.py index 542c9264d37..a04812d5c80 100644 --- a/src/ethereum/forks/bpo5/requests.py +++ b/src/ethereum/forks/bpo5/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.bpo5.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.bpo5.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.bpo5.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.bpo5.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.bpo5.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.bpo5.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.bpo5.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.bpo5.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.bpo5.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.bpo5.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.bpo5.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/osaka/requests.py b/src/ethereum/forks/osaka/requests.py index 542c9264d37..b53f81a33bf 100644 --- a/src/ethereum/forks/osaka/requests.py +++ b/src/ethereum/forks/osaka/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.osaka.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.osaka.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.osaka.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.osaka.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.osaka.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.osaka.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.osaka.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.osaka.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.osaka.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.osaka.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.osaka.blocks.Header.requests_hash """ m = sha256() for request in requests: diff --git a/src/ethereum/forks/prague/requests.py b/src/ethereum/forks/prague/requests.py index 542c9264d37..08b28c61115 100644 --- a/src/ethereum/forks/prague/requests.py +++ b/src/ethereum/forks/prague/requests.py @@ -1,11 +1,31 @@ """ -Requests were introduced in EIP-7685 as a general purpose framework for -storing contract-triggered requests. It extends the execution header and -body with a single field each to store the request information. -This inherently exposes the requests to the consensus layer, which can -then process each one. - +[EIP-7685] generalizes how the execution layer communicates validator actions +to the consensus layer. Rather than adding a dedicated header field for each +new action type (as [EIP-4895] did for withdrawals), the execution header +commits to a single [`requests_hash`][rh] that aggregates an ordered list of +typed requests. + +Each request is a type byte (see [`DEPOSIT_REQUEST_TYPE`][dt], +[`WITHDRAWAL_REQUEST_TYPE`][wt], and [`CONSOLIDATION_REQUEST_TYPE`][ct]) +followed by an opaque payload. Deposit requests are discovered by scanning +transaction receipts for logs emitted by the deposit contract; withdrawal +and consolidation requests are produced by the corresponding system +contracts during block processing. + +See [`parse_deposit_requests`][pd] for how deposit logs become request data, +[`compute_requests_hash`][crh] for how the list is hashed for inclusion in the +header, and [`process_general_purpose_requests`][pgpr] for how the requests are +processed. + +[EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[rh]: ref:ethereum.forks.prague.blocks.Header.requests_hash +[dt]: ref:ethereum.forks.prague.requests.DEPOSIT_REQUEST_TYPE +[wt]: ref:ethereum.forks.prague.requests.WITHDRAWAL_REQUEST_TYPE +[ct]: ref:ethereum.forks.prague.requests.CONSOLIDATION_REQUEST_TYPE +[pd]: ref:ethereum.forks.prague.requests.parse_deposit_requests +[crh]: ref:ethereum.forks.prague.requests.compute_requests_hash +[pgpr]: ref:ethereum.forks.prague.fork.process_general_purpose_requests """ from hashlib import sha256 @@ -25,38 +45,123 @@ DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0x00000000219ab540356cbb839cbe05303d7705fa" ) +""" +Mainnet address of the beacon chain deposit contract. Scanning block +receipts for logs emitted by this address is how the execution layer +discovers validator deposits, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + DEPOSIT_EVENT_SIGNATURE_HASH = hex_to_bytes32( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5" ) +""" +First [log topic] of the deposit contract's `DepositEvent`, equal to the +keccak256 of its Solidity event signature. Logs whose first topic does not +match this are ignored when collecting deposit requests. + +[log topic]: https://docs.soliditylang.org/en/latest/abi-spec.html#events +""" + DEPOSIT_REQUEST_TYPE = b"\x00" +""" +Request type byte identifying a deposit request, per [EIP-6110]. + +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +""" + WITHDRAWAL_REQUEST_TYPE = b"\x01" +""" +Request type byte identifying an execution-triggered withdrawal request, +per [EIP-7002]. + +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +""" + CONSOLIDATION_REQUEST_TYPE = b"\x02" +""" +Request type byte identifying a consolidation request, per [EIP-7251]. + +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +""" DEPOSIT_EVENT_LENGTH = Uint(576) +""" +Total length in bytes of the ABI-encoded `DepositEvent` data payload. Every +well-formed event has this exact length. +""" PUBKEY_OFFSET = Uint(160) +""" +Position within the event payload of the validator public key's length +prefix, as emitted by the Solidity ABI encoder. +""" + WITHDRAWAL_CREDENTIALS_OFFSET = Uint(256) +""" +Position within the event payload of the withdrawal credentials' length +prefix. +""" + AMOUNT_OFFSET = Uint(320) +""" +Position within the event payload of the deposit amount's length prefix. +""" + SIGNATURE_OFFSET = Uint(384) +""" +Position within the event payload of the deposit signature's length prefix. +""" + INDEX_OFFSET = Uint(512) +""" +Position within the event payload of the deposit index's length prefix. +""" PUBKEY_SIZE = Uint(48) +""" +Length of the BLS12-381 public key that identifies the validator receiving +the deposit. +""" + WITHDRAWAL_CREDENTIALS_SIZE = Uint(32) +""" +Length of the withdrawal credentials, which determine where the staked +ether may eventually be withdrawn. +""" + AMOUNT_SIZE = Uint(8) +""" +Length of the little-endian Gwei amount being deposited. +""" + SIGNATURE_SIZE = Uint(96) +""" +Length of the BLS12-381 signature over the deposit message. +""" + INDEX_SIZE = Uint(8) +""" +Length of the monotonically-increasing deposit index assigned by the +deposit contract when it emits the event. +""" def extract_deposit_data(data: Bytes) -> Bytes: """ - Extracts Deposit Request from the DepositContract.DepositEvent data. + Strip the Solidity ABI framing from a `DepositEvent` payload and return + the concatenated raw fields in the order consumed by the consensus + layer: public key, withdrawal credentials, amount, signature, and + deposit index. - Raises - ------ - InvalidBlock : - If the deposit contract did not produce a valid log. + Because each field has a fixed length, every well-formed event has an + identical byte layout. Any deviation indicates a misbehaving or + compromised deposit contract, so this function raises [`InvalidBlock`] + rather than silently accepting unexpected data. + [`InvalidBlock`]: ref:ethereum.exceptions.InvalidBlock """ if ulen(data) != DEPOSIT_EVENT_LENGTH: raise InvalidBlock("Invalid deposit event data length") @@ -150,7 +255,19 @@ def extract_deposit_data(data: Bytes) -> Bytes: def parse_deposit_requests(block_output: BlockOutput) -> Bytes: """ - Parse deposit requests from the block output. + Walk the receipts produced during block execution, concatenating the + raw payload of every valid deposit event into a single byte string. + + A log is considered a deposit when it originates from + [`DEPOSIT_CONTRACT_ADDRESS`][addr] and its first topic matches + [`DEPOSIT_EVENT_SIGNATURE_HASH`][sig]. The returned bytes are the + direct concatenation of the unframed deposit fields, ready to be + prefixed with [`DEPOSIT_REQUEST_TYPE`][dt] before being appended to + the block's request list. + + [addr]: ref:ethereum.forks.prague.requests.DEPOSIT_CONTRACT_ADDRESS + [sig]: ref:ethereum.forks.prague.requests.DEPOSIT_EVENT_SIGNATURE_HASH + [dt]: ref:ethereum.forks.prague.requests.DEPOSIT_REQUEST_TYPE """ deposit_requests: Bytes = b"" for key in block_output.receipt_keys: @@ -171,18 +288,18 @@ def parse_deposit_requests(block_output: BlockOutput) -> Bytes: def compute_requests_hash(requests: List[Bytes]) -> Bytes: """ - Get the hash of the requests using the SHA2-256 algorithm. - - Parameters - ---------- - requests : Bytes - The requests to hash. - - Returns - ------- - requests_hash : Bytes - The hash of the requests. - + Compute the [SHA2-256] commitment over an ordered list of + type-prefixed requests, as defined by [EIP-7685]. + + The commitment is the SHA2-256 hash of the concatenation of the + SHA2-256 hashes of each individual request. This is what the + execution header's [`requests_hash`][rh] stores, and what the + consensus layer re-derives to validate that both layers observed the + same set of requests. + + [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 + [SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 + [rh]: ref:ethereum.forks.prague.blocks.Header.requests_hash """ m = sha256() for request in requests: From ed9d24e43e3633aa94d44070ac0b084001f203fe Mon Sep 17 00:00:00 2001 From: kclowes Date: Mon, 13 Apr 2026 23:59:53 -0600 Subject: [PATCH 006/186] feat(tooling,test-cli): add just checklist and `allowed_exit_codes` to `PytestCommand` (#2648) Co-authored-by: danceratopz --- .gitignore | 3 +++ Justfile | 11 +++++--- .../cli/pytest_commands/base.py | 6 ++++- .../cli/pytest_commands/checklist.py | 25 ++++++++++++++++--- .../cli/pytest_commands/fill.py | 4 ++- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 5d4e44aa209..6d26b16d6d5 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,6 @@ logs/ env.yaml site/ + +# Temporary data; used for generated checklists +tmp/ diff --git a/Justfile b/Justfile index e19ba3ae476..23e2829b95d 100644 --- a/Justfile +++ b/Justfile @@ -89,12 +89,17 @@ lock-check: lint-actions: uv run actionlint -pyflakes pyflakes -shellcheck "shellcheck -S warning" +# --- Consensus Tests --- + # Generate HTML coverage report from last just fill run [group('consensus tests')] coverage: uv run coverage html -d "{{ output_dir }}/fill/coverage-html" -# --- Fill Tests --- +# Generate EIP test checklists from eip_checklist markers +[group('consensus tests')] +checklist *args: + uv run checklist --output tmp/checklist "$@" # Fill the consensus tests using EELS (with Python) [group('consensus tests')] @@ -119,6 +124,8 @@ fill *args: "$@" \ tests +# --- Integration Tests --- + # Fill the base coverage consensus tests using EELS with PyPy [group('integration tests')] fill-pypy *args: @@ -142,8 +149,6 @@ fill-pypy *args: "$@" \ tests -# --- Integration Tests --- - # Fill the base coverage consensus tests and run EELS against the fixtures [group('integration tests')] json-loader *args: diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/base.py b/packages/testing/src/execution_testing/cli/pytest_commands/base.py index b66c795bbb9..612ecc9ccb3 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/base.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/base.py @@ -5,7 +5,7 @@ from dataclasses import dataclass, field from os.path import realpath from pathlib import Path -from typing import Any, Callable, List, Optional +from typing import Any, Callable, ClassVar, List, Optional import click import pytest @@ -137,6 +137,9 @@ class PytestCommand: pytest_ini_folder: Path = PYTEST_INI_FOLDER """Folder where the pytest configuration files are located.""" + allowed_exit_codes: ClassVar[List[pytest.ExitCode]] = [pytest.ExitCode.OK] + """Exit codes treated as successful for executions of this command.""" + @property def config_path(self) -> Path: """Path to the pytest configuration file.""" @@ -173,6 +176,7 @@ def create_executions( config_file=self.config_path, command_logic_test_paths=self.test_args, args=processed_args, + allowed_exit_codes=self.allowed_exit_codes, ) ] diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py b/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py index dda4fbad103..90024ae3ba0 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py @@ -1,11 +1,30 @@ """CLI entry point for the `checklist` pytest-based command.""" -from typing import Any +from typing import Any, ClassVar, List import click +import pytest from ...forks import get_development_forks -from .fill import FillCommand +from .base import PytestCommand + + +class ChecklistCommand(PytestCommand): + """ + Pytest command to generate checklist documentation. + + The checklist command only collects tests to analyze markers and does + not run them, so ``NO_TESTS_COLLECTED`` is treated as success. + """ + + allowed_exit_codes: ClassVar[List[pytest.ExitCode]] = [ + pytest.ExitCode.OK, + pytest.ExitCode.NO_TESTS_COLLECTED, + ] + + def __init__(self, **kwargs: Any) -> None: + """Initialize checklist command.""" + super().__init__(config_file="pytest-fill.ini", **kwargs) def _last_development_fork() -> str | None: @@ -81,7 +100,7 @@ def checklist( if until: args.extend(["--until", until]) - command = FillCommand( + command = ChecklistCommand( plugins=[ "execution_testing.cli.pytest_commands.plugins.filler.eip_checklist" ], diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/fill.py b/packages/testing/src/execution_testing/cli/pytest_commands/fill.py index 126767bad00..a0d42c19c4d 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/fill.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/fill.py @@ -60,6 +60,7 @@ def create_executions( PytestExecution( config_file=self.config_path, args=processed_args, + allowed_exit_codes=self.allowed_exit_codes, ) ] @@ -82,7 +83,7 @@ def _create_two_phase_executions( args=phase1_args, description="generating pre-allocation groups", allowed_exit_codes=[ - pytest.ExitCode.OK, + *self.allowed_exit_codes, pytest.ExitCode.NO_TESTS_COLLECTED, ], ), @@ -282,6 +283,7 @@ def create_executions( PytestExecution( config_file=self.config_path, args=emoji_args, + allowed_exit_codes=self.allowed_exit_codes, ) ] From a830dab6f130151ab9023a473b7543120aa21961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Chodo=C5=82a?= <43241881+kamilchodola@users.noreply.github.com> Date: Tue, 14 Apr 2026 08:06:32 +0200 Subject: [PATCH 007/186] refactor(test-benchmark): remove unused bloatnet factory entries from mainnet stubs (#2670) --- .../stateful/stubs/stubs_mainnet.json | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/benchmark/stateful/stubs/stubs_mainnet.json b/tests/benchmark/stateful/stubs/stubs_mainnet.json index 175cc36ad9e..583f8263f92 100644 --- a/tests/benchmark/stateful/stubs/stubs_mainnet.json +++ b/tests/benchmark/stateful/stubs/stubs_mainnet.json @@ -34,23 +34,5 @@ }, "test_mixed_sload_sstore_HST": { "addr": "0x2e2a539285ce690e4c6bddd42deb7e37bdde9500" - }, - "bloatnet_factory_0_5kb": { - "addr": "0xDf9da7E8660d38654C8aA267635222c9f5Ac0530" - }, - "bloatnet_factory_1kb": { - "addr": "0xA52178573dc859741499946148CA1Fc3822Af600" - }, - "bloatnet_factory_2kb": { - "addr": "0x88c159584059308C4B466bafC82c45d52De9951D" - }, - "bloatnet_factory_5kb": { - "addr": "0x3f59809dac4b33e251e518acDadf923184151334" - }, - "bloatnet_factory_10kb": { - "addr": "0xf90E8a6Ce32A949Ce5F58803BBa07476404cD89F" - }, - "bloatnet_factory_24kb": { - "addr": "0x091988Afd81E0a2A3E20530A2510c089fF4bfAef" } } From f802a2462c355eba397af97eff7bd20ce85132ae Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 14 Apr 2026 11:12:41 +0200 Subject: [PATCH 008/186] feat(docs): update content for post-weld execution-specs (#2662) --- docs/consensus_tests/index.md | 7 + docs/dev/coding_style.md | 4 - docs/dev/deps_and_packaging.md | 130 ++++++++--------- docs/dev/docs.md | 101 +------------ docs/dev/documenting_clis.md | 2 +- docs/dev/index.md | 8 +- docs/dev/precommit.md | 16 --- docs/filling_tests/debugging_t8n_tools.md | 2 +- .../filling_tests_command_line.md | 4 +- docs/filling_tests/filling_tests_dev_fork.md | 6 +- docs/filling_tests/filling_tests_vs_code.md | 20 --- docs/filling_tests/getting_started.md | 3 +- docs/filling_tests/index.md | 8 -- docs/filling_tests/transition_tool_support.md | 2 +- docs/getting_started/code_standards.md | 56 ++------ .../getting_started/code_standards_details.md | 135 ------------------ docs/getting_started/getting_help.md | 8 +- docs/getting_started/installation.md | 104 ++++++++++++-- .../installation_troubleshooting.md | 10 +- docs/getting_started/repository_overview.md | 42 +++--- docs/getting_started/setup_vs_code.md | 52 ------- docs/getting_started/verifying_changes.md | 91 ++++++++++++ docs/img/annotated-coverage.jpg | Bin 414051 -> 0 bytes docs/img/eth-diamond-white.png | Bin 0 -> 35921 bytes docs/img/eth-diamond-white.svg | 1 + docs/img/favicon.ico | 19 --- docs/img/original-coverage-loss.png | Bin 146953 -> 0 bytes docs/index.md | 110 +++++++------- docs/library/cli/index.md | 2 +- docs/navigation.md | 128 ++++++++--------- docs/running_tests/consume/cache.md | 20 ++- docs/running_tests/execute/eth_config.md | 6 +- docs/running_tests/execute/index.md | 2 +- docs/running_tests/releases.md | 7 +- docs/running_tests/test_formats/state_test.md | 2 +- .../test_formats/transaction_test.md | 2 +- docs/specs/writing_specs.md | 4 + docs/templates/function.md.j2 | 4 + docs/writing_tests/adding_a_new_test.md | 2 +- docs/writing_tests/code_standards.md | 4 - docs/writing_tests/fuzzer_bridge.md | 11 +- docs/writing_tests/index.md | 3 +- docs/writing_tests/porting_legacy_tests.md | 128 ----------------- docs/writing_tests/post_mortems.md | 2 +- docs/writing_tests/reference_specification.md | 2 +- docs/writing_tests/test_markers.md | 4 +- docs/writing_tests/tutorials/blockchain.md | 2 +- .../tutorials/state_transition.md | 6 +- docs/writing_tests/types_of_tests.md | 2 +- docs/writing_tests/verifying_changes.md | 4 - docs/writing_tests/writing_a_new_test.md | 6 +- mkdocs.yml | 46 +++--- .../plugins/filler/gen_test_doc/page_props.py | 3 + .../src/execution_testing/config/docs.py | 8 +- whitelist.txt | 17 +-- 55 files changed, 505 insertions(+), 863 deletions(-) create mode 100644 docs/consensus_tests/index.md delete mode 100644 docs/dev/coding_style.md delete mode 100644 docs/dev/precommit.md delete mode 100644 docs/filling_tests/filling_tests_vs_code.md delete mode 100644 docs/getting_started/code_standards_details.md delete mode 100644 docs/getting_started/setup_vs_code.md create mode 100644 docs/getting_started/verifying_changes.md delete mode 100644 docs/img/annotated-coverage.jpg create mode 100644 docs/img/eth-diamond-white.png create mode 100644 docs/img/eth-diamond-white.svg delete mode 100644 docs/img/favicon.ico delete mode 100644 docs/img/original-coverage-loss.png create mode 100644 docs/specs/writing_specs.md delete mode 100644 docs/writing_tests/code_standards.md delete mode 100644 docs/writing_tests/porting_legacy_tests.md delete mode 100644 docs/writing_tests/verifying_changes.md diff --git a/docs/consensus_tests/index.md b/docs/consensus_tests/index.md new file mode 100644 index 00000000000..0971d147a44 --- /dev/null +++ b/docs/consensus_tests/index.md @@ -0,0 +1,7 @@ +# Consensus Tests + +The consensus tests in `./tests/` verify that Ethereum execution clients implement the protocol correctly and agree on the resulting state transitions. This section covers the full workflow: + +- [Writing Tests](../writing_tests/index.md): Authoring new Python test cases using the execution-testing framework. +- [Filling Tests](../filling_tests/index.md): Generating JSON test fixtures (vectors) from the Python test cases using the `fill` command. +- [Running Tests](../running_tests/index.md): Executing the generated fixtures against clients, either directly or via Hive. diff --git a/docs/dev/coding_style.md b/docs/dev/coding_style.md deleted file mode 100644 index 6772746ca0b..00000000000 --- a/docs/dev/coding_style.md +++ /dev/null @@ -1,4 +0,0 @@ -# Coding Style - -!!! warning "Documentation Moved" - This documentation has been relocated to [Getting Started -> Code Standards](../getting_started/code_standards.md). Please use the new location for the most up-to-date information. diff --git a/docs/dev/deps_and_packaging.md b/docs/dev/deps_and_packaging.md index ab52eec197b..a0d6997fe9e 100644 --- a/docs/dev/deps_and_packaging.md +++ b/docs/dev/deps_and_packaging.md @@ -1,8 +1,17 @@ -# EEST Dependency Management and Packaging +# Dependency Management and Packaging -EEST uses [`uv`](https://docs.astral.sh/uv/) to manage and pin its dependencies. +EELS uses [`uv`](https://docs.astral.sh/uv/) to manage and pin its dependencies, and a minimum `uv>=0.7.0` is required. -A minimum version of `uv>=0.7.0` is required to ensure `uv` writes `uv.lock` files with consistent fields and formatting (see [ethereum/execution-spec-tests#1597](https://github.com/ethereum/execution-spec-tests/pull/1597)). +## Workspace Layout + +The repo is a `uv` workspace with two members, each defined by its own `pyproject.toml`: + +| Package | `pyproject.toml` | Contents | +| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `ethereum-execution` | [`pyproject.toml`](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/pyproject.toml) | The Python specs (`src/ethereum/`) and associated tools. | +| `ethereum-execution-testing` | [`packages/testing/pyproject.toml`](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/packages/testing/pyproject.toml) | The EEST test framework under `packages/testing/`. | + +A single [`uv.lock`](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/uv.lock) at the repo root pins dependencies for both packages. ## Managing Dependencies @@ -10,120 +19,101 @@ We aim to provide specific [version specifiers](https://peps.python.org/pep-0440 !!! note "Packages should be managed via `uv`" - Dependencies should be managed using `uv` on the command-line to ensure that version compatibility is ensured across all dependencies and that `uv.lock` is updated as required. + Dependencies should be managed using `uv` on the command-line to ensure that version compatibility is maintained across all dependencies and that `uv.lock` is updated as required. The docs below cover common operations, see the `uv` [documentation on managing dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/#multiple-sources) for more information. -!!! info "Separate PRs are preferred when managing dependencies" +!!! info "Target the right workspace member" - An upgrade of all pinned dependencies in `uv.lock` must be performed in a dedicated PR! - - For other dependency changes, they can be included in the PR that removed use of the library, for example. But if a version bump is made, without related source code changes, it should be done in a dedicated PR. This makes the change: + Run `uv` commands from the repo root. By default they target `ethereum-execution` (the specs package). To target the test framework, pass `--package ethereum-execution-testing` (or equivalently, `cd packages/testing/` first and run `uv` from there). - - Easier to track. - - Trivial to revert. + Either way, the single `uv.lock` at the repo root is updated and should be committed alongside the `pyproject.toml` change. + +!!! info "Separate PRs are preferred when managing dependencies" -### Adding/modifying direct dependencies + An upgrade of all pinned dependencies in `uv.lock` must be performed in a dedicated PR. -These are packages listed in the project's direct dependencies, i.e., in `pyproject.toml` `[project]` section: + For other dependency changes, they can be included in the PR that adds or removes use of the library. But if a version bump is made without related source code changes, it should be done in a dedicated PR. This makes the change: -```toml -[project] -... -dependencies = [ - "click>=8.1.0,<9", - ... - "pytest-regex>=0.2.0,<0.3", -] -``` + - Easier to track. + - Trivial to revert. -or, for source package dependencies (directly installed via a `git+` specifier from Github), in the `[tool.uv.sources]` section: +### Adding or modifying direct dependencies -```toml -[tool.uv.sources] -ethereum-spec-evm-resolver = { git = "https://github.com/petertdavies/ethereum-spec-evm-resolver", rev = \ -... -``` +Direct dependencies are the packages listed in each package's `[project] dependencies` table. -!!! example "Example: Updating direct dependencies" +!!! example "Adding a direct dependency to the specs package" - Example of a package dependency update: ```console uv add "requests>=2.31,<2.33" ``` - Example of a source dependency update: +!!! example "Adding a direct dependency to the testing package" + ```console - uv add "ethereum-spec-evm-resolver @ git+https://github.com/petertdavies/ethereum-spec-evm-resolver@623ac4565025e72b65f45b926da2a3552041b469" + uv add --package ethereum-execution-testing "requests>=2.31,<2.33" ``` -### Adding/modifying development dependencies - -Development dependencies are managed in dependency groups: `lint`, `doc`, `test`, and `mkdocs` defined in the `pyproject.toml`: - -```toml -[dependency-groups] -test = [ - "pytest>=8,<9", - "pytest-cov>=4.1.0,<5", - ... -] -lint = [ - "ruff==0.13.2", - "mypy==1.17.0", - "types-requests>=2.31,<2.33", - ... -] -``` +### Adding or modifying development dependencies -These can be modified via `uv`on the command-line or edited by hand. If editing manually, you must run `uv lock` afterwards to update the lockfile. +Development dependencies are grouped into `[dependency-groups]`, one group per concern, plus a `dev` meta-group that includes them all. -!!! example "Example: Updating a development dependency" +Groups defined by the specs package: + +- `test`, `lint`, `actionlint`, `doc`, `mkdocs`. +- `dev` includes all of the above plus the `optimized` extra. + +Groups defined by the testing package: + +- `test`, `lint`. +- `dev` includes both. + +!!! example "Adding a dev dependency to the specs `lint` group" - Using uv: ```console uv add --group lint "types-requests>=2.31,<2.33" ``` - Or edit `pyproject.toml` manually and then run: +!!! example "Adding a dev dependency to the testing package `test` group" + ```console - uv lock + uv add --package ethereum-execution-testing --group test "pytest-timeout>=2.3,<3" ``` -### Adding/modifying optional dependencies - -The `optimized` optional extra provides performance enhancements and is the only remaining optional dependency group: +### Adding or modifying optional dependencies -```toml -[project.optional-dependencies] -optimized = [ - "rust-pyspec-glue>=0.0.9,<0.1.0", - "ethash>=1.1.0,<2", -] -``` +The specs package defines a single optional extra, `optimized`, which pulls in `rust-pyspec-glue` and `ethash` for EVM performance. -!!! example "Example: Updating an optional dependency" +!!! example "Updating an optional dependency" ```console uv add --optional optimized "ethash>=1.1.0,<2" ``` - Or edit `pyproject.toml` by hand and run `uv lock`. - ## Upgrading Pinned Dependencies in `uv.lock` -To upgrade all pinned dependencies in `uv.lock` to the latest version permitted by EEST's `project.toml` version specifiers run: +To upgrade all pinned dependencies in `uv.lock` to the latest versions permitted by both packages' version specifiers, run: ```console uv lock --upgrade ``` -Project-wide dependency upgrades must be made via a dedicated PR! +Project-wide dependency upgrades must be made via a dedicated PR. -To upgrade a single package run: +To upgrade a single package, run: ```console uv lock --upgrade-package ``` See [Locking and Syncing](https://docs.astral.sh/uv/concepts/projects/sync/#upgrading-locked-package-versions) in the `uv` docs for more information. + +## Verifying `uv.lock` + +After any dependency change, verify that `uv.lock` is consistent with both `pyproject.toml` files: + +```console +just lock-check +``` + +This recipe also runs as part of `just static` and must be clean before committing. diff --git a/docs/dev/docs.md b/docs/dev/docs.md index e4536838b6b..a60dc352985 100644 --- a/docs/dev/docs.md +++ b/docs/dev/docs.md @@ -1,6 +1,6 @@ # Documentation -The `execution-spec-tests` documentation is generated via [`mkdocs`](https://www.mkdocs.org/) and hosted remotely on Github Pages at [eest.ethereum.org](https://eest.ethereum.org/). +The `execution-specs` documentation is generated via [`mkdocs`](https://www.mkdocs.org/) and (soon) hosted remotely on Github Pages at [steel.ethereum.foundation/docs/](https://steel.ethereum.foundation/docs/). ## Prerequisites @@ -27,10 +27,11 @@ just changelog ### Local Deployment and Test -This runs continually: Deploys the site locally and re-generates the site upon modifications to `docs/**/*.md` or `tests/**/*.py`: +Serve the site locally with live reload on changes to `docs/**/*.md` or `tests/**/*.py`: ```console -uv run mkdocs serve +just docs-serve # full build +just docs-serve-fast # skips the Test Case Reference, faster iteration ``` For more help (including ensuring a clean build), see the `gen_test_doc` pytest plugin's documentation: @@ -39,96 +40,6 @@ For more help (including ensuring a clean build), see the `gen_test_doc` pytest options: members: no -## Remote Deployment and Versioning - -The execution-specs-test docs are hosted using Github pages at [eest.ethereum.org](https://eest.ethereum.org/). Versions are updated/deployed automatically as part of Github Actions, but this can also be performed on the command-line. - -Our mkdocs configuration uses [mike](https://github.com/jimporter/mike) as a version provider. All deployments should be made via `mike` (whether as part of CI/CD or executed locally). - -The deployed versions of the docs managed via `mike` are kept in the [gh-pages](https://github.com/ethereum/execution-spec-tests/tree/gh-pages) branch. When you run `mike` it commits to this branch and optionally pushes the changes directly to remote. - -### Aliases - -We currently have two aliases (which both point to `main` as of [#998](https://github.com/ethereum/execution-spec-tests/pull/998)): - -- [`latest`](https://eest.ethereum.org/latest): the current state of the main branch. -- [`development`](https://eest.ethereum.org/development): the current state of the main branch. - -These aliases point to specific versions, as configured below. It's possible to share links containing either of these aliases or to specific versions, i.e, the following are all valid links: - -- https://eest.ethereum.org/ (redirects to latest/main) -- https://eest.ethereum.org/latest (redirects to main) -- https://eest.ethereum.org/development (redirects main) -- https://eest.ethereum.org/main -- https://eest.ethereum.org/v1.0.0 - -### CI/CD: Doc Deployment via Github Actions - -There are two workflows that automatically deploy updated/new versions of the docs: - -| Workflow `yaml` File | What | When | -|----------------------|------|------| -| `docs_main.yaml` | Update "main" version of docs | Push to 'main' branch, (e.g., on PR merge) | -| `docs_tags.yaml` | Deploy new version of docs; tag is used as version name | Upon creating a tag matching `v*` | - -### Build and Deployment (without alias update) - -Build a new version and deploy it to remote (this version will then show up in the version selector list): - -```console -uv run mike deploy -rebase --push v1.2.3 -``` - -!!! note "Local deployment" - If you deploy locally, the documentation will be built with any changes made in your local repository. Check out the tag to deploy tagged versions. - -### Build, Deploy and Update the Alias - -Build, deploy and update the version an alias points to with: - -```console -uv run mike deploy --rebase --push --update-aliases v1.2.3 latest -``` - -where `v1.2.3` indicates the version's name and `development` is the alias. This will overwrite the version if it already exists. - -!!! note "Updating the 'main' version locally" - "main" is just a version name (intended to reflect that it is build from the main branch). However, `mike` will build the docs site from the current local repository state (including local modifications). Therefore, make sure you're on the HEAD of the main branch before executing (unless you know what you're doing :wink:)! - - ```console - uv run mike deploy --rebase --push main - ``` - - If the alias accidentally go change: - - ```console - uv run mike deploy --rebase --push --update-aliases main development - ``` - -### Viewing and Deleting Versions - -List versions: - -```console -uv run mike list -``` - -Delete a version: - -```console -uv run mike delete v1.2.3a1 -``` - -### Set Default Version - -Set the default version of the docs to open upon loading the page: - -```console -uv run mike set-default --push latest -``` - -Typically, this must only be executed once for a repo. - ## Implementation ### Plugins @@ -174,7 +85,3 @@ All pages that are to be included in the documentation and the navigation bar mu - `navigation-post-test-case-reference.md`, and create an arbitrary ordering in the Test Case Reference doc gen script. But this is untested. - -## Read the Docs - -Originally, before June 2023, documentation was hosted at readthedocs.io. Currently, this page no longer exists (execution-spec-tests.readthedocs.io). diff --git a/docs/dev/documenting_clis.md b/docs/dev/documenting_clis.md index f7d3e382d71..18fe63ab7e4 100644 --- a/docs/dev/documenting_clis.md +++ b/docs/dev/documenting_clis.md @@ -7,4 +7,4 @@ Current limitations: 1. `mkdocs serve` does not automatically update the CLI documentation when the source code changes. You must restart the server to see the changes. 2. `mkdocs-click` does not automatically generate a short help string from sub-command docstrings. You must provide a short help string for each sub-command in the source code with `@click.command(short_help="...")`. -See the [markdown](https://github.com/ethereum/execution-spec-tests/blob/main/docs/library/cli/evm_bytes.md) and corresponding [Python docstrings](https://github.com/ethereum/execution-spec-tests/blob/main/src/cli/evm_bytes.py) for the [`evm_bytes` CLI documentation](../library/cli/evm_bytes.md) as an example of how to document a CLI using `mkdocs-click`. +See the [markdown](https://github.com/ethereum/execution-specs/blob/a48e0b381d5225a6c3de2d06cd9ee7ae0b6ca9bb/docs/library/cli/evm_bytes.md) and corresponding [Python docstrings](https://github.com/danceratopz/execution-specs/blob/ca2b3b18a5d4058b2e2fd517ba7db31e86919a09/packages/testing/src/execution_testing/cli/evm_bytes.py) for the [`evm_bytes` CLI documentation](../library/cli/evm_bytes.md) as an example of how to document a CLI using `mkdocs-click`. diff --git a/docs/dev/index.md b/docs/dev/index.md index d7fe93286d6..f347d317b10 100644 --- a/docs/dev/index.md +++ b/docs/dev/index.md @@ -1,16 +1,14 @@ # Developer Documentation -This documentation is aimed at `execution-spec-tests` developers: +This documentation is aimed at `execution-specs` developers: - [Managing configurations](./configurations.md): Instructions for setting up and modifying test configurations. - [Interactive usage](./interactive_usage.md): Guide on interactive use of EEST packages using `ipython`. - [Documenting CLI commands](./documenting_clis.md): Instructions for documenting command line interfaces (CLIs). -- [Coding style](./coding_style.md): Standards and best practices for code formatting and to maintain consistency across the repository. - [Logging](./logging.md): Documentation on using the custom logging system with enhanced features. -- [Enabling pre-commit checks](./precommit.md): A guide for setting up pre-commit hooks to enforce code quality before commits. - [Running github actions locally](./test_actions_locally.md): Instructions for testing GitHub Actions workflows on your local machine to streamline development and debugging. -These sections are primarily aimed at `execution-spec-tests` maintainers: +These sections are primarily aimed at `execution-specs` maintainers: - [Generating documentation](./docs.md): Steps to create and build documentation and manage documentation versions. -- [Managing dependencies and packaging](./deps_and_packaging.md): How to update EEST dependencies. +- [Managing dependencies and packaging](./deps_and_packaging.md): How to manage the specs and testing package dependencies. diff --git a/docs/dev/precommit.md b/docs/dev/precommit.md deleted file mode 100644 index 3b8af55539d..00000000000 --- a/docs/dev/precommit.md +++ /dev/null @@ -1,16 +0,0 @@ -# Enabling Pre-Commit Checks - -There's a [pre-commit](https://pre-commit.com/) config file available in the repository root (`.pre-commit-config.yaml`) that can be used to enable automatic checks upon commit - the commit will not go through if the checks don't pass. - -To enable pre-commit, the following must be run once: - -```console -uvx pre-commit install -``` - -!!! note "Bypassing pre-commit checks" - Enabling of pre-commit checks is not mandatory (it cannot be enforced) and even if it is enabled, it can always be bypassed with: - - ```console - git commit --no-verify - ``` diff --git a/docs/filling_tests/debugging_t8n_tools.md b/docs/filling_tests/debugging_t8n_tools.md index 76960b45909..2352bec641d 100644 --- a/docs/filling_tests/debugging_t8n_tools.md +++ b/docs/filling_tests/debugging_t8n_tools.md @@ -1,6 +1,6 @@ # Debugging Transition Tools -There are two flags that can help debugging `t8n` tools or the execution-spec-tests framework: +There are two flags that can help debugging `t8n` tools or the execution-testing framework: 1. `--evm-dump-dir`: Write debug information from `t8n` tool calls to the specified directory. 2. `--traces`: Collect traces of the execution from the transition tool. diff --git a/docs/filling_tests/filling_tests_command_line.md b/docs/filling_tests/filling_tests_command_line.md index 25be31804da..50bba2986e3 100644 --- a/docs/filling_tests/filling_tests_command_line.md +++ b/docs/filling_tests/filling_tests_command_line.md @@ -1,8 +1,8 @@ # Filling Tests at a Prompt -The execution-spec-tests test framework uses the [pytest framework](https://docs.pytest.org/en/latest/) for test case collection and execution. The `fill` command is essentially an alias for `pytest`, which uses several [custom pytest plugins](../library/pytest_plugins/index.md) to run transition tools against test cases and generate JSON fixtures. +The execution-testing framework uses the [pytest framework](https://docs.pytest.org/en/latest/) for test case collection and execution. The `fill` command is essentially an alias for `pytest`, which uses several [custom pytest plugins](../library/pytest_plugins/index.md) to run transition tools against test cases and generate JSON fixtures. -!!! note "Options specific to execution-spec-tests" +!!! note "Options specific to execution-testing" The command-line options specific to filling tests can be listed via: ```console diff --git a/docs/filling_tests/filling_tests_dev_fork.md b/docs/filling_tests/filling_tests_dev_fork.md index 6217ed032a2..4bf56f7e68f 100644 --- a/docs/filling_tests/filling_tests_dev_fork.md +++ b/docs/filling_tests/filling_tests_dev_fork.md @@ -2,7 +2,7 @@ ## Requirements -By default, execution-spec-tests only generates fixtures for forks that have been deployed to mainnet. In order to generate fixtures for evm features that are actively under development: +By default, the execution-testing framework only generates fixtures for forks that have been deployed to mainnet. In order to generate fixtures for evm features that are actively under development: 1. A version of the `evm` and `solc` tools that implement the feature must be available (although, typically only a developer version of the `evm` tool is required, usually the latest stable release of `solc` is adequate), and, 2. The development fork to test must be explicitly specified on the command-line: @@ -42,7 +42,3 @@ By default, execution-spec-tests only generates fixtures for forks that have bee
![Screenshot of pytest test collection console output](./img/pytest_run_example.png){align=center}
- -## VS Code Setup - -By default, VS Code's Testing View will only show tests for stable forks. To show tests for development forks, uncomment the relevant line in the `python.testing.pytestArgs` configuration section of included settings file (`.vscode/settings.json`) to enable the `--until=FORK` flag. See [VS Code Setup](../getting_started/setup_vs_code.md) for help finding the settings files. diff --git a/docs/filling_tests/filling_tests_vs_code.md b/docs/filling_tests/filling_tests_vs_code.md deleted file mode 100644 index bf04ef90d95..00000000000 --- a/docs/filling_tests/filling_tests_vs_code.md +++ /dev/null @@ -1,20 +0,0 @@ -# Filling Tests in VS Code - -Prerequisite: [VS Code Setup](../getting_started/setup_vs_code.md). - -## Exploring Test Cases - -Implemented test cases can be explored in VS Code's "Testing" View; click on the conical flask highlighted in the screenshot below. - -
- ![VS Code Testing Tab](./img/vs_code_exploring_tests.png){ width=auto align=center} -
- -!!! note "Testing EVM Features Under Active Development" - See [the VS Code section](./filling_tests_dev_fork.md#vs-code-setup) in [Filling Tests for Features under Development](./filling_tests_dev_fork.md) to explore tests targeting EVM features under development. - -## Filling and Debugging Test Cases - -
- ![VS Code Testing Tab](./img/vs_code_executing_tests.png){ width=auto align=center} -
diff --git a/docs/filling_tests/getting_started.md b/docs/filling_tests/getting_started.md index a9e39715b15..a96187e22f7 100644 --- a/docs/filling_tests/getting_started.md +++ b/docs/filling_tests/getting_started.md @@ -53,5 +53,4 @@ This guide describes how to get started with `fill` and commonly-used command-li 1. Learn [useful command-line flags](./filling_tests_command_line.md). 2. [Execute tests for features under development](./filling_tests_dev_fork.md) via the `--fork` flag. -3. _Optional:_ [Configure VS Code](../getting_started/setup_vs_code.md) to auto-format Python code and [execute tests within VS Code](./filling_tests_vs_code.md#filling-and-debugging-test-cases). -4. Implement a new test case, see [Writing Tests](../writing_tests/index.md). +3. Implement a new test case, see [Writing Tests](../writing_tests/index.md). diff --git a/docs/filling_tests/index.md b/docs/filling_tests/index.md index 213b3049d75..631c62106fc 100644 --- a/docs/filling_tests/index.md +++ b/docs/filling_tests/index.md @@ -28,11 +28,3 @@ The "fill-consume" method follows a differential testing approach: A reference i Some tests cases, particularly those without straightforward post-checks, such as certain gas calculations, may allow subtle inconsistencies to slip through during filling. **Consequently, filling the tests does not ensure the client’s correctness. Clients must consume the tests to be considered correctly tested, even if that client was used to fill the tests.** - -## Filling Static Tests from [ethereum/tests](https://github.com/ethereum/tests) - -Filling static test fillers in YAML or JSON formats from [ethereum/tests](https://github.com/ethereum/tests/tree/develop/src) is possible by adding the `--fill-static-tests` to the `fill` command. - -This functionality is only available for backwards compatibility and copying legacy tests from the [ethereum/tests](https://github.com/ethereum/tests) repository into this one. - -Adding new static test fillers is otherwise not allowed. diff --git a/docs/filling_tests/transition_tool_support.md b/docs/filling_tests/transition_tool_support.md index 48e26291adf..6049c37b436 100644 --- a/docs/filling_tests/transition_tool_support.md +++ b/docs/filling_tests/transition_tool_support.md @@ -5,7 +5,7 @@ The following transition tools are supported by the framework: | Client | `t8n` Tool | Tracing Support | | -------| ---------- | --------------- | | [ethereum/evmone](https://github.com/ethereum/evmone) | `evmone-t8n` | Yes | -| [ethereum/execution-specs](https://github.com/ethereum/execution-specs) | [`ethereum-spec-evm-resolver`](https://github.com/petertdavies/ethereum-spec-evm-resolver) | Yes | +| [ethereum/execution-specs](https://github.com/ethereum/execution-specs) | [`ethereum-spec-evm t8n`](https://github.com/ethereum/execution-specs/tree/a48e0b381d5225a6c3de2d06cd9ee7ae0b6ca9bb/src/ethereum_spec_tools/evm_tools/t8n) | Yes | | [ethereumjs](https://github.com/ethereumjs/ethereumjs-monorepo) | [`ethereumjs-t8ntool.sh`](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/vm/test/t8n) | No | | [ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) | [`evm t8n`](https://github.com/ethereum/go-ethereum/tree/master/cmd/evm) | Yes | | [hyperledger/besu](https://github.com/hyperledger/besu/tree/main/ethereum/evmtool) | [`evmtool t8n-server`](https://github.com/hyperledger/besu/tree/main/ethereum/evmtool) | Yes | diff --git a/docs/getting_started/code_standards.md b/docs/getting_started/code_standards.md index a1265aee339..189b1809573 100644 --- a/docs/getting_started/code_standards.md +++ b/docs/getting_started/code_standards.md @@ -1,50 +1,23 @@ # Code Standards -This document outlines the coding standards and practices used in the @ethereum/execution-spec-tests repository. - -## Code and CI Requirements - -Code pushed to @ethereum/execution-spec-tests must pass the CI checks. Run `just` to see all available recipes, grouped by category. The most common checks: +This page outlines the code standards used in @ethereum/execution-specs. Many of the following preferences are enforced in CI via static code checks which can be ran locally via: ```console -just static # Run all static checks (lint, format, mypy, spellcheck, ...) -just fix # Auto-fix formatting and lint issues +just static ``` -!!! important "Avoid CI surprises - Use pre-commit hooks!" - **We strongly encourage all contributors to install and use pre-commit hooks!** This will run fast checks (lint, typecheck, spellcheck) automatically before each commit, helping you catch issues early and avoid frustrating CI failures after pushing your changes. - - Install with one simple command: - ```console - uvx pre-commit install - ``` - - This saves you time by catching formatting issues, type errors, and spelling mistakes before they reach CI. - -!!! tip "Lint & code formatting: Using `ruff` and VS Code to help autoformat and fix module imports" - - On the command-line, solve fixable issues with: - - ```console - just fix - ``` - - Use VS Code, see [VS Code Setup](../getting_started/setup_vs_code.md), to autoformat code, automatically organize Python module imports and highlight typechecking and spelling issues. - -!!! hint "Typechecking" - - Adding the correct typehints can sometimes be tricky and there are exceptions that require manually disabling typechecking on a per-line basis. Please reach out to the maintainers if you need help, either [directly](../getting_started/getting_help.md) or in a PR. +See [Verifying Changes](verifying_changes.md) for more details on running checks locally and ensuring that your code passes CI checks. ## Python Coding Preferences -- **Line Length**: 100 characters maximum. -- **Formatting**: Enforced by `ruff` (similar to `black`). -- **Documentation**: All public functions and classes should have docstrings +- **Line Length**: 79 characters maximum. +- **Formatting**: Enforced by `ruff` (similar to `black`). Run `just fix` to format code via `ruff`. +- **Documentation**: All public functions and classes should have docstrings: - Docstrings should have a good one-line summary which uses the imperative ("Return" not "Returns"). - Add a blank line after the summary for multi-line docstrings. - Single-line docstrings should have triple quotes on the same line. - **Imports**: Use explicit imports (no `from module import *`). -- **Relative Imports**: Use relative imports within the same package +- **Relative Imports**: Use relative imports within the same package. - **Error Handling**: Use explicit exception types and meaningful error messages. - **Type Hints**: All functions should include type annotations. - **Unused Function Arguments**: When unavoidable, use `del`, e.g., `del unused_var`, at function start to avoid flagging linter errors. @@ -55,15 +28,14 @@ just fix # Auto-fix formatting and lint issues - **File Paths**: Strongly prefer `pathlib` over `os.path` for file system operations. - **Retry Logic**: Use [`tenacity`](https://github.com/jd/tenacity) library for handling flaky network connections and transient failures. -## Editor Setup +## Testing Framework Plugins with Pytester + +Use pytest's `pytester` fixture when writing tests for our pytest plugins and CLI commands. -A correctly configured editor will automatically handle most formatting requirements. See [VS Code Setup](./setup_vs_code.md) for recommended settings. +`runpytest()` is the default. It runs the inner session in-process, is fast, and gives access to helpers like `assert_outcomes()` and `fnmatch_lines()`. -## Detailed Information +`runpytest_subprocess()` runs the inner session in a separate process. Use it only when in-process mode causes state leakage (e.g., Pydantic `ModelMetaclass` cache pollution or global mutation in `pytest_configure`). Subprocess isolation masks these bugs rather than fixing them, so prefer fixing the root cause and use subprocess mode as defense-in-depth. -See the [Detailed Code Standards](code_standards_details.md) page for more information on: +Don't use raw `subprocess.run()` in pytester-based tests. If you need process isolation, use `runpytest_subprocess()`. -- Additional required [dependencies for markdownlint](code_standards_details.md#additional-dependencies). -- [Pre-commit hooks setup](code_standards_details.md#pre-commit-hooks). -- [Verifying test fixture changes](code_standards_details.md#verifying-fixture-changes). -- [Ignoring bulk change commits](code_standards_details.md#ignoring-bulk-change-commits) in `git blame`. +Both methods return a `RunResult` with `.ret`, `.outlines`, `.errlines`, `assert_outcomes()`, and `fnmatch_lines()`. When the inner test is expected to fail, use `capsys.readouterr()` after `runpytest_subprocess()` to suppress the inner failure output that pytester replays to stdout. diff --git a/docs/getting_started/code_standards_details.md b/docs/getting_started/code_standards_details.md deleted file mode 100644 index 98739b18326..00000000000 --- a/docs/getting_started/code_standards_details.md +++ /dev/null @@ -1,135 +0,0 @@ -# Detailed Code Standards - -This page provides in-depth information about the code standards and verification processes in @ethereum/execution-spec-tests. - -## Running Checks - -Run all static checks: - -```console -just static -``` - -Run `just` to list all available recipes. Individual checks can be run directly, for example: - -```console -just lint -just typecheck -just spellcheck -``` - -### Additional Dependencies - -Some checks require external (non-Python) packages: - -#### For `spellcheck` - -The spellcheck environment uses **codespell**, which is automatically installed via Python dependencies and checks for common spelling mistakes in code and documentation. - -To fix spelling errors found by codespell: - -```console -uv run codespell --write-changes -``` - -!!! note "VS Code Integration" - The `whitelist.txt` file is still maintained for the VS Code cSpell extension, which provides real-time spell checking in the editor. - -#### For `markdownlint` - -```console -sudo apt install nodejs -sudo npm install -g markdownlint-cli2@0.17.2 # the version used in ci -``` - -Or use a specific node version using `nvm`. - -## Pre-commit Hooks - -Certain checks can be run automatically as git pre-commit hooks to ensure that your changes meet the project's standards before committing. - -### Installation - -```console -uvx pre-commit install -``` - -For more information, see [Pre-commit Hooks Documentation](../dev/precommit.md). - -## Testing Framework Plugins with Pytester - -Use pytest's `pytester` fixture when writing tests for our pytest plugins and CLI commands. - -`runpytest()` is the default. It runs the inner session in-process, is fast, and gives access to helpers like `assert_outcomes()` and `fnmatch_lines()`. - -`runpytest_subprocess()` runs the inner session in a separate process. Use it only when in-process mode causes state leakage (e.g., Pydantic `ModelMetaclass` cache pollution or global mutation in `pytest_configure`). Subprocess isolation masks these bugs rather than fixing them, so prefer fixing the root cause and use subprocess mode as defense-in-depth. - -Don't use raw `subprocess.run()` in pytester-based tests. If you need process isolation, use `runpytest_subprocess()`. - -Both methods return a `RunResult` with `.ret`, `.outlines`, `.errlines`, `assert_outcomes()`, and `fnmatch_lines()`. When the inner test is expected to fail, use `capsys.readouterr()` after `runpytest_subprocess()` to suppress the inner failure output that pytester replays to stdout. - -## Building and Verifying Docs Locally - -Build the full HTML documentation: - -```console -just docs -``` - -For faster iteration (skips the "[Test Case Reference](https://eest.ethereum.org/main/tests/)" section): - -```console -just docs-fast -``` - -## Verifying Fixture Changes - -When writing a PR that modifies either the framework or test cases, verify that changes don't cause issues with existing test cases. - -All filled fixtures contain a `hash` field in the `_info` object, which is used to verify that the fixture hasn't changed. - -### Using the Hasher Tool - -The `hasher` command can be used to bulk-verify the hashes of fixtures in a directory. - -| Flag | Description | -| ---------------- | ----------------------------------------------------------------- | -| `--files` / `-f` | Prints a combined hash per JSON fixture file. | -| `--tests` / `-t` | Prints the hash of every test vector in JSON fixture files. | -| `--root` / `-r` | Prints a combined hash for all JSON fixture files in a directory. | - -For a quick comparison between two fixture directories: - -```console -hasher --root fixtures/ -hasher --root fixtures_new/ -``` - -To identify which files are different: - -```console -diff <(hasher --files fixtures/) <(hasher --files fixtures_new/) -``` - -For a granular comparison: - -```console -diff <(hasher --tests fixtures/) <(hasher --tests fixtures_new/) -``` - -#### The `compare` Subcommand - -The `hasher compare` subcommand directly compares two fixture directories -and shows only the differences: - -```console -uv run hasher compare fixtures/ fixtures_new/ -``` - -| Flag | Description | -| ------------------- | --------------------------------------------------------- | -| `--depth N` / `-d` | Limit to N levels (0=root, 1=folders, 2=files, 3=tests). | -| `--files` / `-f` | Show differences at file level. | -| `--tests` / `-t` | Show differences at individual test level. | -| `--root` / `-r` | Show only the root-level hash difference. | -| `--ignore-missing` | Hide entries that exist in only one directory. | diff --git a/docs/getting_started/getting_help.md b/docs/getting_started/getting_help.md index 8e370fb6b49..78bea4c7120 100644 --- a/docs/getting_started/getting_help.md +++ b/docs/getting_started/getting_help.md @@ -1,12 +1,12 @@ # Getting Help -The tests in this repository are a community effort to help improve the development cycle of all Ethereum execution clients. +The work in this repository is a community effort to help improve Ethereum's fork cadence and the development cycle of all Ethereum execution clients. -We encourage contributions and recognize that Python is not everyone's primary language - if you stumble over issues or need help, please reach out to one of the execution-spec-tests maintainers either directly or in the `#el-testing` channel in the [Ethereum R&D Discord Server](https://discord.com/invite/qGpsxSA). +We encourage contributions and recognize that Python is not everyone's primary language - if you stumble over issues or need help, please reach out to one of the execution-specs maintainers either directly or in the `#el-testing` channel in the [Ethereum R&D Discord Server](https://discord.com/invite/qGpsxSA). -## Contact the Maintainers +## Contact STEEL -Write to: +Feel free to contact any [STEEL team member](https://steel.ethereum.foundation/team/): - Dan on [Discord](https://discordapp.com/users/danceratopz) or [Telegram](https://t.me/danceratopz) (`danceratopz`). - Spencer on [Discord](https://discordapp.com/users/spencertaylorbrown) or [Telegram](https://t.me/spencertb) (`spencertaylorbrown`/`@techbro_ccoli`). diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index 95e7cb33636..10524ae291d 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -1,12 +1,40 @@ # Installation -## Prerequisites +## Quick Start -The tools provided by [execution-spec-tests](https://github.com/ethereum/execution-spec-tests) use `uv` ([docs.astral.sh/uv](https://docs.astral.sh/uv/)) to manage their dependencies and virtual environment. +=== "All platforms" -It's typically recommended to use the latest version of `uv`, currently `uv>=0.7.0` is required. + ```console + git clone https://github.com/ethereum/execution-specs + cd execution-specs + curl -LsSf https://astral.sh/uv/install.sh | sh + uv python install 3.12 + uv python pin 3.12 + uv sync + uv tool install --exclude-newer "10 days" rust-just + just shell-completions + ``` -The latest version of `uv` can be installed via `curl` (recommended; can self-update via `uv self update`) or pip (requires Python, can't self-update): +=== "macOS" + + ```console + git clone https://github.com/ethereum/execution-specs + cd execution-specs + curl -LsSf https://astral.sh/uv/install.sh | sh + uv python install 3.12 + uv python pin 3.12 + uv sync + brew install just + just shell-completions + ``` + +Further explanation, troubleshooting, and alternative installation paths are below. + +## Prerequisites + +The tools provided by [execution-specs](https://github.com/ethereum/execution-specs) use `uv` ([docs.astral.sh/uv](https://docs.astral.sh/uv/)) to manage dependencies and the virtual environment. + +It's recommended to use the latest version of `uv`, which can be installed via `curl` (recommended; can self-update via `uv self update`) or pip (requires Python, can't self-update): === "curl" @@ -20,24 +48,78 @@ The latest version of `uv` can be installed via `curl` (recommended; can self-up pip install uv ``` -If installed via `curl`, `uv` will download Python for your target platform if one of the required versions (Python 3.11 or 3.12) is not available natively. +When installed via `curl`, `uv` can also download Python for your platform if a required version (Python 3.11–3.14) is not already installed. + +## Installing Python and Python Dependencies -## Installation Commands +Clone @ethereum/execution-specs and install the project dependencies. We recommend using Python 3.12 for the simplest local development setup. -Clone [execution-spec-tests](https://github.com/ethereum/execution-spec-tests) and install its dependencies. We recommend using Python 3.12, the following uses `uv` to download and configures 3.12 to be the Python version used in execution-spec-tests: +The following commands use `uv` to install Python 3.12 and pin it for all commands run within the execution-specs directory: === "All platforms" ```console - git clone --depth 1 https://github.com/ethereum/execution-spec-tests - cd execution-spec-tests + git clone https://github.com/ethereum/execution-specs + cd execution-specs uv python install 3.12 uv python pin 3.12 uv sync ``` -Static tests/maintainers only: To learn how to build the `solc` binary from source (optional) follow [this guide](./installation_troubleshooting.md#problem-exception-failed-to-compile-yul-source). +### Testing Your Python Environment + +The following command can be used to verify that the environment is set up correctly. By targeting a single test subdirectory, it generates only a small subset of test vectors: + +```console +uv run fill tests/istanbul/eip1344_chainid/ +``` + +## Installing the `just` Task Runner + +The @ethereum/execution-specs repository uses [`just`](https://just.systems/man/en/introduction.html) to run common tasks locally and in CI. Tasks range from static code checks to generating test vectors from the spec. + +@ethereum/execution-specs requires `just` 1.43+. Note that the version currently distributed in Ubuntu 24.04 is too old; many other methods are available in the [installation docs](https://just.systems/man/en/packages.html). + +`just` can be installed directly with `uv` from the [`rust-just` package](https://pypi.org/project/rust-just/). + +=== "All platforms" + + ```console + uv tool install --exclude-newer "10 days" rust-just + ``` + + Using `--exclude-newer` adds a cool-down window that can help reduce exposure to supply-chain attacks. + +=== "macOS" + + ```console + brew install just + ``` + +### Testing Your `just` Installation + +To explore which tasks (recipes) are available, simply run `just` within the `execution-specs` directory: + +```console +just +``` + +Then try running the available static code checks: + +```console +just static +``` + +### Configuring Shell Completion + +`just` supports tab completion for recipes. Run the following command for help on how to enable this feature for your shell: + +```console +just shell-completions +``` + +More background is available in the [`just` documentation](https://just.systems/man/en/shell-completion-scripts.html). ## Installation Troubleshooting -If you encounter issues during installation, see the [Installation Troubleshooting](./installation_troubleshooting.md) guide. +If you run into problems, see [Installation Troubleshooting](./installation_troubleshooting.md). diff --git a/docs/getting_started/installation_troubleshooting.md b/docs/getting_started/installation_troubleshooting.md index 032761ee3bd..e405b385779 100644 --- a/docs/getting_started/installation_troubleshooting.md +++ b/docs/getting_started/installation_troubleshooting.md @@ -1,6 +1,6 @@ # Installation Troubleshooting -This page provides guidance on how to troubleshoot common issues that may arise when installing [ethereum/execution-spec-tests](https://github.com/ethereum/execution-spec-tests). +This page provides guidance on how to troubleshoot common issues that may arise when installing [ethereum/execution-specs](https://github.com/ethereum/execution-specs). ## Problem: `Failed building wheel for coincurve` @@ -77,9 +77,9 @@ This page provides guidance on how to troubleshoot common issues that may arise sudo apt install build-essential libboost-all-dev z3 cmake .. make - mv $HOME/Documents/execution-spec-tests/.venv/bin/solc $HOME/Documents/execution-spec-tests/.venv/bin/solc-x86-64 - cp ./solc/solc $HOME/Documents/execution-spec-tests/.venv/bin/ - chmod +x $HOME/Documents/execution-spec-tests/.venv/bin/solc + mv $HOME/Documents/execution-specs/.venv/bin/solc $HOME/Documents/execution-specs/.venv/bin/solc-x86-64 + cp ./solc/solc $HOME/Documents/execution-specs/.venv/bin/ + chmod +x $HOME/Documents/execution-specs/.venv/bin/solc ``` Running `uv run solc --version` should now return the expected version. @@ -140,7 +140,7 @@ This page provides guidance on how to troubleshoot common issues that may arise If you're facing an issue that's not listed here, you can easily report it on GitHub for resolution. -[Click here to report a documentation issue related to installation](https://github.com/ethereum/execution-spec-tests/issues/new?title=docs(bug):%20unable%20to%20install%20eest%20with%20error%20...&labels=scope:docs,type:bug&body=%3Ccopy-paste%20command%20that%20triggered%20the%20issue%20here%3E%0A%3Ccopy-paste%20output%20or%20attach%20screenshot%20here%3E) +[Click here to report a documentation issue related to installation](https://github.com/ethereum/execution-specs/issues/new?title=Setting%20up%20execution-specs%20failed%20with%20error%20...&labels=A-doc,C-bug&body=%3Ccopy-paste%20command%20that%20triggered%20the%20issue%20here%3E%0A%3Ccopy-paste%20output%20or%20attach%20screenshot%20here%3E) Please include the following details in your report: diff --git a/docs/getting_started/repository_overview.md b/docs/getting_started/repository_overview.md index ff08e51f135..260052099a2 100644 --- a/docs/getting_started/repository_overview.md +++ b/docs/getting_started/repository_overview.md @@ -5,41 +5,41 @@ The most relevant folders and files in the repo are: ```text 📁 execution-specs/ -├─╴📁 tests/ # test cases organized by fork +├─╴📁 src/ # EELS - the execution layer specs +│ ├── 📁 ethereum/ +│ │ └── 📁 forks/ +│ │ ├── 📁 amsterdam/ +| | ├── 📁 berlin/ +│ │ └── 📁 ... +│ └── 📁 ethereum/forks/... +├─╴📁 tests/ # Test cases for EELS organized by fork │ ├── 📁 amsterdam/ -│ ├── 📁 osaka/ -│ ├── 📁 prague/ -│ └── 📁 ... -├─╴📁 fixtures/ # default fixture output dir -│ ├── 📁 blockchain_tests/ -│ ├── 📁 blockchain_tests_engine/ -│ ├── 📁 state_tests/ +│ ├── 📁 berlin/ │ └── 📁 ... -├─╴📁 packages/ # library & framework packages +├─╴📁 packages/ # Test generation library & framework packages │ └── 📁 testing/ │ └── 📁 src/ │ └── 📁 execution_testing/ -├─╴📁 src/ # execution spec packages -│ ├── 📁 ethereum/ -│ └── 📁 ... -├─╴📁 docs/ # markdown documentation +├─╴📁 docs/ # Markdown documentation │ ├── 📁 getting_started/ -│ ├── 📁 dev/ +│ ├── 📁 writing_tests/ │ └── 📁 ... -└── 📄 whitelist.txt # spellcheck dictionary +├── 📄 Justfile # Task runner config, run `just` to see tasks +├── 📄 uv.lock # Defines pinned project Python dependencies +└── 📄 whitelist.txt # Spellcheck dictionary ``` -#### `tests/` +#### `src/` -Contains the implementation of the Ethereum consensus tests available in this repository, organized by fork. +Contains the Ethereum Execution Layer Specs, each fork is a sub-package. -#### `packages/` +#### `tests/` -Contains the `execution_testing` package which provides tools to define test cases and to interface with the `evm t8n` command. Additionally, it contains packages that enable test case execution by customizing pytest which acts as the test framework. +Contains the implementation of the Ethereum consensus tests available in this repository, organized by the fork in which the functionality was introduced. -#### `src/` +#### `packages/execution_testing/` -Contains the Ethereum execution spec packages. +Contains the `execution_testing` package which provides tools to define test cases and to interface with `t8n` command interfaces that are required to generate tests. Additionally, it contains packages that enable test case execution by customizing pytest which acts as the test framework. #### `docs/` diff --git a/docs/getting_started/setup_vs_code.md b/docs/getting_started/setup_vs_code.md deleted file mode 100644 index 3b122fc9e6b..00000000000 --- a/docs/getting_started/setup_vs_code.md +++ /dev/null @@ -1,52 +0,0 @@ -# VS Code Setup - -VS Code setup is optional, but does offer the following advantages: - -- Auto-format your Python code to conform to the repository's [code standards](../writing_tests/code_standards.md) ([ruff](https://docs.astral.sh/ruff/)). -- Inline linting and auto-completion (thanks to Python type hints). -- Spell-check your code and docs. -- Graphical exploration of test cases and easy test execution/debug. - -## Installation - -Please refer to the [Visual Studio Code docs](https://code.visualstudio.com/docs/setup/setup-overview) for help with installation. - -## VS Code Settings file - -The [ethereum/execution-spec-tests](https://github.com/ethereum/execution-spec-tests) repo includes configuration files for VS Code in the `.vscode/` sub-directory: - -```text -📁 execution-test-specs/ -└──📁 .vscode/ - ├── 📄 settings.json - ├── 📄 extensions.json - └── 📄 launch.recommended.json -``` - -By default, the repository settings are applied via `.vscode/settings.json`. - -To enable the recommended launch configurations (that include some useful debugging configurations), copy the recommended launch configuration file to `.vscode/launch.json`: - -```console -cp .vscode/launch.recommended.json .vscode/launch.json -``` - -## VS Code Extension Configuration - -The extensions listed in `.vscode/extensions.json` are required for a smooth developer experience. - -1. Open the root folder of your local `execution-spec-tests` clone in VS Code, it will prompt you to install the repository's required extensions (from `.vscode/extensions.json` - you will be required to trust the `executions-spec-tests` repository first). These extensions are used to format, lint, type check and run tests on the codebase. After all the required extensions are installed a VS Code reload will be required. - -2. If previously installed, ensure that the following `ms-python` extensions are disabled for the `execution-spec-tests` workspace to ensure there are no conflicts with the `ruff` formatter. In the VS Code Extensions tab, search for the each of the extensions below, and if installed and enabled, open the "Disabled" menu and select "Disable (Workspace)". This ensures that the extensions will be available with other workspaces that may need them. - - - [`ms-python.isort`](https://marketplace.visualstudio.com/items?itemName=ms-python.isort) - - [`ms-python.flake8`](https://marketplace.visualstudio.com/items?itemName=ms-python.flake8) - - [`ms-python.black-formatter`](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter) - -
- ![Disabling extensions for the current workspace](./img/vscode_extension_disable_for_workspace.png){width=auto align=center} -
- -## Configuration for Testing EVM Features Under Active Development - -An additional step is required to enable fixture generations for features from forks that are under active development and have not been deployed to mainnet, see [Filling Tests for Features under Development](../filling_tests/filling_tests_dev_fork.md#vs-code-setup). diff --git a/docs/getting_started/verifying_changes.md b/docs/getting_started/verifying_changes.md new file mode 100644 index 00000000000..7bbe5e7d427 --- /dev/null +++ b/docs/getting_started/verifying_changes.md @@ -0,0 +1,91 @@ +# Verifying Changes + +**TL;DR:** Run `just static` before every PR, preferably before every commit. Optionally, run the extra checks from the table below that match what you changed. + +## Before You Open a PR + +Run `just` to see all available recipes grouped by category. The checks that CI runs are defined in [`.github/workflows/test.yaml`](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/.github/workflows/test.yaml) and [`.github/workflows/benchmark.yaml`](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/.github/workflows/benchmark.yaml); these files are the source of truth. + +Some CI jobs are slow. Only run the checks relevant to your change. + +| Change type | Run | Comment | +| ------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | +| Any PR (baseline) | `just static` | Lint, format, mypy, spellcheck, import isolation, workflow lint. | +| Added or modified tests | `just fill tests/path/to/new/tests` | See [Filling Tests](../filling_tests/index.md). | +| Framework changes (`packages/testing/`) | `just test-tests` | Framework unit tests. Mirrors the `test-tests` CI job. | +| Benchmark framework changes | `just test-tests-bench`, `just bench-gas`, `just bench-opcode`, `just bench-opcode-config` | Benchmark unit tests and sanity checks. Mirrors the benchmark CI workflow. | +| Markdown touched | `just lint-md` | Requires `markdownlint-cli2`; see [Linting Markdown](#linting-markdown). | +| Docs touched | `just docs` or `just docs-fast` | `docs-fast` skips the Test Case Reference section for faster iteration. | + +## `just fix` and `just static` + +`just static` is the baseline check for every PR. It runs spellcheck, lint, format check, mypy, EELS import isolation, and workflow linting. + +`just fix` auto-applies formatting and the safe subset of `ruff` lint fixes. Run it first to clear anything mechanically fixable, then run `just static` to see what's left. + +```console +just fix # Auto-fix formatting and safe ruff lint rules. +just static # Run all static checks. +``` + +## Filling New or Changed Tests + +For PRs that add or modify tests, confirm the new or changed tests fill successfully: + +```console +just fill tests/path/to/new/tests +``` + +Pass `--from ` and `--until ` to limit the fork range, mirroring the CI matrix. See [Filling Tests](../filling_tests/index.md) for the full `fill` reference. + +## Linting Markdown + +For PRs that touch markdown, run: + +```console +just lint-md +``` + +### Additional Dependencies for `markdownlint` + +We use `markdownlint-cli2` to lint documentation markdown files. This is an external (non-Python) package that must be installed separately: + +```console +sudo apt install nodejs +sudo npm install -g markdownlint-cli2@0.17.2 # The version used in CI. +``` + +Or use a specific node version via `nvm`. + +## Verifying Test Fixture Changes + +When writing a PR that modifies either the framework or test cases, verify that changes don't cause issues with existing test cases. + +All filled fixtures contain a `hash` field in the `_info` object, which is used to verify that the fixture hasn't changed. + +### Using the Hasher Tool + +The `hasher` command can be used to bulk-verify the hashes of fixtures in a directory. + +| Flag | Description | +| ---------------- | ----------------------------------------------------------------- | +| `--files` / `-f` | Prints a combined hash per JSON fixture file. | +| `--tests` / `-t` | Prints the hash of every test vector in JSON fixture files. | +| `--root` / `-r` | Prints a combined hash for all JSON fixture files in a directory. | + +#### The `compare` Subcommand + +The `hasher compare` subcommand directly compares two fixture directories +and shows only the differences: + +```console +uv run hasher compare fixtures/ fixtures_new/ +``` + +| Flag | Description | +| ------------------- | --------------------------------------------------------- | +| `--depth N` / `-d` | Limit to N levels (0=root, 1=folders, 2=files, 3=tests). | +| `--files` / `-f` | Show differences at file level. | +| `--tests` / `-t` | Show differences at individual test level. | +| `--root` / `-r` | Show only the root-level hash difference. | +| `--ignore-missing` | Hide entries that exist in only one directory. | diff --git a/docs/img/annotated-coverage.jpg b/docs/img/annotated-coverage.jpg deleted file mode 100644 index ef4a403ec344eb6b63156be08eb1d7ea2667f95d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414051 zcmeFZcR&-*)-b#Q0i{|&x(ZgB^cujQ(o{ffNJpx4>4ea1pwa{sq$9l}y(XX{z4sED zKte}J2vYqv38?p1?tAa^KHq=uXr`Q*J#*&lnNwzW`7!Wg95{GYQAH7eKmY&&{sVsO z0GyZYY#ut8Iy#z~oG^l&uzYB0&gWoiybJs>3_Jx6fQkA5H7zYQ!$JCk49AWhK791p z2_|On-w8oZZcgyOAg?ITIUZ47HK@2aR89N3@^x)nBO}|FPhJ)ktw8>75&ZZF9NJGs zeME{Jata_j1R*~J`B4k75!OIKSj*2uNk+bpf(o+##}Kfe)G=xJv-AH|{vQYaf8>B{ z?>`~uaFEtRz3$X z6wCh$@MlA2nr(BI2lFaUi(_!r>(PSo>)K_UY_UJq`}*7ibL!=;1oHMcT=i8Ctk~QS zK&lo_YYFMAJO==VwP)Ywp2WEfh{m6GwM_;f80P68facUs%s?tcqVZSjFEy%`S2qAo zOP{}V5CJf(8dHyG)f7q~_4-MfvDpeQyGV6h3_J(F9EKjdG_)R-my!oOaMD?hLT^_v z@IUpy_NJi7lki*Liw{@joQbygJKJGV3Lm-;U(|~X@(-w$4KDN(s}C@4z`t*g*hzo$ zx?U8%-AylSss7#q#~O4*y{jz5J!OsJP^AA%!bIa4e>M7vYJS)q=2CC^V|B>qGaNnu zjW(TU^vlKDYh#}9Mg7fXWKY(ZCq5H_uf!jNuJt1~my6-c<>0_SCr+VD@_=XNpTVRy zByh!Ce%Y(2`kb@=^qqr|46Ws3*LAU&{qcQr5*j!Z4TdunEzkA?z(gv&%1dyG7vH{I zo50RVPtm#2&xqdI5MGI+ir{J;(h=zVr7Fr0A-Z+_zjx{^O>#cII(-~%c<+$ z5*y7bE7f*2(_P=~yhgU(3FM>PXdg=oY_R$|YI&9Lt)_`hVb7Vn&zM8k3(Vn3-(Ugi zInLg%4?p1k0nB*uwQ|4O2^*Dt5Ny^A8)+*YL;wJc(&rv&v*A~N;mW_~*1L6K zM+{MM}u)8|0asGJhZozg*bXs6Ou!RFB26BDV%{-hWKU)PtKfoZDMbcU?Wf^#%ZGOYkAF z?11L2?EjK^koBaw7Zxo$&Ko5+yQXJ%)HlwiiT(gCH1E8a-r^~d z52?)4o|4g=SC9X;6S-bd-z_Ki8JWBu$0MjYENeN(UK;PwD$$(i?bnDbsa-!i!y6yt z^}cu|qN{>my(&O=BMEJx-a&O_N=|n{dn{C%;X$xR?5IS);_^YxXxa4jZtB~O8|2VW zL5mSUAS;laqKHg z{b~5GeVQS!y0?M{DqLIFWZ$h{OLEBzt5C98H`5r~vG4Ib*}5iV5QYqyxe@$!=XI-( z3q5(>hC3ZrsrQwv;Hr}xraDvBHWEJ;UBdnYn5LiYrI)VVN%6x5CwLjgxXQ}4dPS}K z+My)&>CCG~y2Nh2xo)n+H0gcwBW%rU-Q9cmd%w&^?26i^GtPqv9h}DV2rm~4-OvZw z+Huo6VpFXfdPl53^Ct9wiyU|ZSOI@1-kP2w6XVd}P&N9|u&C~NZA2iUy*7dR0>6))=u z$5_qFtohFhZzvhJ1bl7CY4m;&wwb(se{16~%0ytMDjLNOzcTx?I`sdMA6u_CY!HrqMkgt z9-lj<`Q_TA)LtCS$1#z0wyei@JL(@H&q~5a4dsPbmR`XIIqqw(c(}i9LzHj1_@T0w z=B0(ItZ>h3Z&KIOglDZg0IIY8y+dL(BnCLlJnOmhLFGrkX=7pUX@rHAuOTzW#^vh$q+w*DUIOxDr(Z&+{a60)`Tc9$pKJ6C!6l3GBq-OG$1?Mu2LS(5 z%p4B`JR@vL=pbodFfL7hLH*w{eGdWl>7@A@gFLC(Yk#@IY_I2M$q;!W0gw&&+5S%} zC&QOod`N?huc*A)<^Qj%DVuDtyhj15-tk|s|ExyifovVk0JRTsIAj@lalO2&z=zOs zze$8q*ANR>G;%$Z8X#Z1L2UjP8TnIVy=DFIb(;j@Mdt0!)@s_$yzdDuR#}@YB9uH~ zVbO}>Mt32LvDpm90{x_ zB4U#&TZJo59U}n98@7Dg;$k;DfC-6W*RiV-Bd-8j*2vpRvx5uPv$?ib05E{dk>-3G zE5HkR@ua-3==d<~SUN%|dK_T&QcnW_tfsNK_cb*y&p^HH_ymAm&dvlNYtcq!X>v5b z84I4{)-eRAlR35;DF6sQ9e}8}JFK^hh8tApb!!xMUv<`2i*2{ldhM|}hOR2HOX#=U zFc28FaXeKJ$mp5tt0YOKQ`6m??|i(wYFqB&-21>Fy{$!h4@(^ugzR4yN(4}eet7*+ znlh>N*?h$hz_|c=CwoK|BYer#;@Pw6ba061`?na?M7+W2`Ju{)^#~)vRTMJnC6?<> z^E4Vg@>DTA$HunLO}fYfT+Go`ZdX$IMEsNm`ITz`F({8(adXg{w?OdcjVpX~Gp}TW zfe?7kOaj1as{wK&5Y^n-GloVF3K01k(o#YF{H9f?gSZR*Kxp&H=M zNsm2-V4BCS*v5oJC%(WfI%%eVU3!)ousV8q$St_592NBT^=7QHMMsNhX9j&GM={7&nx!={~V=r&Y=)a0Cp_Ov~P`i8D%7ClEL?y7bz<@&s@w zpmkJEcGOS>=ST&Lo3;DhSS4O5wFhK!OtS}z=4ZRnkanU=Ixes?$adn)Pe5xqp4LncIw?&+IgMx-U4Zv z-x^bzgwkpV>-bB8VCWYjhi1+!UtoUbb*l+2GO-$WtKykTYGgH0S06yiYqSBNVe`wsllNG8 zB_YVKw5GWXAj_cHi>)c6Us`SO7Wyx)ZSdzEubq|A)ar&|?oWA2zrtBy;$@rDbdyq6 zpb>@>+d@obqcc*GN?dOrh<1(Wx-Tn@%%8X=>mAu;=)RP(FIWXpDfkz55CQv6F;sV} zy^Ao-FIzL43e^jc&iXcM0FAX0!5;64uoD0W?K9#*1l)_lO6s3UvI`!N2SE@!f0tGR z{#32w3;I4B53@BLTS>d-I4fU(*rl}aI-zVEZcv|byh)SP;}3if7_GGKJV{=85#(#m zR_O8r_yYij9Rei)$}qjiypY;8_eM5XaaOxx0GQo`p8#Yq60l=~_#NI{it27>-UQ&7 zvcaAjWPrkEu-)yKFnJtt?%$S!FO5H%QiVb=?=T4k*cF?t5cH| z-PS#Ot8>jwN2&%~3R+C90_{S#z#b%5?nAg5%XzlNMUm1wf&7_~v{!9fpcVk+KX3kw z_Mzjc&gVBEBrZx0)k=s?7aQ%jsG|i z$b$&N1{g`T%@A6Y3Q_VzXhWegv1HEsH5b<_Xs~h>Kyg%`){QB8Rz}$KU>cVr`x^WL zU+wBmy`4CoNP*|gnZD>5#L#p-BBW6;!LcfPzjqk*N&T_-KfCP~Nk@JF_u)AmfT)}d z!47Nn+6+~@6yM5fXfqzSPEX=r?&$FW;fc(FVSN6musXq%s1e#|i;$&@Ae2Ewd)?Mw zfx8BS@0#z5L2Yq@KyYI^IheZg?4P=)_O1eKT5%m_n~5_?8t__@Gd^VzA4p`T;b+s0 zhSgcGFiqa(*3SvxIEq67v0KJunt?2%3twOk(b4K&KVuC@=6ZE@J+}@lKv9LU+H5L{ zvus2m$4+v=F@GS8Wr?rbP}q(42N1O?-RbExDPS#cd`sE&kLe@Z4B;t}4{0~1*AG7R zk8){PJ3SlbC3rqh=N!iK)DE67?Qe;UsR{YQ5wS!E6LND6lR&@Jc?Ngs-C6{110<#E zn&|g%aX2j<{U`U}DV-#HuU+1xDWwG~7fVKe&td+SVQrT+y%_-FBxi`Xs;Gw!)NPy< zDrgzm>?r(7k_3$woM$u_$exNd^${Nc(3uXU&Yh@p*XQJ!9dx&$y4_w^LZAso;phA| zrTmPNWQgtBdRY+x)+O&!c#r#a#QhekMCM>sw)W7sPBd)CrpNJ=`(WKCBl|{FQbV$E-nf07|M8aL2Sw5u zSDa5`pz&{)x%4gvE-(C3I^V1c)sAW8W1Yei;XJ` zY{l!5zcPxvrKRu1-~&Q|{Zm%A`W%Gb2WezGEly-USxg-VD9>^ZFJLO-?7IzLU!AII zGDWnKSjFcM6n3yf@69FrElGY`KEn0qUs_6W$ccqCCFTdc%SMmflCxOeGl>9jYKv!9 zPb@9alN`Hd@dZ2>^BBW%9?Fl9n?{U1cA{Z-9SU^iSVXPVdU-dStq%w`^1i(8;E6+@ z)|6Wm+_C9jr_i&Cn{E|?wWZdEx_-o0cr`Xj^WKGYo%B@Oc}ST5xAbf!FHx7#w8`t` z`lvbi>(=-0SoJ3y`|>cB^57Oa<)C`!-ukci4_Xyn;`VMHAPX|H2kR>}%RZ~1B8xl75jI<%xccW!#{5Hh2>>7%56O1F5=r~6Ku zgJAq2ST1lKt#>xgiS6E1yZ#u$HWogi_~P9Egv9C*OlTUJ9h75 z>WrWl>c!%hGl$?GGd;KX=sA3^KbM$~Wm(agqFW>{{N z=S^(JOQrF~)>J}uH!{9ktXm0ZI0izYj2g`sHOMh2rCegFwbuX$9kdCz)IOgX>$AC@~V$>6{)3o+)6YH{t6IKM^? zD~&KeztSO3I)a|uXDi(06tgyXg&cOa$1=IlBi`Nz1mAZ=&y8PrzGZnH1K7x>7OM*+ZABRtXMA;hxOG80Csvz1d(HLt&B$;rtG5DC7-CzTnU$J%A>Ur z0B;%xPts5Z{+aXnRRve1FM%IqFKyS&hjRGgwyRnklZ4AtKUU=EXT372IQn>1>pRJT z<171pVG;c6>F;ieO+Fu@Q zQuAiL(~P^2;*S1{wUdE@{eP1z-JDMl!Q~_8i6z-a4WXo$em>LXD9%7^0Gc7s9ofO< zv;<^lXSZwzef$nk>hEGSo$Mf705G_y|FU{S$lqrWBZhHe&xL5xfE;;3$zgw8TqPo6 zfe3>vHY@Q3_yB-#DQiy27%!k-JWlLj%5fu>6hDBUwg$%bDQwCI!1g6w4&iFzfI`q& zte*a9qxv1wHrjNH*Q7ibrFao(InbOD?dbIdsNzlzhwW!{#7N2GfY`adFuD6Fwg@8D zy{!Iu-nDH&Ca@6-x@DLld63cfBCjhtTVGva{N{K*aeIuUAd6E`^IuuB1Nqwm?+y!a zp$rKK`h?3lg!GW8k@gQ?32orm^nEt87+pZ(>X<^MnDwO5moJk(=1cftXh|uPvwlfn zuC3^M!azO?2S<_Y?Oc*Vq>8H2>no++nb!=7|IK@mnLc=)varfb$9VG&v&a|g)!uc? z(Zy(b)pnE4<;0oN_*(bdVOj+x4Wg(x{HBUKV!`T8|5vv>>sRY7?_%3da`fQ&!jmG- z93JHqn2ocaU&DWEj=kHL6mQgiv1n+gdVxVBZRSR{SKv7UNk3Dt$6${OJC*T^kU-7y zdm_{J7F+P-d@+fa!r#8S4D^nXb~|LsKCqV^3a2y}{W4I$9M7NrfCTLgx(r?L-x7wEi2uli^ZX+L{I&+gJ>Y!H|G)DPfV54FAI;y}IL z6v8F$a<3uFQp8Ck``pj23?VLbZzN*cF1<(|#5H@U=Y3lU*p8Wxcd}6zpXs94;>)`u z@L?+UG3I>SzaAcOp=f62Q4Xr94d||!V8<_&=Oa$dvuzgJ2iCzg(idbZ?YY~kp}YFB z*#F(&oWt5$dXEO;0sj~H`vH?(4hoiQst;J4^yG{gS9gh0cD>WQcAT*8m19ZG@hjG5 ziXSft{VsDm7iJvJCCeR+Zm9u|Z`i`~`?P6>W%T^6wvmkRKHcorD(d+Mu+n~Qp301t{nwE^qfxBj*0>efugVpVhS>J+IKS@&^+c3kNsadF&aC%$h zV6lJ6TT*RRPJVhrvM(*weyOyvVvIKeja5#@ zW%O7_(zZ7y!z4+ms7oo0U1v~3!gu*+rNdB-XhlQsp1(aglJ@ho3f2NES<~w%&o#pf zgAqMc08{=nKHL>~Y(PTYJ$%L1k-NufRJFW1eda3^U8j>igZA@R<+hh{$W=(Gth#sQ zqlK<|loQ?E$C{!I9V=S7OQTO1-uE|XZSG&9(t5sh;7s zmiyQCZ)oRg(ACCbmwo^>8>MGnwMf=3$GF%^o-GVJ+kvs->2L~oQK^Y7J^>mKBk{uA z`Rt{9F?SXdEmiZkugz_}h-Ql_L>4am)*-0yN%Hdsqe`2pZegOjBWDpv>s?BswEZNU zV102nbb{Tx!pJdm_?_aJhXCaIwfI&W%heGwa&yz{uWN9gu^s|tGMKWV+%Vcul|hoH z%#v#pmS1mW-eKo{rvI1g#~|Vc-+GSLyXz`ZB36-O;;&xSWmC)ySM~7P`2m~~&;Qs| zToAO(Q;P~O3aA=U8)G<7UY*lgiH`fMbsV{5XEdi(DSdpHQZ~(5Kbp%lZP+p$HL2ZR zn{UU2%9eA{sv*#_ml%s27#;+gjeQ!m5ZBI@oqaftvA&(9!=xC@B<(PU04kx1hUlXmQF}cA{xU(vIlkbEmLld+<7*xyPgc7 z`R3^#Ctqx3gE2=dG&)*UZ##}sY^c^&G@Utg{Z0os16g0{PP|X}}Y#t5OWH&Y>{we)*KEWZADPe|v1uxz&8J%e7G;?mPTTaLgvJW=0Qo z4Ek*bHeZkAh-1)qCvP)mYiXTlSvt~t#-o&mJZYu1xb4x&;7d~DUsrdXpCV-OU(yO*vq2S#fupjcvn}2|G+hBU(e7xnZ>nvgnyvctVi&B zEb~(Vsyqc_hsZNevKb}sigarwRG+LHRTL5#-g@p)Cm7s)^0@X+N;^BN6E?zZxxC%# zkrMc@Pt6!PU>{c;{T?q3iMr$<#VMX@aCnYwEYYThMApB_C2Xm0_3jS4EE$&6CQlr! zD2Yyf<&;BO3K8<_MzRRJP3v4jJWKRl)z`ZC=Gy@@Wqh84N*#Z@O8W+{^h{Oslxv)G zt1I^cDpiku$Zox=OZ051jIW|e2eP?7^#%f6pHwwH#1}5EH>op_X8Y0avpE}H;Y|nr z&;Z4et?zMc)ls%ChrAk{h!g+2jNErTc^f=>BBXtnBc#}H#43ai^Y&$0EEQqzk<#x1 z0Y0EzUp&O&2Q0FTT69UeULRZ;t!z9?yG<*dpcj4rTC4i$*n56z<9Y^>hA#SY0-3(L zk_dnG@^BTDFD!9-Vfj!DCcaCZ2;09)>mEoR$9@#@Uj*O#pVb87HfKt@GVCy7?S!=#bk8s9!Ntnr-w8P zk$y95YLYlpL*V7N+&l@wD9Dt~{R-fh=#Z}5r!8I`an$hpzy_)Pf5@rWI|`-a6G)@} zfMunE4iF(hra0qtY~4$0iL;uCkfDNZ_Fl@2SXh^RV%6(Y)<7jz6{;31tfRDSo z;jsO2esMlBII3WEjw;d?__u_!@JkrXgz}Dgz%aow*!nm(Y<)0?3~aLAFPOhm1R6<_xj1t6n@^fh9)SF}-SPCmH zOZFE!jWT@I_O7WETL0!sMX7X;y6XeXtuGby*m|exE7){7mFe=>AqYhr?$Vw{l$j8$ zL8U{{{^V0DJT<&4t**-5pVFjdt)hFgzb&OzTpri+S8o$z*G8Y^ zt)1PByHgf_LW6m!J#x`KOt0By^+5~2oruzU$!3a`B-8!>K&Z*1{_r6!m3F5-W|whX zRi$*uc`f?0Y#TzQ>;ZVhGIQYSsFEX%_u#}0`X_Rd$vp4WgX4HM4q;1_?oJgxc$S;r zbkXKcVYC9yKnZ>X9W}?ZSk))qVKfvJ+w4(qa~f*+^ZvDYsx5OY%VeF+a>%xgPJ4Ro zn{hv8Yp7f#E8Iq^*CSf57iqWD5kUU}yQVXA867!f8+u>yo5+xUeCyfus_s+;Lxk@i z&mH4hQ=6wpG##HLbZu5ohb~2$zg*=vem^$VnBcH*&t;CaL&$b6=@y4~uc08vVDawC z{!Kw1U$f{#?1wlQbUN&g1fOm>UEe7!`C{Lm#N(ixX8P*ey|E4{_ABN}{DUG^~%f$R`p+L%WtS)8++;$1n(3*H;GVN%HZifrZ4vb2E05a|0jBXxhau|oo z#e41_3KTy#E7PC1!rw{lk5g8C(PnG2b9w-K;?PotUs0FCPSQS<5w4ld;JtljskU0p z;Fb0GYtx|%969E1aB()LKXg0u{Rb`w?SrcE(s>9v#nrW$l3Ik(%>SMCMJ zCSJm>W_U$h!f~>6ZnLd73t3TJ!)?4cBA#eJqMODjIBa6Pcdjh!I4ivzm)ds<8rLFx zinAkkYUazfW2oy`youNvg44ON2qEmV%I_G>?dLK|)n(^&x8vg^JH1MS)V{;!6m#Fw zz2YM|L}sc@*;RE91qz=*xbG=}LYpdl?V|SYe7+-em z^{h^gd3*)d#$-SM8D76^4^Fp4xgR`*8B>=57?ga-34_41{y}X*G3XqxjTEpm9=6;a z{gYK>a=QV=9-5zJ$OGcb0)+MfeQU0k$m~;%ll{JJRv~7`GI8K1C*Ni`1e~C2LR~() z*O0>>JqD}ovy8KWwKZFRbE{x1H7QkL`rhhwO_5pub=OOCqhFTO)m6d5fSLs|p zTVg0%D}SQ7nc(?yrrIc@sShTVQ0uENYU{G;wF36gvZ81Y66i>FWOEvlUU;Iwoz!sM z&(l9)#+}brHtIfHAv0nCL0Mnk&cUgDVXsIxEEQ<-|QF_8tAJpXeyi>Tg>G4%D zsj^t%48MvcEkh7B$ZK_p(a_w^64E@s)W|;XNFNgHPdVgNr}iG`2=5G4BtkgeN#9B` zxDhAKt}FHfxP^%d_M92=l)Ln_`JJ#^Ow&pJCrk8kX=UbVl7jpT8FnVWbq%qQ})*Eyuir)mX%pQ!a7nymOL#cEVqn+nD z%fe@ZXXf#3J=Hbyy5giD8nzjjddx|w;wUwoHo`I1Ws(o=3q}->f_d3Mb*41f;Ow--A+$Mct}7+md8DAl@ouPr{sQSI4_ z><^K({BxKXq;Yg`{EI;5*&7xpu?0JNJ*cH*;Hy29qvM7kN-;g2xPkf^LHDVA3w6oa zud~$`Tk|^%3wU(suA8U-F^#HEzLL~0rRyMA+3;FH6u}yWlhKovL2|h=YPDeSLe~9H z*k=#E=n=wM9X6J-D1VaxZXwe?PkI=cv*ZKPTzjrM04S}$-J70zDZKU4^V-vU47Ch++h(~cP7zXu>vZF-lpbDur(W9 zKhXH5JLUQHDO49~BY;jMFGf|YOlN;>p_>uIJJ_jGsPcy*5x_Ydr0A1FrWT!~pKDOAOOXPvl70etDXQcFguBAXDH& zSHi%L(4s$J-U`BWR1#uFdQ2MOOm;0Z`HXYJgCR*<*`m2y>AV zC6;R6UL63cPgN!n&xS!Mfl|eotHR5se2CruKngE9Vk2G-d}86>k}M>F3z9B;WHbLp zenVa4mCe`Xnl$$joYIw_`1gfx|E#Y`gH>zi9RPsG=YemSMLY$cArs!?F~9EyGQ!vx z>^2_<-^XM3_5oOj3RI0Q_8e~(}4w7ISXb!(jCUD9tVKa8t(D{Gz<)?4&2s%1?=-z1=TNj6XhNDuZ~W>CSm_u)z3PJ zmX(pC_B;^n*j(rzb#Cj+PJ{yVg{j>GUptxSsM&Ad&3#ChgE?vE(avheazuO@K^Am? zuwyD*(pqP;-JVgx0UH;M_|x_V)F~lb=lL1UD!K`Ti^Bxlg-^$ICw7}O3KeV9xQci7 zVWfoLoDOP2q$#B|hfG;IiEw|57f{B2orK+VF2fg!DZy2fQk6JTbNc2`E*VlNxK=b5 zBDJ#{RJY8b?H*k-Rji)QuQ(c$g!JB}2Yp|&%PD}L?w>Q&a91~ZI|S|1KfQRSU1MS) zN^l{9MzwTcKG{mJ)vMck$?w)wrhqDZyZAX;28oFZq?kQpRw8YykXpB9QN4CKFG3fq zk$~WC>8rO{sAx|Rk#QEEJwaUmFE4HX4?vg*0yD^R9t89huwx$Z$uX(|Nk6H6pS`}_ zd&!#nguMAJRwmXrr}N|x-H4R5JShD)mD}#NIdXP%7Jlke|MpJWI`9nEyUpXxXAgeo za~#o$vojyx7+=bcYdSUB;=;DsTCLz?og&kmFk!*{O_c&ZGpARMk>(EsW^S;}+KJ3) zBd#Q}C#g)zwlCL}4zSE7AAy%*V$Uk&y#BCySYlOry+uyIiY-#!bvVem%PDH`I_oWv zm#kj?PPsY=1BSm-p3Ldo8TSz{dUny7>b&~K6b2L}#z#W3!)(;zfmgn1y z&yQXgQiJD$vId>0co383oe=h6s{BT7;IU$EOqoM^b?7YjW%D=Ga~BQFWtwcRc&V}l zDmx7f^9LU*<$mJi#&;{oR6G%SCP>jm&%A?Pfvpl%0P+J&f4hAM9a*rztgnO$G41nL zAXtnMr*mSuS+Q5YPQ8-#BOmQ_G&l%CFN7-IaT-W1OuAxv$U-a=dKxQmsTv~-?ja_r z*Z`ZV%XY~jbMNl9n;x<=lcx7XkEK2+u)psq9zM~Rh~AKju!XfXC&^1GhH-IlcEa?b zO%^JX;u~q=pNBggyp!6xl`5!siXEa%?3d4$+^1ecP$|TwcBo5w`oAWKCaYH<6@njg zGyA-_+)Rf}@sQvhHH#4dZ0(4K6)ZFAt*htdfqN znbSg|H}#*jZ!k$@C0sdERei)b_+?m~owKaB|An#3rd3!m7-g)(Fe~qM7#qB?^`R7A ztB~I@R_a-6xvyCB5l+y>727@|c4*KIdxU(i_g8 ztEXeI?;KIEEi>cR)ySR+<)VQu3w4n+3*%I5^O5f@pJL{)9v=y+Q)W`idUWyzkz0Si z`G0YfP$N@FECLJLw3rf=b1$zOJ2dP=a~2_9qzC&Dwd92g>sxm^lMXAJJkItEqF)g$ z+7-;#462>ZtZqAt`wBpH2^S2ho2`wlBs$W(bj*gy>h<=n4w8zeoCXt)`u+A?lZ+o7o#&VMQ$>$+vP~2zsAT?%L z7i9Zsp%KcBGZCL1OHgYGP%ri*^y> zo&A+`ak6oU#oP1Fy-Px(Q9ppgZtZVu3I&VB*RG1*(-aqXc9T_}>?w5V!}XVvAjS7& z?H*oKR2;i9X63lZ*YB!PzIN>a$PoS|oYP{#ss#Myf~g_;*0U!U{JX>%ohw=KwpMFV zRYwLz?%y32rqYZq)kv#t9PUs3d^HibnLnu2Gd$Lhrpy{a>Qm-5GDb6pm91$Qd+Qiv zX4ynM%EE$PF#!AYuyo`(kyHO=SOc1s1^@t!2ms(U7y&?cOi3Qt7biRpkSTG1e-wZi zu0R%|E`okVBF+Z@7Xko>(-9|t1B}tfiEgV8_?3EmrCA4Y`d@NSXDvg7{3WByE%6}& zKY}^_awh00<%s(L97`fK0CkCb0stukKjC22Gw=cEg7S`n`{Z&K0Elbbfdj#h7$6nh zpqn)`zX$+A=y7r?KbYjqI1%5kfI#avn@a53%^+UwK7=Y+`@RyYxM1*;2I|ea8%Ni* zUm}u*eAVQ9$lhG$0{_U!;yeITb?RO&%EC3&1AxHbSFmk_WXd9MR|-~#QX!%}fW$nH zm3Lvm<3L(douUL;uq9Z67yuf420(oQS6%?nU*c$5dPAD}S76^(1-^&~y_MI3nC$YG ztiCyn@-lWjj1rEVrPkK#7MCFtJYS6XVc>YBHoW{&cJBE{4!G(DOrnfNO&6f(D? zKHG2fX@vvmb(GpOs z<^c?nOX176%ks>CL-e}yHw}q2|IYR}W4P-O|GkyUzO1@NEb9dXJ8BaqsJlIN%c>+J zFYuaxasL#h>4LF<1;;?sFPEB#2LPBB4$=h^oo=?^cYXOaHjkxavr!mWFlX2%dvl@U z+*)QO`ktuFoN89LGQKiPW-`SZTpf9vg?^K%6Y)-IQ8MvGDP*g=M2bmzYak8Y0|5BD z2xBWys^l5pcyE+6j9M@d(eVs$m8NO!{Q;=;Rzon{v$`7=W}LlH!s^+}iXDx%edxVI z5>OMZlKtANAbSaKheFWt#*GzqR}pUkopC&xU7kqxulRz|8C@V;UKr0A_K~|{amTk( zJbgtyj5=}#w>dAm1lt+9NlJQBKrh39s`p7NKU-+E$i^(xebG5(B)n!(=PNxd zJ80Fqf$BCv-s$!+q)#&~0DmNY$1cH3d+^>`$HxJRd3}Ida@1+E7k&|NcwVC9oJ}P9 zm+Qbg->@w`gI9ZeC*iHdsjjze-DmH!5BD2;)27J@v~FE`=A0w?_Gx^oj1ngbNwC??J zljjzF7wsmK7jKESh^K|hOX!&Dza13zKxGYm#T zpc(@|qXJn=sR*id_XaSEHzfT)N^1ZBye|Mi+|>i1t|w|XP?i74ZlItey;A%qv$a^~HQ@r@Gzm!9}BDHX|vl>V;@D`@; z`$QZ8awW~cRhX6Yz6Rl@8x(>xf@+B+_uQ=G4dTqdPXEmHkM@8s6e?1-2;P}7VbX35 zyxk+yw}1e!P5y3Lo!h3gezM;67g;xVIduMzkInyvl1 zRt8<`=MfXYG`ezw2Yas{%XBA$-H^bBo|Kyr)8BK z(8OL9jntChuof+6t_Zk3!d*?yWJmUT@xn{Hj3na>#CzYX-*ARvWtKGj#n9}IeZ>6)`aslpLqPJnrf>yF5J=L`=W#Sr-vXArQ+Xc@bl?4}*4bh*QH>3M7`hbPLV+rS}%@e02M^?>rj zq9e+9#r|kp?vAa+Eq;T%e&e=p%a%nquYJu3Di|HRPaCcs)V$hR9xpj&Frtw1p83q$ zB_oYPp_3oDwT9eJKU7KeZ?R~VCzAD7o+*|@AyVsvOL}Y_-#dqEF>g}nVR`BH9Z8#7 zQOjsLD_G7QLr@DOl_1}P4T{L0j-{q4D)h45HTZz$hgHMi=?U`%oOrg$;``!oW-T3I z(9hvhTHl$sKZ)KpCo;*ah62GUJ7N&E(pEW7G@e#900n5^4tm)x4xb>>_xo-yq>rlo zR*3&&}Bn&;`3?6Q2SdY|NIx_cJn^fp-ep@(j_puIR>yXiGid%?9xX4XYAawFp z$>4*@Td`gxnny<7MbjZG4{I_-|B=-e0&ZqP0_}vXUmT$(dG?PSP@_`D({Nn&QDLJa z{fnfng-EmdOR>eac*A`3yO;8@_8z@UMMCaHN9~FkT{h%Q?mBI@@=1o5#vLEB8s=7`-`qo z^WbT3VJlT-4n+ogjw1SV^pMA5U7<~IVta%xksxq??00#>OQ>5^OkV@7>iNFW=9>1t zDYLg)E`nlrE`YnT|HJ&)vQro9jjc#MMZy*$*;CpFOqDOLxTs!NjP(4t?L$yX02z`Y zi$ZERvSQm8nd6tun{^M)(gtqIn&%6rH9S-|OusvDUuwKT`1O5l5FqiEttv7G>hnr1Y zNkx7(9ZjzZP_-9IFAV+MT%NpU5g7TxzvSft{(Yloi)BH6dSe~od-Pw4;D&*TB8c1? z%t2*FB5GIdlO$?as=#5OKTh-vh<*U^eu58+A^I%dm9>$2}%n4C*XZtlO0gcJ^pn^_mZp*Sfef6iW<4g1I}V}0*p4&U@JK9c|T1#{Zw zP%Dw{d!Qzdwc&o%vM$1*YNu)IsOs!PpmsMAj5U~Oz&&#muAx*clbX~8Y8LQg^Tf|{ z-{z|bT9|07S6`hk_KJa*^1|U=gvIPG2#k!+;nQCCxD(v$7WZYX)E_`9VLN!$P`zC> zD7NDwdNhb##Y^XU(5XC~IOXq(x0p7n*2c`{T>+mb&&}tp4iY)LGR z>`%YcDTNGPV5od4iv>nj+9Ni-3EpJFj}U81EP`KI=Qkyn79WR8i(~68$9(=s9N3nN z>XizOB!m@Un0-$nF22n&{5pw^dEnt6s7+!pxVgY_f`t7(aLILXZW{<3xqqA^*y z@+n)R21jS5S;0W?rzq2@(aY}CgSNH>P0t~w&{__91_u#Ge*k)iN9QX}6628f5Jo?o z)j?(_t27c1b~P8IDKVO3^e;;moYc`vw#-34k#62Db zuV&F|UQ7Oyq6(Ls?+hndq_G2SN9VbB#lf#GPpv2_vdx0%SQL+wq&w=P-P$Vxb-&w0 zSZ07S9(=*VPTETMg1MQ1;1gxh0=K7K=VS90-Z7 z&JeYJAo9cXp+;RxV?UO+6G~?eZ3VVPb6Oo~9h`F={91nZ_ATe!HP?fo3IaON%$|6q zXVojjvlhba1mA)vl;lIr;Jyc?98`EDe{t8*CP~7sVgtzq?>}kZd)4gvO1n!UqiAPe z87JWUmnHcne0+N)H41tc9b<9&`SlXfQ(ZQv9Ag>BgxIh6IrV>VEUn;Gsj@U*;PNiU z-1H23sdMGjt=k;Nj04Fb8NO_`1_xhZW}Oc|?~@5-ioVck=Qt4>Z{!G7^LNfo_eEDm9u03{UZFgzexGSG676Ylw* zP1?s3B^~~dfa&-3z#Hl!&a6i7+}Euc9KDayE4A#?Ebb4q+@{TSwm;-OcN^#D}>qN@(3fnoe#;noZvoFf82ql*L8E9}%oSX{KEseGXJ-yNN&; zn8?5*Krjbok`(alnp%SSB>lh>Js$u7#qIC?Jiu>d&32H8>eoT7&Lm05yhI437BS#nh@HwEvn2$IFC75p;;)BYAf7Qp@D1UiC~jF@7A+j3Yrp`=#rw=-?%u~7DrNnuE*Tf7^0tmL~Urf#zQd!(Mf#D+45rP@j>Pk(9L6660M50 zGKz+x?vCAT783l#^m;hgyTR zHh8~ZMjxX#wXz<;Q~z4+DtHnQG-YU2hSB-YNO4pBf9!o{SQJazXb%XeARH42DrON8kStLQfJ!>3#DM`N3Bv#q9g?FS zMI?zxP6`T24i3l=RdS9)29+EJBum^|-GhL;XTSZPyMOMFThBAy)z#G%-+FV^;Oj*n z14UlG#Za!ltq9C*paxHO*T4htpvJy~J&KzW^4R$-w8iSOLqFPWCfC9$9Dc36w#Fe%WeffZJ9W%Ui`RL!gc}i=y>VEdPQFS1eLaq0%eV% zxmngJWDM7b3{c@C;s#Jc2Bi>UI5uPt@U97yt)!*zm8qDp9r8LyGoI zpN%#vS(@ZIb1>V_XJ6|+wQS9EezoEbEQW~)D%GY-GD#K^Z3pUrTDybM3vPwX;0m2(`VLfW zG?Ha{K@Ld&HZvv1R+nOp#$#GPh8@UZml(^fcFb|@JFUMX1^39``*nFh>D+Z`2ht_l z(2<$$GQ*{$A{p!-&lR|1n$g@_`1F~wGd@?hV0m8N$-K@}xITCw0@%|nJZE8f?$s|w z2B%~t$*d6De9cN;jKj6WEk)m|BS*Ix2D@Zq=ex`!QX}fGi$`(*`2u?i>kr%LVbp&{ z=^zRxw!}wO%%)jG){2t4r+PHYzzUfKB7NKpbyc@RY9K#OXotK(-&8qu8F@qN;4M(L8V=l`mB&J+VtLVA`R5D_IIX3Uc<6I;BQoy!} zx!OyH&dKp}2WsL8Ncn3Qz!+`SFo2{flCm&+yBDyx?L{_S-kF$~yBNA^i=ZP9JUjyY zGGGP!gLgT!b{IqF*TrH}{>KgoWQ$#@9@N@5rF6~;*M;!yqlXKhRAm2^r6==r_=xK> z6|i#YyT6E~ZCjn1bSpf@GKH`8OWZButYS5#Cx*1RpjgNBEkGr!ZpXZ>sS_h8A6(4=+(fo8^mSPYooKEk=5Wj9w zpvRl~+eM_r1MS|{+7k|x=Wqu%lO{Z8(evB#8AgA!nZ%XI`?`7(TW%yizjH#<@Z)to zH^WK(MkWF=)CuVjfOjfaTisoQFD9cP{Zh#Be z2*5hYST#YQ?S7O7&X=mmhD}s>Z;z1JoXlp5U5K-xc9h4Xk0jVibtuxX_RK{i^ivhx z)k!}ej>ua)zeLqAIKQBS7JDRs`QhLWg;)^ePXG^lC?Vr*vY#7;---n(sPRW>G=sUYEh- zWzA?ElFubI|JoEt-M6PZ{L5I6kJ|%e|G$yw5%yt?H7xueEE&*caobEB zQuc-&?cZB6T9KUS0by`Yh}8#5z(k-Y0^hUo0&XUg`rDqJ{0D64V6K9ooI4x8Yz3eY z&VUaEyE7g_fJ@q}`S=Pa{A++M3vfs)q&%v$*U*V43hPd)X*yLxyd8Ou9Z$im6g!ar zSgf?5Q)&K>H4N5xU7&!HNaamtZQ(?Jj7@77`^to#{azme8>?W2j6kwp2{828cA?~iNEzHT%*63R~M}Hb|My7^JMIb!Nv-X>Vlgt=ARcq7r=`m-#s^c!nvB1?Z zHbd+&DZpCM`#-mLS=HB_x`wchV~}|^gPfm@XT$J=-&pyui~NqS;D&4lCSa7P_#vn{ zNvU^OWw!U!etCPaBI< zXCYkJdZ1g{!t%<30G=6+52?eVi;sm!n9I-ZTGiYtpMI_ByMC~A4%J<-$>6&qfvJMK zxyHP6)YvP=pAtU%&Rh#=B1djj z+a5k_d}H~mg%?|^+;O}8da-|L{ z|5kn{?hmK9Wj3sqO2dXkV#Nu8q=+QdE1fVnuBjvF4x}sZ2pCF4ESl?r?ABEbt3%@@ zrxKM822C^nkaU1VP&GzqPVK-^%vz`aun6Hg(TZK-2lNYZeL!?F2b?dgZ8hHvqEk(R zxLqYRofnTUw!3DW^lmv;XD*h*vv^Xb&c>NypUAinb^;K2nj%{5=uYMD4cXjlYYN5& z=!e*&*Wc4K+cj+l>3DM6^V=;6F|MJ7CB-@SEntuq6M261*goyX8!#7IU_etuvs}X^ z=kwQZll)zxOihZNEr^ z0mJVW34j(CGU>^eoCxAaSid!BW>j10l;|q~gmzsBdKh6`MR6!aV@k=a>fzGfUjQr% z@8oIJYRO<+(>KzG?!Vb`>9(;8viyIkCO+}1IGsaUwTTbO8z7afwUk}_>spL@qg!Hl zNdQp>;=hwC0TEhPe}atvUZ2bOL_(<(DRqN~v;xTc?*e1yGLp=?pnMpdm@*PnNENz( zz{O&z14sZ&2EcEx%@}yk>`Mf8R&C$|-oAG4fOW_QFtabw_Z%r{qfS$x6#u*MTUXP= zT>?cM$-IKt=o&d0U0^XWmT;PDAJeNzVdTG?Se*~#n`(^A;33V-iWqGo)pJT)sxT+W zGrm)|(YQI@QV5`vQ;o)^Lw7m=b*8BaJ1?oK(Zj%CYYkK=6#^4@V?Ud2$&;irMtJ3V zpk63y##s$#SPi?hSpbIN*2p|N>uj5ZLyJ^_0qaa#^YCc*x7(Ij025Npt)0Ci^K6ym zT$Zyu)nCZtBKNYyh`>_=R`h=a5+w+m$z5-yrYi)g$v?7+@HJUwZpyHEh2+_M0sLaJ zp|x}%Ffo8L+EQ-1x}t;qONS1g(9jG$W^wTy8t-q!&nDedd)TzVL`>_1Q;(%M-WUFhgOo zx?88@Wlb#4a*9mb^3Xx6>G~}}{#F)oN&!z%kJW-(uOMu*Gh4{);gKV?*q_%-y2r74 z=}e@JcMW+pnZ0caRyB*i6#NH-N4mbjg`62JIer@*U28fznPfa*=6FvlEQ}*>r8U2H z`@sB#ASbqy-T3XnW)ppV-_+b~anT*4<;k?-nmY2T->%1s;_;Ii^*vQa5G~brX)8a0POQLv` zNM*WDoL$<5kv{G(JGXF)qwVm~skD$>6K+tcYY0tYDe(r8}?Mo)6?_S^06xwxMz8l^Grz72#yhW+*9 zOQ(>YZ(dY*)(*4DG|_CQ1g!;Sa%9Oot$IcQP+PTOhg^%Fl=Go3pIcS#O=;a(-=(k#6PV*ZHv% zclilj{X!PHZ$NO{a1_NeErsd3oY^5-SFHPu~<8)JvW5aIdEX^Qh<@JO`+;08!y zc_p_k)3OA(jlZa4a=Ltq0Sq3g%O22|=~g$j-7*qBh?6P@>-Z{d=kRRf(3vI1NC#yP z>N>t{Tjln+s-NRP)lh-PfGgK+AiMYs_xhJ5m#Q^M>!)(sbfiZx?zeiZF1;0?wr)As zHjC(nXEQCcbB^efnO>rnb$}{ll$kykPZl$kCFR|Aa%MdXac~`R2bB?y= zR+h)LaRsn_VUe;?miF9`} z^XXiM5v}n)xRM`+djhQQ7RH7|w72lHcssP7a$ZULc&XaqX~ltw8)>C)?<*7Icy@DL z%?bf(t=|F|zm)TdyBNO$GM$WA$4v6Ov|BX=(}d1u0=^_835X*#2@e!)?F37IV=`QUB4$uCtt=)CHN_4j>?fff>BG`-8p{j-u2vvD}*WD z#GEreEvM=Yt|bTja79-!x($9eNzFJLUp?#LZ^b4NL$vx7?^BlkJ%^GRb{@zckKY+5 zE*L80)l()I=TN?Tx(17F-#FoJCJ+1hppld1pC?rnj!vF{go!;n~4f8E5_fQSXh+dpa0}K%mcBl;K zI$t*S6XBU@gT72Te?-dK;F+_YtylD01Xi?yfU*j%gY~~5E-?L|x~1u6Qt3KO+fNUC zlm+a-kmOmaT9yJ-v+%E<6TAZ^@wq$9*1cp07-L0L9dTKE}=10Ri>eQ|2-#hCEE*O z!c#n_6AKIw&a(4bHpX4~ObzVvg@0^&Dh{0(HZvZ4=5;mN@4NdX;D;KR|%`jzu~0bdDTrHt_e(M;y2X zSj7B~t`IIQWSP}Inoe$HXv0d}MQQ=A$AiM%7oFxV0$KxmCOQ9!bY(NGIcwN(XZ3!L zw1%jRrGr2Ifj6mye8uLdbG55;>p1SG)HAt0zFV&fLIP4^XvRk`5wjj=ygEaj_hWFlew4QXG29Lx#EC~O<~^QV|W6_tUPOTN^SH04%M zCfbqBB3U@<2*@}rYjVc~sZ5JMS%tNZ263wLvnG-zYR(rl&S!V}?#Jp9bDIC?3BI%1zYsiK6U>D-FNwBlvac@({L$YwIH={;; zpZtY`CB@z9?&j4a$Lr&bbX@sbPF~#;GIYAf{H#NoQr_II;K3J4Qs`D<<1ugj?xDN3 z0;c&3wf&?sq8PdHRb!;&BgGUB0q1M^t1toz}vOQM}JE7Ca9GycGc)fbuf8Z?_gqyZ5U|8Z==E) z?-X-^!imwzD-P%1$PBYX~h0W|SQAR59{H+Y(QEzOYeUG?r{PyXrl{OHWVgK$ORw6?kFhg_Z zN0=>NINa*rapZA~@xhichvo0KZ=+-75^Q)`PgdgMIw-=6+Bco)<(O&$Jbf8`OfdHJfbx>O22IEMFjBRsnZ-m>A zvQiZGNyWU*7_WjVq6MHEJ#lvYRs&@^G9fxyx>0IC+VnOs90C6z)V7CJV$0LE-c2ho zq^Sdw$BvuX12>(WDmO=Ms4H{>&1aOpgtBbaEP=_4JH<7{M%ODp$Ik85o=clP zYuWXswSsCbqmCEb*v?i_#B~ebV6OF5^pi>ZEL)yrBkfuh5#oO!yjcG_nD8b&-w>qvbbySVL{+!$wW$IHG6w)! z{F|Ju_7$Q5?gbuGSz0fV8vm8<-kU-ER;X{+t_21qWENTQz=z8NQ&?fIt?iVU*qo#x zU+($n193nNcG~!(%i{aT%k!K&KLk4g>N_RQ9$+} zpfS+QG05;!e0bMW-24f^$m=vw_{=SF(k0F6!~*XJ8PQ&_b0_Posob9$XGRZ$sbsyy zYN~x=31a;gw)}2yL}x2Vg8;t{ncbS&rV8v0sIp$XYXz7L5H@Rsp4o?~%0l}-;2n?e zFmbIFaY)7yC(V)y?}&<*`d!tJuF0?w$8&bjmM^NSu|{cO)%5^Ru3c|10gQ)AnXuL?X??@%ItZo7C>LbwB`?cQ+_ zDi|M*-nM&e*~huo$nhGJg%g#fSosMSLtMY_>DN`7G-37niUZ z02Ux@=0Hla6!X0Yn?E+(Hnb3$39H5>kvT~U5zKysTTAstDQ0dMWHD-^dO2DMhxL)@g78D*(dv09>V^$0pKa z9o8UeO_+`}LnrY#!0t?5D|GSLg3Mgl_ELebnbItCiW3dFXq^597?y$)-LzSo?MZ-Y z!k{9sAcpCa<_W;fc3?b%*O21C`7=Y$y}WY^0n1W*Y=4p^tS41_n=BU+O*Bu8NSX#J zHL1btJZfDtmy%$YCQhCH#w6HU`rIYtain(B1p68xVG*{LNw^Dep{)4y2P&`jo6Dlq zlZvBrXROlh5Y7AF>uMjXH_Kc=5B24Xg!$97PJBSKOG&8v@9F$n|30|LL``}I&5uue zCNFVWN7Ika-+byrTl%T0Otufzjb)QZ*#%FnlCN$J(_J4X5J5yffeDii0(e;CRm}G1 z9kaiDAGop&pg*^?)#f0UK2@p8aOX0K*ggBz8jhcoKet7LzX7jzSEh|bWh7)v`|=)2 z?y9p}9!kHrHc*B^RVhh)hz&Z*nGjQ0zPZ=p9i`yK0)zZ4A z@!dXA*o*+*BMn*wIrUa^9MV#O+)?@U=B8@#S@mXtPtH5xcD9Px<7So;c|NiSJ11@N zS4}R@b2~5WJ7z@ymFPSX1@I5 zpka)aB9%Qk{QT;H4&$A9g0sL&CDfJGq*p=LT_L@}`DmrNU}|cXIPhK|$S+_zVr038 z&>3L)U0$$@H9iW4s@|ru>$-RZ&#$rCGpR&Lxdd-Nx}0qoS0#&dU^5EJebU>Pxa81W zp^DR+N?}dLIz%p*Q}$qply+PPF-n;<8XXpBxnv%n7oDRXA6I)irqWl@@lGrybX-j- z?i^Cy+C@Lr>^o;r9(Y1I*p2`L=MBZ4y?8y&rW=|s$uKgK7n}%ODKE`|&5F}(73mtu ziy#K{?~khV`SeQ55;zi8*AS3SYFYNhbO0u&CiP^Nly4?*&njc!T~{WRCmRoguNd!* z&V%9N)iRP!L<#{07J+y3JYbt0L%5?{KxZLn!K!~Rm53i#I{3u79pIGQX6Gb|%$@CYaU`oVtXdrb-A2P_Azs^M~e zUjRq~YA^t~Z@SPe(Ps*yCSE}h-GWuZ0s6Lt7K@c;-R`cUMkCAk!cQIA^Jf7TB&gNS zY8VT+jQhbF|Aq@rPcrG!qsY{$BH(H2aa?swZk~Z_tJ*4JqVET<(u5uC@*v~u=y-Kt zF3&Qdn(V+@fVHZE71H~1$pF z{Fyy41o{rMDAWEkQa@wk@JA}wSiHi)C2mcTp|gBxuytL;Nt~6BPosvCqt?cJ(^-hq zy9@3yho!wl+nsjIbI{=(@)>$Jf!8CgX01`j6(urDv-B^B#WVU%jc2?}F+r7opLJN< zi~bwuV=mI6MK-Pme=M-uG~#_HR;u&stt*+&voD{X$rrLzW2^0+&SpwrmCpAvnm8sN z_HN6kU19AF6lwBRL(=<_4TwjE23SIA_6F0&DS;>Et91!5$7Hux^MScy(152tPl|$P zzoQsC)$V&s;*t5p>;ZsXXd*9>#mOUVGA~0AI(3-Sh9lj)lqmTEa7r+@bX03sx4IvQ3LW6H!);vQ4`0-@hnO4w*6IM4sWtXqau&@fYAkq zoGw9qmY01+$0eBLRlbW0yH`=O9`xeaX= zYW@KM&wrM~3;Va`c7)qUX|HhuTXQwv_VBa?eot3QIXC`n5LZiW{$}Q>S|j#Gysw4P zfvLN1;yT)^Gx?TO%|U^ePF6K3yj62fKR157UD~(6N69`daV6aJwEpgZ*Vma`G3`m5 z(}pa8U;=*&K!%i>KfYzv0;Jk>$G~nX(Z?_hhGRbvEr%AModj_)s?9ZVNO)MeO0 znn-?I<3_=~V>M>m{bpOUPW|%u|BVg6?<^usPDK9XjAT;!QVY%vY6*N_c5l8krZk@g zV|sPvw|)bA=%+`op?SbI(#-fa1A_izzBJ#tx3L!E1V~pQr}R{mIq2G+g^3T%zfc2S z8Pfo}RKk*R|LNSDK$(#7rH6B2BGMQ9|058Fw}V>Sfs_H>!UEz{fT}drz6WH38{gCO zLdp##lZ%T*+VpY`Q=79vn$cf=Z{V*dSWO8BVi}MLP?|b`b|LO8iGYyes1yr!Y1y7F z4>B<*15R$;+Xcz;6Og!bz3n@e-J?jlO-NCj+3~LgYSKSlQ9v$*lW1!H08$4{e#Z;w z-aX)Cy5`0LTxF%4uf29Fq;7E1-%AF$=aa_^sV76gP9jp%Jz)I+8b*?Z_Kv9t#CBkD zMCX!kx;a5!Q2g@A&2?Uc^m zu4N4|gmEw&5zhEK)f7z ze7s`bZmcf%1@kh4_U}J0q@LAMpY{23&!D_xy-r^{qs^%~jqm$2{aPC-F(GIrMK)`p zbh{2|FH^&?SpOok4*a8>`j%X8qboC_{T$MqkXSO8;@}uLi~dUQu4<*}SI55&>%0Vx;C%2WjMA0A^a!W>e;#h? z>opn}8E?;tN-A;IsFlOh>aGMIg0QYd7Y@HOy!(JPk|^bb+%{bp0}J6Nnij5C zfbG;nAEw%4)Sm$SAV>g`LLG#%X$6Rk2R`6)7;Ql1aw)H>TVNaei9DaNRy3@|NK4J&hj=E~Z%4VtRV+sr+?jjr??or`E~P?~ zK5`4NGQC@*6K@$U*u3%TPTyQx`gekLL%IN^t+$Cke0<=pBiH+k64 z74B(B4lq1+U^~y$W4qH}^CHA@Dy3m1UKW3;eJD}44eUv+Io{^*6>i4HJZTq&@pYME zz^*Iko-}Q(sx&8jlI%YP{Zx58MV7AXIRtH&c&vDUzN2i8)6LT7y>ypG=uBvm3}?@N zE@8l`2kY86bM*)4h zhuwURG*?c26I~c=L{jD7` z{v%*}g28mPrQMg84$BQdLyk)NekPyF+pXKx%zuU%c8rY{2Uo>$Oi@CmlE?Yf6Y#>V z6$x_A`hK}Yc@4qkOZU^KPVkhHo>tfhqzlB@5h!seE5v_W8)?0(}0X!$8&UhjbFuL zzd2C(eu@`Anhco7hBKzPW7(}3%alc+)4;#0?&}h|Re2)KyDO3a1`eMxxU!#hcYa{d z7_EL4$>NyR(X^UHzR%y_acl0g$^UX4j2rjB)N;OY<1}ogrq6nsE?EfocHPjAO8G`{ zw+7o-J3g4TNd~X-oh&`=Nm{N-vUk>-Ic>PT;N(-?=f%hO=ifj2!aUVMZJWF<^R1xQ zY1tmtA2NA@{~6{G&Cgk=%RzQsMHbjgEVJi$FTJ9Y!g@88JerhDu~m1hN@I++iXT|v ziduTya%9mmNDcTXKNYd*DiF^gHJM8Ub~eh&LU9+Y#4?+hRFoq^E(h*!?mf%rmk(&u zg_N@Fw`h#}$O<7YwET#xiO9~7VkfcVqb;!8j*2^nGWZi%&DVK`T)5;G9lbUSaJB^< zIKVUTqJ1N?X~2mvK+l=)a`luh^iBP#pUNVB{;Kzo$c-{@G^aOw5P`sgSIISC=BH;k zHxfDJ78DM&=#WURoMRpV9=vrVyf61eRHwygrFC|qyjN1ffB z&4lIQ+mY8bYIoz^%c#@rymOKdL?0`~w1$SvsFIlL}dH7Pjg z@CK}C3^qsH1TOO4kEt&5mDc7aQgJaBc-0&ILgyyrs(~$F#}+|;{;9haanARSrz@Gg zIt*!hna>r-HtkRlAC}6v@4h?Aawg;ku=O)q^E4!Jx-cXy0$-8o&V51ZPwYt9;fpNI zutCP^SjP_f4)vpDUt(y;6XK5_`TAoz0UH_@VtK+Zc>a>F`SIuDabTQafBBhnZdfM) zH{iH>Ug1;Clff||18L+4jF^CmLb0h;HXk z+UR0y)12!o1iT5i!+tl%MBiG`$3SeoWj?)+lVUyB{%mfQn4KxI8e>M(ef+pZiv?27<;Ip1<>{F=MO=|70D9hPgw-DRR$iC$QaRYq!P#8%w)g zIJ`-S7G0$J3hCrJf6D+(i)HJy}kS=3JSCx3>V<-sC=$lA$3C=SOmyENq}&{#|cx?E5awjC(Ayr+lZC&FAqm@bqm!*|g`H z4hK%&2n@(5aYiO}fc!??oRN`{sW!DDk*t=B+BuZ?ci{K3i*qcGriRmA%-UuQLz4c% z9n-;nj%~T%_H3OLI0~4cQ(FDGvZ$OmE(>-~=#Adf&SG()3;URb&CCkuzf?=NFS5I| zGTVFng1bYg5N#bDX)=B;2M?hvbFoc$7w4}~bn_@XS3X3S!;T@`lZxw*G3qsPx(U&Q zJ6%plK-#(vwe*AR?%NtZ>u?thhe?H>B$)Pss&*9 z)H`(qtp&$*irQ}J=RHb|uHmaihj}_Pnx)i!$kmVc%-4X2<&}Z6i+5dI0(ewVU+#aoYi+X=_+YVEAZ%d7Yll?2k)d64HRar$s z#M#E$vj1vZbiVra$2}<)78ZdqqxydFeXB-IQk*Q@A95(1i&C82f75T2ZcL0R0e-QL z+aTcO?xEGGUDr2mxKu?m7iI4o<~fjJ8|~j>D3?dRJs}*F^^v36ha_isA+3FccVHBp z@2Rb=BOO?IA#GYcyZBSj2SL}?-zo!|8Rmg3;F0tX=nh05med4XVS|J5Ewde`t%YW@ z*<)Gtyp#jrb0&6h+Ntj5$FnAzr2+>;8Wzmz)yMAX?qf#XAymaBaeK>zm>Mp>Vt-$$ zg?`%C9hWbNwweh|gLB8WT4v7mT+k&oIccWyeM3(sHC+=pvXqx=qOhyRzsYBU7;2{8 zC{cG$z)-uRbwqC1t@P0+U(V{*lI5e){&v zHw~L%6<{KDPfALPr>esU>DszD0I}LnoCR7NB%u6)*J5io{fu5j5+&_P>>DLn<8i_ILk_g}w zoZ0<=hQN{-`~w@8*M+s4m-ayrjbRBU}F0Z z!|_BgqmQa2v$x;n>*MV;Zd8WP5`bdl@}|y*WFZPOL}Njg-7_@LCd{_x6p45a9@1bD z;3>y@j$iK<)f4W953Z4F_{TP86MuaE!{VroCy7Pqu0sgCtpv4wAfkcY``s|S zZ6$(3y3M2WJU6M=aSMi<}r(|iGY zDuUq!^h=NCqbL1H*?uvZKvjKG4-Kj_`ZhQ=qj|;{7c-xBy48XQR;1myd@}pfTBo?9 zx#Ndo5mg*eC2j{o4K-|r6TdS`+Tk2m9}(-b7Eg|}*-X5LguB>Q-`@|y7aAQF4Go>&^rQs`n~d!WwLgJIGO`l4w^a`Gb{!;24p%t zFH6SBL0(7`QUHOcqdQH_3*bP1Us z;}EwS>-Q#%ytzY2yujc=?VK!#f`joS$lyQ*^I735#GqO7TQ;3A(uAlp9RNPsYPJ(Y zKhG_?MWk)&6Ma~KQu>E|85H1Y0My&y2cKf9{{}dq)z&W@tHAENIXDKNzQtjAwazgN z(QpL5I0!gpar$%@+~@4~%o1@{)ZW)(@62Jt+tXxm z)&eKM-KLh@HiC9Fkypq(u>iOIw*Zz?kqKCH5L8S(F=(2ZGG-C3m`yJ#m+Mjs1k6+x zVU8+~GxsH}kOhIPgG7RGsB=1ww`&jqp|GWB2L;aXTe8A7SkbaL@b|-@E z!Q$r-P-%f3e%8-Fq&DQYWn}WaxO@hr)6B|J-)>wtPNO{W3Jk=2_$EIp={$p9C>Ff> z5upVXQ_eEW8`v2EET9a6*hFO^YS@7E|J{LMEKc4({_emqS%^-zbSnUfXv&7ZAGTB@ zd!00c*Q(px&3kKU|8!#;V@;CUscx?17bDMtlSgy*=^P zV59sMfZv#|Jn6kluLwIJK{s{=U_kEDr>5mZQi$p=lz>WVE{9be)UYvD+AZEYLRb@w z?HUX!q%+<=U(4{@4T#^&=g-1Pe?%6*n)4l^oKiu@lszzWA6F`Wc7zp!RkDL??^x%m zbM*jQv?~{UEaq0dR(+*4N43)X_C}9Ef98 z`(z~8F`y;z;a+-JQ@hudsTsz-#uWH;TiP1sI`Q#tfx{8-7BZA)^`wMlArLNt6u&#S zu?dd4Q8_ALvwspt`+o87c#H^q-$`SeLnohNio%Lcrg|K3=4%Q*Nsp*lTJw0u*w?S`XDW`hC2BEikMjU+F z{#nD}G4Bj*!?z{Y0YnBHope4G4R$%e+i|u|gtnb@1>@Gzp(QaP6b8I}3y-CGiz${B zdCcl-18*bR0}XZyWh>9P|$u}g!hk64KkX+!Up|@<9WejhEpoYzph-VD${nV#5 zCyM@fCPfaz32d*Kerx%Dy8)UjzOuUxq|y4>U4wBs*l>Ntu49MvE@z6UNoL8Q2<)ur zb!toep^OGo^W(Oz55QW(qZ&s^KAlu^GhO0VH@mEt_LSp?_Q%0K6tMZ7Nk%y%Ar5hv zcQ?IIK<;j|aAdDm9y^1}gb%6S>SYTKSW9u1gjX;hm+jy?8Oj3H@4L}c#GU+eC zrD$a72c|dy+Dn&bX(^xY9Uu>oh=8Cu$QXkT@Q;t-m-@xvahFv7?IZzn(}tY1spaci zR3h0efF8!R^f*B3S|Brwc1@L*XRH54g&@O{tP5$ri*-?87|NBz@e+mD81pe~~ zp#D(=9YCQVS`-}C^P^~Jx6siuZ2d<&v=v2zurllK{$GyBMQ6O_cK%lXq-o0y7hJNz z)=X!$APrf;kutc|TXgZAFXxGCK3gQO6K0+YGZ>dU1UXO#ey$x`Qzaq56^yk z_qX+Z$zirq45{s@cC*Yej+h-7`8JbnJ%bklxjJCP!k!p0v{8T5M4s(ElU zUuV+kK(-U7m3nVbQf}!(I`( z(rn55zvX`Wpvau;+!2<+9@>)fDB~QeV}_G$3#deY*k<8xE8A#5t>S6gsJcNw6<73w zKr-jNV>w~t^}mU+Xf`fb1Ijw?be`+qWZ9I=kTBws3ZCay`27j%=}s@!qyH3UT(Xee_+aY?5WidnE*_{6aO~>IFVHq++#j?-)3pt& z^FKJ%M6*;yf}y$m&k*l!^i5jwIBIXeduwJ(1BlKpp6=aHZwCfXY>Lu9Rls%)`=$jh z=~uY?T1ePat{K{*Bp(nA4q!US1kUX_&voD@igZ{(O?(WM|YnMR1P7Lh@4{ zZ_R02XCT|*Co>HVv_UW7@=(r38^wY@??|}gc`@^YEVT7GNM^awws5WY>6W6RLI(a% zD}zJ#pG?w!Xb~hx-%otEEjYCO6=&R?ExXZ>?KA->!0n)eS~VZ?#d~xm1Y=ujm3S4~ zg$KY3YLMza3`Oiz79{&j7(sNzYL|(Jg^+M;M82=b6R?hHRa_-kRHI%&*qb`bna?5m zzXk&d(3w2pn5e^mH{>a|5U1}Udsk)*CoiZf&PqsSLiKa(!T_ozi(f8#ZW?zO zVxt&0f2w>1?U>0>vGnBvIFjD!au4h5n=0w>puVB$_rph`93wiO1ho4nYcI^M)yXvb zHlv+nG6nu0xv~C@t;0g7y{5hkv}KMz<&b6&E8u&-)$1#G2D!^Z&}c_RV^-6oq;qca zS?0*#QVZN*yDY>zG(GI*b`XNB>Oorsr_|cSA5pQ22+j+4pWPC-x=@Rd~=lJcqUgv)_SejCV8L1+F`FsNHAj zU*=u${7f=+!erGnnm1mnMoI*rS_qvJhfsDJ%|yNYL<007J{%~)&^b+$;u&=i#56ND z$7K6g`+NqUo105Orp9xK#-yndXh5Q848duFnE_WrRXX(o-k1qXOAnVf-j|5<<<|@v z?(O=vNJ3Xo+Haa{_`;dPC~_969lNhieEXcr^*x5 z+!%LXjDeK^{);qDGiA`hY|xsfosy;ZJr{is00nKHE?yXd9NY2TZik_*IvE0yRT3X_ z1kChoJ?65B$$IB(7WWJ~+RWa|kIfiFr+_*N!1_Z1{lRb&HsE_UMI&Cpe~`eSsv>!J z9v^1ks0yGYkJ-td?9!SFF{q-me1jgzf&DS6kn%|A%$&XPr*g0%K~oyYlu16na2C@y7Q&e3q&yMa ze#0pBw0w-d!t2Pk-bTvlkAz)=ZDUYUg#FFgllYme zz0N;cYG%cqm-Vj;PiGEAUZqSgtS$Bf`5y1Q|38r)HTvZ%=Zr_4_K7t}!>I;pS!DJMj? z>dW#UGa(sJ1@#MVSN>OdX>+<4#$}PLG+l&^Pv|T*;t&eG_CRwkFS#e|74k%TpL(ah z5+KWh2)A--=h-jmh0tK-2RQwUH8fC~@TcMazwTlipsmwOW6++399J%`r|??{>KUTm zkt>ruJitr>W7F^NWWDWM)UvG}j{Iq7I~>`%=;r43fdJl~?S!PNIle^(bok=qB^Mkc zuY_p?4)qRK*!IL!Q^ug}E*&XD`L-{S0@qsjM=&yR5bZ&jL!f15u0c11EpqA&gxbto z&zVL#CKG3tm!&=6Z*F~r@OdG&Dj_X#fkjriHu~p=2J`fEML(E!6nKu>5$I$r<|SmP zW3yH~r$(R(v60WM%1I#S4O|AbA6rmogM)*ab*1+ZKpHLJ2af&;ouDyL(sXxwSwx^c zA1=IjpRES|074bi!8aEEg4&Rp+41jL3Wqd=hLJbkaGO!=BPgH3ePgJ=S4>2x@=qoQ zh}|4KP%rI;+}~Kx^=p5^zSgP(Kwt=;shRefE^hemB#@jcw50%@1g{RR`Yj*$g&*%H0-Y|~B> z{N>G3dXm|li<;@JR)ceQ2c`E}#V!jEea|xGi{P-ml_fl9Gu$$LyGN~e;T2phz?#Sn z0u2WN<&zF^-W>K$P?r7^@^YL?a&Zz*%90;vN+;)M>{w3Gtjxm>r}tFMygTX^%(kYe&vS>kSV$w#apyluV>*>c#jC0iq$GlnG$j7^c!o zLISO{2MOY{5W5{@m`Er!05HUk0rN`R6}1KVgmnbkcHu1bYakdm?oM3OEEsystDJzQmEN2BCJ}yl zot$!5Qszt-b9Ep{Rpb7N9g^8el?Ns7wv39H z3MM~mWj6;6H{>Bt8iV5K%<^2U_RVBd3L3vM{O$X?&vI3U`*#4*gsv!1aQOurkNe z2`64|f1zZE`_6l{X3|O7v6eH^R7JS?$@K0$4RbK$~ z(Y_S2`Rim3YQ+NG&)Wk49H4sdmFnajU~R`svqZC3!ISYtBo+%dP8@PRcpm7yLExEI}R%7{I_&p$mr+{|h{ENq=pCmIq z?w2bjZ*MOQ!SJ)aH8w>1E!;~`gU{2_4BzOG766r3Jrh9Mbq%;XTWp}H#D$ta;gV>& zG+STl_@4@Sc#@IKug=dJA2z5b6l(y#gLv-rffazce}Xyb<6`H^%WuAkO>f_e!DY}{ zTwmx8+dRRIS?~m33H~fd4sD=T<*ML2NPtUY9l@$+G&FjDbKxWM#`1I=a70v{JN*3DP41h|d8)pWf=Ac`~O;fYld(_TVDz#&XYm<9BkJB~F z#_7;y0df}Hq*5IW+;1?uGXAwwg>Y$%_No{>cAs4lCe6|^xP#B_nHOoVU~Yf%&;B=> zTFnCCgHPdXdsBgQvTzFG8Wlkn;r3Q!hB?K&AOJgSNys{3c{MNve*rPt>1$m(d170z z$6w^Kkf$e)Ul2I5o4pQx1xxxj1|Ztu56G8Wp96r|h3a28Oq z>KU9JLIXgdF+ig5O7$E|;9=$hFTQsy4Mq{nLZ7IZl67a!^c%24A9NFO2e`wu## zn;vid?inT)>DYW2jX2{O1GCW}>?OKkUO8tW*j4(B!}OAted80E3=PfL5Ufa=kAGkV zKoh4EiAfeh`Fg@he%I`$?QWDzlClPd2FIpz?7t7r$ULnvW=neL7oE8e%cfCSscylJ zi|Bn$+v)oUQbpFy3G<=HB1yMfqRoO-Y=v>k+&aVJUDbagZ&7H?L34%-gKZi zGB5jvJA4YX<3Eu2l3sd}g~9x$1xz>OXk@Z0nv<&>zPQY#c=zI3PXhX&dF*$jco^@32)#A(1Q06_ho`L})%ubDd4;1UdV7&i z0NLB}$>}8Z^EG@MHaPWXfj*lucalI3| z6C34V+@Wxoq5kf|VYo0lQdm*(w_R_ooHUgv`2xqyc85@B3!=jvAVAwjYx`a|XK~$# zN)H#94fS#;)uyfk@tKHeIL5NSM6%V+W`>ew^-P$+(eYr(pfa$^UB!Z^>LS*W z%xS&Du|zKiA=2Dijo7Cza$mvKgPH$eLx8vv&cApPk=x!F6l3{+n0pVXD1xO?cosoH zLau!4dBmW=^(=Vr z{qA@F^S*Qbcg}l_PS14rRCQNXS5?>a%&P8LCBG>@Fh;E%nS`N81U^u7mECEQ50$7bM7Dzh@(x;-0!>QA%4{44mTfhJYj`TK zN0aPleK}wYe}6Qjr+Xj|00@cQ?DGwXcrmHv#zTqQr?i=P0{5)mx1)dE?=96W)7AsS zx6Mj_kh_uNecOoFl8fuZ?WWa|#m@0hzy`Kf`SdWL2Z{%qyWAsVhdUkAvP_jr(j$cy znpR!cprsv_2t3?TqEDzkx@T&V#iL;n>EU;5;4+X%?2RL{KJ-DvoAYa$pOPG+vTs=2 z1?E3ZJauj;!Orw8Y~)73E^Xda-FlAisv~FKJ^=EFsg4}^dDq#YrES53TBz7TEGN*x z)*d~A=C{SEors+);WI6{pO*6CSjOURGXYVV&JI^>EsB=`XY)jW+#35CPbdbS!N8BN zUzZ``4bXu}lwhLGY_U3NICEaE)?rN%TfO=eCM)(A$38G0%=@xyH4sE~h!N5SF22Zi zKC~nIPmZ0*KNdBIKiPGcU;+Un+ws9BEE;nzui(3gKB>r)OpAh54mtV-0Sr-Tup1sy ze-BLaSnZH1770{po2|l-qMb-3JOv6vb7d^E;knS+KT#zS==?d#>y)8j-s=q|*ZH%J zb|=1z6-55(NC)!wI3dqSUVO(Zx`6;0lUdPj#KzYd6{jN{R^*AYr@4qxZZ)f9n3E^e z=VZ-p9T+RJjm!J<5(IvA8LTjD^p>89{RGI>igr?m{ZUi3&wUzj$ zk4j1azcg@PmGS;((RzEA6fk5}j4GPfH1a)cldW`1L~~}qh`iC-w!k$V5Um!=yW?4W;bw4k|AUR zZO%;p^Ou#Twyos12t7t%ZX_@{LBuOyYFWAcc+e+{?YaVV?Lg$)VQcrFIY5Un*aztQ zgGtM<=wsw55tN~0ezNmq>pj?$(C^ZL*_8jbv;;IfB4bp6-;}))O@Iv4*{Innm6aMU z0@sl{tnGT+ZZ_Lq)geKA7Efq!e6*V1*ma8FR4`Hea*MCbJ-%m^j?s!LvE!Be2B>9L zq-yL+5D=%8wx-pDd4Y!~_b!in`t*?Sx)D|ur-QO!t@L(t_E?|GzA^zW|A6Q7`_Fp2 zyVSIhJ3=Lkw0=3$l$BgAtb|&k(hx40Y>4vpy#0`H<`Zg^v6F!dWIl^bskJw$?*Tibnw82d(WBSEqL3#xXO>q*ZDw~&-a;)!3C@KX-H;5vi^ zdU}aMx&~3@#R+~oYsoT4Dq~6Pv{C`)#0Ida2+UD!dqO{xGWfGTKN@u&y6kc4N^V6z zFuyvOjsw2Lq6mD!s$U)0@De*%*^`tf&TWDq%%0++`2j8`G|Vt{!8?CRe(QV-JrR-@ZZzTzcg} zUK7i=rN^(M^@vKrbA>h3`p(%$tOVdNU+x5GH3Pm_Mh-l-$$5W(6KGgwi?d)U1Iyq8 zX-ix4-1zU={n`f3{=-@Wy|Bd)sW5^w%Tf%`>&1($Y z7uWJ>`B&8+sQthS5q&yD0B3OU=mhxmgIvhXLyJSO(R14-M~cS(x^+dY>~TGtpMBa6 zG&0N-l4NqNO(GM1y)nuIXgMk1*(i{n>vz6Ol*X(i@$Ffq$Y|RDiomqVy9Q^lzrC~W z%KXsM1q*Dk&;(pazYMn_o!!{WkelQs07J+n8O|&Q4BpIcA4nIkqHGi^Jq%I))1v9vrL6~&B`Xvb}chPnOOPQ6`{9f>EX!DC6Y^ikRRay`8#yqGYj?- z$HTWXXB08u@et<$C`caUh%T_L5*bFxE($&%E?pjTdn{<0laTaO89q zt+BxM1%G7DnS7p9-KK|%Go>T~qWQeyd8{N=dChC`FmPATk8R%$vA~&b4Qwz5{j%$B z?#L=5RZH1SFWw|_CJn`qM!&RUGc%T2m#Dlr#5lnGarhZ0p^)^Y9qCIe1(kC(XFW8+ zX9>Xi78fHRB8U`%SV6r@w4m2EUBk1=u!(RvgGDR!Mx{ z-pXOw<2~S~rHwLg_#wULF178UK{Hq%a7BCZIX|s}KRRx(lrrs0DT%1B3i^|fFWI-R ztCzcBd?%A`r(1;5kj6ZweO5zE=m8Og2!zm6$b76mQg<-L;bP%S#pfMCsh;{wqrLfU#wGl#=}bfjz0Rsmh+ zKSK40V4VF&O9K?`cwI+%EiG+FR{ua$ZWED1kxQR9j9(M+pDBK(k0E5LrJU3^`0$;0 z7}tN%HpIXbiEO`iMbl93psoV`!E1|J8fsVroMLI>r*buVvmy74>LM^C#K7wKLBS?4 z5U>KwOtUiMq)FFBqPXrI6#eT;IHjobTdpj_s>Yx#kL|%4xAcU7%sgxb!5Y<-s$+6~ zOL7g&lGAapQsfaoP&x;YNXqkuUZ$6&#pF*KtPS8CYyKk0NqGUHC@#AZ(lU}excW~S zC%yFFWGj9-@crw)1uh+EwUDb(w-Y?e?*ixl#6#FAI4VOJ+YQzONc;o#UyF%Vb>eQ- z{RK^8*A5{hx@Mm*3DJmo7}as{A1sbY>Yrygt@!}y2Sn~L2+&=cY!^r0zfpl{0Vy zsX}x>@M>u&pnGa1k+1SpGX3Zfi2h;4@|*5g;s9|@#|^zWfJ^(;fp&ztu zn%rRH;#9-y))9^tU`_a+5-apqOHv;0_xMk({(qJk{EzN`^*?I$f2ENZ*a^n?cPH3C zdvLfDjIa^x2<1P^{~td?S@k4*SG5lw(W9|@knRd`m770^-+}t#Zo(a>(f|MMKEK`v zS?(m;`*(l-_$JyKS1=isB70BWL$WW=$F1*Du3=8>MojgkjW~?hqPuiK{EkqCbq}(v zv#gJa7p3`xx&jZUjF3nDsPEo%zE( z+#U6O-Csjli3vg-#rN-SEY?r@T=A5`g;<|bs*v*$tpo z4-%^_rKuL%tP>qNy1VY?v^A|Z5j!))cpZ4GD{aM!8A*AugNTuDk1ANfs%`J2(SOA9 z&q8d1E~5J66xc#)*{5Cp zAFZYSarSQ~M~1iLE`u_+iM)^9f9t?E4G?zAV2hW(0ngpPg~0IPSb>mGfdj;xl(~ND zc0c6bXZHYFcc|LEc}CYBgP-5_#}|l|Kr%JdikYmU-5|OiaNICTUH`r!o4_6N4zXt_ zHrE<(|6wB1q{3YbfQS_Bf#?b7`xc_z2c12+ucY?1 zUP<$$_D0~D@kb-ZBvbLYR}jJ$o!Li@j-8YKEQ|@}mQ4>&{AK*FvK9S2qGUR33R2~# z{|ff8aWesGPKp>C4b6SffB=fX4T;K?T`LbA z;DJmJ8EcGh+qtea5Jfu#eO;7?j>N79kM%>ursPL4wW<8D=vQ^Y4GF(qvSR{1bzl| z-B`eD^w+L5Flh{*M~u}zZ6~Sq{iv8azCNn0{tgcvyHw(%BM;q>eORx&)D43sR^>cX zXr`>J(13?8;q?0tQ~;fDDrZ;FXmTe7j~oDvHY<~&=PN;Fr7Vk^tdx}H>2!TlJ)#~^ zVuS}z&A^+FI94Fax@KnD`T@FT-2uEbw&=sobFs-IHmi{k{dz`LR9S#^r@JpiV#QB& zAACJwV9V1waTCmif$u+q-N~wA4I|H0xR>yQ5-N!|5K$3zWer6A*78j6`_0u!CAEw= zhDk=_JL<|XrP0tr*^O4-i631vruZ(HA8t5|># z#1nXkRH3Q-01ASd^>AkexISwDJILKAko$j zTKpIV)FpGf6`NRr$dZwIw?@%6qg*D@v{?M#R)6yi4=);DaIvs+>Ih&0-A3g(_rKmd zbTme++323uVA+Xw-sFh)!&4RFP2vmF6{wVd)jtGK$5NJl!4~4^q~a9pqV^4Zn_9Ew zBGdu(psQ)yUdNG^na1Hex1<_HMfE74ch%&u_8%FuPr>KyDF6h#nzgkbAdZ4487x(20-%vEgj2RR0eu7DyS7yoSd`{Z`$0o-`RGxb`a@Vb6DJ#4HsMT zS4$jzu<>g@O?a@%8Em^+N4@DC?z73bO{Xv?T9OfZRBDInl%f z*eeHDkp73-|58Nc(NS@t1{5hD`>Q_xOZ~rIAiUB;Vqbw0{@#Br{?F&t)jq!ex#r(X z$0pa^YyQ3PKVBbmD4BM`6RM~VGQv5+=3g!#+Bbwku*uWQxM&_|cQ|!*9pr?gfIP^K zAd6oaBTXQ>DpqhsvH;QbNfUiNV$%$rOnd~9ZLDmZt0IJ&pd*J*?m;tT(C47+QWue1owMcx-mD0@xU5e>K(uM65p7ndkfFzdV)iJ zkTj8o<1TpO9qWRg^(oK@7%+HtLPyd`(~1U1jQMd4cyNhu1qV1!ABRx@t$~L#X?9@A zcC3;VXAcGGfHq79dqTDu6j_Oz0R$2w2z@2m00S0~C+`NpjPPfz2)AGX1Yd z4l1{%B9$_>&4u~Jw7jNDCR)E@?jTnOlvRIk#Reu9d#=a*x0G~owi7CIq%C(K5Nqpv zPv$~X2vSykG7-k{cd&$W0?JYh`b<28aNiLbk{M--$&>JF5Jc~5bhv0J9r0xaDfo4 z0NX2iej5(&f{!IXlGu1JzQMk#ervSA{fh}*rxnCSuDe;P8x2L1tS6Q15wAKd?0)Zc zku{Xrt^UF`Q2GFr$2_*VW~!0!>SFo0bH~$TALo@H(y)D7(f(GAXony|5Sy@G$pzpEFpRALMR~cJ`>UtS z*D74+P6+0U7ysENUL?@~k^-ymhbO}$dmj?-vAnE-K|@pl=+f>Bjn%$bg19EFK$_PBOzQ0?|N2r@tM`%kw6{rHYV;*!W2BgbOhFK|Z#b(29C) z&C)7W!v(>AG~ka#|EF^5XcU{L^%S9u3k1fwZ%Xe~#}aNu(Bp|!sBFSGh!vWlt8B!e z5FwZkAq@XOcZyEM?{4Eyl0}aWdYX?lBBP-QcFUxue#Ox%UD$4VU z-mO4$g#!xm`GPS)5=4_~hiZ|uQ2_;*oYTa7+xN}BUr9Xa5~cS5ScIVJs=;^oWa|&~Dv53Dvaws^ zx?J4Ic2e7Q0|$M;jv>b0ZiFB-eyqCXAks|Q7?>r38RQp>$qr3nEE+5l!VLZzGjO(a zo3j^=5N&lpqm^C(hr_QQfxD63I&+hjQGv6AAo#7ky+p&1eF;F@t{1|0RVzZpi>YL-=rDa0tqenk zh)jS(u>a{U5$GQtrZbYjRJq9wN(7LX!y-U_L|Kpf1ZWI;W7eK*wqcW#9_H86b%Pso%!c)9VsLecO}CYtla_=l(z<{A!sZM2%b~ zs$kk9kz^%g!$(F!&Jo}T-ilUeNZyEf>k!*R-a9h75uq?4PpBbotkxT*+I|301^42fdXl}-K@;)QCcCPk^bwD(BP6d2+OT6)Z zEy-bRoJIR9;C=dgG*=M<+i7)lxSb1;t}S@h(&i3g`C~8vnG#=`O6)`d&Z^SNKH=pD z{tG2VB}EAqggT(=H-fIRB+eq}zyEgM?Yd<2k>z&xqeI=>r&T0aNJ}s0``b1IV{#N!S4yXYVjeK=mh)$gGN4Yv#6|xuecB0 z82UKlo`QS;+dzci*#Ylx*mgMVkgW;atJyhqs&mJ|94I`p5;M?$elb6w!j4X{D1IUM zctFQAwIT;M18_l$HqqJb$le~>?BxSw2q9^(7XJR*BgQ?Xtg+|YuloLp3lRdV$29P1%9qW5kVFE*g73<%3F%Olh0r=$1 zn$dq#sv%wYze<%6s_xz00{6kH5TXR?_#h#KnLr^*pRLtC7-m$N{^c%l^ZUEcN zpFEH|{xcf&26z}ybVTo}or9o&j+LovWa}gl(^Jn!qRQ4MHKsRq7=gM-o1u(G6;=!g z8YX;=rd8mg5E=~EA3t{c!@3{=lhVcWG&EGHy`~qQ@a5JVVn-Tp1|^ArRW0m{O!AJc zvv|ydA9&!;7`ZXyURouQJ09D9_6x!Cm1Np|SBXB$n~+Xp=2$ki|I|46=jyj@fxI8? zAt^tBTIrwQW{7#Rsy2^(HhK>o`8ZW;dz7Lec9apn;c@D~JERI=(ABBbPS=W#_S5}( z|F9DXA%_niK5lnIN`@?D8ZDcvJB}+|FXufd{y;QyeKG^?0)oZ;*+5(9Q@O8@J$5zb zMT&L~ROteP;O@oSy|rsB^0jcLegc?awFdRu(Wp$3mtV*S&1i_4pVj6{YjM6iWl30p zK%^}ICD|cbf)Vp9dWF#Vw^_0^b>vGG@!Cre zE&($Q-Ht}mfeYFEYcg*e2zc|<*a6I5(blg>81LC>!l1EX508ARhdBeZP%}7OlLrTo4j5GO3XwFs zI|Zv08VI&rr?P+J5$nca<{kb?Kh;P%Ts{&BDd5j@Ag@{Y`LSto96Bpzp8gXQV3R5E zFt&3ixtFTUi!z>O4Cl?bXO;l>o@CKI2Y@n`Wq|F0QS3Svrq$Z7v-V%zhX!}&HS)?} zX9LqCNZupJ#ZLv=k`ETWlNGoQ!f+q~H~$(Jzutgy;RkJg{+BDkC1@&??6~w^7jQ)3MD>D@5e^4VCHg%zi5J&AP@(W2 z!8lltB`d$!?)s-&$$0F8#%aPmq>a?jvrr*Uezwv>Kr}R);*z_9kaf>*=PK3EEfxvS z$t!uIfJMnI1P;Li7odX84uxYMuSfO56TnZ{wkdH?s1Z=8dHDu( zfn-U4{QmFBD|iBYssK^>5_2_c>Y$=F1@!QuUD;o>fH~$3zYZqSB=^wFo;7#eMm1;B z$mFV=rVtoCS3f{W@;y-+#(Z~-5nvX0F$=$3AHFkrY`!un9cZ0v_VMjR!1U>*y#nmX z{D9p1`se^NJALa-;EOsa)Y__A@ml<~uUy=V-yDD8A(%7kay~3+-V-5o0&jsxpku8? zhz3fy;Nhxi0k@E3y^|pi~nTT2djfX!~wnw}zTlqcUw?owA z!UI5`tH5PK2vP{cwMX|ua_fy_4{#*iNDn2AR*3X(&w7;evam=jR0wER1SWnL5@-eA+V03+f=xtP*KQ5KMd~0!KdiAPpI>d#550L7^@%cu2mrZap z+{UJfaB^_KgD_U53d9T^TEK~zjLER(NZeuIOPOp;fan!mE(_enxG(V8VFJNmMA?$7 z7VZ)1cE)T4&_ax^HRn7Z!J|F0j+Xzo(vV7^$V57xcgO zRa|kA(MBe?z=n1%?So*z)HaKG(t@1CH#v+(+9a$`)3V4OW3$2Q#*y#aYXtP7Y0`!7 zARN-y4%Q3IWnS$w@Zt;Wo@IeE_-=Q9$mFF(yuEK7Yb1~uKMLl-5M#UOTPzK%Cx5s{J%{~iMVDsXCHIhcc|g}qS(cb4;o{>H=UutD1QKS-d=Fv ztyD=Vc@l}es)^eVlZFg`&d+}bQ4xn*{3_A>RJIz%{rC{ZMt-$3F^^r*;eyEC4d5pq zO*H#-ZX*3&+oyGwDB34Qg5+9OoYW~N_VSE*y06In=UK#+wCyt@g)BTt;6 zzQxO37hoVqlN8l$h#+|cBu_Z95<^#o45ZlU*IIMjAcaj2liXi#KY`u*!Yp z?OY>9wg8GiVkl+wS@SA7+GiM<`}aS}eol#UZOjW{EoLQGEU2jAzf}XqOdH#Pp5iXb z_;?T!m6qkVhx}-uXg1CB)CXgLWM+@Z$y3Qi{P<3zwi0PbQ%js|%8FDblIP+;uoB}B zTS1Z)U^;=MBoyBedI6p37ogii?RO1*SdY|5V`XrBd}eZM$MI!Jyss!!c~++|Xhoz@qZ~~}f#;Ej!66t9fx_8A zI4Ec2-h+Eazs52IT3l*jA_6i#hK=_I_~^0|=8k%&A!hey9Uwn=>FXKr8Hm3gz#whZ zS4h^ROZ8L49~As^EqysD=66Ww!uK^9xk%901AhmKrohoJ!jNIfOk&FTuy)0IZFQ3= z37Cfi!>s`8If(;k#O9Yj=te!O+c85Q$C(^r_?H+#`?f>s>cgG9i0PgEq=s#UR@g-& z!w-UYaKOmmRmtl50RS5>}Mvk@~(?9YgdFiX6FnaKDoLUpPRC)xZMm@Y-0U z7ksDyvt_x>A|(je1=t2m)?2XfK!_#f{I0*G-UV7L+~4h*e_{svq>qKf2$~q&52rxA z1>Zj2c0Az%K17$jZa#<=T8FMDS+071sgf}62MdDqk--7vL9j60e>xj*Na2gh^6-{cra#Vx+NBpI-d~6afd!JuZZxQ4w9;Iz)rOnLEIy#X)9#JFgo&KT4eZ3i~OkT4pA6 z*+>eu5_nWbJTiC!cp@SHT0tZEf1pANfQOOae;dTK=jc^>(a#arnSg115CY?3!Ty{n z$qfr|ul|CM2K*yX9s#07{~_@~XAVorUO;dDLxcYlMTndK6DY*Z|C3h#ciO-^w60JB zB?*xb9XWP{mY}2ip*?+uQb^<&E4#3$nEZLcn{;gA*G%q$clWO2UubeF zDAwE}?BYT|2vX<|v?tFlEFi1$b6t5bG*j-Ig&3=?#`_%Bz>x7lywZ)|g}Jz;KhW*r z##@ED$~KYV>d9_2TJ@Tx%a^a-mO`8Rqd33WYeHZk=UK(VAJ>zDGGS7&aa_8o%n;FCH#Z(bSDA zp)A-6;%Q{AEBLgSwefW2cw-6e7Sl&f?pR72$4jgc;lga~--Hy-HoO_au5jWs!%u#0 zD-!9WV;OtZJP!6z*SD%^T+6poQ_EcXHp}FZ9ZEK%Seyby4=S zW^_rtfqa?YuB*;@j)rhVZv|Z*+!`@CO1qbQPYXqb44}R_(pKn!t-0l7k{!9>qt&J= z6zFJC(&p%GqN_iaB|0_AG9T2^?gt8jxPw`1iuo*wu@opGP!|i zd%AL#W5kDvOgA+&(4@gP`C z-By%j%ag07y7A#wql#uKZ-SzBl@y-cz^Y2@rCtrf3z49G<u70x2VBrGi%($}uyH<{2ebwR!tNW5ik+W$ZW48>oUzLoziCU&dyeVR< zHs(~mU9_t@{Z2F9-Ea6SeNIr;4WA+&2Bg+iW{YduiDmif>4p-?_xg zV;b@LO1_nXarUkn(T9N>#kSXU70+&+URc8DwQ5${ZJ)Bz6!Ey^x32e;Nxl5h&y#WG zCrJWTG|NV+Kk6u(exZ?5QHlMWa%{#`wb@r~eRYppy|~OlFkQpBw>H{8wjkA^f3&_3 z=X5zHyXk7ClhCGuc5ixRvUanu%JpJ1a|`6$e;{X#4VXm-bO{(zkX%S~%a*v9MoMKe-@jKrYte$Lj z`K@meXWhr*@7ZDFF80lKk#X)SN8bEZ5(+U?D;w5 zJei2pyVg?bz`ZGWVu3Lm{rWQ2IQQd#?y0oMo5@_I>xOkCM{DUPcwfi`Xfs9?*)&vc&%C4Y4QpYzP$a-ee$+&;EWu$^@zS)Y zYJqJQG^m^s*>I#r`B`LuhECf)$_8fZ@HS zv4Kau&cwZKQFjE8a={~P*YVCN$|^>V)({8YIsqD-6t5wbs=m_ zi*k)jh4x)}`D=@)CC35FaPKj3`nTo9`@DMlnO_VXCBsKg9Gl5}*PSjgM3dKTuIi)J zVAY$9R{jH>Sv(>56q7eoZgr1sUa;FGC7~>Oet{%}fvx%8)(uI2sRp5r>5~q`_Z}UI zyM59gEmdOjrNlf|Cm4H6Dna>+4tsR}Nzg%j`KcxHWNJP? zgL>pxz*CAh%c;JS&oYlQ_n3$`B%|*Zwc0jTq%gnpW9~LvQSX;ctS&PUesqQM zwd9DfkDYbkd1e0vW%j*zb3bhilYO${^XIAIY>%JtrHZRzTFPGCQ%!HV)q=ab7uV2Z zG}N)ACkA8*O zH6bn7G6jwjpNmm>lrt@TbNm#yOfigR+~>+_`)o%gG`$@;hDGAAt&7jOgqbvoTU?~= z{rxzZRSjrbcc!iErd-K>e0ja7*G3<&CAqA~i^=3t+>?D-^p4r^C10J&RG{Lxo_(3n zxhG~v-qPNQoiBf_FFa^q^;t3e$%=u^IHu(#(bd$wL_=8~nM>wqI=hlL=}nSrr@NEu z^3dGEb$XUMBsqHf`juu1vhfNMRyo%co|p;6%(QDr-zq8oq{L8Iy1zMLD&@@2`1I7L zb|0zaGt>iYM=ph6wKi%+k8`Oj#_^o?gWo@lk^PMUAK5&qwyBnV+-TNz^_e{~ULBaZZ3( zFTdqobgAx{LSJvn%5Or9oMr~sI*^w1#SM|VVL|-0wOd8q>QeU4`EZmtlsapYF%QG^ zlErYXz4@q}IY(yCGehx};WMqOpU>a$&0%~@hLe%HGpw!|NT%TH=o;miF06g@-Rg7+ z&Y9KsLI|d|h-)8U?T+U@?(>PWLtkRW- zmSh=hSB!d7+piv1>N{Hyei<7W6l5nvMO&t^D6lx2^YpItTo7Nq%9Q)HtP9PmyN=5_ zk{#NJKgJb}Ax8WhnR z(eNn8!0@sQGa}I*Cl#pIU!A7MNGs<+b1M8$;O_Qu9c3%l&(0J~ zU4MN3l%Y<7`}5NKw}R1CsEm^)KCJE7Iq?J@wp|g}mveMNYsEZfL;77}4Dq_4WZ@Dn zUW&9VJH^n2V+$wRFLb>LRAH)Y>K`a}><=`e7rJJZd+m9E_wLVIvT^l2h%(uB500^H z7dD|g?JCUVf!=RN1Rl~{w%2JEjxKUVx9`O%Tw^`EtFsop_3}LLi)Vp+Eg#G#G^rvi zD7WJ1IExFOF^?9?f4$i*j4sG&o$nN-h3cDr&;AZ7RlZ8~h#z~^3RjhfRSKVdS;wF4 zqJ;6JHsTO12(lXzZd8y>(oQ$1M~_;Tb}JZln+xAH)bpR1E#@#;sFcN6$fluset6Rd zJB$jSFGdNDoWg38v5=bje%VZ6W8|^-Zgx|OL^U}UDD+g?)E+OTZV>O4O~qs$mt1^1 zcI!*fXuP84aS-y)74PR-^cZeo{?#z|?Du^;XJ=!b|p zc~v|zQV89hC2{|^aInS9pb+`o*(3fkByoe6=xbj1z5QZ9W1xnVG^dtx7%7*Hz1FQX z6;_XPPzx6vJS#z=n&%mO1Zz*f)_J7FpKB@fgW1R#B8s|7E>ertV)hS6b z$T3B{UPaZB_(6P5=-Ywf5~(_kqT5m3r)+fFJT*o2gx_Qg)4p*;0|!&G(K|}#yize$ zi)d8Q@P{)BuUBY4-BIBRzgjT(TH{*7CRNNeZNJqs7Ue^|(Y&oKMe2-q2dIi}drOx{ z>a=xRy$`=)a7MKqy=5pxHRgQ$s>YU6rf|ffRyPxkI^XK24`K7~p41dKiksib6@3tG zc|rYrVEvCz?1fh)qIDr%9d!NgnWR=U8cuh$*rU;>YqBLVROpRnZ zdNuj{M-}fdg=?+E3@Doyj~<>V+$uC{O_X88ZUsnlg!E*S)+LnM7_}`dCJ4!Hw#Uze zjC_)@zjnP9qdX?e+{0GfpT;jK%&l!RLhd3%S(jHc~WQaXw}2$>G>e5 z#wboT>yhw)B`x`i3Xin*z8}vG#E{WrmfrcxHdL6-7JEhCrKi+gPKM#zQ`S?8j}km2 z%QJbJ3pP_38b*rn@o2j?UKd6&oc`E5hmp(XBXi^mtsHq+va2t)BI=c$kLqD=J38=b z+T6|bx5+3w$DFnv-psK4mPyw8 z(2gwHCf@1`CB&n+**r|ec-VK!Rcc(LU{h*;zmzv^=qS z>a}XFcX=!DA4C(A8?9txYWOcnTFAaC$G&~^_`JrI)K^n#BS_A{>I}UXEJg0}d6&;T zv+h^c4wFq+>unvO#|ACgH1N`o`Hzw;?TJd9evr#Js2;uLMQ%&3e!@$@EVGvC7+WK; zU>|V@(jrisHzUvS8ailkN$81LgloD1ecRdG_c+rh#bxikRH+_2@-A`)l&f7V5^bpy z3i|zMy70meQu9pAR%eJ+cgZ{TXWMik#q(X)6?o2aTZ`V%>XD!bW7nihT=M#j5m1mo z=IP>!-MdCo$T-4wh4`Ko-Dd5?#jVqt6Di%YbC_Lg{t@J> zqSsU)fs1@GvZD9&9TF)z5+9XNlrM7m%(ZCBFzXePJ_UAG?}(*Q8XAOgRS$pl;snRB z<%vC`M6PZ-$T=}r6l)=6s;iD)$4a8b1o?A z#O@ol*~#$dFPGLAj-3RjV)@I1^+lMI9slh#rD!y`%T`AA&GOd2o))8ndu(MC->lH4 z{P)vWE841%l&Z`yOrzPl<@M*NuxzgqiPfebgTeQdgKtAu;^F`pi5C_Bg+W6#=da{RXln#svs%abOEnJ?Y-#80HD0dhsHnf-Cl zS0*gi@;DCJW@SGUcxTVMH1!18qv?3ozF;`?`Mt_<${(FdFD9G_ZO&IY!Fw*|P2lxW+}jHQ%C9ll;@}J(d)Cvs zVM#WHEpJOgZ?n$o6<;d|H+x*jXHceN^`+X{8VdQWR{WS+-25!&Vja#q9vYLqr)HS7 zaHnM8Oxrw{n?G~M>y=uqkdLFc=+0S^qi#J35;`tzpoo4K6!V$SsGe^j0OiL&8S#v> zG{G~!L z1CF26dDdmC(~)hJ`z3s#k+O|^&DWwsd@?5s6NfXNMBj|HGZcDH)t?Y6Zf8In)#_R* zdf(*Yk(dh!PBJ{$;?#n6&SrcO7xHtvN*1~CkQ7Cs;TGT1qtYGa)i!I!FHodmr#I{y z-L6JeO2}_H)40~OkMdt&qfb*qArpj8TMH>w5S7o?ocC}$$tR&AK^=9;EthvBQ_$BU zWeZ>T=~-GjZya@ZO5Lx-;%WAK)aIo2ijGvvoKlxC!2%$Bko>wQ$n>Hj=1b&ykYvd; z^?Xgc`1}sjd0FHaxGTuR1i%<4S+Gi7&j`qF}j|?&rIr^M1*hJ0H7s zPvnaJq|PRBBcVKtZ8K0Yq?R5;{Z{qL(Z;4182ozUV$^H3U};a9C9162MA>jx{m2EU zC7K~c|LOD@+hx9U`fgHb+6pn`TR{e8?2KmK=rGCAH`XgEgmJtHzGGWks?%O$&*ej192Wjd zZ$dM6Mp1xNY%QY-btAV zbm-t%WUr}&*a%s-#Re6om9V#euy$`zzTTeXw|a3DWon{8?Wvqi zxq4?h@FD3t)f5x@%o;|f?+YeW8Mju9e?ayLeD`mS;+zCyMZv`FA%Tx;2Zv^GzdW{Uc>9Z@J z{H%SG(I9?@J+o1de{f7p=s3wTcVA(e{>7)uy<^HBKTd z(uTS4+?UTcpN-a0-`VJ+34 zvwX#yZ9o){WmkF8^hn65-y#40Ln=dA$_uL`kHgMY*Y&a4Qwti3_UloV_gM5Qo5k~e z%DO1pQKwt-{leHtLjeCVohNoyRnKLvDs&iFuvXl$jV>^?zw{H)5x6thYdS;!2O9Pk z>}U*l{{Fe3DzD$ADpYD{s@eG2fNPi_)w;oMCfQ;kzjME=^&i`1NWYZv`O%IpRj%L^ z#|0PCCkA^N72P??Qs}B?V?>vsc%Qb{%w2ra6zs~HqAQEsaLTQIVig&#;bxM|eK(Q# zmNoT8)JYP=T9J{}TH}*$m_8-Vk zf@Yc_P|eY9daHo=cK0ZqLFUG92ji)j9t+9zWbIF3ex&NO55#c2mYE#0pLl9s1o<~L zBmI4%F}Oy0lFu$5hf(&sM|yj18FlH?ywgVH_-O5V$EqoFWYn#wv+>6Ay|tT2obe{k zF;Mmu^Fgb2rzY~%WboU1JWZ>}(_cAv;;QJzd++=cPr>)A&hp;<97eTr(dvD}lez&C zi?1&p3>%G>e7 z!^9%$?qtz`Xt4|zhmu)w1p6qv({eQ^wZzF2LS&*;mC4Dwo1?EqC8)U5#vQSqd?)dN!Yu*V7rNNCbaNPy4@RX~tV zLhn@&2uKUk1ra<_1B8+QflviP2Z7KP=tT>OawaV1kq}vy@dE_HW ztvkuk%Nlo`+M>`+<1*UV1mHlZxh-Z6Sd*)j)X6wG3o1i(B!E$M$%8(tt_On z{bo~i$l>pIpD)gkH2&qV>iP%zd4{!>Nof1DCToOJUxGM;n&Hrj1OqGfyDH#%$|m^| z#wGx3?~uF>lA3qG5JT*|yY}g}M9xs1n0R<@r>ezQP4#{0J}urd*?wm>r(@8Qm0ps0 z(rBHQc^zCNfah_s(1H9AH(nFbZUh7F??L$vq{OjMtmC({sjVmSW=ZT z&?A{XWi1#g6`hr1ovmM%07d-S1R3GVfo56hrvOZbNbncmio&TMiU+Li$4+%=yp zrCqK`vwSB^X#iSX`X)?YP6_=c3=LRr(VtuL{JdW6^0@qMP2ygAq~x7y|8-#!4VPs~ zJHC4@S7CG!X_M{sQNl~KW=8O{>QmRz0+1@Chhc`YwNxc?503y$~Ae(YkxL5QNsDG z*2jW#Zip=P-=)=+_p>HpM>zgX{P%?X`(^n59V2jBSHEI*QjD40Zpr&UZz-T`o>#Qx8_!2e4*rnBPMF3wF26$<-tPNw-A7uVR*4(-2x{yhi(eh>byVuMRd zvVaZn#l_h1B~DQD9ITWATF58%C!<>c9Kol1R-}Y(4tv4nJ?-o9@@>Z5%VbB8Z*bAS zf+)(u#h4`D;MiSsm0F%e=km;6qIU6qK~KQRPa3T#i?16gL5ssiVtG848U1_1e>Sno zx0{bv_+NFy|IN(uUFgJgEb08VOSltkBB2B!PYL=OmDZK$pC=yw&z#_}kdKXJi{HPk z^QQ@JuAU*BXc>7WbvsiW_!)#RNXM%nZ-`YTJRjwJ6a4X@_kNyY+urMqq)$rsLstF; z#Q239Pxah|GM6Xj^`2$Kn(XF%t%wvASaIN;cubv89vmo6Tf8*YrttIB2YXIk(m#>Z z$(~@teAoBh&B`k&NuLpluTwq+slS+`{hz5)4TkI8W!xH-HxNt+8-Mx!ZNR-}a{^nm7DX-M-r_C%MHU$C1Co<(b5)uHC?XD44h?mzYU}A`u9L z_SY?AFu&uFBW3GmJW}3(C(V9saDuPf24C9tB0Qw&^kKqhy?s83U>ww?L>?XoiYi#y$x=kZO z_!CQBqW+I_0{-#KX5#7<#|0Mb#|5Tmjk9OepC=}fRXD6=oC13PGw3C12hwf69Na{U zl=>!>L{I0+-d%Uyaf05w9OPt{rsd)-RKwI=?=v>krq4#*Q&e6K^DXoNyIFq7UzC*F zatY?yx6!+f2~ACYSEX~5abhYU17OQwgM*4p)Mj*G_*T@iY`u<%E?t)`Kj>S*CJixX zYMnPelGYrHx&959Zsw z^T6|ZyZ@uzv_hEcJ)7EbJlj1!))=tto@;tpN~+ZDZG_+i)u|-vU=Fh%OW?&0!`qTl z`y@R`JsL1$GEB6iqh06yqiM?}rBhbba+A8~hc0aTXm`7PRFpeXM-{^SYTN@056z#U zIGJfZ!ornstFpSPcz~<_9tRo0MC_I6sfxOasz)WZcNh+-)}*!l1z)15?-!Cxs=l4B zv@CFO$*mZ0?WQ92Z{g4h;Jb2wXxdhAHeG*FjII`-i|9RT^Saw|)KptHaY@foXp^<| zQPR5ks5+&EO4^IWN-qalCMQIiq1$LXz|(@WYhv5v1Hs<8FlMirHQy~LY8kGN95h{K zNPO+Qncj4lqjaTT&|NrLcL%WP7l&ub`k<%qeYU?Xr_!uX1njR6dfBjS2pi($<*A(K zD4nI~PmGB*WOmAcWbt{lGY#ijw2F;8O%D-e4JPK|Pr6pHHw$LVCk4}5_WBJ|p>@h& zj5%v_X6J0;LT2bwr-vc@B__6ash73ISm29YvlIGe%Z~VyLazr6{VayeL(c-;LVM17 zGz34G>eQtKQ3jjL_k|V7Rr{Jai;Q(RE7C({rry-w1gX>6-?U29Nl17b7R@5!a-%s; zY{sftl28r&^xmGu_G3JQKqF10&6^(jVG_Tvq|MuaY|Q;o;CUF*$o^@+K*jpt6K9`t zU(n!{hTJ9|4*(+1**VXtaIf|Kci+;!$B{4S$vm`|yM-ZJo~p(i#i|MYslu03W%v0# zL@SV4{J@tDn(&YOHePJWeLev-}r`gMmGX;Ns{k+z&NHJB;! z!lKSaF<}A+hHfDUu;-6iNys>DlE?b+Xl;Inxhs zRb`#@}V-#FM0lVZP{hf^g3rC1^+G+N70!>){X@bJ9c zsO6TqopJ3(@)m$xG6uvuNm(%rbtc93j_<40eP?#PGH@R5R!^6VipoVN9FIo%FyJ9k zO8rfN&26C#`od1r_@qexU4{cX&sFhjf7nSo;fH482djgl)b9n6t5BWej6?pL_%QaO zdAYGCp>l^YO0eAL8dkcro$}OepBgM|UF+czG*YJIO^MN3Rh7ZBq-4!hug0M+&nJF$ zh>`Pk);D;IdLXYJASBMXq5=utue&tZS9dhjz+>w>c0uW=xGUzD74>+=ZWhjXx)^5E zZ;7lZM6a-VWc${_Y6Pu(VJxPfJh{e2?8ageE{kDWtoysgesk@Jb=2h}l0?dO8J8WK z*%bMi+#Pv(XmCDjFc%B0px{IhtkhNCUtg>uM#cj@zgO>A%3>{aRlj08C8%Uk;XrnG z+a&)^XcJ@YGceYZ%TCc5Dc^Ub$s4(q6;foghxDW&MmI;SR_%Lrza49nXkVO?jOs3S z_p05S;mvvT!p=+=+!J^+42pIP5nyvpK*8AQxL+>kiC+L)<)_G{4 z?W(<`ov%Cq|2Su>c*@hgl!Ml1qN;Eg?eRiEa6?C2LUm?>aFAn`j7?E_Mx4Z+rG%f8 zM#^)zHeK5_QGEqp%Y@RyqY;c_lYt1U6w{^F>&H($>pP7XP{oo_NPB^|@yAd(MVw9{ zsf<56WLw?jV9Slkl>-?Go*dZ}XLro8bZg?l8prI;3ur;0zUj6{JKsc91XqkjC##eB zPsdk+7AR}U`-FILdTds|{}di1{MB~lTnP1Dk5ze3{@r5^$j-gNuC%*mI^m*ZH)F>%I89QWq`u&-~y*mevMV|$@ zyndJ5R>_;)0+Ye8!!$m9Gk4wo`=8kS1WQcTJ}N5p)0vk%zF3-Td_u3&_78d8V%lPvp$plwKyuA?fF)Wz*CUC`g0g0Td|yyJSxJ56RrH9!=LPYME9 zpjVf`V%nJO68iy)MZ3HjwVFJP@p3CFM~+UE*n7H) zGoQEGn<hwu>{cCw2k*24Ie)I2Un;Mo-edA*i06A(Bb z2v0L8k>v#_#s=8&GXBw)%UL;;1#{&ZKr>)-jdxaGB=UHCMF}^ZWZ6QZ61kq?;pJ2> zHg(dW&t5Dla60WI$0(^p%9TX*r(Q21d8j&mJT(+A^2b;6r;;+mXOuR$F>$H6M2aOu zCNi^~n65ldH}>XyjVark{4c^rq#Hp!(4H(fC7M=y{tY8{Sc+s|Ws2jI?4r&! z@0o9H#?f2Cl>F0jC;ik6M;qUiew-^ca!ezW4WL3)A0pIb-HK^@Sb2p$`L7HBGd7juH@kx3x4( z1=!)~z(%#iWpCXwiDG(PDGyWcs)_u+WGBBh=4<++dkJ5IAM*!(qNXPTrGuR>VI(40 zZePwynS}X$zeup`k*4c95`p$Bz2Qz-9e8C@k?~Bod4eFAhJ{K2`J^;cuLdmqhv4k6 z#KeYE?@J*y8USg}x^(P|@V`jjzNbsxF)t+@rgZ9xjwT?qrCVYd%ju|1o@schMpva+ zXB!rfl-jRc{?1qMvb86#SJ`<{$B zXV0C2t6jk!Gv*byJqoW@PZh_C)dp4uT|U&~V;hf2gp!7_3&vc69W%)WwwPL3_EbB> zDq0=TPsib2r5ID~w7~v!nTomEiJqxf@{)6jv9QndRI84kEnO2Y10R#)RT#6v%AM0# z&jPmFJ+t-?UnTaMn#yC@@H8a!-s9s$Oba8r%yb+Aw0AW4!>TxT$M~q6RB7SG62!)1g&#m8Fm5 z*Baph+S2$*TavFvmyqs_YuHsSXBVtaH=`e@TG*M^aT7i8ikAlWM(r~#`_^k032|&L zv5*j!o?7D+KW8!)ahKY%A2rUZ0nIgCeK}KNOW;4PboaU@r zyf@%}?w8J~^nCkPrE8M3p0HV&F@5n$pQroF;x>_mnILNA)!C>+CTYH$_^Wa>_g3V! zX7rY}SPy8rZ^mJZnss8VJ5{g7I8;B=h_n~>Hgob;M5SNeY^4{&3&R_pjc|2!+jVHA zqPQg(y-OjB4tC)bi+S z+>dj&#d}%~9#j7ZmxE3nZG9%GH;o-?86fn|5Llcfz(r*G?d;$o?(4AuJ%CnHjwQwa zoeG<3+u-${G>oFq+!t^`7Ro?ct6AmGkK?cLB58$t6<-4!7BV|jIFXUwNRA`XOK7%* z@3;NJRvRel80eYjR3s%nPApHNd9gatFS-((_^n8d1F;P7IwtnM;9~8^@eb$+Z@opc zgZI)}q(;A)4+Le0g6r=(4rj!}*MFQ_vhI-6!J%fZ^@`Hw4(PQv-qzc|-fe7VoB$5! zg*Ons=F+A*tDOyAFT zHX>IRV1|u!an@PR@(muo{6@!x`F<*;x4N@q6yL7tf7YN$?!3jy3MSGiWFW*uJ~ave z2)O`cGhHfH{`td$O6ZzM(a`*PXd;~vlXk+ULvDe%g-RG)?2FNW@)Fu4A8Nlv^tbUc zt@8=y_PrQNAOTsglTV3rLU#KeKbl$BaKQ`|R6IHgseJ4KF*n_&uF>2G>{AOsvqOTyF9tLSN z-%k+8BBkx2adByZSg2g-wgt)GLp1SXI=;UP>ZI#c*g-N%XS<+L-Y~sSF+8(d4G|m` z>2-MX#71zi)5(Ccl4G zK>oW$NDNPR@+KaDQ~jXOJ6%3go1$@Wg_GFzMJ@I( zkFNeDp`r+21ftYk*j`GeQPXOCJxVr;8J2#V-VyPcy_AA3f-e$>>ZT>T*jvDNu zhQq!;!`ZXDiI5FbhmSDT>SDmn7*|L)%ksgM>zVRx9o_4+;u5|gkqJW__ILgT#0Xlh zv@YDDS=p8iz2=yL!WHdX@6&Rj1c9C;;9>=;@I5Ezg`y_`0klbv$NxP2&m_fnW~-sL zcf0zfI0KcGgO?6^ujR=<+#_uyaVzigSf!jBt4pH-v?22T{iJ^Z@$%l(v?z#A$Fz>! z=QN$RSiRingPFqLU2$KrAqn1K6ZGn23 z(FexAr$U~--+NZQRyL)<=`*I8VNx(v7AVBb?I6{AO_?yM&inI_lN{FnJN=(oc`{g1 zD0MXqX8h+Z{|la_YAFpOr22>+{Wsjse>*>n>8=z9e;LjOY?pP+`)?YC8oOVG>fdj0 zBhJ9=ShsZ$xVN8P@Mdlf`)n5|r^<%S`6&bqJ8lQyUYnfvef#6waFAdkL_;eBi_A)u zVk(iYzr#P2#D8+1lb*xmilQVt8~X_Tr92)%QSjZ-M`t(Y;?X)mSAn0oLTEr!ZcX?E2wmV^_5OyqQa~%FlkQ%=}-EiTP4mgy6^@kS8Mdf1Eq8jAO|{+(M)4A%3Q; z>GB@EIs(#E{cECyHX2*}K%QYg$$EXkei7%GMQi%XYO6G?iO4n;b>OpyyY*19ASY!R zxm@@~*u^bMaw>+Ak2~>1$+iHi*Rm5ZtT?r5e7eylPkD8^Q-}Pc7jgZNashoZn&ICR~IUb$hF;wq)9HMG*{QRs*?n8@%~Y3UF~m~dc^o2ef=xTI$jg}BPXGoA9-b*Rf#O>PAA?d@-P z%+;%XyM5i^{Cd3&%#TW(dUjBE>f&jvIm7CuOl*+%o?W5jeI=LcJIXQ}*J9)>&E8!u z0}$evDdtK0^(}#E{ZWr$-lA+;qh_~z%JCep4VJ77^ufNEezaz`kkakF_B~HvZItNB zCS_6=L1|63735k9O&4t$&cdCEAsg}hwEV8{e*S3egcjTwgdXu0@|K#X;>5!e+CWaj z88m$Ol(+;2-sM}c4=|R*{W8Ua{9WRP6zgRVdvT=Ld%>Dd#Pozvzo%+uF6h7znfR%d zs1(xb7NyVjz1bL7jTtedCn(2SzaJ^AL;m*-^1p?B1z}lLlEMH((A4YnWNaFYPbxo- zHNFTYlQ7l@;J8r@zh@#M${Le1v=>il%@nx80OjSk^<9uD|7N$~3Dx7!8%oETMHjn+ z0U;^c1Al2OsjXQ?1q$y|Rx7`z%L>29vtXcn+Z9X+81p7|plVT_@ftZH=Rt4M_4Ob$ z422dqBWWEqjqPN8;`S4FXkTm!AtaNYJT>S9t(>0tjX(*`Ei`TOdLM1%U3gYQHLB6| zUgpm7K^~w&uj6G++YhljR4;7@y^6nT)x^ILs_60+$&zVI+zZvw#TZA_nbM)MgS`2Z zspuVU^NYp#xh^Qnfztv}#@VU&3hqX2;a+XtH(E1&p172to(_QBe)Wc0?)b3-Q>*Me z^9aLJ8=X#x7ok*OW(if^i`dS?J$`I+aF|c5Ef^kNI6S8fgyfc+@7WrfkROm!C zRJ*92F8xLcp#g(YOTwrSCbn(LEt*fFX&z+vbYq8NSc;-0qaky_1}#~}#a&N{UD&MN z#J=jXJ+If9t>+^?6y-#8Oa|5xgw(V3%AJlwC)cyx$~%p59im_Lcv*d+xki(0AZJG>eV#CaQ4UX_Ek`^QJ<3!l|4t=h9x3}gwfnnDCr?L=ok zhTi&hh!pR?w@u-yRgvRKH69|n@?QNxQuvLhzt(%bTRCB{~}lP zwlBs|4ff4Yz_Xrpjk}wc&+8d<4|>=tvy|?LUwSz3tzS>!AVw3MTdEUfsCs_RgMUzH zcIR2n^qm1~Uj^YQ*G_*1`sD<;3rRK`EL60*S8tphm9j!17!vbo_7DjGw~%*4I~uZqj7B7R2J3HrU{rX4X;Zie!jS##la8S#^IF zVx6}#k&7G{$Nyn}^4;&NLwB`C8a|IFuhkFiSMEAidPDE#Zp>wnaW^$=IpcP9B_5eEJpK|$D zO{CdL37G}OF$KF9d76F(7@v2dtgvKk(Pz!TUwl~nhno6D$-7=(>G7{wx;Qb2&Ud<$ zrW9hoNm0Y#RnXfL5taLRUP9+MEsTbl&~-E`j@YH=u(7z zyN_rQl>$@=$2tzj8@2~`7|lOfxhYji61JY~@zZ~vSh96VOVhW-O3ie<`hnvPeR<5R zM#OK@z9kJA*L`m-&SqbraSSkRX}q4;@51R+`pKO-PoLn-KjCBMOi|Sj=k@>WPxJkW zCEP=%shO=i-3@lxSMSQJVwP@1!v_&je_DX>{Y(pr4Bxvr{b1oW$@m!$99BtW-qe2l zL^P&tlqnD8un?6EFTtYQ)p&iP#H1n!!_Oa09CI7ru5zT*nksIna*3b&i8`vzA)PU&n(>LkJ#TNIB||PVQ0dl7y7&?c)l7D(;~)~Yv#6*%LHyJpKNZ+U zQ8}_O%@--FnTr3-XP_9gga3do^j6R-b`n~*C|SHqH(8F*=}LfaahQ1Q+^z}nP<4)5 z)zCCgaMewVNt;j9;Unj5bZ&31y2Jg9&Jc5fYvN_y1*)*L?g@*kTMZ?$S6wxOnw?V9 zgQG?H7#5$(2zweZR(sE@J{Mpz>8&!or`6f?5nehGB>w64nrMXrD~2MABp)`vF;&== z87RAxWk_ShUr_v{P111Qp6W~bmlzF^mrs5!1EFrV4vRyvtj4JxK5qk>fyEGa5C(HK z83z2h0=R2E=r^S_J|=m{+R%vKY0SUPLzHq{4!r1?Z(et0XZX>@A`oH7!O#p3=9HG8 z5d{e3*NYf*@(g$C_6=UpI4|^ zc|4*d++p6-E{!9`$G3xssz?}A-4Ju_xhK(<(YxnDXSi$&-M3e z_htt6G@^S#u6hI#$`NTdV_DEK6l3g%5pAO<&$rH_JF({JJ^P#~D;k#ZY30Fu_rwFeP5EZXi!RD3lw6=8=BNg|A>=n70;;1%^ypHG$Q>f1SplpGn-%Gj)P-0o=WefWe=@$% z7#5Cpy4I3XNoILr^#sr+s=E+BF%=4{MS#T?bl+C14G{IxMEWy|ZMuy`2ZX&Fi7?b# zp~(CjKhB+Z=R4@WlxBwJJD`K|U6UUQU`slkT5s`cjHyf`Dd60^+D%_P^H%ggK9i>% zz!{d)@T6!2S%|2)s|!@$1;n3x1!Uh6hf@57SK1G50us!XBS;KXO>6qCY_^8Ak(#f+ zc{DLLnlDG$5;q0txN@{lXPza^M_x}V4n`3@w=d8DxIjD(1WDA7bNzaz0LF_hJK$1< zrf3?`woGJsoRxCuN5U${B{fn_Q}8X+C(i3CNTVk|&Vjfll;?jtc6FIZF-569@;70% z99;3U*0w7DIo{7rPal(>9z!D#zL z8muN4_eW3>2V?imYuRQbyX{>R<1vn4`ta+rf+1hc_g|-XZ zGLdboL3lgrp=6#ysuI)0i>Pp9Q0hnHU)i(>v;4bi=H|eRB1gv?8Q5HEpkgWi>P$O22*L z{QkoEm$0!2JtB{*^)+_~tH)7i15P1;WfzM4dphL6CIMb_woO?klw{sS|1!^>p)nYh z-x(0rS`U7^BxsSGh0l%=^B60xkMtFJQ@a9t>n;cuEzNQmT#65$*tHz08B*bOIl2gZ zK*9V}FacQQ(%6_)&8F@FD`_Oj4nln|htRbgVuh3qnVQmZa6e%RKI5jyumfNYR<{eo z3wht|gzo!G$FJs^i}?`kd>1|0GaT9Yy;BhCdLH-OR&GN_ z)~2XXT_b}N2sg!8^;To6g|;QFkh*5faY5xEiCj^hs7E=lFYOV{rvjRCix!MayhI60 z$=p!Hw(yfyR&OTH!DJOUyTfl_j-nCWjTLp)j5Tq;vx{b$!}3n*(LC7~|KRK5Jebt= z2`;nI={60d);wqgnstvVlrL*QZ{ZJZ-yUZ%spRu^o@Li&A}TB0J?_l4K-AM0Zqot4 zV;D3F-HDbV1U0yNZke+1>@afpQ zyt{$k{%Mg)H+=}j)Co6i0gQE4;{)~JYi!zoRGU(n`yL_Gh*-!?`s8_3=#n95|Jumy3k^hFuyE?;3kRx|ymO<6{{2z*SxvLY&+yO7vU-Q{(8|iHc|G{Ua17>}K@tfG6&(6ChsRiV2R*JcakzT1r4xk1dq~krt&x3BDNL{ zKc=_mY08Wg=I7GCT4q5X2fpr|RXtHuW6Z>O1JY%a%wcg;p^>P?mhEn_ZzH0r{J^8X zr&cC9r!)tmEc^b)xyh6NcrDmB*4QiF&C#cPn_+xGIg^%bQ3wLXD2-fRGNw;GAb zzJNE5&uv?xo3y5@iG4Xwiu5j{rd&>0x~HGg53lc5hYsRmIpG0Cyl8wN!bW&|ho`yV zB`iRw2I-Ij^JkIXD$&Z}njdFHRF={7JHn_N#Y#wr&3RjmCD=~$!5d=o9~TfgG2+!G zGa2liH405Zc3r_p6SGnq5A$JfH|@Z-jPJ3gF>4B6l)itZ(svrmG&GF(F!h%28TGPo zs*TQ;z3=<#>PH7{KJ$ye67?u$8?k9CN|W?dO6H+LCPp7soYX%x5SCo+G$pYmBy2Ex z%2;RMyv}w(zmg6dlFr$Kr(qYdb)3^Ku(X`<8^~nPEzVWR)Y-D^%+FQ@P=jC%3v6IyBBS<7#)&cVyu{La(*VQY1`;aITiL3e%D+`Bym0cu2<8sK|KCQ*-()u5s;?wxneyWFf9g+J1#b;&BJ=_9;vNh z_*q?5KV&8go2-s^@>?L{4?gl^sMw9?VZ7}*QTgf0>pUV)!6!>K4MY)9pktnZU_~{y*oUA)djH6dXaK$2Re|-R)MLA6@dx}?6WVZS_ESiUP zt+FGpKIkp(Q7>~vRx$1rqZqshVDD!8v<`lafz5QH*@{?yeQv4;=|}*;HubZcha2B$ z+M0``U0+A1ZMscVZ2CKLAAhFw^URY06&D=%q=tB5fkKtKS4IWA;ijp~KTz@8l1mB(0Uk2)wWf zx9a%l5Ac*|X05C~ls(Z@zlvzG#lv$ThRI;SX2)@+o`eg*1lvukP>;%=zGOSk>dq}_ zCph=PViJ+_ST!l#L;O;&`)F>H&AlU?wC0JqY;Cdkf%k6}zoysD?|aSqtt>XSd2E zXR3yci|`0!uS@$hub1@35Nf;elrW*azRL2_LtfJ8QK3=V7g2%;I?cy1`czQWUce?uYuklC@x#;d)t&-ab^Cl4v=Z+R@qJJ9nlUBVrkB2`|w z)HTfZJ#LD;IDd5zcyXTMfDdlIL7biQqK7HlUyj1B-yz40yK_;WR-;tBJx{k>M$p_#fw35LyaB{-Yg#at)uzQ_xAz zOFvEzK8ckig+|d)s?%1fSKrfjJ%x?Gmnu^|9GR*8nK!obN>CN&d@cXL3wu~Ps{;fg zu=Yn*fm-?~zJ4$1_H06ug3gj4{3+L#(0OGC3bOv&PS$^^%7&^A zEMXjsI;$bLsI?UND()<6^2=hYUqik%z&bgL0pO+i6=nakOUQypaxjhnOouiC)%Q$i zg^>A`+<+-m5!nCo-uFUzG1LiX_3e(m!dz*kVrT@^Vqw}YJj2dZoYqJYs|n#Pg~u$zsEe`ATEFSOj^6_N?h_GJI37KR_^U}QxM z&sJ$Sh;$|wMN2@ z^*!>Xo#wg^s zx+3ep^T9_TL!!RD{L{&O%I6Ge!OVO}X14&~Y42IxcyVX_C^CEIf1;`-Q*DBZ%NSds z^m!IVTX3Q5)(1L;zq^7Y1CqhdbW~pbZKIvu-S-v186TI2J6s_c-n`gU^Xde#Q z{)TyfB>4Y$Nz$9bQefpYe9FJz(fl#QFQqUIS9lmG+v zDLFa6C-+1P5g6yzMGn(AVH;n$d!M%Ya`TUK<&2Iwj|}!O{G3tbTwHP=*(S74F&R6$ zZL!q*zB$(ROIQGxx_6QEKu(ugR*sf%HF#6-APa}JA$uEnhTe3W?}$v41xIjHVaHin zU3IN_`CZSzPaR1}pA9*P0_NQ}+$^lzCH@_I*SPflZJ1zw81<83-EQ+C!3p1*f?+5K zu<_1S!#bz(#Fz;?-)#gEOu^-<$ALlm&tuQ^(mP}fNrW39 zw#t$GuE&Bkjv+$eL-+imaH^l4F9XnHCRg3$_&a?TX<~5t{;Hb^o<>W>9zEtBB1!y^ z$Glw)%IoGEv+)9y#1#i<|rHs2i-C$u#^O>JmhH1Xr?y>oTPg&^BddT4`igPuc9p#Cp z??dO14?Nrt758JpEV{UxWxg@g@Dj4p`|dD2cWgFUhQYFt%=D<-)uW=+85D6oEm6N* z11lx>>7B%SbT4)>%0mNRrDfpl2jAWYlt_VZJkk2y6XA}-IIcaXoe?4Rm)=%~$p|^c z`Gd;ZB);dk8FLBPcFBAc2D(ov#>n^?T4Aeel(&8+xYklR>y1)5V~TPhqidIRf&2Cx&4$>`9l&}E zcHs*-#chHunNRBy_=|ucRhBdkN}gpVW-u)moRc}hsx%e7OmR&Fn?_Dh$x2DSQanTL zPT`Po>YoORE`@zISh<0d(D5i=qAx8B1Jr0LDzf=<(`}8Zkf{w;f*AYLDM>^wYboL0 z0Bd}$8Se2;eb9Se=F60tlh+{m=+b9O3NS9GtFp}346&+snP0&4R$Cw6+FyS9PVV>W zoKEIF_Z;JuWSk%Eab<7My&uX>bnMSynh8^kZ;S&FT7jZ%kTMxU3SI~t zeAcqb=O^>pEPvahr$?HfvDq@gV(kO8tT6!+vA{KchH<8HG+RuK2~r+;iyCj~1|LN$ z9o7Sz{16)I#nAm1krOK{xO7*Tw`L^eokbLyTR zwx-n7a5RCgQHB2FGY@p;USmiPU)e;~mt%juoF-CbmAhCG#q6_{P|q%gw;4A?c&*Ic zqf9O{*M+p&(mI9s9n!Pbke~vfne8U-(kvZ)k)j7s#^8v4NoT>hS6mNN<=dnV%XR~X z1*NXjS`DQjn@D0(u2D~0_R){ySBJjaxL&>j=0(tU(KTP}E$O$$QA$mPUlUjNkPNx;CFlyL_>wkTLYtNA z@C<_EzNC4@yt`<#Wh__S-H^UOS&6$v>ad)b!bkjr)&%`iWk;8htOJ>lACf?P9 z;Jn-wP{CZ?e3GY-eA&NJ$Lw&|A6he#?bMPV9&6V%)@8jAAtW1(Ds zc~9#Z(!M5T=~OZ`mn}bAF`+y^?(hqc8v3vvT6xR;MFagqe))z{(181n!Ykwb;JIgo z7FatIJ)~3XiZR0fwM-3Cl6AqWjrGWuE`0ITuE46(>$!dIg?lbNcZ-Feo(3e?K=X*k zl~)QtuKtz%aT*H&n5izajr%txi||)+0$(*&poa=vMUw)`W5&g)MFF2_lbnY}bonEv zu#&&KO_mTZaW*C+>(0bgaS^@`XsyGc<2k5_UcWuvQcf%7t(IbW>Qq$c!EIkQ=07Z| z$7g=@;bvbm>pzMH|5gqLf%cn-yLJQe+E9@*X2L+56hsw9L>ji?Y)#Vd zOU~V^6ye>f>HNcH+U0~FDS)U6K@`^IEFrWr`l{d(+Md=z<9Dlge1eC?6N00Tfm}K1 z&(Ayh{$BR@rGjT)W}q3Zo?6e=n@wW`6jtDBpUyxNw<2S*L!zpd9eY;VGN?8`&$gNPiR=g$c<_C5U=cB4- zCXhaD17+QiD)#Wz*^khVl7Un9H5zs*cYP^x?C#$+Su8GUMBO(d)X`SGZ4z9$I-cvv zMRt&2oaZw7c6}*Lt+^Xm$`U1mi?`+5f7nx)|VzDXI&l(o$-c^Mj!IB0v* zE#VR;l)jNMSif8yV3qboYcklLzDNUT`K^>OtZ^^W9$8r=)6-I;t^siQrE?u}RpXN%Xe)(zmWr|==&gVBN~Y9z6_WzS0mvcb@>ht6Rv;`A_q z5#h7(nL;%)D-W9VhT9ZvmAUGojc7^l)p$g;B{Ot;Cz0$VlV7NIWH}zUmwnq4fUTN? z-n}&0U+w4~N@Dz8{H_M?km>bgR4M~ZBZ~kwl_ETu-xfi5*>tPmJ?Xj;)O~E-}q|bSS4?M7AZyYud_L^8JS(mQM*EuXfv`uUN!^)YclmS z#J!7{!1DgFBvCsFGaS-Y43}wr*v+Woa4bHn$j-187N@9Jkehhd^jzOi3z(Pi6+Cavyf87}T8qFE%EMQ-602Np+z_6!Yd1 zqz_|1k8Q;23{A%in+mRQH{7RR3n_bnXAMY7cKZN~dc6I1f@Kl)5zp6IUCaa^9;Y9# za1G6?);3b#@epbzk|so0@)|XB#TkduC3c-m%#z$8-pie%bm0v;a8F~LFi^OQDt~X! z_zbSr^76dWO+py3w_Y6c?n6IKRx-D)-g5*N!tMPOoqIoPwjbMYt6NqMYpq;A*FOGI zQtk_H{Nh*3O}FOB@Oosnl8G;@;nk$w(_tt_M1)`>{Y2XJjQF2$wJs~vgeyrp?V4V2 z{-a`bKw4Cj?fr785SIn&F6iqfr5qf}Cs1f)!n~o#rAj51ff2jaQW(;cRFbOhV#@^g z-Bx#JLnP`O+iPjuZW!tb^3t(&Beg^zBcI*AKWT*j++lmT6L*k}8o*UvWwqFE%6>vB zL#4H>O?|$jX)?clJipH*>pc*Y@utfv+S9tWo0-#3J(~B+pdO1BEY^`Vh@I&D$@6VO z(+pE%BGY1y%i%Muu?>!ltdZIMIHe6n7#+|}c-y;LJ&uI5KjnIg_R$$RRRCJcBFC#< z*>&K-zmUI-4+djtmoBEhEb^{gu8-PYOy}qi+7ANCJK>A1=GoFYiRv&Na#l|uEW~=Y znI^j0WL>uvhb)YE+@b@YIp}jNGJf;sh3HCB4>yUtMQ|7a+F@I_Z!1Kh`*EEZS>RWr&-pv1AWsl+F@k%P76bjN328yVkI%$e0r5wBJ z$i2M=j#TyLm5igB?`nUfQ}Pw6S^9Y3DsB6b8q0C)F*eY9XS?k zuQjCKImTg!F~5!(SQKB0^RX))kXuTt(l*Hd)EV5h@tpXD!4t+xz}nmYrSJ6nVF%8e zZ1-NYDt7^@3kDEPC0Vu8iv(eqbQ|=T=8Eqo$n0UBcx`MdCf9@EG%vRo)-a^X+o`HN z0EY-x+DRFx{)G`~$Eb~dx-9%M_uME@61C30Pl+YfQKI5ll6-4BQ_Sk$Y1`xkoen59 zH_FBCI3tS-{Jl}=Gt3IS8B=cFI81WG{s9&3)PLlXE(r7#v+`DP54<#+jdUCo+_OK4 zbzuieO82e9p}Une8k=mE{%T!8lx`%c#Th;P#^L0k0pkCc7Q>jFPK2C1Wk8d<6GT#lo=#ls${YM?v8HvVAGNL`Bj1?0(FS5O5c46gg_5*;U0$OM zda}-}%-7?d)rV*<{ow&#;{3S}pTS`hrEGT(mn)yvR1Mi4S=7P&j5#KygHR%C zTxD9=s8xn!UH){-k-OCL@qY$;MoA_~^bg++%nJQ#rxfa~cbp70<(~}pE1c*VEDvR$ zQuuCw+wJ~(m;{Mle(sJN!X&${BF1_M|A=4aQy{M^eFM<$DZY$frY_s0##UQ2_V*-; zM(A33n3W^tn|&R*e+Dq$>W&KAIgh_wK@SYMH~ogaf+UyQ9U*>=>~7Jii{3Myr0@G* z?7eqXlUuhg?%o>h`D3inXo?Nz&96LAU({Bsfz>veIK#_#f1fsQI#vog8w6WmLC@p`4| z1ER9zV%67|U=6t%bT*w9&N|5?bR02e3IVcKY`LG% z{$UdS-LwCC6#ybCV)?n$w>?QvX+8s7-mJ-#HLeTFPNt6j%?=)HrT%)Xi>BFlv)6!6 zT}rLsHv|imj02k}?_ofH}AqBG-b!K45cBl3O zHceE1vc-yiwZGZnRQ;gONnhL6B-@{&GGIZ~0%O`gFM<2HeZucxZk-{d;NICG zv?qy{Ur-4)_e~gX!WZW3ZxqT6s?Y9`Fdc}!)U+1i$nl~6nD7`_jpA9DR~1gLFPnzG zUNUp>3c8|AN~{oy8yOH)Wt)1!YD0G{(Q+9Jc>9#lvC?@R2eSOKCy#708<)T9rQuk^ z62H+Yy7^+CQ$XkT$-R@FebJ;7$h9TmMwubPiP_O;;j{iUXM#0^t|s$G<6BX)@M8@? z$+Z<_kCB-dR3;}mQKZc=>(@Xm`XktoHCa)#oM*YR7OC#8REE|;gwi;jpXNpvQvbaI$4HK9rwJaBa1WAaxzDEhwG;Yo9Ftv3y0$I zgGOSwwvB%J>O%_N7F|6(Q{S%4D>-fRLVr4obVV8V^YrhVWeJU1uWqe1dI+=OUxgh% ze*}IkFyo;*ZBOf3MY%9SJPrg1OvHIEL($V|zC?;6)%CwnEQqzU!|Q|O5x-sRyoslG zw=rwptG9U&S3=B?bVTXK))q_caH8IWH$-#IG^;eTaFq&S{XUqX zqPp8wPA*6B{k}8Lq#^5ipI0igQc3t5iC3DaZplA4+UVzVI1^TR(M_Jndb<>!&_EmA zzO2`gbvM@A1~Pp>td$#0Pgfxsw>)f3EBmbg_{2_3!3w6NT}Uj?pyOrPzXPqTn#a^M zDz;fSntOzFQ9~EdTFhkkD}XIW*Fuy`4=5^vm-|I1XBCEJg1;DvynujKt%qMTjQ69a z%rOh1V7__zqHjAovS^t>hEIFs^ZBFi@{mH=*^bhj#p=jarQy_%ZKE#h%|%krYQ0*A zXPtUol*twZ9NC7emqNSqnEU|}qC&;DENNp*HA)Ymou8W%hOe6q}ZOykeiCrR)mQ?fM5sjQ^MrbP=X^m~|9NHSG?AfhuR1u8O6>1r;= zRFmoG5g^%wDxD0L%DD;aq+}rqK4Sp;nG0F$jssl{)oR|%Y#z{Y4xW@e&Tq*OQ+;iS zpp(>3y5s}hW_JAje15*bxA@5yvq6#yO@c>E|T_esf-PNX%og z2P4jXJ{pk4v`@9BET>kwbaZs&MtPVF_1S1JdaUmOrG<_&b=_qd;ggfOd*o)_UvHI_ z$W4+h{6200^2;95dNTTDE-dv0p-+;dE9Z>Gs3jJKi1{3a5BvL6;yxI}jS(|NbA$(&skF)vYfw-;4i_Q(W z{3!2@7l)1G)sO@z+)gs5;P<8 zwIgy}V57iao@ny;ZJzGuu=T7*tdZ?kAT~maZFDl5s}sT21wQ;@E#A0M zRok^ODCxW^wv%ialwL=d?k_JiU0&Mb8(KAqv`6kUMmze#c^J)kU2!U9a&(HW#?aGx zwJm+AxD1TOpL_RQZ^zXQM+yU3&Oe3w|FLjd_ z5?N9iOF$XFmLY`+tLuAN-6}ElV>1SW)r~Z@_!xDyGKilFg17u}6Z2Z5(+8T*u+&x! zSDB=`(#3M-Bgk4_Lk zA>5UuT#z#f6dPQ~Ng;P76Fz<^O3>lX-Vxoq!6YmB8)P9!&5s;490AWDaifUg#(!r; zebJ_`nYG{t$!+1NTdyoed-t@wTlDj8lUri<`IlD!yvJt#*h2UdyNG`F?Q6G!_70Av z?QIz;;ApV*C@tf2PJ0sNm+1AFNQ~hjgD{WY=yF!{CLPdr5c+Hdg_^c~TtR{CSDlAtauBpjtB0 zN?u6@1z!|oUAQgqhP;&eUsQh8rImZ*^dC737S-;5|AT$|f@H|zw~E_p)Hb?F_%!yG zsE;3_q*NEAhwdqe)h_g)+oVrictGNGoqmhP*SS z^}g#3i0&&J#vX|mdA0QWt>{Sbw$a4b{?DMgf7F*2rej&KVplh@EKk<&B&80KQX0-Y z{Qck?d*s^nA=0&>i;}gM-+8KqWS~^V8Cb^#>9xul^TJP>iy>Ui3G*Ei$9pk4bHNm( zO@w=*d2u^2SP~+*mGauSd@)Ga8cz!CSQ)a-NSai*I|G%?$GIAOleL(uvUAU?G0GZ6--?Q7E42*{iCXlGQs)4t#CA*5Mx|K0)Of?%a#o$$gch$^J;Fy?1J_u9{#ikqCC0+ zZzJca)#RgRX3XJ?+1$#x0EG_arh=ZLK$r1E?{65rxw7!U6sh$^#PLd;t#>GEiHkK2YFXalq2i9$i zx6+k9r>-49NKI^|au}_)l85?Dx(B?>EMFarD2AbHVyP)@gwJL*VNoL#Z1k25_*R5V zt~W=AbLkGJf?T!Nq1V_n14xabtkybac8rD6s)W9@WIyw_5Ob8jLe1!EqiZyO$rr1+ z8zNrS{_@8S%f_;(+69_n0)8P_|lpM*xeZ2R)5`cw}hyEi9*s|;`{m( z@A4}jc?v*htOLa**Y%!^w-olY2&v^&2|TtP%VEP9Xir&U{BNqDRuPtZ78zHtAG97R zEqiX?<)eB((~}2*VWVcc#wz_pg*o_zVa}sbYb@n-?r`fKb2n?fowatl zm?90jAM^t>-!`di*Ro_AS^cv|euDr_UPg@hAc_U}*}dPD8F~0?N51lmtNFAxm9MUg zm~+W+pCZoFd*B~CLGyhe{%`d0nK?f%X;N87j6X=Bl@b|H#SX+iHnCS=76?)qrIIrDg4}~ z47#@m6k4bgDV&p7C}4iL4q%(zww-?F!jt)y0gg=6ETC?kv6v%BK@ULz6VO{GjLj6Z zbO`U9madk9f(6Ec+cPWW6(Y*Wwc^V)^I#^HO&^CSN#AkFn8>paC+L&Iy~*um(x%|b zqrGjmb)h)Es0x;t-83<`P%>~Z^Kp|)hS!3vtObj8g(OUF7jC>B!BUlk7wFKPnMZD% zoA>gkH*2`xB20IBat<*gw|fbP4CKJO7=xKXxhjNLFYpP^omETU3`)D2FIV_6j`WxD zCW#(CH)N9y4Iov!tZ)!L`v7<8-8iZ*D8#0cu|+wJGBt(O3sj-w`fvdlT!Lyb2xX#K z44NlQ(9os>H!N|8AdSeZE2b$8^wyJnW;mGc#ezIG;!5d#)`1eL70r0YwDq&bPEv;I z<%qhL<)C+FTNOr7BH_685sw(qiOxvcGIXIY(ELXr8hp>BXig}Ho%ObfCX688P?jC% zw4J11LaDu<2u(`lvZVOT$E{q65*mmUvAP| z(febrFsam&0%fF=U`nYR6c79_;I=xA3vy3ddm34%Hb6yg#<)nP90pI0vAl4#Uq{iP z@A3-Wd3jb^82gD&GtRZGw7YKp+@E~^BzzsR>;dxs`ih@cQ6 zw+F(l?ukwd2j~xQpj`@be#m-SY{O!U%{JV-inK}uh|f;wJktBYTml%Wp*_D*_rxjo z9xt4xE5-BNWQ?(s0fB%O{bT}hakhzDSC^8|c$dFtI6GI&sRW2uHxFV zF-PyB??6zlsO#mHX;lhs%xVR;ry;l0Yj>F}rZZcUo2Dxqi%a7Q^ zZ&19c>oa!5vf``2qwLxy@qjvGEM)@HQnDymAwsqTEyrkF#AEhKaEgT&g=-;r|zIWng>-U_H1o-6H{TFu^dkY`Y8FJBWnah2(rVL22OCIm_r+-7{q{q*=Wk zDS%w)%(a*OtmHmnPpcWA&OE;dWkb`l!m@NK5jx{Yl&+J|_O!nq4Gj@*savx*$ zH%3}j8><$WGC~(l8~%sRUTo}Mlbx96bGjft&3j!W?vD9+2_BlrVPw^%cYo>awDB{8 z@xTR$Yk|X#&HL;hS42wMrM(k9Ei*rHWBKXU6>@?;^Jwu6q2ieO)7>0(69uUeRg3R| zErUsDDlKPURgncPsI5$oxVs6e|CVY=?pH~X-dzS0IIyGdB(v74UmIWl^U_W+A+uGC ztw<+r$%Qkd_XKOyIL3O9#ms&rRK))JcSyPWX`U9dVpVg4CJ>v>?CP5Op{T2j^#TVI zhqB;9n}W#;0cW3cHAX3u{4LCG4#Auj^d-ATI64P1WexUjGAxLR5a*m-ignpi1{aus zuGymwJIJ-KeBZSnVHv-DeO5lGnfru!ZY`mGQzGLeLjg5hqm@{?LO}e&D<*@1`aQ~# zL`AYFtR>V=rl?j1Bu+Rj=!x}$-_*Rbgy`i)e*7bD?_%7^tx9u&EDSpGowBiG`7+0t zt+vNsF)X(NkJhw}K{I>r+8Wh#QzlDcCbP_PE3dtoB-=k_6#`iC!To*{-Cdo_jZ;p`w()PD#dCb= zAbbcg6v%#++>Q2^SpI%Lp$Hl*Y2hH(+wSLb(z%1ZU@aTksSq3y^4imKZ+Pg)m>(v> zuPk*NJ_Gcmvtiq?dR-U|aoA<7s;CFyE~d=Q2F z3ZtXWo0Sbx97r9XfDi5xQ;^(3ljH`D7$wtB{QU@#P#a~1I2?#>b08DqtyU;vy z(fbA^c6!Uxf6)7rdFX~5@OWw;0MbJ+sPksQlcb@pfo`_@7VFd^J+uy!{cs{=y`MVt#=05glx0jq`f2z3&usW*#18y(82fE) zoI6@@4yS*%TGdo|Q`q6iKxVN5&Jq^GJW+cl0LhS2rJyq3Gtmr5>X=N%d7rJ-fBqUZ zx&Jv!tW!qi;v~+*D2xr?Z7B0<^qq4SqOE{OUJl|_y?k zxb>Aw`Py`^n71r%S9K(nZR9jrBn&zefW#bT?-o#Y;Gy0m1LL7w z+) zzIs(PdgW-;K}S&1;V4u02ANO^W>(E$`uL+EsBFO*kDs}POSX~YEVZzK)z(tHWQJwL z&1>YwpLg%U!si@edfcv(*&`f{i4Xm{tf;z^Y@&@l3(iTVCnoXYr^}1||l2Bm|=UPyno;&o&nk zXrFU)NOpN^i^;t&o|!R7l6?UrLJiSh|3ewQBe8Q2w4S`#tfX6; zcOuuvys56SxHjy&%5f*3U%*y;VPHmTRl{HJj!h!@#>tPJ29_XFZ0|Jt59zQM4JrEq zJxR^l=!k^PEpNW>OqxpE@~2+~5u*=-%TYByS{wsGLnnimMYm}d)_cXKgL zMC!JR_Kt)`n=kUZ1;eZag_yM`lUkmk+8y@;zSjU-Iy+<3oYh`cV`1>zIzooiEuAb1 zI5#p=6jY{6X*EV@nw2=I0Cs#q*1jY`;1g>!QKe;zsVLEERQ(E72Yg%F3a$YT_haBL_fzR~HNNq$ zihu*M4j(#ZpT2&_4YKTeEkH*;wvO&8< z%Zu45{o(a{n_Z1b{Xc5tVU-nl&5EtY7X&-Se0|R5?QpetUlt*};%bN=O0?p}+K&2E zOGN|w#-S{zoZJn>RI@=yYGykGC1QrsO?Q@3V#P^ojJdi;#`d-Ys`+&!X0NX@{oa90 z6GnXw<93b}ExPh1N@Q)<^QBb4zME#E7_$>efoD0npZXm(k1m%lZc_N-XV2CHUo-ae zif<#SgzL{;ut3SeuL!a={&--@O-K7Xxf9HgbM5IXfi+Tx$dB$ZS)M+f^lR2y^cgn3 z6g$t+4I~Ir-qrY~2aWotH%qYlaQ?pe7jww(F(tO&gY#}}>#hw>SzQ}&>nyTzN?3V8 zJ-p~h+BI1cccmZ3non03inqPB8KcrrRu1hr+$S6B61;;^L&l^<)=|Y%4~Bs(wQhPa zXO)I2NY8cNCa7+nA_gbC1UC)izyn^!wGu_c9sSa%Z_%2Y;oGRN4|;Ujb}{ZWsU}SDgE8I^5dYeCoJ%Q`TQq z8dT$|PhwTd7#L{AFz9Yk$@5L9Tv1?w20&L)A&gF7M#)xGKM`9whR>EKcpB_T3`igN zFc^m2mQp&s+7vicD2bBHN@DkU+`OQpuQ)8!{bnz;JTJ75%dYhh(AzeBw@hF4-rX@< zC+q3d8@P_*c*9iZg3<;#nV9Yo^YnfGZRVSKyjS9z8mm&JBypBezgFx|Hfwok>&54| zroIn`xzIU%A4++OlaFj~ri_$buFXtjkbmaf+*jp&9ifL@w#snZI!l}Akm!~WF@YH% z60yMznd_{|j0-j$_~FB**eMzBOe%>fclN6OA4+^rKakK73aJIj< zUcz`rJC0ImCyqx7c|Ui-tg!DXh>u?1^2zA36~sgDGDL>$*=u4+&(w}uS|E+g`bfy& z0?Yy!Gy6m8^4KqPZBPX!uiGiedjku#hCXOvp^8!4+q-m6t3E9nJy}vgc+tbPqUjq& z2l$$V(z7-9Sh&6CDSI50x&%ev^o}YQer_ zSJ3cFEh%-3oh}qLY;pf4ayRvMaE_I~e&>0oUf1VgYO_^xajc>gQ0NU-Aon74poQ^- z@zt!U)Xw9Z_Dm;I)rEqVrCo_GGw!U_=iPVk-$_x-CwV_FaYXjcbyubZ(0e*=WK%|z zf2vgo|lOi2# z&IwRp~OByDZDWu_@W)tVS!x*_FOU_-4MEO!n~)N*NXjR)hm_h*c#q$%J+A zsA8c;6Oc3%DH@aeRc6Q&XfwnQ%U@TQ=!`-Ta!4Jx zy0?&~fqOaW%~|V`NNH{iKJNeTYqekNvoyHh&sGb!_^S=_Cn_Oyao?B(ArzIV^ul%e| zVn;ZQh|Qa1Sy)>aq#l7Ae^>nK!204mM)5)ckWH0-_FAaPf55vi}bU_?cG?Qk+3Q?}v`AkRSd z*Er1Zm+tWypPmR|LM^XCvZfhTtdHnAhJc{9&O|;nJ1rks zcU}ddp#oLP2RJK6hvy=S+&cUbr(a&o&QOfr`to5h5neiN$;^*`|U zGLC3ZPw4)@gfJEkV2y0s=x)EUrq0*QC+u`1>%~RVt5_QApsow58o$xSz+Y>UzI;M! z#6UUtbl!c|zM7_>ydK@HpxhVTr664rt)L(s9aZD!oI=siW2yj7p>T@IeOD5dLZK0r z_O6nHj{hO;yU`S?p?9M+6fa4Cs5$)H`l2Bmd_t>qSFfQIG$ng^Y3Q!`p?_+Esyz@;Nl)AsSTTDR6`y}Zx=++L*rL>ny3M{fM zS*wS#i^*kMYdG)ifIBvu)4ywbeP_HE4i>NfkQ=FD%Zc7vk(F(?XF2v>G8v1h7zsiT zeeBC|Hdd{#v%q^c`D(ZXY>b3@E#y)bqCN8yQ+JtYg2LjKy;~RHOlFCPV#-2EcjroI zm!}kMM>;Z*tGy8t_g=8#Y8-S-m55;@ONg7~LSy zzja1nRv1th$HQ8#ld=rK?wQ@AdK>@1x&!u=T3Ca9Sgnlf7NLPQyL17uq~+5ypz&s{ z7!17AsjN5`DShK`o^3H{_i*$P4Ln(ZvQHzTK#yj5~ajk$ebcLn<= zWJ8IeX5Z=f=h7wPyhAeg|*M&fo040&^WH2mq5Jx6qIq<%$D%7Vp|zsor=Di zu1ro*7eG?-pUa7Y@kGuW2lHzla}$})H%}Wbcjz;_9Gi0kOQ;||GoJC{th43>uMyQI zG_`>Awu%w50D|Kbt@t>DVF;$m>ppu^Ayg0-Z)Rts88Czm@TBEuu38+LWJJy;eRU&& zwkszK8lM4$v3V7GPhVFhe4`c{_gb~(^|-qNo~B?nyD>T=dAUI?5ubOL{junBI)%O- z5(g&Kbjk`oBiIb}XP65*w*S0T(YHU};jWVvC7=^wz(m6pSvzK+DkWu9tmyOfpqU9d zSNaNh|H(#)RM`X!fW_#~(}B#iq40biJECyD>!Y#RT<@zeYh9a03r}T1VPiA$%yerN zv~gzchuT)hX|ZaWqn5BQc6|}b5@SeW@VKuH1+SPO%{J7uGZ*)pRB1}3dE6la<>9>1 zA+cX$AA`PEU+kQLoL2NQm-6)3l1_0Gc_oODuVrjY#|j`%#Ie*fdilLI9UCk}Pu<=Q z*&A8}{@C0~^}=>2aieTa;<3M%WzIK#)_yBpjaY48fb2H3)^>Nl$!Dw1CK<2a*nf15 zxOC83aW?1F?g3eSa035%i992w-6$zp0O?30){Jv&c=lNM!`na+We$Aw)li93}ytB+Y z<+p5V2^Tn90U8iAohx^;jfB5bOa7Igu4KV{p!pFW2evJcZn9><-n?XfN%3&f=RB3e zB%02rv5>~YTR79LQGfLE1uE7GB{riI9WSu~WlhisaBARoS$KPpIf&Hiv4=Qp+rg@wN;|m)W&&VU~ijTC^T}YvGzpuW)`MC?J@5;ud|aOc4}X zmC_VDZLj&A+Qy{xD5$7*fUT_St6HHwr@Uc(68oHlW5aq*O9H-4BiJK1J2Nh4Ci+QCwkHBcZ(Li2 zepUYBkyv$t$8N`Qe~x>+BsJS;*2+`5Jo7%HGnP@bY z@a~Sy*@#?!dDEan(tMLf^q!N9 z*DLHpZ??2@-Y3@xaJ>Wr_CC=m8BIw!8lOek@~Ab)k$0DJlx@`EO+iMZktUQ^LyRB( zTU1ctiyr2t{f@YlGH4Zzq{+KPoxAb8fyM27e0f?1SDVp(@L6y5W{26 zo_$!DK|8#o!W3vHlWm#*>#JvhAxUDf2O?a$LxfyO=0ZC1mvdQ{TMFc(rfs)XE(A++ z92pm!t~w?P$D3E)Qiy8*nr=Gj8dckj&AHye8(;ChCp`1V3Wo^&R0_LmJqT{h*G}e& zdbYPKh$%CPI-sSzx}2W=7&gExbU9kGn?@Z9RelF8QBJbti z?V}lq(D6Y6$cJw-f+9yK?)uC zRQD0Dm+ESqzhZhZ@bzZdYLYTytpHQ+$|?q7I|+-<`|4yd^HR5%W&ckE&(BMrBDeCy zGQC?xMK)%KOs=0f)<9g`Vx=$0|LS5dr3dQ7-*mA>mgrepnbRfF4U`X3CvDXJ_6MNj z?B>d~gHPJ`qLjPnmfxj(B)fN?zq5z)@5;Xg^7mx;`$hO$GyH3`q7Kjs#O%lLEzxvp ze!%1gEMY@?hS&p0PtWEgjNO`t6eJ2={#N*ZgccTItp|Yk{{ZT|`w;H-cllcae@ozR z3H&c4pv*Z-$#2cPkSt8*q849p?>i)Z;6JhSv)O~kw(K?k1QA?Z_fAmuGG0WaEHaY3 zVlDlgEkgSZ+J9I6Es(z_!{0B$- z*S^s`BiHa>Uk9u6Ji6Y2Uue2#4?2kALn?TreQIZu#4q&aJS*k8nXns^_PFV1YkY-&r9zk{^2SzbhjmZNP*l9l7BjUSGgyCIpxS#7Unfp0Bmy@ z5Bnpoi{uq5p@(M`cn|#Uy+&kD1ZTiMIB%`E)5xE{{i_)Y{|K&yl(1W@>U#?gw@;5E z|BTQ`dV$$f_?ExHFv#;nk?e3tFhxxzfP6j8kR$5;-GB4O3$*eQ1pj`;|1~<#Ay{(TyGZL>`h6uLr}~@D5!{TvNhCQOQw;Yz z?)6&DezElrw?829R?bCR5lOpW4^8}eDJmWC6#xj!GyC4oN-RqMdFj$Ckq~6eNKFP4 zuw3=s7gbC3!JXyvF<~}SnF;_P_0A`xwXnmUybb71-~Av{C1)q z2|sMF_8_t+U&Z>z+q(ByAoha>-fCJbq`mTKJ%9bj$6#I3mH6}0ETiiA>PO=TpKMhD zImy-^*R-86GWWG6IvyKvI_Q7Xne3=llsd?NICL(h%8|O{oWo@WV*Ii{s3sP8r}4WIlc(v1JX6j&Tm0@d z%O5r`a%^MjpyYb9w*|;yGREl_9q!UB&R3y#Blc34hR(0WYFXWyX||Nm>v9)%iX|nO z4f2=1SxA+7;<;Op-AHB9??~q3ZTj`<_F8xJ;m4y>{)pvgF<7XLsTHhlA@d zw`u#qZUXm(-)Y5*vm1aTOTv>!zkNbQ*;Mie6!Su+*qkW}^z$?QsWCEx6{zUp*$>6F zC30mD(|eiGHC47H{G4UaF?{~tEbCfaM%${BR&i?h9b?*(gzOSb>}CntK8B+_*hR!= zrWaL!Z+5YYOyf}$8%1|0B=aP%OxUgh_(rh)FWM>{2^kpMj%p7@5ARG*KMWt7u-&Y9 zL)jyvWlC6JxY1_0r9r#2W;+=pTl||)fVxrZhvI$U8#7uPuj4YBFU`Eva7}kIUnZ?E z0&*E=U0iWHrrls$pklRUp1p38;IGwErGQFt@s+U|$ecB%e*?SMGDEk`EQ403_7)R} z1+exdYYCvIi*1o#T$37Q!uG4Z{Do=AUJHyk|vsZ9J zuar7+Q~N=6E7JaNi3z!5-P@qM)5ex}G81xZRe@>kLH?*jO^;j<#e4?`4T1LT* zDYGgZ?YS>o@q_6`Y?hpd3nOF#tpA)ko841jpZ~Uun6|M4m-=W{*yY?2DNO|!W|iKu zIBDV9ig4bns^&Z#OnUtG7-fF-En~<$zt2rQ;D!OLD8-vCFReG%kLZZsv7*H#WjoQw zE|;JK)s@PdT||7Ddp0(4B~q`x-?3;1KPU-GThR46NqDa_%xt=w6q=CDs0-A!TXr%g z1<23&+EnVK>eCkQ1n33bFo-LfkkiMk>^CRg1i2e{(bY2f=ZAcTZcadef*Q?6)^|qN zEjZ9uboFHfj3C>SY9UvfoqjRq7_#WGEx(3l^vj3%v>Vd(XD^bNNLZ(QWDoVh^~E55 zo98V}H~B`=(xPo(x;O|#V%-=%tW=BzfW8G!5Qwp$66gjF9D*!-_2&zI%9vRxtowGF z6S>LDOKIZ?ozQhl6cX$FU%cJYTMg)&zg}IvI(z%xhd$K+p5_mUxjB;4-7Z2aCN%)z z{o;#rS)~Cc_f)bC56zi2Dv3cnnO^( zu_kv1_*6$tm24{b;7gNMhUPg)$U;k2Z^%l;xR@e)csr))$>fNWhQ8T6h-hR3X(N%9 zLlQ;Nr*i8q0(v2XnIaqAi-pu1)=)M2s;484MA^4I$?5TyhNF^HxE4sv%xJKb5oD*C zAWgdz^V-K7`fk|Uve=$94A z5cH>ri+Vh?kw}X{aBs^wRfmsiKDW`|HbsYhmd!H85`K6uIT#hQdLev`HLgQ+WpG?P zx%ljuzT913;DF}2_>2^Jr)+8Y&1QC^P@8g|QFA4qKFGZx;46z52diJXi5J=J#}u!7 zK;P0zQ?l1F{pW-7nNigwVU{Sm39hoGG#}(SrZpoA<2;0i$|_^TxP>OPq>*15t>*Bb z=iW@pX6xL~^p)|^l&O2pCWxgJY;ke{LW2jH9wRGtqy~w$(z}BnZTd zRz}FpD9Y;A!;cejksIpT6S-m2Mt$80vGbe2Sf`kZ`K;Kci4`g8C0O7_L+*D1@}0M} zIRp&E%@Nd3+Q-J+jfv zQ#-<^P(78HYs&By<2A4qw#Aet{T4>~>dd54##@K!G`oUHHEgd{oxjlgA3VQzVuIb6 zEoCjBxEyFQn$Fuh9rA%nrBP;^H9dTnqgyh)lp2X8<&bXb2TvRSj;X{O!b(w+%8qF-3L(H!ZInP<3I^(j3prGi5~GTa zEPm*F(vaX=dYiy)UVkMEheYJ5+b3v>ixe!+JkF6GGB<7e_VZHrKvCO^CGZk-4F`%G z8Bxy^VYA*S5zN$oDJ4$=v`u>m88B9aP@LJox&9QTWk|0eQN91Tai;WicFc-?Z!7P* z5-xAcL-{pM$6{QlSVrGNIZTk%s)(`C;Q_xnpZEm-^_t{HUbK~YlTod^N9KwlaPr!a zSxvgCG-fBAaVBe}8zvKl&vTas`+{ewrX-F_yf9Y&6zW8X6>SUNh2MiOWNeo4#pqu; zuOUkkziQ~&cg=<)*Ol(|zn^yWncxTF(6eoaD}9wmWDwW%ppVYEQc^$q)KN`8FQpif zGQr0`*ZO&>$8Q~_R&N>=%d05fYIfPe4C#0>=W$o(uEtFPwJgE5^!N=af2!#2syOZt zyi~2lc##31EPD>i=j|))APo``K68`SFTm>rjd3xxKv9iU^Zl7gnf@YF$5#b4;-Z1` z^HnB=IQ^mld#JykYsvS8R6EAwtmYB(4DTjs=~2h8m1=G##FCko&`wz=nYP)e11O`2KLikNVF?Y;{}avDht%^Qj^w#`B7Od^1zx_s`5lG`fQ!B0?vU zxMw<6w`-xziHe6t6D71?B7dHR4 z3|*B0Lkm^jD%8k99Rh2mhdA5<>3+0Ky=Rx@6GpcZJ?skj6WnRAU>9ec2DD2imsn5F z&t@tmNgf^ig|?y2J2wW|C}n)+ZbYpAm0wltcO#pOM3SQY3WbU zsY3pU$s_4ce;iZK#)YI~L)ga)KitW5-t7J$Tk%?2@G(z7abx{^=z0N68-hhcj6_SZ9pM8oXwPp5Dpn9M@{ z;Qq)saww^y#JXwJS4o7gmGlt8$pra)31R1Ba+7TFVikSfeh=#;(&gFTi(v4sbDc3k zEV#dZ>mSy|1D5GvI;c$~tK97ShwneH{N-%xFNBdCetkbL86i$T^kx@ZZJOQL^({@& zaLeF6h5=261vXgw$)@;=u8Q#6c{%rswuo4|4SObFrN+dht>{IR9&3BuAG_=i*Gq3h zHJE=djY>9QQ`Rhpn;ATb!k4Mj`^Xy-)9DSYb2XgXeJaM4Gh~BG@fj&%OkP}B!ejuq zo7KXbT7Hgaqg^34^pU1rFhy)<^v_H2q%?*{ z@u*W~l3A6ML^87gtV08k{}cY9>R1;Bfs)jB-TB}Rd`T~Kv&Dy{U;n4~9}$yU!;8?K z?)WbvLy4oLip*?D$_icjEHon$X(GyvaeeatYlNAA5n;Tl;IJJM0}TK38l}anY&?Aj z+99p^bp=ZwM7vWr|KZyHW68)6fAO^c<3#NF0B?H!2Pzli7iIv?^sBd45b`sZYbGd- z3cf9+b$wdY^r257@;B1DYkDYBb-@^Dv-)MK(qjsuB_luQBT;#2>joa6Wu+E8r_@+L z6H6gfon9V92iO>8kRsh70&@SZ`Z0#)M`mTM26gy4?GT*SUCcw)MF?~tr~iZ}G2>gp zV+;aZae!lQWG+05UaXL%<*ROn8W`a#8 z2Un#mdfxiq>9=!7d5OYTjuHQV?zsyT63W(!j{ZscFx)5@MZxwZb=f-pHw4{7US(<$ z9-O)UPYz9jnG}2t6RM!|kyJwUcjUAB+@F`O zU;j2v?qKwOb?V3O8a8qqRQo|R+l@+P{kq(4@X@3a<#qnAhJWri4j^9ReqM?p-dYsL z*6evK=`zIq5Z^%_cgfL*naicXj8QP)uzKcZl17X>l|ocj#oGpyUowbi*q~wrh=cfL z8rQDhngH$ZlpPscFBJ94$g{!cg0hW$oVq4JYmt>rQ~9uBYwDJFuNKl^GV?tl#e!lv zEcRa0%iig{9_i+%r(&;kjMI=~F~=i;(oeJduIA@_o{P|K0T|;5SW^{W2+2y!`G%pq z;MMqfX`JhrM_ldE>nS~fm^(W?B6EPR-S zTbHG`fqvLM3x>VMoqf8+~@S4(I zbvQxaK7YNW>r%|iLW4VLMo&PctJG*~OZ5hlwOy@^rZmmIRAf$w?maDI&x3M+hRwC4 z*h++ke)JykitmlypPpfy25>$Wc5Lwwzh<1EQ5p?lQO7_Onj9_d$Q()+a!Oo~NdErd zV>;d>IZs`-*OX6TMZp+p^+h-%^6A@(M`4@X11HJ9}mAwdS64tvP>luDR&! ze4${67)8#oF|9qllB*I z2f&dr5oxPzRWWCfU1e^uV+T&$rs#X2*oCp17Qe+P@^>)+4~3^6a*WDyouG2S)2>X{ zfUx%;(6^&fs$>uZtgc8>v_8VXcBG1qG#S95;*{4v%za7Nw*0XZil@l>c%kU7Strzk ze7q--*4H5!qBParwK`#!?Q*M-7CA?uB66}qDp;E8C_coNWt@y!w*L;mwXKWx2vOAw zPvoOO{1*4Wm2sD=?jMScO#poWnl$aZm;NyUs}#k66Dz8q_Xy{B!QHrN zllm93cWSWc%zTHA2Vv9*V&sqA=CG4-UxV^yi!ib;=`@u^@c9?|V&V+a7* z^(Ye+?r>d9zqka(NAOy?P&9uCb*xI?GS9Jh9ilNxGM&hFRI0xA5Nvv>RJ}IbV39%d z8(#=hRXTXcDET|I+H4I04t7(@aM#6GfLHvu*s&#yI|9vl!KPn-z_vE>HDhP>byXSn zw7Crp+pRnQV1Eqtl9|ywdGTa_7qfW0f_R@CZ|YL1rrf*9{LGJd2RR14LLjSiu7Bb) zkV~6v;(elL8!bmo@gXI&P>6AN+Y8)?0swh(R(w&GXvuS1 z7}%0@l%J>8_HFBC7m32o*=Y9|^ff+guA+nT+77wpoDc!TV)uzzL}m$1YxF_g51Cdi zb|^^+eWE)QY0~fYs?_qH+j8G6G=EdZn(lGl`cK-KTs(|(H?-5^n1lLM9;)(z;6-#l6+FrB5MwUl227V_86CP^%}0TPUzGY!>tNF zQ*a}3W32bRd-x&z#8c7F%GX|Uhm4&G!i%+4R*Szf77Dx^(4)kT#aWMF%7B$kDN7_w zR?1n{VYG9)#F$B9c5H{}dKCkim(SyH%l3m-Z2~kW{Yp4$Tk(KQSzY9%`7Oif8x}0hE&Z&U; zQx-+a;w(V(n0-cMQJSf~WX1|f;9K1&mIo>KUNlVcAlzUcEhteo-e_9OJ#|mWD-Q23 zw{IlSDnEX2ikZFFndAFR_kr-a^p_7D^C0Y{hZ(6Q(ULoHosSNQ_V}xk0EjX%3VT2V zNx?p*V-M_yo?WzVWPmWT=<|lRgiBvlSvcAg_*P{tpx&YEhuY>cW?8t%&}8!0pi_X8*@7#_WaH&clxw6lhW?5wDfRX zG9Sw9S1=XYkTV-ESD+PnH@CbG8%EUZ+oTP_L_SS}LcH+PDvM;V>fcBO^WN4dS)C~b zQOs*_bbAAa@l!%)c(at?V)3X8I~@MzAjEL>_N`KQx+G3BAnEj@GXrrl{R8gZ)60_3 z2tSzxAhzxyyMm5eygfAwNlzeJR%{sY?+7Vv`F*Z`zfM7F0GC@bfT*&@#$=k zHuwYuT^Bp^mUc7ePY~@zUr3Fq!vKG`=)0 z-2j*6%v?uNF2|(w$!W0P0;lf%(TK<3F)eT(!_w;S{)2tWoOFgOC)_0BsiY>e|3QyShI-7V8X$p;q0$w6sHzlDY2IBHOg8;%ksZ(9nsV{j!L=!SY z*Y@D9$f}d#Or4{`t-Xk5KHM&0xy~d)49U71lAYwpXJq2J*P~gs4 z1&pE;ux=c}Y&B?21hA$*=S`W65bFQjD~K&1j*N`&sxE1=bfWI&o{Ld(5KUarEv(^k zzQ)>#MlMKy8$x1PE(whmvImhn)ai1sq?DiSIa&)wbi+6{0lDtYNq%(7%TP<~+<-E! z+7Z8%Yvg3&062GRL2PwbqM`hWamI`0>z$U#dv;%rTYd|Ew*NbV{D-Hf$Sc835>-DGat2ZaGBW>~Q?3N0$a1Bmjy%7DtOqh{SCmQWx)D89!*>?2tz!%V`)XmQS# zNk2$Ky%fR4tqyT0Vd|RL(rHTiL}M=5A0tH<^WC`3>(7hC`cv>Oa_<%_xHNb&DQ*aq zm0~A!X)vye14o)7B)ctY<_baT%q6|CqXI+1e3uzB4E3WB>Ggc2v z(=?So!xFzCrPe<@H{Vnawa?u?=F5FmLI6ugg;J$rh!l^2uMu$*>}x1gUFvS$twe#| z>|ZSDqj^W@0$W1cD-6gJ)F@)UP=NA64%eu>wRt@x8GTFgyHU2OKctcVDpB^-6eCD) zPis05ifhm5<%PIc*c<7E#wzU;vhA&M)W3j?ZV)34vJdU_;$M@H5BIR#*VcMIOq86? z{AhMqU~ob11K%gA*yj{W^R~$_BKirEl-QUdXA1g66;(?Gu>~43vcPFfFtw4M$#4tr z(8qi|T=w+cyFnaZju_vDqIEcV&Z}7{R}{{oH3k*s2V%0GXqeZ)z{@+H)Sgr&p@7Il zf#j|J@a^NouAqXWZ&PmZs}zXPhix(Ia3Qoaqr)dl-CxLoI}Q2SM=mE8>ZlIre1dQF z)2hQnjX;a6-KH1W1^Yut`dWv=u%ai1+;P@B!NV}1YR7W>F|~nbviw_q$Alzub8(1-`G&Jm5b&esK5LAqo?Yn(!G9RxauFifvb6I ziTpS4Quiy+xaTDGtSEOE@g-tvr0j_1vN|gej!UU~-2DU$=>g|* zUZvMdX0A_CSx7lHDsMGYFBF10o!6xPwx+Q6_`SrJ<579o>Ij_%qAXPWirk$wEssD( zpX$MT5?T8J45d?&aIrE=47{F_c{J>mD2vc^7S=k5NqM*+%4n%$&=UA^W3j2t%gxYZ)zm zy-RF&*C8wR4OGM)pwvzAz{qd{DycIj#X}pdD9%`891ekJGZAusEy8PsmM{5klGv%? zL>C}^Fz#R&1z#<&WY=ks5XJww``2sNxoU5{)>+f zSJ5|;rAUZ8-cSx&ONPAoRx3#5(SxR*d*dmHtYl#hy$+zbDc5}J3b6C4_Mq^I_0u1s zzsFw9wO758c;Xi3+tZQN9a^`>?|wpi%jT~(%0EcH`5~YyPbG}=c3q7|MFG&-$I!%) z%bwW0&QIG5ORID>cm7HoOCJp0kB$Rj3wUk9Q&Mv^nSO86rm7n9^hWK`0EOInDag@3$Ta2Ygyc3-KL44M{?VqA8o#8{EqVkEzu@; zCu&SynYlEK``YS|{e@g$$SPL$)MR4U$lW>EDFsZTi=_>2#)5Q!847K$m0b#N)#UOU z(Q%{Rk@#qO>SoMt44a`7`Pgg5AfdZCom-~0FbAfl+5YKbo+$2q{p4mzS22t+FGHiS zsdk1XF-IQPG8}H-;dV(+C&C-~9bZ~9lP(TChFfCi2C~=(Y=ujsgd!2ebW;Dl^=87`Ao?6jIL@x)LPsxf=n#9BHQS!l$kjjdPs< zK5@adT)+9%@aPakh*koEg&#@r6H10s!&6*_3XH0G;N)3znR!RWECrXeLiR-|<3I*e zE+QTew3~uGhkCz|;|w{o6LJ>u+{99T8|v;um`TBt6e8p+;w*ZC|ESNv+8C0s*I~h* z{rpXal}A}M$BSWb&*xOXfX0(?C2Nx}$RSKHXIhxR zk}27ga%?8^p~n#32NU%C>y*tc_&_rcA$*7ljt-D{4l!k8J72XP7m=gcO-2!ilxI;C zKB6B#2y>rE%*8HwE9spm@rr{;rA|>4a=mJ(C}P|1ji;K7p;T(5{b}O^vClIS;wu-f zg!Auk$%=e_!tF!jCH3E!uZI8_PXVHi=jLdppGG@fv^H6;0(>1<)UJ&eZh}gt3}cXdIGyl79G~TD5xq_RHN&qK&R!pFs$1Lr64hv++Fe;vKnWbsA+<8h5r}cwW)Pl#rk?AqMg`?%yorJ>j35 zT9ToD4~WIypL?rXpX`5WM>NiGY>0~~e$h_l(`sQI3Y=x#&sLO%qxmxfa-7HS7Ro)m z6ERP{{ipFki-n*XYTW5=K#8Tp=hhUIPP0JBY|X;P&Tc$hpLezl?2a{&l0=x1eiJay z6D_H1rJ)K8!Jr2j`u)T5X(ixf*UVp4yH~WrV^cHYc;&f-9*t3;)>)Ma8-= zBR>^h8i>z@rsH;MhrK*Vy?UtRYr-17rHyH`yX@w{R)qdL?P+V?O8iC*Wgj(`Vjw}Lr zv&^V%QSb`~4Rc_C2N?2(n(70@GK;^f+K1l_a@t^9#@WSu(kaxyQLMwVCWYqvBjZFf z?RRQH)|gB-10aO21@D53qmsNb(6Q$E{ByK&y>9eCH5x(hF}19F!EFE&;j2rtMtvn{iF)p zgsn7423)W;Ws`?59@@i`%~BdhB<5gb!SJ*4WBzG&QHq}ZpJKO}n@EDV;q@Y9Hl$M`b-e&68Yb0jLId2?=+6I;|A;9ju5A7}Zv#=AdN30^NWG5Xf)$L7@UXW7&i_ zW`4(uON+7+W{-*%68538C>&d`asgqKsIx$zDI}u+;3k-~?f<83ks#zX4s4;9W+E=Lk8 zv}Fc`gk7mj!xoW^Fb5GZr6pNN#e{1b?wR_%7DfG<)h7L?=m1_5-VGgZm`?M^pkY>z z?HnZRX5U6vQxcnSif+wyrxBsYt?bL0K0r&9co=R+ZkSy%FMYdiE6akmU4aoGCzSR- zQ`gOJ&G{?olRP0?6trQK+Qo;?htW$HwVy`Kgxw`qHT-#L?|N|2w6NEBN6}g zQIm7wvlRF=ID?8zro23zxfoDn!JxPW=AzXnlUgc_(7A-V92r9#2Dsyp5-E6mK*smL zvBO4Q&A7@FHQ^<4ByEGPisDJR!(0@gI7Qd@ww<3NFZ12{BS`+h9+I{%V zUReha-jVViO(Xoj97+1#1jlvujOkhbuC7>B<^MhX|DFb&4N3hEo2!^w$R&N;{$3Fg z|F2HBpQj^Zht_xm$Vsyn|HTtSsgof?Dr2fZu>QZ?>`+U;`lBm4@BTF&?%2D=|NGo; z{|fJSa62wybu6%F!C8a<%KyFzSjPh=cAKK(|6=dVsLebqY~@TXE^_>K&wB-b_QYAI zr*-Sfim80_Nzr`_sIKPRfB97JIZY=0i|iDta*aED8{u!a^shDhM3I-t>gE4O599QW zhkK!w?$4F`x%@0$zm;RXvR#34?~)#i`5P>)i(`5yxnE#=l+AiqZ!xICB;`S#kg6b%l6AR`eBvEaGgx962`} zY;ij6@)NffN_Sq`_csfo8vKVZnXg0|<|Xptd%qZWBL7n5zb6HqQ-=R%!@tmg8E122 zIN0>^Jo@H`S-NefW!JA?_}=_Vd;Ztw2JgiFe^$to;XDfY?LT5b85iL86E{HZ*4I|c zgs7%S(GmyS0{?+l0po4Yo?iJuybs6rLjuOXQq%7w^EXOQ6gCL74P8|)pg-duvQI!f_3 zfFX?rOU{-T62GfSxT^H6Aqp7pVWsZ2Wh7m<<#z^evo@VZbuofv+}ibAn6yzL%1JZR zmc!@Id^vJC$Z08R!@BtQ;&Jv<_Gcrf`_A+fCfbkp%Q`P}*LgEpo;@bXAHo%{9;5v~ zbOX`TC|Z-iWvMTp^l@kp`pa9B(I8x~V=W&s&oIk8ZCeUp?T)KU`l#ojk#=3t={M_? zipb|KGm;viy#<2dfZXm3iiYyg&#% zs@~MZ{cSPReAx|f*y4>wA=0d4*$qM*e@K41OLx!x_aYCjp5Rg7Et~B*wv`MU$+Bl% zKYLUtMWV%URs4g8o6#}YB)7}-D&jdTJGwa%8NRq+$7mMa3Os;qv)rm`hfp0;D^NAL zo|l`}2MTIJDJ?m&{_BNSCzp5tji`pg=h-5b=$@LMt(WMRt5R(ut$`bEZ6#gxKk6wIe@u3`&2?f+^3~)SuIfa|PQ#lEFf=#yZcd9-5N+{0rK#T zr&!ve+c~;!;w;4(;$Od={?>u}+|=sL78%k=5xMU4mf)Y$)Yg7^ra&!4cQF3>a@d18 z$1Gx9MXlbxt1noto-0Dhh#*=@wP^R6@RFwn+|bh<%10@yxpvKNktTx{-(~R4iS+^QU!cmrxmPzl zo^x|=P@Lm)k89|ibNIjbK{krb{`ye%C$=TISES>uX6N_)G9|&{*+A!53lj0Y<59~j zX&xy^(WG4{Z8hfI6e2P*bd;*$lR;P|3Z1JLz`Kd~Em=~xZM6Orsl!3WAoeId?vw?G zHN4jDJZFbj!@CqE3-nWyl!ixMyO*4{hxQ*T0-4E-$O7<$j zrM_jAkJ_DX*j#y3%&6&SL~4^&8Ej_bKZj)Qbxs*-8oh3>S>i~RM9nufGQq;L(MF3l zNuNPB=;QloC*6B|dvx9#DtIC%;~Kw8B{PheP%0poLLyVIZz2u)c-*IG{I8 z#%(xrL;J$=`9Ieliof_E@nUB@ttQ5@9Hb-|gPhk^PzuaM$YSwVvQHR(NKH(0qKcX! zu38rp-N&>EaMG+|2{qgILBT7fqiBwUskUqE)=JSZc8$)=1(hgQcq+nVCqfBT%^S^L zN$!m7kf9o23?ah!=VgJxn(jnCaLO8K@S4J4kv$)NTb`P-}^+8xdScr%$~~Xk-TP3$qpZ%eq1-pYuZ3{ zU}y7P2Hc3&KrsNN z873%n&N}8Xi8Yql>Ox?+FfD^SjXe0=W26`40{^%IVM_l)UG}h}OI|ggcS2!pBTwJh z?-gGf!I(6SXT)+`+ob!%B_;o?%UQldUEtAN9{0Ho=^K@ME{CtPi^MbKjLorcS0Eqk z5pX=~>`nb~>DeB|LvaN4%(Ksn@%gL18_!=7x7}1?u1^5%T|Zv+d6>NEEdi2jdJJu3 z41n55?ztQwZg#eeez3N*LY2Jr0^GT>sMY0va|yTKvq+PP_L%&g_u;GbL{2Uvman_h zI9uLI_?x~o-{y{vY$;h*njjxpa7z%1q#uFB8aD+8-)>5suY%q}+W#I?n)KZ7^i^2R z#_8il9ODfIBIhD|AA)(aiXaUL12OK{PZdSo37~y5#cD%7B`Z?e(z=MrWNSE6G*LLE zbV|8WRE|Y$XC_;tw;T_f^!FJP3QATE7fs7emS)m@6~_IF*?>RT{pYvo|lDNtVJD3i(vd7Ga$jQ0EBmM1UFk1uS1=UiM0U4pVc>oms7 z+2Mx^_z0)VFrUMm4r$Rf33bx7qL*13zZ^Lcdx28cbqlD959Ij$L)puAXG%#uJzy-9 zVBDv)e9QG{O$SebxA971;pZ-y+JzK2w_Y02X8BQ6T~MOA+^`GL5=wm2OIqf`-u?&oQopyvE3s*dLq?vuc|1+84adoz3lu+guTxs0SzhJJ@$wi6 zUCGjE*~DQ@G@hMcD(Sya<9=IjTw=3l$&8_EfBWWI4?pyZe{X#Z@O=i0K zVi=|+U<-vKN^=B=UJ4x0Zg&tNv_uO}#Jl)4%NoG7T0&5zqB*J3$Xs#vLbkZZOA5;K z8IeGs`=qi3ZHsM+do62*0&Pdc+q^ioDCskcNu2gN$$3#slJBp6IpXq!5*dnnEos=V zt}4aRO({v>`VE!9Np}slw8N6v3FFZU=`DIn7)}1F8a;G9%UV#`6?$)9c|HhuSIaFi z{E7Q$`Zq1hnK~gP70t7m{tHpUNg;w;)47Ym+GRqa$WP~G+T3)X5u;dC1rNh@-536i ztL2+K+l<>67J8J5sL4DP7p#~`kPqWh(yve;ki=j|RZjaYZgr(K%GSG1pOade&KH*c z7GXx4A|S|cg1pKBjy>AgUnR@Oh`Owv*wNr@r&~f{v%f!C8=$Wfz9f9xirVcrmFFEQ zkax73SHBVQ`dWz5vxZ=lzR68eh9VferR5WMKj0y*4r%I^a%~!?*A+yEKtU8;0WZnI z-LE9&Q-~FIqOtJ~Op=Ga{4^_-`ogk6(~am2`6I9v9S@uH9nMHDY#6}4h)Kl5oSAC2 zF_IGITAC>Ieu~h1K7)@?+rXIaBQjCWLmvNu*bK-ET@NHpNr8oZ#k_(28FSsuNe=?) zQ;&WU#x*gW=jnclYaq)YF(z+oS396gEve_uUV$hj?Ti-hXt}a+TS#_8#ZbJrULkHh zrUk7m^}oGfK&lVlP}^det>0gRYiL z7RvYB6HZW2c~UeCp7I{ssKxrA59<-sSK~D%GRr>fGaVVSIrTfQu z4~r@7JCuBnXRnPV_O8#L+4f{7&Jvi<5c4>$qYr1iEQ!>_W`8v=6(>L~gUSTus+BI8 z1Tb2xLbfxtbUl6jwvxe8SFFCXEO6qg*p=MHp{UttQ`a%65}y0&nS!hjK@?7ICniSfKHhS+$;mo7#kp@5dU(o zW?V5C_+vJ*GEulZkmwZhhFU9JdVkhV+-tQ$Wt&kG`z~zzwYk$Tmt+c!d^x#fkPq^{ zDp?ysrPoK)=G-n@HGMf!XsyY{C`K70I)c6mV!7C~6O1G|4{;02!yIQoFF=Mo#F0*J z74MSYs(NTeg^Fyj4Mwq*R1*0%Y1-eS+zRK)t)_xuVU5?v^z)YlA@5P_opmWSy? za<994O=#6uc?{C=MaFMq{OaXj$CX^p#LqX&j(()sZx>b?z8vXAf4ZqtDR-=Z(_V~;E*9{7qvij!@8>nCDKi6Ij1JqBpmsxbK-}$EwAyM!hOWvP3n8|dv^7C7I!~gja%sL}lb9msz zk=AVieOH`1Z3_3N+N0@S<@pe7EJ833=qul&|@o7d!+u8m!L*EN#3M3dRDGaDaoy_lE!@N%{ETO&)DyM%~X&D98jI#8DyylJ-)KefZ zEK%qJ_QU=%N~el9^?z+Nt$F!h`%r%rrE!zGXY%4(hrV7+2#Iac?y2kXV&v8m8Ssvo z&@L37aKkq3TYnkQ+~%XTjr$lcQHjZi(K~`@`@b^2E!;Q^KtyO-`V20}^~ZKfa$7Br2aRX4Lcj+t))tB(hQ0S)G@~_4 zXli7R$Quc&hxi7HuoT(`GF z8U+pkr@~N1bT+~T`k6eZn}v4nhgjz8dDtryXs+7TOAG?w3t&DE_9zJZTS)k@OVs&N z1TNv@Z(rH%z{{PKHM`^&>9%CyHMSkt&L96YUfZ(|)VP#1x7q*Z!afeExnU%kkLa4NxNPB*85fv>Elx3$F|L}Gasz4icfzu$rg$05kJz4;>pAc zJv7a>*NJ~*ZP8Pe9?5SN-yB|K+BUmnD)~Z7{o$W@;G6<_j=Hrc7+dY197H9)c>Z#%Xvu2kh9v}Z^M0UBp zl>S53;WRl9n#Xh+we&-$&@w zpk?>;V;hOrj_}xR8kypg-|GLc(j=PxI$0j1eax6Or*FWxY4lC9Phv)juuQA zJgp+AF(<+f>ued+OpFWhR7^=JsZrJF(p@H0?U{C_pg?loizi&<%Y4)F>f%YVt6;U~ zinFoLD_4E4(Z>L#PYGzE6rh6{!f2Xz$GTRX?2%8x7e4r1JE;~@Jdp*~OW^L$ITtCE zDXEq-wv(12F>Q8*X^W|Cjxu@MPi9sfBL7A?T+V8nJKmxxyNOXXs?lK4PuTinY!dnL zNe!89QfN9E#1)jeqdUi*2 zLkLjA+%^|Eo$mfzz9LodCP6SSdOC&6<(qS-u!BX_}~q zf6>h~3enEv)h?1G?`%#wq9b(D7S|nMMO=klIC$zubRH*BzWL~5DRD)!EpE+zmxW!) zQ!+Xfa0H+(iF66=<&n(Xp^+rOn^zmzvE1OEuUe5*Qnvzm+##vkZ0!|S@z@eu13TBt z>;7sb<4&|z)p(PrP85bQk4MT`2`4{sBl<0?Ci@anHPHnKlG{k!g`T-51hrsmnE_dp zt^LYLdYm>CJly^w^Sj?8p>0x=DKJavT~pt|o%>2#pkAkOB+K=CH{P$oyuji__<)Wj z8~aQo<8Z;dIEO^>OIWzY3D>%;a zPlv^RrO;%Si6A>$n~whZw9601pY?m3iQDGBGinzG%aJzMt-+eb?#2nyfT@qsJ2CGDht7X)+Z)56NHf7*;tB=tePr{S%jtV8U!rdI3RR0< znTK`mt}Ml)efW{H(ZQUJSO+a|S3>lQw`6vEwTX4I`^WSj@GCFPd)@W|^t93JeG+3z z+KBxE7=wy_!BazgS8tfa##ommBI`yRl{GC?Oz7;7%>}WjgoGtVu24A&FH=0e_AV$C zWhh!J{p&Y#XCle`%C1!4VPJr>b@6=L9ik^7sfRpfezrigH~-3v6nnS7Y!^JWaYKm) z2(i#$)vIzRKbPnF*jf_NZ=A~BqxtNI3qz0u3662xUQaNCmjI~CMbUk@M*8orhHn$3 za;MrquWBA23pI_ zJJ^+@s#3C4L>Ps>50*0GEQ!Z2aFCU)@UKHdMThIkZXVio6U|}51vxR7M4U_~*oLQH zFPF}4L$Ex%!qRP6PB{Aaae*DtRR;^h>&Kr*sYaR|ircSgWH|s!Dm^s$5>U}zZ!&=n zRAg%!!7W=$73-KY+PkN*TSql7b|4R%#6hzGpq8x4l`P>xQ@2}z*2yk*@;UHit93R+ z`Q_(HW%Vzr_5qSK*DkAz&{R92E1CnH375Bt~=s^yN+Q>c6|K5J*u;6y$fwZTuJ z5M(WcGd18}juc<9YflYg&+qdim-;$`kubh>v{E>yaGtJJ_w}Pw1`#}-Gi?{k3fS0EmkV*!PW!$}V{fH1Z93*q zdejQ>!ap4;J{;Y|ijO`6Tjup}_9WYIg>8oZ_7T{(>l^wjCHP%ByMMdh?WgbMUtdW~ zzopGOgRzs8PZe(Mva+oTxux<=9q#FwP`yhu$$m62Ac=rz^?A`cs zzTXF^;9+x6sF?n<6Ct0Mqp9apK3bhhEWfbM)mc*Gd;sYYp`QHh34)gBur8B9aZ)#V zlNh;NQ{_7yoA5_C*Z#R%b;VX7>Q&|I;B5u5&fj(b221|os3Fp{xjOtxe^^;$zN$+hq&d?1xjFS;aTR9uN5_D6;TqdmB4 zZ(CSzLlqQEtmjCCZ2sJ6XJC$7_IQ{?U{h$J?Ls2U>;BX8lM+<7QTK`07O(0VL-`s` zJ}~Lp9;58m_A2uiXD^VK9yd_Z7G{b3lgveBh?XE>l==5YTQ%7y3Fil?ChLN zV=v;|kQ5P~!hlB(_~wzui6)JtZjL@5G_gv&o2SP0m_8p(d#`FFL!<7xu0xgIadlp1CUg# z%z@IQN`u!k;TB2|UGnLtz_QlKQb(PoxIr({=$;?b+2yz4Ks&TMqgd&%WH3l4ZL%VI z#89RqTDiAYDNO`CaxVDxWF0vlWoc|nYP6!Qp3+-nM6I}@69f1|Yp<;4=1fP6tVYaY zQB%3|m56XdGuA>GI0p`n_Xc*P)B|3~L;_9}N7fqqLQOXsCnUmoy^fyR1%ad|SV=I#O`5G!0V_`G#iH36nrT^*B@ZODgqC_(%4M{DYKdYZau9>+UtDri)k%aFkRT<#l zfrX$`3X?%FyVi#O7ANFbF65XRNDjTQS_cZ9jEA{76qT%V-AUNP--6oud5etQR*SSeA_Eq!Pzq%nMyNFOftd+C)g zM|7mGPF|htdVJ?i@tBT6Xug>0v0)p?Uu;M%CAZ_be$)AV6(L&B#kZ!tq69XTIY9fc<1OndwIb&<~#0s zSYamYrsYwuALY=>30{$C!rL2knV4Wy{1nU1ot!%V{!(+dY%&`P!5q98yIl1x7-%%Z zEb}v;?b)D{p!iIVT7V6=lzOxEYumo>JGOj=nGG)5zn^NDGtx3~vK1&$@Me6rJ8ac2 zU)ou289TwY*FP|MZue?V2w87AZpmY z&7i{SPsWyto@uxcpNq~tD0i<>M_(=daE(C=Tkv_=(iA8Q(^oQme?8NqvQSdu(j)m< z1IVli+HI`pp@SZ=f5Vlzves~lHfMeisuZ0aS_&hho&Fn5kJj~9B?X0ld8YKXa ztN;xyS()^Dq9L=g!mjutPjM>^taWgcZmNaoHocamF`~#rY{pXq*K8$(z|UVVn#5;Z zO&vERUGOvCcG0MtO3tEA4g0viVk1v!`(dE9YmTHS!>IVs_jkJ-JBf=+xkgehhPI|e zZ%{JU8~agw@7aq5hbWlQLTL|Akz8u5L<-~Qrbutb=l$ZL4_#(Nsd!qGyP@^6s&^h% z`W;ISQ7aRyR1I!A?`OKDD|V$Utx&!z-RjgXSHn8W3o4qfP*InXe&!xyTcsfne@JP- zFd@S663?+D=LTZu)evOcr*8{oZc4vx+eOY@U<4u@S<( zn#m4A|3f!Uc(TqeXe2?85&<@UIuNlaIL^bQu69WFXoHR*_=8mGjuFVwKEZoA_42`nkxvBDw_3i%7rq+H*^Ir$4H;DBTo_I=)qv3exGJf zQmQ@uHuK#?nosn5Op0EWy(>OK;E(a?TKPwI%86+hm^(NZ*mpuJtJPkLDYh$=3>)B4 zhp2sxDAC-(yeD_L7~#X(X{#q|v6r9ISDRww6;nVc3%jP;Q3D4$8oq%o)N+x-h5p^; z{uM3h@T+T@r50Nm={3!U)8Epexcwbdydd4Qi&IL?&dqAN>asag-iNOe$ZGlduWA3< z-z=ZcxJKZsSf2O4Hq7$x(u|eoDGUxx60bFjAGSHC;J-e#RBINMO1B-Gbq=nu?D5xz z(Ej@q&4W{U6lcS*X@E7epDF(Dy8BO_(scEo6!=cN?&u;t*eoGB9F>y4@%Ns6@1)rE zEf`D#5De7cs`&1+gn@Xm@+1P1nnVVn5h-!d|LSERB~R;&s`i7I%MIF9>c_n=UBfjEy-#nBwocd$j*VrZ1A@QLvN0@0|;1jH})m{o}+;)dCC3$~N zfwFJT1~u2n;qd*#N!cJpgj?(k&;MTjw@@Q|xc$-p2u0Q0IIj7f1u?tY1R{6@{yRSO zN#TAXqAu}QX5@dW>l(VeOg~Xj2oXp3&shtEQ+EHHx$-j%sLpr&r=DBu2^#zfUS?2i zx2~}5>XD@Slyrgqn?As#E2+O6>-`BqVs#!1_z5bW8E&oq3DFGYl^3-53DI?%8{Ls} zmHnqRYA{!7(d=-9ym`&rQ0)eYwm;j7)`92u&8r|c+ul2VEGhuXF^|~wU7gry7iwTH zb!(e@ktN_K37)*S|C_0LBVZAQdUw_LYA(hF9R){d!anG1Npw2(8Ifj!p5THOzxtkL zG6o0b^U>g>%zGOrT;)sC=K|^Kc#_yMTzs#Y67&yR^WM{vw)XxAs-^ren0jb&-rawO zb01)L5;l3a3@&tiU&RoF`W_y~_H{u(P*l*@$PKnUnJT#h#WwE)2@i@GSi8l=_AKZ9 zoC`~T4PUnP%_5+cv0!vgp#%kbXy(9toR~!%d5$U#sf?+~Ucws-Wz!0yoNT|uJ zQx}QnDi&%9U*EQLvxiz@EPdCQ`yIO|QfhOyD%KiFB}M(Ai@s6-OSBsA9GZ$Ne-$g2 z)M&d?83F?iJ+fmvPOK2rY^dPn-XRKD2rCX;)=`^Hf~LM+myt3@@@0&VL@fafM{@yjOX z>Z#}H88;4Zar`4jb(*MoA~3hT`)iC7&AAl$6-#pZ`$WchA5)l|9?pK_66ok(IP%SW zD-@%p%Wi*`=ZT&Xa~3&=8Y0X$j^)!LKklF{O%i^qsW!zCKJ33oEjj z(a=WOlZ2lb-BZh0U6rR(Nb_vt+ zLU62IovbGU@J_T?beb9*xdP7^NOHQXR}4oqW`#iY%`(Ljhn6$iIoR!( zJvdLT@*l{GB+*jTklm~(irlK@E)!=9{azN7DU?H*t|Lzo-)B*?%(Hc}5_;cTj=9&R zIcFRDc$w%{J_JB6=~*bxK|Kn9nbQxN#qlT^SstkVeRz)?CK_|eI;>ix_}qtF5ngqz z@+!Z&lIJpMeALvE#AG?&DYZYwc-4h!fDiq8FoatBqE-}oKn^~49Zju|$ihxVj3HAN zk+h_FVbWuD0z1>(Igtr%PRzw_HuKhLl#*U8qyNL+dq6dnu6^Imj0L1fXi}vmflvfO zFM>b_Bmsobs{$bqs(_#<=tvD!5+D$o0-+b_P0&N{Dxpfzp@<5IQe?#XC0M3B&v|Cf zdCvQ-Z>{fL%M~{}$=>(A_uhB*eO>?m?>hKYYq#a~V7pIcNr1`{F>s3`tl4R#g5YYZ<5=RTVL2GPLOqdmfw0p%>Gi($hmRpYz0Zt_<+qYi4MRDe z$g_Yy&8nh7%kI!{f39OdOMGWJ2nN4gp!sZ?d^p)q2iWFk4<&YX$u{~cuw|o2ZfVQr7Db6h)V`ovGrf|y zuI2j0L+rpl1)Awa7sPOuZ;Ecq_JulUNXk$$83Hgl+-lep)tD-XWIw_&$G<)sXT8q`OL< zY>M!a)k?V+b`(ssG%jr>^WVJWA^ub(Hp85754l<-CNOXTBN`f?9E&8EtjC=a79wJEaD)j%ge=LjkE7D8)87U(WZC={5{i)TKS0jY_ zN0D!!%p=kRmo+G9jqM&{uXDuRgz}N7y;Aw7>O+*MJQ#(LoFf9u*LA>6CZpJLRqThK z87e?^o$D#ecHb5AL03G`Q7_vg3uQ8(JDyg?f+nDwH=o@QPM$g_|xNPt?F+@UW zp$A0VBsDnufkJN;|5nRt&H z>=MaAEWUUsOE*AZ@9^2_4C7LX5vQ;E1has3<&nnxhtoDqcNc*V3Nlk=hB!r8_tvW0 zNsHzu%Q|lnw=V_HHp9iNzef*IzRiHNe2{)(4gYMq1VW{DsfHa<~5UZ(b@ zM0~dExMX&($sgz2opxvn1iZ-7#2vxI`;r}8@b<}f-E7#<5IED#I8C!ex~bA}=0J*a zqaHR*wF_1-6X^|YHxZ=#WCGujU`0I!yHC}R3a6HcOW!oxFnuk{>$>2eAf9_99s6;NROmAVQrwEh`NZ#X>)Vv_)R&**AJcG2< zGQQB52=4N5qe3lKf909AZ4i_^MS(@5O}8q1^7EBvARt{_zJ1QjfsNNkF8-|1_5;+> zJC&DLaTGwwQ#h=!{9>4358|a|l(pA?UdJ*gUVL}%udMg8Q z^VhC4M?fV=y@PCS&ulYQKZB-qPVREZQ86EBWlx#@F{y%vJO##MrM3!;jU-Pa-kJR%X^KQ1I!N( zWP2;+aZqRP&23?7v5l*3mOP?}ggjq)4#4{I09OUuY)Ozht)i>Qm)l14DPZ02fR@ zH2Ey#h}S~pmH70Fjx6Aa^HYAl)LBO_+3Fd=8(bOv)C6ZpG3TsA=jLQjAnZ2#AD^eM z?5>?Us9SibE~62_5evO-n+18@U`xPAK7`rEV+bc)D&a+K((NvCTVtaPCNw*vH(7JH zp-Ar_3Rw{U*=C=g~s; zPV`?>n$Y@VY0&1=cL~+w!2^(9sD1L1QIl|XEG*=gMl|+)jLVEQfT{_t!;a60{w9T| zE3#wGPfk#lFP(d)=)it0@w*eNdkD&2vM}gWtU7UN$#N;tI!VdtUs@bF|1W(_scU~1 zLY*U-Hw?Jsd-PPXyugOdvd!M|KEB%mo^AfkKl-T8+4Fnd!f&ny{;oX=fZX#j^= zz(`S^1%x4tb+h%it^RHYWv^{~e>mZGLS3xU(BMN9eIj*L_5DkjT;HRDYfK5(2G)N1 z-35I9ESG58ryuoimq^8f+hmxQ7*618-xykxjKn)JdKbkI-9$HHBG?N|UBOV4(PHb$ zX+=y$OV@r&b>A3MmAgIX_T!dt0kWSeUF`+sZZfw$X?*H>ZxAbc7KrHsoTQL6!t&Dt ztw0b6NEDU*qafk^NaOKC%K+ zWWbb9r8rqaLkecy#fNzQmZp~u;4NF{6L-Je)O-YQ&aNnsx6k$1!{(;TEvln!<(4Ei zs47N=IgY=J0Z32b+}B@*C678h;|5hjs6#xKh3%)=8J=Q++u+>bl9 z(Kh_&%=W@!s>hwQg_z^{8;rkyI(#LA(=~>7uL#-ZG1-cMv9u*S;&t%oWN~4*k6p6C zFLh7^8I}g=Bc;7>G(XOjCZj}61FH*IZwTx%zPx2XzEVU>ka|=nH3bj$!dCE!ad&V5 zApSF#)J~!?nT%j8Q6bB7jeW)=xe_7v+8-0im-s%UJh^DeT0_2fJ9%+{L5Y8IJ3F~? z$@&g`1rXt@9%vsxe2*nI7d2`2egKAZPsy>aLlI6!iS(MvM zyz^3UH@>htL&(^}1qgR{7k?BGmgT!e^)w0LcD4dgHy#mI&VHE>yj^tIEzIEg~4u6 zH7@guZf5Q&C&V!cEM(Z)w#qdRSrlL1Og+vjQab3=xaY3aXpE z{0=4+;IlKQXU^9>HQ2izo2?T#D@-)kVOQ7?D3!S%O>@FDu`gih4yE4-HbaN;b!veH zg~beO!1}CCvj+KebK=R9g{NyznfbbC2$19jCZ9c`1v%Vz%ThgyaCdl58IeF8ZU-Zk zR|TcV{)<#|w7?$bc2^*;4Z z3Mas`@`obOi9I%e!Yz4GT~>KuxhW?5gQ2q@O}1=P^eW%YxZqe1z6iX?#{Ka9K zT=ZExaLd2vxlV?(PS$;8!)8(;fp596@gn!j?U~`s>)4&B7v~*@X1%;iMKgKDxxBRW zfRy~IUeuX3T!j3d(5X7gM45%gdUUKP^Z1|#$%^Ai64tQ19%3S$U}v)j{gfW9?XyuezCA=~^2aPV>J&HG!XGdZbQIOzScJzQ^ogI5Y zU8<3s3sJsgeD#UwjA_;TJ3mK0I$53Yu!owR(ztj=5fI-LTr78sCZa$LGVh@LppDhU zF;AqIc)u@l+|*6|{pEBYXHd~(>g1W^xu{Y(;2n{+Np}L1?Gdo9ElhQ}3xaU^xIYDF z-V)=e0?K)cRg%!Q$U(pSJo|IaL!pEddp+uipuXYE$@qBQld7{MEEl06k`R{n5c#aE^BaPmZOOi&Cza*WV|Mq0V?{m85NpyxSu zEt8(f!&7=t9ZJ#2kM=a@x&ANT*e;~hHA!8}FGEL21uR#zNz{Z<13k%htnchY`E&4d zuPx?2A3!E3b|3Px675`T(jMjE>!=k)U4jlsiK+J|!Omr!jXMRpD*6rJa(9cRcbs@L zvUo5Ag$&CbM7~MW5+ENMF|ni8oO_J4V#+Z1n0CpsB!2Sc#~)^@jSDLn)rbR!!q@wI z^shY3K>1$!v&7Sm5rgra0C_5arIJTiJazb3M7UZVCKUk%h<2;AlHrU>6c&zw=@Tw# zGtb-dHir8gB&P7nvKc!+dsqKR`FqaNML_b-#Rj6>sc?1}soIUmohG0f=N9fWq$xo@ z$)C{EQB~M!zFD9mSgWf^muJy`@>~Rz?_2}Fmfjr#iXD0cg1OW(5yW1$ct!JPwEM_M z2#GU1j$+J6WdEH(asR0-aWu6*{&ie?i?sA{!ZqISQIQrOLBAe5b9UU+N{p}#Jhft! z29YXHi1B`+Faw9_v8ht(JtQwxf+aZ_qX+C_J%N2c!5#zm0NnS>8WaQl`yR7Q4VGTne@-XXc3Ts+Ta1|Y;9 z)c3gcq)7K^Z9uOYZ;wab3(j7jA>~1TK+kzIfWrKlFxKyhw%E%luD9$3-zI#CcGzge^5+6>3IJs<$^AL zcm_(VM^yLeA0Hlc_uqK%zhKGyH$0kyGfYEY<=R(KU!|0izrU##|8!4m?f($&r#xxN z^-ccYiwPH&8WT^oJ4xTRH!gqs;J4ZPfM1GCX5wtzn_JW}QfkY}s?d%F1phwrCR2%L zSQOv6*&;s1;zheA$S}cQ7ORdg6~!UiZoM-$E{PMMObuNLmWg0*S6dES_|f{IgxQKo z#eKInDg|3*MA^fz(eb~Rkcqzt@>!Spc ziqc7LP!TaQ%a4}NOR=5q2fJ4E&5RG=4&c!^T!{$x->yXwUgczmtArst|@j`&^E@w5tz}&VJoY^zHYFoazIMBM3pR@*wp$ zd7H1>@AzDD1Z3~Rw2My@H)&*+pqG-~T_Ff*Jl+AOCXKP&bvu~YG~MKh?9Xb)FV+UJ zoP|a!Pgo1~JyqSx72EJUM)=hVwy0G@;JMM-%5bBVf>X#9hpr=XbP#R0NktVDz^8DE zb5tngk^>=Ij1z{5y4L+gG4sLuL4NXyHx3_2pDrAI(%AdK;tvmTJ>N)J9~8gv7?zXi zkNx}C3vF~;q>I`2=>~MEMOW{O`^=V?CZ#MxLBAWZVsl|Gy}f9zTS=&*kmyRV!j|BC zED0X3mRK^L`yRu((LE&Q&^M0F!@c_JN=LQxN?ELThT z5LcH`NF3hqW>GihPO;x}$PpPEaTEE+1ZDE7fe*ILR_3@egDCLVA>o&)O=pze+(>#4 zRcDBSq^cR+nz%ET5hisjVW^_quCQJ3DThIjiyI-kZ+IJ;B@ABefKc__<+3L=o+iI) z)R|TD3w>#vJcFms)k+Nb&vJo73&5F;)y}}k2U+g2hOzF>y!l@n*T|l`_o#;Spr5wS zyJ5fnWWHP*k~hn1Lgu?~-Ww9VA>L>UvJRFM6Z55dxo2K^nQS>9hwq=Q&wNCtypm2x z2tQE+(HN8(5*2yk9bQ#o0fz_VDtR9A(@deHL7wuGQ`60tt+r#;4Og^6qMsRhY#W5u zvf7PYd}cfm$AG`{GTD*R$B8s^oTk)5c9n@)4^7>tVLF71v%(iiIs>%=n&abp(zzav z!*57PwUgu({>JQ4OhkQ#*QC3<+$2iLb{HKCw+dv$)@}qUtqI=8R_e^!R*_H;6T%9j zr5b_Jcb6u4F*WBdUMOn~O;bhC2QdZuAoljrmx%11%!lV(_k0rHmi*46aWC#G`RSX} zYG6NKuz$VK%n$pCD*2Ufp1(`ub>)~3xEtzapAURbF!H<$;?~3T4kV@=5lFZ&AP6-u zB8&n5#Rb->`WKk00nT8@skdELLRrf~by3`ojXjX)f}GgQv&n4aI+P zFaKWK{^_?k14L?F_m7+(tZd|+@ksvv8-L2pUJg7=J0Jh?RuKfIc*l>(<&X4aEP4qT zyT(@dDOtY$7s8|BZv;eC$JD`O8CQOkq{Y z{c^SbRqrs~i^lwovnoe(?);su235rB4l!50NNWBUI_u9}+Qa!%yhHSjzj4hm_yKwU zx;vDO_^&bJ|HhT;%(5KucP{qmEb6&OAOHGZkc+N06IxhezhBTBxm|qygZmfx1@Kes z|HbM4O{B1MiuT5T5~*9rsWP0CE*8`=(J$z5eg9?BP!L03a$TxOR&V*Koc>Y~8bmx| zEgTd;f4PxVb$WG~wU+)uUpj~)RQ}k4RDa$Z@|}w8Dc^RzZ5l+_^OSG>86~zger{eT zBqj124L0Ib;cv`X78(~n=qIy;VZNbEl*Bu5A^BRu z_q@g1?4gcF(skQ~2wOmU+fM)b<%Iij?`r+#(Xl|R55nzL%BM^FBtij1z=hWqd*VV5 z%&-o--GQ@!2i^v!Y6SkrMZHT!d)>s80e^<&=EwjCUA2=U0_ki?D4H3mTa35}_*-uP zHlt$ByGW5m%aTju7(%5pVRLi!dI2m&{Z%TiYTPqfabscVoHIh&|LXiW&!Ncpt z2_y1Ftuc&Dba|NWg%ku4-M&jisrqd+W#kAC(V)9lhO`{+mkHpN-6Tk}Z^^9&KaY1i z-2APa$&?@N(Y7UUDcv+-69wL9ToZTdsuUUiPSqUw^tLYrN9a6`C&?p5gnz(SyBSYT8 zO~=n!^eLnNkxZt!Z-TR5m)neL8)6$t$|)AzAzV%8vmW!fya{A9x)Xcb0iRQ3SJ_5N zT(AyOKe*gW$Ic?-CNGP??e3qNkNDL?xPx3Dp-oG%?bfh#bYQ5_BDB(dn?bu50?=m~ z&ZV7RJy>opWm{Eq!a}NbnWKPtE_;^~wMpa4eOy0txfwT$E1Mm_t30py`79r#h6Z_T#T$OPaYO9Nv#3|cR?ft6dQLu^nt=#}dwvnl+zSgXK`76<%uECiZ^&VNgoj=DEjr_BO}HCxN=|eJ z8>RLo`9faoT5Zkw#E_dy6RMr$MTudt>MHZl?$K-A68dm&KOLMZkl9~ z;7BG*rwM;6h&#ytu?v*#Su8DRZIv>57&-@aZ0H(Np3x|4fq<%z69*@~^JfM_BO7ge z*G>PC4#>Vqk5|8H{5h9kt}miJg6=<*?6={<0|X#p znz9Ur(Mu&;G@9+6{XQKeEH8|#d(@oT_|Jv$k%j6+NS5C%jE|ynCciODQS_J|F0cOK zjK@D;A%{e9Ok$q&-}tJg*)UEvZp5&pNvAHBUG*20bb>1A+B)+xMw|41>W@{dw~e=4 zX%}rdXcRjD)PkF)dSViI$Zr@qm|HRUlP~4!lsVcqD-r(p9>#ywqqV_;pA3l zTdA-hu?14isWY=3@R>UednOal1@SJIUaJsL665a*^4S1K&+zK#9*-?lat1|b6eksl zib&Fd#Fs5DAaKT2hhR1+bXNC`+Hufo2eUMBtLJH)i@q7)v;*n5{5mVlNFAt2vO`ZO z`Ocs5ue~lP|0+XAW$SqJH!j($R_Y0zJR_^q;RXIGDy9V9Zf-#Ii{a$GK}sxW(I2Ph z-9T_Ch5BZI3qJ6aDmfqnsQz%Deq5|O%ON4EK{IUzJ3d&F!il`_B;tqs(>?52^_R#l zwZ}dm7-Jhs#^rYfq5RmihUBJhAF6E+IKDwcpk3W*H6-TF+1dM$YNZ-PjfWUF>=&jPL8)tCIJiv(iEC*r~Mhh0cJ$}5NarbW)oXImo|`$ozd z+#(7nWc%=!ks6G1ugwSb%Dw2I@t4y`UnwTLGSMn(_wsFy<#~TfwFQ3tA2Qu0(RBkr zj2rpVO&Z7~5kpq?IXe41?O~>9Vyx7<0Ptk@!we}!XBAu6qv%C%5vd&@?Y14G8=N2C zt2dH(meLS^xfNDijl(=>-nSf%F2m$Cx5JiuJd;}F@+om{m=F_?uZxxG_#`^+^MN9- zIeK)d=bCHUQe^z+1J9E`ANcJDf4((6ua=e+^N~YZ4lgB*7Rr|)T~r(sR)0aw96wlJ zdMwozcphDs;FaRC7};y_F^>NbSNDK&* za8bMw@(9jh(&}SOj?S%@Yhx@3J7L~zY|mDz(bcq|vh?HT1dC?#haI*f$~?n)lT`y6 zw_#;31jSH~iBT8l=U%tjrATTSlXpVm`nUs+X&`*HLCm7YkQ#x>1Sr<{w%WE}nnVVw zzQnC^+-$^tB-5&a9gPj(E*%@m*F_JB{5oHq>XRCm+NGmDe<95zx?+_AA)6@Q832=J zb)59VMSIM%N|8+|M^_VV*3ke6I!%_dAwX2*NoZjsysODBTxIXg$0;oOk4f z{l}dT1DsF%TsQr1?43I2w``E`CBV2zfBrgQJCKZEHzh3rxXeh;BByVwV{v{C?uMkU zSpS0>#{`@cjog*|)Ea(>nOjS}c za(JhVMi@c87aID4PAaE}_^s%2>V@93B_u)Xj0207&X(kGKBmC{hR_%I@MDFw7tMjj zDTMJ^*n&>zoHzah13jbus{E=UXwVw|jmZ(>frTFGD$)C%-|KsR@kbJ^DyETeQtC*>TUq;2c7EA@(kYu+`;MUDtk;%$GrrQu`w@j*=k2TmWssIJ?k5Sp%7h>&3U>*1(t zV@exJ+vy974{8ycou!`-yp#T;*+IZo{l>sNvIlqn);gabR zc&V3O0CvyP{t|9duA=mu4%?(%5YwUTM_G(PaW^vZW?QW+ zTY+1hq{^&?1;JNLGvY}(l8rgVcLjsN$l?br0$G}qV&pAq9U3qTK96oqoSGaIO?bUY zOx`fjM^|vdFVGw7=pq_oj|97x#1SFyR>QzPC2^WcC%q_M6o11{t7SVdFQgBfe{uZ+ zN1wAazKV(nhiQL4!2OHC3=u-~tTN-0D#4=qofaAJ?D!A&o*I3z0q#cax-n=YpS&tw zF)Vt2MJWDHf~)u!O2YkVEL*l@t?|_2_xU1AwjL=WD~v#~GdM$;VAj08YqfwZZ>&cq zjSgM!@yY*3bDYNj`gpsTXhI?j;L>o2jMz?iN6A-!_LY(^0PP#!pIjK-xl(K`U3kU} z2du5+0f!bfft~Z!#1{^?)?Tsib=Sr<$J*3fDxPPz>q(R;p0yn_N@$jGOL$tn$m_#n zmd;nDBinO=*!}{|A(+-&%HhyjW3JnHDwLa;YJ>zE*n3zpk;ts-^HqYiShdni$b8o_ z^q70(&5U|!siQL@bpu?`_ji1bdid#|i+#ZL8~1ErqJgU?{|3A7fHKCo29IAedq})_ zCwb{o?kfr=)9=`%TpMM;=WVGd(*Ll4V}1ij)nud|LvCQ7t-&>zTKD4zRp_d(nQp5s zVM8xt$2OdqXm7a^&-wc@X3fh(M^1W^IxKr`|4c`qR}y-0%4TU>AV$M31i7UqYE$DzLCL? z9Sz>RdpP2108 z_eV#FU9Bt}o;SL<2ptek9TQiQ{mCttlFcvuCi-=?uK*1`VUl^aUy8sg$)qM-yS{Vx zj5cq7?;~pwe7RX!2mXPqf4=Wkj4uC6xhLIOGNma4KWdgFDy9-f@NR_r37vB)JgC4r zQ455$A{BinddUPsjq@1&h1ev0`~(VzG@l5t~v@PSNX;b3#o2u3aw=rg*f*n0}_6VIxeXLk(n#;KDVU+H4@*)dU zv2z9l>KFkKg4$!|wlpJ;WI4BGS7*+ZRsstU(PIdN!1M469viaujJ{VxB$?K0AAy2n zY2pxg{2qbS6T@zr>W!wa$}uGZ)GnjU~ip@_L$LU*fIbJ~$hH^<)f3^b;uzl0llNzwwRX^nOD*oegJM z#bJLNG948q>i|WK?-)%ry>pQkcXg97sZWrKH6@D1$H%r7f- za9&h5$1B0bU*9+g@DYs~`dYnX0~sBI7ewXD1lVbgZ!-k(@~t{NcyCKTGgn~7e2lHn z*f*+uh*?xW%gj`4v}Y<(%-(~hvT6f%`#)pol1cFZ#`-fZ9*PzkaO54TVqlEmIf`Osp zn59^?^LY(`{C#QCdlSm!43P#sV{BH#M!rC>-DGS@C~atu^d{S8E6XLuR{>XaBFB|Y zXEf<0K+?Hdj3Et!oxuzt$e5oPk&nf}JKkCRx>o^dZN(x5M;+DkAxd1#)`|!Nx`E{C z;*Zbt{8P;=G#ny8Z|msL^@eLEZ-|T%1(lAWiqN{_6WrU}23#MGg}xg=MMT$du!>pG z^ul>kulFZ-MloWkrS~wZ9D@c5Jl+jzDKB zT=4(Q%ejnU;I{17@!~&`uOAJuRCZE~9Wy_0@9RX|bpVmR_Ma=4_1{RG{`WPw{(rGi z=X&9~{{K|fvVYQJUF-EF8q5dF8Rw^bWA3g{k_-u>GJ-_9i`^0NHR(s0$0!uYMfduAAY zgi5LlO9Jf6&N@>BqmzUAbf$4f{_RE1QCImN7`**gUPIi+@75qgvp~Mt9l&Olb7Vgr- z)BVp!Pqur|^-k}TG^2^0_Rx$gW9V2Ax#~XqF_4n7!V~d7TCU^$Whf)YMoBNo!nA~$ zinMcMh)m0-qbA`dJ-|#ajz^bBwV>}LT>sV_+Mc~k)ebu0u33}5G*3sIMwV}DsPM8; z;dBZ^>d3%Zx?~mGzP7kS#+8XTN8?)K`t-;N6s-~x5&cu0tHO4ZE1-)`ey4M7=me#C zQkS;I8Rb=kA?uLy%^YsiIZYxB(m?Z))3^^0=!GEZD9MGT!jJ7*GGZtX+3#8`URoid zI@xXo(Sw+)CaT7i;l=x&h!Vmp%`ID8^H^eUwy)xne=&ce>Kv|j=|8qo}}98S=b}XhD5*>qcj2iknb@cYjJ|Y|Om#%cHsjI580#)qLRK8k1Y?`CDziP2`c# z@q8b-N6NF(-`s|~!!(3wf^W8{>iREA8m$Ym+;bX?5qhTQTh}wipCk`goPtzxQCmx% zpZ(({kkPnctl0eWT)L1&->>pA`MonDdc*P1+qp$`P;HO%&U23W%z1q$CpF+VrEZRj2WKcwIOhI;R7e z*19I@4E2D!FYZGjW?E`2Bv#QfbM;{>k1sOw=Gd#v+^1C#U8p(XD@=S*<^ybXlvRk4 zxs!l4+Xs!);lvHu=L=*yfHeqTuOn0NG1S{~EPXAc#dA{U~|p#rSLrt?apOVmEsb-^*LYidj{8 zv%xF}^N|cA!PWMfsl)xR-nrNhxE1nFK=x#_qMO)e0?lUsA=W>WJl2zW9IDQ3Xq7)C zXD*hN`Q!RRBNn+)9Wbn*uF#Xog<}L`!X{a5qd{_e*x9iH`Bl-!KRyse;n9J>k)*=s z;%9Nh5%0TW10zD)%3oX}bmx~LVys8u69=s>&>t%%&cjiNqsstj3f)61{{yXrD3gAu zQPgEaGWS8mrG#7M=8)GJa5THSJWh20AUKm$2Z)tCKj#n4(8T{{qTPMvP0JA{$lI05 zJw;wQOfnbZp|(stn)6Lz*KrY1{5ZGcFznX+#=q60-{6lIc5n)TT|Kqr{Cr)|fXPBC zyG$Xl26JdAI)^9Voix~(tQ!3&Ud0ZpEErvq%&*(_U%iJVJ2dn*_c!!5nU3DJ{jccl zT(M)SH1u}#3YD9N-k!QBU{pdIT>!klvA0JvLu;MnaV#9b1o_=YxctQIaT1fFx3mkp z_b)BwKWT+j9{SGL-Q^Ecw~puW$smgz`B;+|+YtOr@s}LFWu^d~&Wl#8SB%~$@7JB$ zFYdWd+`cq&xsrJED8<*d!|;z|qVH1-0;jmCELN=XqRg#M_gr`Q8n9_5MBbgxuEocW zLpUEL_A^oyqNXr+VYxcJk}c{2#$1upg3}8G;@%PrM)I6-yFvBjqzb?atIH!HLogu4 zvQGkBgA&0!qC7QReMaO03tsUbF&;&k$Ihy78|sh?C2yWXGU$K~>bw4^P(q`Tpb_@V z=ubHv*2k|puQf!@S+gyfEerXIvr1aKON_XoxOn;a;L!tO>>+G4_{nugZ#AbDS^$*N0+Go$3&>Rc~}aDRDeemxmkbDU`#(F^LvRTCS{ z;AHHy?ZaW})u`Y|BXQe8t))wk)vlV!NJdmxDwiIUS$aYJFoiJcLKe3^jC0f+q4dU) zj}1<+i&}$LCXBPryiD!)RmD-PvJzCjh6W#b4=*M1P48vllwJ_fV-RF(X*t(+5ws2{i6 z!+XmGCJiaLi%>g$h}i&%NcqS4Ij=Y0>aop)bkfRCtb6m;HGtEhK3+;0{BBRaXreS0)O(}&d?KqntC4Oz*f`l*5+y!#;$Ew(Z^=F z;1(2sqro^DpmcaAK8|&g(tjg*-NYL_e)Z3g*q1{)A{HUlCy%`+N*V5&FL<9VJzDpv z!&@>Qe4`WNxbrE8`Gy!eP>~Ln9?lXk05P)Z=(;DoCVyx zsUy?LJ*6Py3X%ASQ6(6Al@^KI|JmQXK}`_a?Twu70Y%-~d61vGIOco}ItWdEeAF42 zQ}W>tAnAq0i%RoDue*#l96M!~!hTn)_5@uhqx!;P?GTw#PrtP3c!yQ08lbs5gI&?!JA? zwAiHJLPWCdhPu)T)-D9%{gu_&>N!y+f`=pkSZA-hg2sjcJ_rRVd3 zL0u?I5KtfaLZ9d(y{xF8p&N@3lSUfcO0a5;f_q2R8k-#_@drT?2{T%0vvT^r)YR^v zqXP^UP`M`R%OP7AhLtsAp32e)5n7o-QhPBKvpRM{o_yMSg(lWV45%?Zj||9EszErd z!SZ7)4{Iz_>S++%{dkCFfg~(CPYtP*fHVMn|oPbD!%+WgLl4B2mfzM-;PAs1u>Wtsm7AY z&n)(E-iECQ3_pk%a53kEhbEhG%l!X8@Ud$xu++i`nam=XLDsl4SoZ+Y} zVM;3uZ%jAqo&`U|2=^%{_*(&Sp{YQGZUH;8;jrOX0CN2fiM+QNxgw}szfjK8U*#qa zwp9@{0iO_wkeT8SWV46q9UM~CZ8yu$O#eR0KbytWS;^cKoL)h61_NfRaNrh%vPHc- zenA`5>vX3vvfEY9M*YW!kJ|SAy}u3i7g>Gn9#}`S!pj4#H}C#t)lF~oQKn`|lHUv~ zBCW4f9-Fb$ia=(2HjiWRN!A8d1+SEfvLh-i)Wk0-dD)C%!c|u9BeYb?nwk!Ov^Mo) z3|Pe!Al9u{L`F*E!hvmX%xhz}1E@8#~ZG9w(*z z&_GNqkE6koIm9PWH0-h255)*ra6_EC4?M2Zw)EhH)jL5IY0qqT?;UGEF3GOcQ`d=g z#BsdK=Gc;A`G6G}DlDD#1+AU(GF8NLb@#kwy7(seCPEIIpCvmV#k}sYwlq`L-hA3)5 zC{{7OIX|OJ9ZEC2G;h%|0ksF_AQy!jXFeYw?>poA`1MjwRy^z$K*cTe_(X0q+o?s% z2y}5LIma8w^%P{dj1J3ttnkza{-1e6cPh;PBIBNfbn>_8`m4%=^<@4u<4U-T=HW-0 zU3kzfDu0!(z$EvKRd!;KamhBbj?Yd1Y0TmqJ~Tp9^s3~EZDSY1ZAIZ^*f)pllNP8v z(%DDQlF9OcO!xhL@U1`x%u~Uao83htvWYD+4~U=(pS~0NKK5mao8s8y)=ZzO?;-Ky zq!Feohw{7>JWsOXiWz-tJ9%|PPW<`zWSoYb^POm{8_uZmDHw(vr10rVnWifx9>h^; zs}~cxxJK$j!bL?lFY~I`nl*;&B7h$-nzp=Fzy#&rnOyCuIYgt_C+?*epSk|v&3B>q zXQP_>(q<(xYv$;&Beh+T#e6sxAaVa0iEfLxYH&X{dMjr))a1kZFF(4=D7`6U)f%04 z<_0x;!5nzTP$1PVmg;ciz9aT~!GZ-LLd@KJ*p#N6Mo53=v)|uoHzst#?6TJ_3u-2l z`s_3WJ=TN%g+;gZ( zH~qT?9YO~~0k8iv|G|=O7F{&YcJ&YWd|+|u^MT_+Z<{|K=;`}(QhU??^MUvq9~`dz zi|fVWR}EvvE_grx8z0$g z68CyD*q0QPwDBM7x8uh-!;bkGocYULi}~r+{$<}D^Yf1Rs|$rKvHj>@cfX&X_QT!4 zzd8enbR_L!`al^%OVv21)#}*y8y~rMZ7q5~!ayd3teu{`Uip*V;d&MizK2S;y#BpE zaleAU6tr*l1d`k*4JMLlDu(`Xg!J%=0b<#MIQZ%85n%13<*K`KYXt{oq@=0bi)^+f zh1FlA+)eD^BZfh&p?AOfNjD$}8nE$gcxe=7`O4rUFl>~U7Ynl2!DG)T;5~EAKn!+P zL^RgPs?#ZE&rLY~nyt)b-r?F|Wb4$f%4MnEAGgHh@(DgQLYcHWWC?`;{Zhe_dHsop? zDV2o%BwXff=WyeSEeJ*$fVq*8buk>1et>cHc8JfoIuWh;)ugaUO6A4|x+d$5v}`rM zH~ugm>O2K!@Mq=5G0{Zn6H{=(3+L#NT3vdh*LW2AL9qN`60HU>T2Sw%Y%Co(_Hj?a z6)vU{qNG(38B#+b@SCX9!`m52g@rf^d)0uCywK^mN0nne7Lg%B(gkdlx9&?%(}REa zz@avUS%tBsBeopu8Ob@uM+Ee6N|3CwXY(_@7SBfkl^fQEYHmC+Zmc+LAI+2Ss(F?%AxJW`Dt~sSp4$Px*ml+ZC%yVZS>+@K^O}@rpsl2A& zfpUK}oopAvHxwSqjNO48rXcUB_I-SaO>KOWocw8!MOWZHCDlc*d&tvv>QTNw_9oX| zDswChlRtd##aGlzNUie(q?b1ZpW`DXGY41k=b7(zy$DF0gEJ1pMHaHHWg^vch2jm4 z^%TS`j&^N&EWE8h|G`f6s*Hd(chdj*4b}K}SDK9wIxFAFF9EK%D=(YE>ib2_Pmr0^ zj(XRpdU%B=gcc`W8a;~094eR**)LhF8wkp(-KAGx1 zgus& z20G(ybeNJ*p<|MyiF$E%JN2Fb?)gLP(tIkECli9`*D*u&(}Erq zn@(jv8ApY?5?{)f26RkWv@_~^mBR~?))MX-ssT)p3`6zO+5$7@iKhIDwb?y{M!k;AF=8@RlWXfZ8j*iN*}?myJ#f`(wZ}uEL}8UZTcPgJOUM z!?2Ss`4$<+Pr@~AJ@?pM8|P>OYXlPt2@3Ftr^)UJ1Po zbQb92AUJ8&? zbdZlh>xJS>s-L9g1To8~;zanl#0oWbZ>(|CGv|^(fyt)oL@(n~clN^K4K}mIhWbvx zA`Pn;mFP5~rQig}d_wFxO)F{ohgcd`)2O=PX#Gity3ol*J2-Y%3{M>qXB~;X28>tc z36UvfWq*hS*;Sv(5;b18Spz~;llbt%y3IG_FPnkw{gXYmK>3#4mmYAS ztVHo?00Eo~4KNi;V(u1GYKj$=!4TcXTf@=%<8|XC4r_ialwtEnb1F~4&JVfz8970K zC_aITloPs~Mc#J_qsEwF<>4vrchYG@b~qg7Y)}YxepBTWk4XhUM*#!(;sxO;F@Yy+ zm&t)M@x}JCdCTl6q9f5KP{?$@6OyK0CSuW^{qonio*`-jbou>kZ?kvlj))5Ex)r0r zGxE$-6Ir(I(=lqL9^)~~%AG7oD^N6wDr)SBRucPkbwA!Ktq=zxG*rN zEzQ8hZ2nPFo&Yt9KVCmx5-Oa=9uNH%1orPuel`q?{(sne52z-#c75D)Lr<1gHi(loocf9Y=iW!timUzRu&V?8_u8o9V5RlF-=K9#cb7_%9GZAA%l1xs<@ z#qq_ord%f{c6|iE3Ta@~cX{2pf-=%Y49Am9|x`FMY+OzSB)pIvhhh zmAi$a-a=0YlIm@`EE1r2P@jhxy5?FfHG63%9ji-vyz3=jAg&*U^$*qF(lxUS=dcv@ z$Rf1IN{l%)&p;LIe8u9)ErUQ-JIyll(8z^5r*AeM-8T)&Z~i_QN!LszJ>KE=YJ*d? zu-M!wp+K=kmugu+b+V9k0ho}?T%*3pQc!|FD>?lD#X9AmjR4TYU{_6o-ejqTyDDa) zBH3-~?F?g8l4+nsJnWlbP;<>XBB>eIGy@(mJ{vXa#*X50MmNTE&`#I6=$hBurx&)G zTkSDqaeT_yEh-n(imer0mb}V!60PkBC5NX`VQG(+psmhzsXQ_B9qF>ff`x`y(pkTV ztg*J30)F#=8Kj?WZ8z8<2YiJSiuV28bsSak%?4$<=!`1 z%LB_Qq`5A$pw)Kc@zII&N3p_2avT<2OeIef={Q$%iJsD%s1tpz%zzZ#OtD#l46gE1m6*!)vlGLGSFYl*$xd7A0Te^KX zlxa_VJ=+K4_RZcX*8X_)hYH2kSf1&O3x_XK%|EFfHa6|genPw_REZ5(_+quAkDBYW z6D{*F(A8?HJAJA1K-6!X#+8Gdo#aB(krBo8r&P{$%r16EV{?LBb2YV2EnTK?EB z^I|6B&3$gU;TB)OkG#`=gU&$K{}@-V|u&AZ0oIMhK& z08HSFX2}1D*4A%lYDn292?bCPXV!Cmb*94-NEe_JPdC1^<}FST!2R3D4(?lbMr%a% z$K`i-U~j#ojXerYU`eV*3A1%xbFB7zWfQ&$;qfYeE5I2>cBgmmz2T?tOU>Hh?hL_w z?|y>1n5QsBHt`BPM$hQAg)Nt?FjLFGRbuv4#aDHUf3!2*1x0S8Dv8Er=?A8&_8}`C z=0-6j={1Bs%e$a}fV7t^7)6|Ci8^N- z*)D#W5k4hp)!NZLLJ2oLDIgp2B~3*JlmbqrY|NW>#@B)EMYx79|GgndLk!deZIz#RuWNcT~hr= zGC;aWNR=WjXH-vD(`yuw;sOj8mK80{QV>v*^ku;~S*Z)cx_j7G~w8$z&7Q!hAKR>FaJq4Mz?REn+UHOzEG zIJ%ToUOyUuj|nFNU0ATJb;}e5AC^bm4M;Xo$~9s#M}E|#U7GMPbUc(`BLGx^qwHm) zaI;Ml+RF}yW1%uF1r!iE8tF0OVQ&yyro_m?x#V9x7bxFwzf~l+M^EAIJ5j{hS&d|Q zYsEy)o2|`5&pOn7{4d=t0OFE7EBs@R!(B|5Gd7)MmUU_WXpPU*au>HG0AiI=9sRv% z;~|C2_`_bO#TS7+X?oXxKIo~rj6v`f^pk(+dY03oiG;l0D1}D89-wYq#78Y()pnY3 zUNI4C@3PtVrjz<3ge1R-zKSmP?RPoJ89xGuZqrlgGfPdKFFVfY2VP0c`f{XM@lekJ z79iHjr0pKdFh7EH@7I8vezJZ{K+jXeK`BtyI0yM65P(B|f=4rH(VnUkQ(oAq$gZsg zQ)OKfzY%Sx#HbwN0kAFz+!+yTR~)~t2vkI7hC!~%!2PINUINB%DdYa-} z!D9JRDmk#z=5(It?>P%kEIv3_C{zEzhV3JX6AGP-ThOXaq!5eO%pZbPFGLV{gt8g3IJQ|bLfD9<&}Q-G&B=& zBjs6ljW9zntpZ;=uTO!Kd2UdCe(8+7!v1@u-Fudw>XaH|C5;%2N16H`XuR&x5h;V> z3NkG(bLA2}*1(z4_D-0KF@;vG;|VpCe5ru3-VJEh%H=@D^YI6<@$T0>IX1y_9ZHqU zR0hmd!O;HWyyn)DJzm5_D(~;!1DoJ(sTA}2*BZf{1v5_Ry$SiX5gP&lr&R0Wr(>fm zYZt9}0R){pH4m{n$&t?y;LL;t@m8#kUSaGrTlD$xejPmVqs5={Ho-ln(=qY-?R$UZ zx5*39J=2QicemEVw8ElKJVacsXTpfbQUu~;kFBviBQ)FFtnr`~tYd_7#UN8Vc1_jj z%+M}l04;Y;Ti{Azgbf`tN!tIB(5KR#2XMCuoK-ICl;j42zB%21T*x17R&amTWC_MO zR%&3uo{mxoFP-<@Lzgwjc07O_-7|2OC;$elx|NAL!jNWG8IL+x*xl<=$f<_*mCIrkfo~1iFKZ>K^xMNAL*))7^Nkfcf({cj6+$c^cOR?*zdAhNn zszb;)$#65)rpzSws?~LC$xw|8^6omW&%Xk^g5G$#yEC!XDj@>wGLCmT(gjYh83`}m zc)JN6n64 zTvF>FGw@~-i%EAE;iGawOy#b_r{9?rmTse6WZ>^W4X-k|6Rl0$O3d`j(pR8+Nn3Ry zj@_Lz%Bodk;AdA4;fJ-+zzPEn{N?f-OQE9V09_0qgp@hJjXv z;<-Gwt;_f zC~Gyt#orU=2`b(*qtWAe>{^<7v8izS_CJUzLVkv454a@8K_X8NqL{3edDHQinrJkTnP+b=zlXQG z$i^fc9mUn&7Q5)!u`RR2ou%W+qw6A>XQ{+f)i564S>~|4qkZ#C=Dx%4l7IVHPbSZ(&A!4-zSKE6ETqcbW~Dx6=7&OYv48RCKqaj2%tskdeNy?5R=w}HQ&H;lh^%GFAzO5hvM!@-$_F7>#cO*d z&GZA8c`SsEjXz!}w-__o_ym2TA#$oUMGVF{ik_x}yyD8gRSS%KhSjs36fb|l=xVRa z`b07h0RZrQl)k88m_N2w5{M7e4GLP732ZO#?vWrcD3ZD$P740}oQ`U4+%V`sw?o)iOmR{bz5q<25gZe(rW` zQJ(a5gI53SfqCOYZR9aOd#|^0h6(lkY|B8}LvmZ!a~i!1g7=fIu4_CiIT4c2|1Yna zA>%&MNS6QP6ImINPxvmA$$}ss4QC2W7zi!dH?W2^(hX($YB9hPMBv1sfznK>NG9>}^?+4(6evNzifE znzdzzlPGYt!W22ITTZsVxmh5XkrR_C9JfPj4XqZrqpwY>21;{MiD3qB+rFEe-<;ai z@|sv?usD8Ybu{R6XzPUh@d0m(MZG{zQyVJwT7jOyq@CtEAL6KkG)A#Rr=;Vi$}h{>0VsjILZ6OxLZZ#q zzZ@|sg+o1$JNIDeEc25i%92u0J1_a&wP{h3V3+R-HV0D5M2d$wRp<#cAaa81_jIzR zX-x?@m)vf$(cgnzy8pHe4;;ieqw7BY=|TT+N8`f)EQrrtFGr`c7(ojdGBa~8nZIGsjj^;3*EB`PO zcaV@%Ln_(4=rBf3@M=!WgygHOTVwUjl*va&IRId?{5q#{2KzB|oovUAQZSA@O_-7t zpt_ts>KuBJ_AryOjMcWWT>;(J`Ihq?RiK$eKhf_GQz;hxSG$gBkFXkq{lk6gKLq0U zzjD=$<;8oSb2DNJlB`KoiA^fmN{5`RwX7d$tV;4JkJnhthg0YDXNlY7-U$m%Z$l%G z?dzTlWl1&EI-_o}shVw)u$?xuF5>2U=$Z+y+N)}Xz_d)ue3maqy1zm6mJ%HTG9q~W z-}(#&gqJ^YMc1re9QFOAbo$@Fa5Uc%5d5u|Wk=-uEajc>+Lt39&J&pt8Ow^kcR>c) z8Pn4Ax&u_+dqK9B3Zj%^3Twhr3_u_z!!%qx197JGXN9@8_b;Gvz=7HW9-6@g5;OMsJ5g>`XpUj z0o7U6>-h%t0q)5bJV?DP2fhlV!C))9yCNc?!%My`E^_ox6_31norBO+%1f^$V&D2l zjBHZA@1zo4LKcFv6VnSQYaN+Mu$>J3)l)df%S^TY60G1_DMh+XT4rzmAZl3}Xq+vE zCD1~cKCAv}(1Y)tt_uiHLs(sx)oIkEeT<658x4T@_*8yDWy(3lu+c;Eakxm4+DS*R zdM1hDx`d77Pv9F7Yo`~fgnGBCqf-=o{k!s7m$4ZuPBxf(ygqW;VjmP}Tuz-bNRy`` zbfSPDwiqMk;AJD*Bi}<%AIFvTKyV@-nCGeCj>IfE1@E7a&-JfPe3{oe;PEv73_vWl ztTbB=k=%cI{t8ysS~yesawO-$nUGH(-FKb|XR5x6nHS@`g*Y+<;w~KVgvAVU#5L?O zL9WJ(+Eqo0=NVi_Wg{W@!m7QT^VXwIq zZ4BV`_%pSR%AU{=q9c88%IFS-E>4n>n!`11VYtKVEk57{bdbEc@}7Iz5?7U%76JCg zSMXl!IzW6mqEP=CcA@Xp&`pvfMvP?kIxFJbzEGWqS^Di(RLW&+3dF`jYB*1g!0U~l zhJ@8il^768=c1y?M&SPbaC$spt*)ecCMHa7S!xw%>}^Whi={Yq3&&p_ED~Z~%{7CQ zvpr_bx>IocV>WpRcw`TP3l{GK48NdD6~Yi=PWF!!{d9yX) z?dVPoyz?_p|D;7~%u+P#P`C}=I3b4ONou=T`gApwq`>;}jy14n0>Yj|WytMzBbs9I z{REg<`98ePwYxtRPkN%zOc47JPadpR(|mPn=J)_B&e~R(HA$!RDQqmAQ!hQMy|KJg z$3yM>t6TZJ>`3G2&*4t?JI>993Hu8GKnEdObd0py3sT_miSO(&Y$XS3lI>>vbGw)^HK00QQX zqV|H@E$;JB5+@`jUr@kHq}7k{6omQ~lMK(#xIFC$=eDu_{8qT@Ep*13`ZD?+cG~Cx zxjW^(PW<(gsb&ipmDP9hQ>TeE=#LId-4Yg-D9=$IUJuz@%DFB6jvl)Kd%`NOgeVub z+%yE7)~9f&3Ejx&52dbJl0o34hwak8+ayI^v=|8G0MYAt$hqmpe8<@|t()cOaD7Jp z?m4QLgcr8sxOGeLqG*TD))a=P^AxPl-4G-0-`kWLL4koHCa$#J)DlX%_FITw*L#@rBsFs%`OSuyjkjw@p9ZzNrrLBcF8r>v z!(_6(Irvq^kA*ofa zD$Gme9;J~hgr{KDd{$ZdaD#n4PBRY1h=xq4zEq&s9roYauPx_)&B6VusWPWH>`Iz4 z#_*mry(ho*s0G20hpj2mSu8v`tm`n9E|m@zNDD0T}wZ) z-dsDGxm{hyDRKCZdgOH%hO;}WP%5M(atVl3$lj$z;uk%Lp5Y_e%L9>qhG6@;c-N4f zjKqC&Ywd)md-~}!J2SSX)=C@ry!_N$)udva3XwN=8}fuZqEr-V)9b++cByxuLyW}) zsO>IG8%kePr^yy#GaskRA31sgXnGwY8nbU{ngLPrVPtRyF{&z zito%CLnQy@KGWlZ&?y+ZEHB&~s)o>H&-HfJR_QpSI3cmQW+dP{m~4|LSYSmeOZU-W zt~_@~yv9T(igD%sXH{mbq#U1;CvE?fuGeL1>V+jx6BciwBeU%9?mzgpre=fQK!mZA z)%7MEsaLkIcsurVvkc%3MOHoxi2!kwDO!Oem)TM%g%yhrK`?oEtp`YP?zUJojfc-? z<-dS0tzV9y7?gI>{z(5%sF&AGhJyWbK|Mxmq9zEukSvKF{?V@EI&O;dM9CtMhKz0& za6H9{G(T=Dgv#N4eIj-#=hqwV`gE{zRHnmsFzu5ysCn@A^SgwI#2>1oi#0hqr_S)c z>xYGExg!{?p>vgq+$GK_%mCvi>L8%@iudes2CXpIzR~V5l{pBndHPPD1d@H(YA05~ z>3-)W(R{fm7s>aGJk37>H&25Vj(s_TujF|{0q--NeDWkonh?G(KJ~yesL9H({$3UP z@r^R)hJls77mWEaWw!Rm&xPK_%DB3w~#c}Z63T0w4 zsa8s@RX#Nvtd!T_8gurx}VY^@ZOC<4hz0zPE}<$??3xG{A6iyC1kgcP2JNI~g!c=V6{Ievb7vrzK$Cq7t^ObU15xP6Oc zg`(VpMCJ?ws5U>B(PJ-l&PA?0?Y4lp;<33cur5eai$>2^!tC6k1aE*R7~KE*^_*=K zrz8{Ku#2$fVLs5dI{eY@j%>`iE#?aXC|>T)5%(m6>_C}{DE3UqqUd^~-EG@z?Zx41 z3c%=S6vrbzC1>TFa2MtNwmAB4ybS3VNT0V-!%Wg`#$1({`(WZtb%HQG-PnsNAs>rI z1kMbJJvFD=CMR^!d+@r(mm`0528{|kjuFM{ljbDvCNdP~pk+3YG0NmGYy(yoKr3bS zlrXaOivhbFFlKQa=E3P`9rC%&-_XH9N2!WZoFjACH+sf5oePG=@{}7Tl1i3?=c*)L zvWq2on1zEYeMP)Q%hm@#^zq6z$u}U#_q3&P23^JxeJ8I|IUdU6U|FA{{nMGK)@g1Ybp3hkShb6dVX_L7foqoJgQGjLm)0}LnlXl>`tfyH>MU+v6Avk8bM)UB zMzNKg6vX<&#){5lQ?t)C&AiE&w4^t5?avM0XoGQCQe;^i+nFm=767_O9i77iDaQx= zOc@eu8(4LxhlN;DQ8Bil*d`+be4wd~Furb~k_x==y@PTqtBbB2y%a~#T&b;9sc)CK z_5dO(@e&zKHU$}nj-sQM`XhHEY86eL>vT#K6%uODqBj0_0xoV({D=`pa+xCG=ci}n zndjWRYm{tw%NZvkH?#tBnuh=7FSuI}YR1+D|By^w7l6)1=->;DWh@87^-L#C!&tM; zKJbS-2Q>GPd~}4)yVRqbk&1_`r`L>wbgr{8hGMG}3V;-Ab%=3}sHh|_HstZ2guJg* z$=H*qp^g!NLS4WfRt~e&b(Fn>fE;y<1M%>Ap`OXH+P;#?{d_j2Cby>z?#fVEidp_3 zfeK>2*qftd_8zb3#Ys$ZSf@(Y_4N%;6Qm^f%HyTs9ko?9NS31<9qBtZMq*)-10@U> zoJQk%l!PfaGoMmM>ZJd)20>EXNdW<%5_4^2nhyTmTYX6 zL>;MCWU!i5=gxH&oIN>OB&g6g6M>HIV#034A{ouJ6`3Ql85rWMCn{r!%<0Ti2^9Gs znv#REWIsN+5v?o7rM%U$uqWPtylo^Mc``8u`-nm#{Z88Js!0=^W%$jN{%f(I?LUVm zJIlOuLSiZG`wZb?9+%>%!nB=ZjwME!A5H*sc7#w9@(^9HdVWr)J~qFv^~Q@GVRk=F zI$fvU+6@tiSZ6f(x1Job+@DYs>ag0*kmqRR^rke=^^vsRhn(;vH@B?PCW>+n|VFtU>U9cC*;5<%t)@p0to&BBqA3-{)%{8V5Hd)!+`%@y z+G4pt1X1gCpqs&8AH3KTjJ(nhTGV%=gr%yO(Y-Bv=cI>w_;L6udCZ!pVBIp$us=Lc zL);p=3&Z1gB%*2NLpRh7!pz1-R-={VvfcFzy?T<>Ev|mJ_qq@eQemWItWYmMtwy;p zN=p_gv)rkb;Er41s#Xc* z@#ed*^RI^7hB+VgZgyOe^iOOkEaU7U<;;+nijaev#sh4M{qc}snda<68({|(Q%g=h zBIb5Kg%X2GN;wX7?V{$PX=6od?Vhfb{2XY5w;GHG-#XGTdR?#k5{kQypdw;I2K~@+^We>g9zc2R7Ym1>^-|5S{ z7j*gjeOu&1jqswI$*WXMGs+6J>gG~&^RaNBhgyHEVBPSO^jxy;VVtr48$zZbA5WFU zUDz)&_qYfsWEh!{y)#|8qS@d7en2MH;y7TnFFvO|!$ROO*cny3FumZzb`OVpG)DC? zrh*ANI^f(XeM-)^L%8h+9E)5*B z6(0))QNv!z0JM8WWK=vwKAEVo@9|U59dDP*~% zjkA_p42iz6b6?QFvZ!G|#)oOFF4xo~{2mU^R0nACrkWoOwrELN&pS1)7*tS~>8^_U zn#g|$fcTxx0^!Oid^^p(=Es_;s{I&CtO?!kU>S-sGz^ojhbwnyC?X&uy zE^qw<9UYi#a+p`*kh{?TKmmFIwUh4`!s7Z5)J*2=0>?9M*z)E-pP?#>{F9RO2CW(| z9#2=?o~uLo|0&ZtDFE*7&coWo#i5;r{+Db3gg!q<2c`d;E-cy|)pj#_60c;(557&& z`xh6q(Ly%I{LC#za65lvEJvCf$iFcpyKarvKQ%T;t*!mm^xrkhCEUBeYc;n-$kBg# zrtVhS9g~Kb50j5w{$<0l_BW=X z_CXOWtN;9l_DZx4*&VFwlTvN;;}F+>U3}?%=7h(!FGrHT34S^EQnaphZpSb2b}GgB zaL>y&JO97Ue~UF_W-_Xe|92QRS#Sg}9wlqj(~-0i%U9)0g!*+PSXK3LsyKB)t$yw+ z9SQ3aFc6^xggyVMCJ%4SVECE4gniX8`R}bqx5T7E{JGnXZYUD-6E~*J4CyD%s}u*B zeM=8DsKcmE{+yluKlfrc8?^A_Kl>Ap46uLrr>@@nChTV(yl|DDYXzPwsIVJv|Ne-r z{BkI+*G?bi&brIoWq{BZmg+}+jQXDH@}vuM@r~J6<|TBWlLV%|k>mWb#nEJQCT$ZH zM!jVPp`@_{Ez^JZs>e>%3%Z)`!%$x&n27n5%cB+pew?EcAtnYLIDjh#u_Np?uWSd5 z)nyF?wj;aqhO~;3-|OLtdK}3w_G=cDvwGp7=L0Noo~SPC4xE(DCaYJ+T_>Th$KSb9IQc)2H|%yg_vUYVNA7qUp5 zP>9xdQA6A?p*@a2;n%mEdKcws0QXC|3R|sZ z;6X{%wN6Jd1rK<-$F7UZvax+RqSaU{K6#L%{K}T}(iJdd8;$rK-w1_t{Fo*8lO(&m zCK|8x4=)tptoj1Ra^5*;bwlnsI1xR@2&oEp{bHiNi_$bK6?;`HN#aw{24|W=O>BDT zxY;$`r;$ zxxKGKGzUh_GYAE#J|0|)(w3mT3G!GW%9>eh;O=C^i{x+ zRt!RdZ%_k}eO%n4Iy~jCDept~%k4CP602#Wyirs%;0`*1<;7t-=%X0d0Luyph{3{u zB%o@8mCT_v-VykVUg|y!Bqu*DUn1PYvU)K}+*C->(;R^#gqpe%7X+867PoC zXQC_$49l`K%^gnJkjKKw(3OThaE-a1AKb~NeHm$b?x>tsMrO?}1`{f`SH60dUvI== zeLf*oqWxps8E2r}@CaA(jRzUgweF!Mn4O+ye)h2_J0yEw_y(H1H(Tq{D0-=T7o`3{ z?wbnTJrY%ur4}{oc=Fr;cc9zvC3%3P`z`D{K>5WlM~eKH_OBYL|4)1@I1H7Ty$I0f z%ww6zJ#!1BhWW-c(I_hgttmunxznM>uA_w^RE{_g3|uiOmEX9~L9ybF4U$24)@#5= zs3^%==ZY;lgw5O|7!0W)bRkkbNw7R6_7dqeMn%JWxMtgL0rh8O_ZQBRj1@B@g{LTWvdw9nFO1Cnt5C;|U&A+Ykf(w(qV3J$ z(zDc*&?##`4%}#=#I$T|W5`TX^uAt+Q1mroCIlTS*TE@)KV+{zN8Ac!{21|<-oZvc zCCF;{tfE%MSuK8+S4rU?1f7()U{4E`&67qL#n{rflo)xh73>67rEpswrH{nqmdEIl zfOJ&6_>UQ(FFU|Yh!v36X3*g_uxV=x2*tKLDiK#aF{RcoBLJRflwTX!lKEOXQf(a; z|CF2~_C1gWkxsi%fG0-uYW;_&ST3|{^^BF25nS=^k*jrV3z%CBRF4642&En8NQ-V7A>^ndKBYCOi}5x7Y-wFEMGOAsCjz6 z8nB!1h=pzowcJTyayoYe9R?I{py>LX`Yb+lm6f^IeRHfp5@{NFGOR*>XZ&O0_t(bb ztt>o7HG=Pouf67~KHM^1C$P?&l*ufa#95QdGXt(`_P^|0abvSmmhb z>c5(zTp^NshKQFroV zsi4UWW=xuuuP^bL?X@k$_0Jf&w-fH<@Y=L)y=Y#HkrxX@Iv5Z6neq%opR(eQ)w!H+ zQ-ToD|BU=Aaz;%Ve_yl;)PA?Be)~T$h0b~7-N|NaY4JH9zlzM2d=;6a z$`LiBrtCydAZSuE4Kj{;d$9llC@jh4X^64pw6JeFx*@Fu0t;zT|Iu52FUO3$C;+{6 z+Dm7a;Lps|6UTY?&Ro08ZV5g6OLJ9irc|b69&Pbpt-#?6cLJ`(?4ZDy3RHF~e|lHN z$HA(Q&w|C|X@y3G^8gDc*e&`=(xZ+aN>7t1FB`-^f7Ti}$_z1iW%yR3GGST1tV$uw zPtv)7YvZEJrQZANQ|bH8vaw#)L87FS&VEz+xF6JupHe`wAT894=~H)wnUa?-8Qswj z!U^<2MmAQ$a#t^puvXDRPrsY^^j!)rncl}P{4_kG@pCwpar9VMf3oeGNNa!G=sql3 zgd{kh!tZjQ_h8_~0)|rSDI(08w-qir?I!;ybRyU*eA&ZsF@PonEK@%<^QqZ$wY%-K zC)%l@H>9@J=v1Y9wQt0ttuP>*%+1(lGjs^Lf33O>&?vbu;aNjKapyh|HJL_G(PbCw z<3b3Rz8tAjczzH*s&Bpe(6gSI+baVrCVi;V^p%zIppm(;&WZk{TtVcgf@Fh$8dhe6 z^zp}jpJqMP-#D?Vi3+|^@SRa#{ztA-1}afEX1@T5&DU~-!U#lgfcvMDjB&)ge7wEw zsM4`!XFEwv`9*_c_tvbHIEx0_lV=2Z-8Z^#*2VPR+MB9L#VU;~i}#PX?U*@*+E=6f zlJE~uC&OSOvn{)nf#!K734W)2SCZQA>WSf+(6JC6r^ZzC zt{GHu5i(7zTCc)o^nvh%@5+U4g#wn5kax!32;Yw#cXTohA|8DMRuc zNBa%@N-tHxnVQpRF<3Uj^!&~h>c}-;|Df#`vLqdqp878!i{K}T5U~$9RB&VB^Zz6T zx#xXWKIX1Lv(z~__2YK>ti~P95fzo<3uW=iXW{kTF|7V%?dNsFxg5I8Qu2Z!u5HgYMkXPMI?(w8BQ#EHqU#_Z1B1*O_AF7@b)by<9p9b4?fU*V18H{d$w9Lv(-|v6l{F~m`Pg< zmZiz5iI%C6$)+nt8 zJ?(&H0b9r}+3R$VPaY!X=DYFdbrh=6bR5YFylzU*WaXo!@$meje2z%W-LG=6pXU{J z(T<6=lO|)4GjD`2|ag7n;wCV9p5FP+ntU zIm|`gS~^|8t-ck1%}K?UV~ByD*TK*D@ZnyRJCyi&=<7Ac$qv*cT@{_b&L`|7ujg}! zRq^d&o#w2y>bF}XgGC+R^9SV7sxLqK2V!9;IE7^*$C!IAxNAa6Fe@@{RA6l3UWT9K zUGr5$5IG=4D7Zv&z}Cg~v=b04S-WS>t(f+dB@7$fqa(R+rd&Gj(F13+ndapzrKc(d z*<^+SmMjkDLig(vND^SuZx4TAYZ<|OQON{(rhe?8fS+T#C;g=~eRp4oSb@U3IZz-G zV+Kn1%DR7TS7J;RO{JeoP^^5|>Y|fM5^ud?M5QWWgoxY%bZ{vfQqmvR()Q_wE!*RZ)I zRVP7)ut&`Nt~3J?hEyjd*KJC0=vxCE>IzEAGDFjzLqx1Lwogymw{twnS=N1M?$73} znNb4wI3>R@Rp-

}wEvO0lMLfp@C{I@d8+x$d07(UuNIqT_=x*wIJ59CyK=e*$Vf%gYKbR}ATM>pHfj@~#Mt)cT;x@DgLV2x z`W~j1eV&;z*_!%b7J7^w=86wNBEQ-Fyz~c&ZkU`$FZ^3qWAbG_LrN7h|KeZhNmPE;2YK-fnjkksw&t?>9M_(9_a^Re z3l1NxP;QNzwC((IWJ6JL_g1cj@Huw_w~FRhwK-JI5w7r+a*tsY73j&9S4`B`Pf+^+ z`IT3AH0bo7Z}}U04;uPK7&#_Aom-2*~+dUs#n~{*PX5HjYval-e z$TYYE^zhtP=yGN=!iBj^niSa%h}>}@W9bmrsFG)!kMs2PVYQjyEn*R%Q=BS(j94&!}O&VZ}LBH%A?}tsBgeU(6n|&=!B`mRCtOwY}v+G+kOtRnBkLFUjeu}mB z65OcEhrM6RR=l7j6=vO=j4NGMXRiY}(Y?*bs!Q2NEa5aoOI2yzygvRQ*mvbYCXK0O z6h2gabH^nSFfYvv+No1D z?kzq$XpGH?jTie3PD7oHy;`tXlauIsvB?N9U5v`D96fIIP?aU)OhJKp8r_s!(YzRA zF0ocdi1lnI^?mK1QWWYAp;-0@GZg5o!3cX{_3SDCc;V}-{3PipV$gOnZ^?4B$9*e96wI%T=& zb?S@k?q`od-7%8SOpQs%b{ehw?MIfM-Mv$K&(w!v&6@q_Vn4D;TB`8N5$NsvFF#UN z7SB19G9S}>e1RnXG7*NqI#hpeK`Drl2Q}_=q=ajIcif-#?fTb!)Nei^NjyZX>I#4C z6H>6Jd2%yRC>8h1;Zdl2Sg7B8080tcPWGOEk*=b&YJJpV9=n6fkb`9++}I&`6`B0?|L;Pm0}nL1G*_(!+5U^sy!0x> zo-55Pgz*B^B0gU&BDOL9vB!Se_|0#P66km;oKom(XW{KWRUhM}>M(fk)Y|MXpU(WI zUUd1FOUgaa*w9L4iKG9%#jjE)q6KVC8DgnWt8ZMncNPjnUeruZdtvWk6%{jS2+3%8 zILmupHyH#X=voG=>)qSQr%8&5zE84$t>3D8^fpHVnmP>Uf6VPI$9OYA+i`Rt_%XME zXo*_)a0)bTL0hhWxDWgB@!^QRCz;z^^uF3qeH(2Q;6%nvMV|4}xeNIhBOM%HzuoJ{ z^$Gp?Gh;`>)M^BfdgKx9A(_bG&>mrUh({DacRyEx_Cs*%o5XFN9TW8_Ut%^iZDt`M zlp9+(15M(b=Gqry%sGa?`DZ4`Le7b=bzxySiaoKahX`V*-oq%e^B*_s>S zUq|6Z-0sir*0&w|6&M7eL!eVT9EV6ORz53xyl=)2D&%J(@cXpR_ab>+3LhJ@QPqI5 z-0SHfZ&&3JfICSBGvD480gbzr=?a*!T# z%ie7V57f5n@zT{|$RXOgpYHiC^MW+!1I<_+mT8m!&1J^q+g1MGzjQwd-Bo;={@+y* z0%e@#O-c<>XR$v}A2;<0w`=Cn|1)jh=7xek z@nN-k!%@L=Q^t?WOwEBeW2fpciI2m^8FhBZ~yczlV41f@qQrNT=m~m zAa8RedPRH{l9kDPce?#<0DCs0ME=!P+V*!kH8>cbA3goq@%WXWDC6OhI@587_tD?A zly{k!hj4f2&fk|7)#kPeQ8I7e&lQ@*y8h1fzdvl}PMf!A_s{LwYL8myOpj?H4FT2u z%T}efi{pm}h%&8&zq8S|-+>)G?9M^X0o1?0DVJs~r?}^>ex_)}$cs{K^!IjJZ!;3@ z7aL#wyK^62p<}(d2k28X%6Vc+jE+&hJ{wzO*$U@2(AC`u`4OM{as-6YUPU54+!`+X za->pSZo9fV-m0bf%MrB#z8%7qUeu77?tfT4mQXU(mo>(8#YAP`{0oJn|HakVIFAB7 zEn1;|+{f>+FRAO+pXi$&0|!N@0ohD31Fn~uD&jka;dwAdF{B0{8fMyhMZxCL-FIEp z3dPaxFce19ygUonv_{uG*4Dl*C*~KZ|0ZT5K}g{{_;E|w0}MzluK-~*3RUKvs!nmv z-S@D%!RpXk7HK3uDAaN49ub$Oob7Wj%TeFVUExsSd&_3F%3&lU$5{pMWr%md)KT(k zYdjvM*d(&s>&cnhWSMUy7DQvqsF}GxX1kx~h1<F_H`Hbvr8;b%8yZXcs`wnFF z*&JkY&0}IQWmZUP4(nIet-aGpktw7`uLWsvr~jN6!5f;CB6ocRo(Gn7tEIvnsflrD z;U3?+X-$X|Si$D!-L@~~OwvS2dK>v%>%PxKOmrYUQ+l}Fg!}=AZ?5hV(~OvD;zKp> zT|WfN8m3W^%|~)CsSi_Y+(9PnXM|f7uEHpO_sga$FJ*m|!Va_}=(re38A;wb=)_4b zKC~LlFFc?fSMP&b#9-Vnun0(QO7sJdur;8GhKbwp|IE)JM*2>icXxu4;|qp z3YPI!GWuVS_AR_M(|>;4&p!>^F2&L?CoHDo!^X;rM(cbXo?nhR zJ8D2w?8oG`sg{)$gPqPyVI(Af4ukE<0Z9zq7zaRFBw9|Iudma8tix+eP~VOi?dqzY z>uRl;I##3qM}MTt0*Rrowe@L%HJId|MHQix>kgY(jdpXPl{3{Ff^GLVGjx;{+1;G< zeq5)8L{4mEVl%?eIOHNT)cV>Ee-=ipP1=SwwUug!emU~O;M)WAE`l0czU(Z11`|w! z8rJ6jj|*;7eC<0vCFKIaMM7ANDU+Dqe{q#T{~{|Bq}(9zGyFR^gKbA`4F*`PsvxNq3vyQNq7|;LRYWi zioUp6H5FL?`fW!^k5u5lBH~1}$qugq>{c*zu6>($2-At*bsDuma)`d%CQIG>|D#pu( zf=QvEZD7RX!Dm}GPw!vRnQ~H%6fDT9?3$k9^yLs&%``m6i{Y8I*_O8|pwqd=JiGSv z(0#LqeJSriL6+(K7E|$107LY2q+4x2C7LC`M{r zoK~i+5Jb{$-T25{{uI%7=&#hNg%8}7ZLY8@K9U^UHqPhoOat2Wgn^{2z}-W} z|LG3PV6R=5Uuex@k!%*f$Oy{vJt2I97NQ@d&D9YMD)Up>%|@Fa0(x-0aS%(&u5U5t zshZDy@2-GlcG%N*=zL8Va{bfFIKvG|YO4@pifVVZVnUr)O`qb$+G@pfJo2+I=Q%8O zz8q<@uZ=5oh1AVSplggzmaHB?Dmn*7Z#afYMABy4doAKej;i50V(+J^6jDZyk2z^d zJ6jdxDNMj?%@Fd6-m<5aE>@<=F2S)I%KC`MV>K1R+fwMY2N^=`nDL^Nhmcc}Wtp{! zm!d+zw8VBpQXLY^BJNM9?2TI&%6u)kGL)WPMhaK)Jfl#})T+VKUL5+MzU%0*~_;XK68cSJSHp;xC+7^v%@z%#K?|oePN<4CI_;G*Ei8b3# zS!`?4yRuZW%S-=2cFCTL0A#IExjd>kk{J?h%BD^GYidtw_Pw$Ec!4%SXr?^*J@=hW zLMd3s)Npgw#|YnT>i2HPIVl^< z?7R8oO7YNL8=PV_*Ylxwov|M3_%00cF0s2)0)rY-Pz-G^br+t)fd3DB-vQOsvi|F_ zP*jjEB`A=Dj!3Vfv_L|W4gpahbOHngMFo%4&>{&T5Q?msn>GCQH#6VtJ$q)C`5KYe%!Y_LI~7UAMlJDI#=$~niCYob zo5vTT`$8v@ewa1d++8z{<9Wti<#t&jngjR2GA8wM|E8dpL)`JL%-aEuN5w9EwPidp z>08JW%*M4C#1b?4JQpNoa^J58y}1HC$w$9A!5O#WP$SgS+7%)3q07wPPVHRWq&E&~ zTZyBaC$UP--Z3WYeGUIR*?z}+J1FW^kiL(aC;WNo%&i2|+y|qaSItc7X^snKlB80~ zQj=Yd>CVqr_ZjYOMNfu2p{=-H>R5st`rxd6m}m1L-Tv1ZG&$j*_Ljrvh#iNr-@JR6 z2pzsv+UB8e%wH0Ms7~EtgVJoo6ka8-&Po_h|Kge`ck-a1jlVD;@5?TUACIAWnpF_x zp{1gyonfHakO$Pss80tP-W1-Usd(Bu181z_#qscf;E^C9_IQ3iI#Sx=-6jEEg9?Fb zc{$-PMhDAmMM#{P0heO#q1Pta&`p;kAPD2|^!~XtlZyp#d472@NzuMZF z0BRx5;I&iQ5>E2fl6`l!)jnd4SV^>~eED8IR)$nmcNfY*2`J+$Rm9+F;04aYThCN6 zTr+$WG1MJQ#l*au?_m^-HtLh|s5sMTD}+4l{fIDGKFvlQVpI(^(N8b+mk7L2^Na-j zP#orvs#Brql>7V`&DJo`_f46*)^l=a%wER(GRK-cY)9Np`9>e$bOO$I+u6om%emnA zWtYy~r?fG;{WiJtFgyu+wEDP4$mJR_?poK%p5LiCIm*9!ka9ZOR>}iJsup8Qb??OY z^eLwgxsy^i#2>99db?<`so7i;B|7Eje1S5`xa7O!Ux<~qVbG&#^OK@-tZ=1tg|r1c zDWS5*QK*LcU4r_l;Q&a!Ms+@YrN-}pEeLIt$r$l0C?g^ZALmVA%r~sW+?k5sjt=?3 zK$hwhlnk_qbE&?LNGT^HZ?|Tt-ljN=>PC9RjqIW8I}iF{es{Ol@%>A-&y&%@Mm&UL z!mz7nnmYScO!)P}Gm(DPlJFH5Mh|t4iSGRef0I~v9VQ0ef-uRB9nX~#$w&etOR{^x z`wuXyUV@7q8-HkaHv9X$=P9Xcrv&JNm(mL(Lgh^OyS3@jO-+Mri)}d7w zMxS4In29u?bl&KjCsUcU)LcI-=BC@~3$evDYTDjR{Pt*?GnX9aKG#E*A@wdnq zsxCNUC08sWkLP1Zgp1^csYeRcJXbs*A8CtvYv<9}$@H+*RrO@jk0;VpE#6SiHpXUx zaBGBkKpBb~oS$mq)+MKy3*UK4ft!)zFuGS;({psV7}1np>-#fOt(fJeJwyR+O)&(i zb7H+2dS~3~D#Zo(AU@^ZZprQuczkNM7}%7jee`x9ONPs*P1tD9>r#KC~spRjb+4dg1iM{My@gYveam z^b7aFio>Pa2jg)?c|=(=M32Xgc=NlLpU;DFP$+mIZB?j)RW>81EGJC^jxb1q53MU2 z`IRlrSR0xilX~P^So$kkCV_hOhg{NiStlR3>_qhuO6{IdZQzdFeIZHv6KCey7ILojU6 zG>%zhxc!?{CFZ@Mlg-0JHeh6x7dpi|A;ntxx-Td_F0Uw@_an`P=Tv(lSA(~%V1!Hg zi6&9Om@-vm;coTgNQb)eE15mtB`wxHvmp>EPf1tl54?p<9((bDE9;ZKQQo)tt6v9B zKADu(L*C&hzuShsQ8ZZo@(0|ZPQ0M^zP&GMt!sLaR>0@(cG(^pygurH8NaNCe7TmK zOLo9ahwQ-YsKV1LS`P`%WZAqc~DG;goHic%{nX7eZ0J$q6 zbc2_L0p0vNjlD@(ATJ9e$l(+<@f8TveEWx3PZs!U^3>!hA)yU<(#O}p>2FrxM3&A- z-6zY;8Q(1@LGjC4NP0-=vYnf_y!wh=1zg`+?K}5;d$-nC8F3^l8Lk6)& zx6Ay(dKgQ(F`#u~^oNu#KYTkU{7U@Qh38HStTQK{M41;aGt%EgMp~^9$jml<0dE*g z`P0Nw)+ljP`hCYAZOnXI*9xY~=_Fez{_pmGtp|8LpuKz&z22q&Gn;-~U3<{pMYc*M zE@$)@2I!<5kDgTo{(Df68+MP7$dXf5XsCEag72p`M(?f~!Ro4?*edgTCxw27>E7

(;%g` z1B8nS?K0$zUmr%Y6pf!-Z2EZjtA0I*2M4KR^5h*>DD*l#nq8(1kNn@=|4MIY=J6~t z(PXRt{qBUJJkakG$(ws;J1<`OWqOtVVkQ5~y&rJ)(hIIVO=HY2&Z*u0^#yy!rQdQd z-K3G8Z|-Tf`I`HD^B1m7UaG`2d}Xfi&EJoJsngSZkxXsUC!REZ8y}kcPyEygiRqF5 zdMNFNhZW0q{=;#1!H0Y5^bB7v>MNJMxf60fb5%Sbh^&9e?~lV;^8iicznO?V@w(u9 zN6~uaJKXNGZyiM=t*c**p8H+a*Upap(eIqMe{J*U4=k#y_+uNtoxV@}V`HB8JBOuN zcVyycCK!`mE#yyUhHTD#aZNHj5>I5$Dv>^Ol(ZoD?6Q z8t80Fp!p4X_s!i%h{1gK!PfjPlwOYHTefP0Xj3sz2pfrARBk^}tW8eGb_KlT7Z->A zDBP{M0W%sm!b+K*6~U&Yfgb4K+ot7NE53iexeo}U*Z1d?jv->%>oYd8D89!u+Y{qT z7uwKnM{?2O^e2s|2U#F_LaKANb^6Ew*=_OAAPbe+AH5l|Ut~0XsU?(q58%~Ef*Bd(kSNAS>U3N3|=}d5V zSx@u|x}Cg2`<}%m6S);Y&0QWRw`=04ArORC|6pf7tB@LHPTw?49o?(u`MzJpO7ng*FsY$r9l6#)^<>BR_u1s6}?DO zygN@qO{Kk)6bs@-ht@EY`(9FJVjp{vd`6iUDielENBPF7U3HwCV}8UP_^$0%JO6);7@LZ0HnP(HZK2}rTDq($$XY(5S_ToS{T>fq zc5jxlaxD{TASDV5XQf?}jlAuReP^(Rk0xHA2&j=;dnceYt2z&=j?Qk#EjrVWaqCk9V%?vQLwc$~x|l)TyWbqoJfL?l zF`>lcWKl*5B57HCBsKMA^&9lbf*j80?y%k-6*D<`HZz*oZbw4(d=~6c;dgGDcbbB(yKZa;yWepZvJNI8~L!`L0IyJW!&7Sn8q$eGqWMX zYC98xeH%*O)cQS>aO!1 z4{QR&4?VI}ox!D}rW}xz#9zwjNKUGF5*kKHS{zTbBrB{b-#VHcEwIKTODxlHEy$kA zk)!CTZrt9y1CTs5B$dkV`6RDPgukxIab6%-MkYcjtx}p7b6cX4;w=Rt>^I*p1uMVn zlDT%-Rj8a6ZgBVt&@|QIhQ{q=sGICewH8ARCl1(ShA)L$xyyo0rUHiKjph0zN}8Nx zJT3=s9JK}KCh_kz&;jUiN)k2Jvdf`FHHC0qiy`jN{VCM7*eVCpG`~mTL++!oTeV6g zHAP^LX<8sOZi&yGGLmXwSywA&0IfT~VkO7JaQ6Ep>hje4d04C`Tm(oZ`Fmo!{-1)` zUBywt#emd8f6xCa%$gA^G!D8c@{M)Osx$nQu(QQ1yuOm#W#){bO7QW8*KNr|%xC|7 zsJ!rcE_n!Z)>tL@?_iv^LiF3y;N$5=R#50s+F{%*)Tbo*Kmzv8TU*o-X<=8fPpImu zdQti>myU3843U%*bznF9*$^Kw3|9`-%#hrGgl`5dLD|$!#Q4kCFq?{e*xKf7XdMlei$JgNMD`fW zztK({VK%W)IdS?Qz+*D3cc^L65I@1@BDN}nwFxd$qRS_Ip5LNP>(zKkCp7PY^NAxE z6DwMEV~HXV&kiS>`8UqrsNdnA@ZV`w)25vCKu6_-%>t)0-V$SKrK0(o%n%94boY#};zP-1j}UQJA74#i2!jyh*DfZnheRyScGnwWNrcZik%a!R=*iY8@g z|NUdCzLS0qw#u9_(|`3Zp8@S`4{(eSobJ~_Q&!4e`!dHr8EjTnih{g+Hp9NOsNbW* z+aRfscYY~fUshhb6yME|JlHHU)SKXv!)cMvj(a-PgWWh)jBhqWf|1mssrY(aBDaWQx zi0?bQ)y`qyTEUh_*3bW5n&EzuPMF{~9+m#7E!|%9Vx@rmpMc$E)q;On+665DjU!LS zA2Bd#&LVZYcNq>lDaZ~AyM1fqUb?M?zU)u6_czD3=Tdc<$kt8qQn{b6EnW&JuJkXy z7iVn+18TUKsU+zyS_)~0ue?xpcyrm4Eyw=ZyZlHA#3Z1bbY2|WTdXHn#L&+1bg^G7 z*P13c4-@DlevcTz?%EN??|T;+z1VM?o%vIVQ)bTF|*;w-f@SR<0I9vZ)QiGW5zL3uF7>O zG#G397m!v~!d1B}WtO~M?LUT5l?$=9u5mK7s1$!-nlMY&ju~f`Kq!~}doV9ymY^MD z%PfXa{{IbTB+LeCM~^d$Ae8?aqGtnv(PJ19C*_QP5eh16bvf7@Q&4KGlvO?UD!{)1 z>Dem*#`jQazfe~Hb*K_S^OicLV1N{t)u_uJtyLY3f_$QPCX0S3!tS#CY0P~wQk77$dL_Yw+V*ZBs z4@>@mxWDDq(9^%?_J=Y6nER}`9$Tt1evp!n0n4Mra-)p^8mI!9-|haxGJi+RR@U%u zuKxp{zblg)Z3uv!n>D9rOHszRQ1Y3<$GKQj!OEs*?Zj73s}3{Q?I}C;F9M0mkFg9z z2^jEklvvpB`Bzc$FknfPm~*rN0A@35*1<+l#{VFqd-jFp^BQ)r5|rbrC@vVFB#Orw z-2;Hw%*y_ABEPh8_CKmXBQgU;Q9Rn{ZUE%;tZWo3UODbN@l@r78lcQSEAbDjX>zNY z#U1%Qqu+|*l;f}z1O^B~@c_|X0EqsqtRCxEV)zqAn5fcT7 zbFjraM8^JUrzAvfXrcf7FqrN}>iqe*X7B}x{`ue)%-=YU49Weoro$C*=r6n2xh$$z zIeUED=(`n>fhO-NzIy6zo2^zD>|L)wWM;5#N75Ba+7kI(PZRGG7q7MV$UU2<&p02@ z()f7V&!=9=o@NYF&h(IO+kR#xY@1B8`uLhr&a@E!kZvU`=v!I7fIfH5d^bD3X@xuu zM9xV8AFu}EmD@s!0&CCj0y3dqG@SGzNXFp<6z%UDTBc;c%rd zRQ(g>=(BA9xd^AvcH5`CeY(w6+x@U@AG6aJ+o$~Xq`zlOQ>+v%B*^}^VJ zpez`0qnEEQnW&r;vs*N2T+FdE1-}+d8ml+ivL>rG1D0Q&FKOwop#OV#uV0>WNHPKQDYhfz{@h)s z^+#2gUW_$gTy;>}l;;0%_+QUJzpGy2GM(*(F5)xe267UPys=-GQS^$u%^;hqTWW1& z_AuK#FAds>UOYj}EAp*;0`{&q&^#Lc-nH8hjd30?lF3({43Egx$pH$g!lHG;%cSK) zZNlF-&bX;+VsWfY2MiFjuv|}1m3{E`^}mo4(@l_mUPi(Z;sieQQ~J89_sboyv7c0H za3$nh*;xUDl|2{CooS1n&q>8@kXFC>H&u7Ud=}a(?e*5BCbD$<>g&j((MtGeni45X zlw+sZ!8{jQ{56M<$<#J+c-6kujsilTT(>fV+4Ex}y{Rah^M@uBN7o%ox=v{7UgOcH znS&EbD&NGlGY%d;(C;x^I7>zz4?l_lZh=BLBXCYw7i-Z4@Bzio85JQ0lpYBith4G& z3u+=s(~&VTnA>4}9A?KHXYG%2E+bdkzsG@Z-$o-jcON6^gdu&4Ml=HPI6k?;j8O{m zk>73LrxKnBHr1)a)?6E0FiC+|71p4s8rvN9V$mwM30tTp7h5Gqz<{PZ^(k#)(7%{1 z35(@N)`f}mVrAA=CN&4w5-zjjM+iAlDwKMC`vx^5R;-HHD>)db)3Fs?`FzF0Iy^Z#fB4)?qM%zg z8$!=7+PmIZ;6`gJEbTMZ?5OsYP>!&Gy?Pp&q}qHoF8yytJa6%r^?RN88oUUmz(788 z=c|rA4f?4l(5ziu>pAMMXNebwZxL}*eh7MtG!8E0dlE6`&~+hEqq;pCv~m1?YpJvA zPSC`W1xaE)Yhn1 zo!?Ogn(bmx;Gd=}oljzu!z-4_`VzQrC(K6)-Eok7A3>YLW5;ienXzqh-n_+;lM$6q zL5!AiNB5k!OC~Re&JZ3|lkFEr=Q(+E$!^=uD5FuEC5O1_@y{X;{J4)#69N>E$bZ=t zaQ%tI!rQZcsYsZzKdJj>uJL8_t>Oz7HzAX2Y8z6U31#9ypk(K~ER1?sR`n2=<5|J{ z6oFqo;TB71-L3IL&7c7 zre&?x7I1LP6-$DVRQPj24_nr}E=h$~Io@uEK#R8Y!g}5taN%~p4cL^{0R=nwvkTFM ziF0N7uV~G8!9b*565baiuNxdGHJ^s6!X_~|z@g}t$P-ZZT+9-6Y& zwuab2^v+H;^rEm99|Sjm-1Dz&+*mG=(yrg4txPE++1{ilj~PI4zf$p^5vvwW1eeNI zf41J6*i<0_>L6>Z;oEQ~KA}MTZK9@WQRqp=Oj3AsjENzZak_9t4wKOl?`5$1{&4J9 z=X6(az*~Z<*0F+m@fOv-^uc0LW7^N;k8xVqgxmz-+AIgaHmY)&tS$cCkEiiTHP_Az zE~3&bBUUhV;>Ge5P=-rnZY|XKSa1=WbM3T*gexyw1x=**Hg1EP&^thX*R=7Fkk(Z_Uwq^eK~7nSVRc6GydigHcoMoYpLTr-x7 zuxKnE_P|@|_1cw9CcdgOnwF}TiYt$5?o=py4TV2xETW!O*%;(f#pmZXA;JEKBl!#h zt8r!m_X#)=!lz*W3par^uJ=dBotbs);hPB+Y_D%@k{~`>7b>_YPU^zAnS&oZ4kUIr ztVbX!`@)ly(=IO@(TT`*NxcfExz@ORwN}^Bzzo>rEB2N32F_eSMyA@J%CU-**REZb z$5e69DzCHlU5V2ZTQ?W9Fgt=S1&AK(EdbxssUPK8}6P#t1TS1^??I$Uk96=JsjH8_L& zhL9Z1#wJfArOfPM4!{Bnt+)a9uuCD5lvMEfcb8JPqtdS*(-?7_W7$Xov|Ri4fp*1d z#8$o8Gi2%P_U*=J;hCnqMU|orP_3xju?FUBUMF??VQzgPyJF13exOchtSE+2a+WR6 zroKv6@e__uHrxY`Nj#G(rk>aN(uQPx^IICCt<>*9b z=aW=R^sJ^_QoXV|ZbAwkk1BBV_;}Oh<${azFpK%&sy2gt5{A#(x8x%n-(5D+vleUz zbD&(TD1>;=@gxT7}g2W*uiSz<(&y-)#WR+LbT%a>gzcQj^i)JoTgYHnG5 z+2tSh+%WuO-h1x92^NRpBJpsfzU}ODx&sx2b3hXDY&gL8wt*9BGy<0ZJNz!bKHOVL zSLb7qh$75v+cbz~W_25N;&_holfibw@p9M|-ulrYom6^0Wg{%qL%N!LKav49e9JDo zCS)(A^$NRb4_VlvjazV}R_9~q`Qs}~sK%gagkt(hfZl8UZRHP$Yk_LP{q_kPq*#_& zpdC}Nn#0HOeMi(VeDP}Nr($4{-Pr^qq+>~d{0f$z!X=_;s_g^1^k4;#YbzHh2QMa( zs9G-$DYyrvr`pOh=Pf?-?!GE7y(41w<^3e#Ocz`mksi<$xuWm9Z$O2aug1>{%i`0~ znk=pCg?YREn)AG{3*;)pdA&Dj@D{VWdq6kT@hOY7Sud58s^7i&sd#f3S6Y(fE17rF zzeUNOB(jHx%|YPHu4mnpv(G65h=-k--)}S(!*St_Zwa}kI+w;SB#=tu_hzexq(49> zjBdQ;2*C*9LUrTOBqN3S20 z+6?^k_NKO|g81y475aXFy_(i(J`pZg9jyv8hYH2A+!L_pPJniAUI6iiG#UXr{shVTa-=6yIb@s3E{U0ehXE`=WyFL znRh}UGJ4ZF`yb_bJ6%?x31?k37=w^(XESW&4k<^$V+DIIw^92KX53k7P@-31tqF<~ z@&8b~baPvf{z5-tDzMM1_EsVam=~`Ni`mp4xWD7Tw?u5;5n%a#I^*D`Y7QJ#=hVkI zr;2)ciO<9e6wQ4X+uWMf5y>Ma)#sXHf4so-OPyXg9B(}>@ezFW&Rhvd5aKbSaj$jT zB+W^Y-=kz@{`vV>((C=4`))2Vqm!KT+#nIaH)Z9th`Kq?9op!iq}Xh_*+`J&laxHT zvCIKb>TJEPxkK_nYJsSo?B{n__zggU$#6$Pt{Icbsq`V8?mi?~@7k6s#E+1O88eFp zxr&HBH69o3V>beWw(Q_c5|@*b*a*`X3WzBL`c&g;ez zhp|O|o;DH`PJ2Cc&D?%7DPO*lxZiuS<&eULlPdj_Y~fNhKsNZc5WW@X;YdBXV~5pL90sw@Sp)^ zEx5(x^$Mz*#-~ZoGgs!*!QlEtj-es9b|2N@3v0*DQ1Ws@4ywq;Z(L)5YQtmu(YI!d3}2Cb1@fTco>Z_! zZJMo~km1Fw%8Ap_MLLBTHg`mlOAIlvdj{x7$Z2DJC_XX{p@nYxYC)=Q(n%ru)NX2W z9pt-KJkkV;mqqZ&;IxFPQ^T`hT}@V2^)SsM(exx0l8wBNyr=k*sC#enx%cXe`o9j6 z2QT#mNs*n{>FUyADuD*`P6nOIBwd?C(9^GWr9luVP>%A@%U@I5GiEPC8TfvVeLzSw z<*f^yDlUdWW?pgu>SH0#3RbSGJ85&fnO`OH0Xg}KBTv0C>tlkw635eR>(dFp*Q8#X zl2VGDlMv%UMQpS%6x||Ks)n{r2HZlOAQ{grAJ}(%7V2|!JDhG4m{0?r^IbjmLcnO+!`FE6!_mR*gH1K`);W} zUwDxvl~2B?og?W;FCf*S0MpKx3ky-W~c)meU@iN;YIbwpJB00VOuAEGQ*kxrO@7lEv0Y<9A~*>nrouWbt=qor z(%5->!Kh(g$3%b&U)ab~Ppg*vGGfDAd@sOiPjMx`<*&=7^p@wo6RqLK(PGR*=PvD= zFu=y?r?@C}yvls`0GK&Q^!!f~jWT7IxAwFg6}tM}Ws30bBcBXvrDeF-cn)=F7s)CN z7xr#Al_nrO?R1d5jKvFr(~j?!0(f|fEi;#Rcf&uK+<)g8(A!6Q$3y4oh=h9C55v>E z(`aup-@OU$_5= zXNZ>xdlRs;=w-KH1!~nO5@bhQyA@i&3k5Sh;d@;gw>*27OGWSn?JoBzb_+ZK2Bp4p z<5GpIrOOTvjXq>pZZUXDi?4^wL#ZamN!UGdZ}X~Srzzj~^8K#oUV z1xVKq>z!?Dp+?V_+q?I*dr0Nd97%jCDPBsnldt?t--z8(IlA|Zo)G9%c|d(+Z|uP% z8#8uTyOz;d(*VvS?^Eu$8(hu!Lyv;X+J~{WQGlou@9CpOGs)-Dkm-jmv>?VE53C!V z6$c^6pZa+XNBH9E!b*P{(_H-^9{Z5f&$ z3%Y4f>hnr>ASCf}1)Sz2xH8R@w-X&J^b*VJQxDm(j)cV|qlK$_zwEMt(+ngX_HH{y ze4C+JRtGAr)Oj!4x7kB~7Q25{CV+p|u0CpiPc7Uc^5vNo4^Va~@M;vB8}IIzV?(bh zq-;oJ9)%?xPSetj<{)imc6cVj%3(bNt{O=w6_w0cquxXPzI z1?`StER4&my+r%u`t*r2{cWAz#a)xl)$k{d67|mo`d!q{3#~OSGS|WeobEEHMnV0z zAc27qkt{(S_<5_!fE@f8-81GayrA6eC7&j6o@)04vzH2qxZw|1H9lH8HlZtUGtv)Y zzr7+&T$D_J8cBJUqS!p+CMI1NtheLjfjcHjPf)Jr zeYD;&!gw-#cH&$QQ1)f%2Rw@w&5+QA$asNep~5`f>KA6IT`2cGv8Mp=U9%79xqely z{pEhvKOx541DG}cM2*rtfS+c*s~r&D-Q}Uh$OuaQ_gt-!k+w}Brav?2X+ za6UWWt=LiAPMCPgw#)0IIcL$d2N>n+XE04=`RiNhoL-vy$=UDjt(ik0V4#mh_$BM$ zRu+MEP|uqO|NHyD*aJvW$qo7cvENZ-B4$afyHwrFG}EIkxAw{4gx|9@)K0L3$20xhZ#PW-=L+rx@6{tj{>(4*^rK~6Ifj-HttspM z+pS2suYqHPHm~?4S8%h37)C?mzY8HO)f* zR6%z^Q7QudQx}aXkLEWjyR`i$x+#=pT(tV5+KoD!E7%)~JipzESkbc=Zm}gk?nyI| ze|+7M*BhZu$xPmn)V|MbNa=Nz13jOQ$0SqD)V)3XRKV{=m8Pjcy0Ll{P+>aaVA-amqhWLRl;OnBhF0S z_I=o$?03X@+q7GpYm(GEpR8B|>}R9Jlukp352GByx(xf{Xhsl^Kazn2pNkXstdpYV zCkq2WBzls3>v@#oORh3d5)K`AGhv8vc#e&DwZ?bKBBMJ-eTYW&qZH}v}|{Ae-Fo|Xz# zEekC+xZzIETGM z62vFFeI)nqrr%}fG}Q4-P6&}PbK%E*miTIx#oc-xjymlhbcef^ zJ9gB({V!*CEq~W(|E6ufV^Z-$Umte8OPn552*73e!>)HO(*p|um~?+tROeC$umBK~ z?k|q&Eb0&{07Rzy^P)OEIs^&;p;`X>uXl>mUn}JQoON;Q`lDj{kRtvq(!~kvBTv2H zBK}R%#cu2)alNa>{Lc$7HfGN(M_n%FUoN~@oIO(<6;#5%Sb8zFYDT={QVIWT>BX3; z=@t5mrTjCM7d>01OXvej`9~`+!ds@j^a9HGskIkjgVPdv7s~kiYcHw}POU`wm-Bbm zUld=T^6EfU@VD=J&O-0^tLi&oMJO#P4_AGrO-sg{%OYt>DO$BNjF!~rmc-DK;uzJ! zw&FO|l(r&_YRX*UxqyRAn{*%c1Y?^!XAr*fN^rh1rqT8}XH-@F^|C#1I#N887q{*H zuV;h!Rcar*1{$?0TI8kJ5Qo`%?mD3!RVlw1OTV~kthOn_|A8IzDY_$sLKD*eM219C zoCw*=H>aQ zh9rcDehu=rDcr5&YEft3m!#SyF20Y)^0*uNsZo+rt|PbTX!~+efkAnVy|vUTC$sRZ zPokT|TvJ5c2aBtpXwD$smLk&K%ax6EGlLbVXE0p;4P}eRlS-<`%=qCn8SN42y36LV znEu@guf0a1*OFOtkeu&aRupf|D^E3_RM=~|0W-9k`Vna{_)Q7S@c!xwkF?4W4PNAC z*#qOl-P)Y+&Y7ju_%L`vi|UF`H>n1R!>Uh48YeB6iO9|^w_I+tzp=AK?K$d{(+*Dz zw8BB98^R9u*QrF~*!d$$*QMg3H!iY9_I|ix`>t+2D`Zo=hG4KX79VB}&Uly-NSm@e zYCUeiQ?SYFn&NZjRFM&APS7phylNH8r68-J1=|79(uOb&!bQ`_!4qK<*Y0Pgs4X9j zEm9zplI|R+BFc1}-rQI1LRV*@jY|uBV1rwF#$xAD&tY{-Ds5qZKm<6HY;vT}))J(+80ei9DSNmwPeM?rn;0!fXn&X@|il2Wz5M zwv?j>w(oXzG2Sj&o7}Ns4`pycZ&{@e^=S%Q7RlM&5zb%;V#s&0B>z$1p$v=`NbAT;{Nnl?q53P8G_88H|!=b+wQHtcnE zmgB`Mh|=t8Y069}XH-l5wqjMI(iy(~_@|Mt+Jc|ldH3jQz#&Y|sbvHve>*AG59l~z zoXkM`Q2q$X?>$%T)o6=Za#btKdQJ{&f-|qVtKH6ezM0!Jfm!!dyI=T1F}Hb=`IWcY zNM-O_QghVJ=Va|BTg;j(r-u_M)o|Rsw|CQ)PclAI^Io_c5g*77UB4@8+FvW$L`ma36qKXg-}Po9Ljljm_ne^JXv@5WP%BIM0rL`m8ZwXee*BP; z@H|kvVVwCXLhUOY3nNPQ(qijQrlFq)3XX^^te_O-s5;O9SPL2iT)Ey{(b%6j2ch+&Q)QU!N=PsUKth1LQmgA5h?UKX1$4W48#|mrd)5D29cFSN@qCYjB zQR$}qlH!>_jVmX9SI3+F@9X}7;V}d)rbhK#98a17Q3l~*CvHxkcH-*#!+!p&Po})- z&ngGJiuxxBfG8Y9vtkic-hW|mr_RIveU9qQjqlqk(pCR9xwqIW+c_j|reWDbsFt;Z znQLH)MTi<&xVdU@k+C$q+na)A4H$|#v)w4FlE3}lMZRBX2k}?%m;Uq+FZgIs#Z;^1 zQ}K@Av-iLGoDy!o1K6}^8y)ir@F!G%+4T|vP+>o-ebCaX&W?%9`fYV-_Nikx5#ick zBSzvvN;4Wu<6qv+W|r{;w2_TK!-a3m=F9Yb1@z2 zNB4szviAd<=5Z-{YspMu6EbXilE2()y%scT5Qi`hB-+`9O3{X=tj9!`k%pnzrI7nf zd{Ia85s9+M?j@;aBk3xmp%mXkHYyw4Mak^LZp`EAq3}!h3zMK4z{}G&Opj@u*Q#8= zo%UjS*onH#@GKv@yNxUyk4RN1-tgZWIb#5cQ*f=t#hkII4=J%QKLZsLZwvH*7EYGn zS0?r6xUOIF@2c+8)jQtVn^u9Fqfjs1&k7_Pm>{LNFJJDgr8UY4HHd)950)x0J-UPmOO}Vpd18`7OjWlZJa^azyy@2(wVA?!ko;P($Qunr4}yRcEkkIDxO))YbSQ z)Pst2(LKI%9;&w47IF!t_)muU>_sT|r#%qz{OK`>_vrj(qL~>?(=knMV|Ftvc7j>j zUHNv_|95aSEEdiz<*rX zY6~Xxye)YqVngLy`y|@Cr*IKK@gWj$QsuPQXtnHhbw2%aad;UNS$O) zZyw_UkQ8gIl8t7krda-x_p~u7@BnH|s^i=(z~%WK*;U24%1P$?-fEnct5z*r4eM!2 zM?4m9n&#b(+G9C%xc1+PGmExUfddd&N(#G=K%V+40tv@yGf(TP-aT$4i9 z>S$OEoVmwaH)VA*tY(6Fz+Fu@WsS?Z))q79s%Dh3rs!Ndju}CySthJmY1fT2KSZdV zNmvWiCfhQPBbduOn?E4YYh)mK3^RRBE#TL+(OoM~lT*`BM`hHzN}z(t>F@cq#@;~1 zOmo>W*Y7@SH#g!Z|cS#JnSCJ{WIXlV(bW^yGRB);^x}L)I&f%1a(ydioea zlW-Z6CozQy(}8T2IGPvwiIjjc59fDxzv{@h!`@#t+&Da1Mjo%Vv`Si^09p%{A38It z9tO);GcYCUU~PHeQP;|c5-!%L05458l_B?rs?_O$Zt^3oHXpBeHilh-)fD4qlH7|& zQldR9dG_LOD;AA|-Zuom=Y+>8nUqiqj5V|6DCTBH!^>cr8Va>qWh-Z;rz@|7}9!dVh; zwpyGAiiTRkuW9m6L>@IDU3}AS%V=!T={I`1V3e|vh_n<`5rdY<^=9{%#?CiwEs#1N zsV3Vi;3dSL6;Xw4EV^F}+1_*lmw8)wh*htEkGO`9fOTB&k2s5h@;)?nq{&N&=Qxl? z4bj!YG$$Fvn$Pz>4s`HZcV$}Tr+8Md)rM*Yel%1I5$323+OT5#aBSaY z3R59`zCoLWnuG1y;4Lv#974_ON@EK>ivg50Xg>iMg=vbZ@Gei-E^>!YYB(IzHi#Ye zfP&D`?>aBtwHQ@Q>;;2xLek%quRf)zLcA>!?cMcnaHJSv7-Cg5o6C3Iiw-5mE!#_| z>e$HCdTj=A4iHO!;m?&)cnLcI8sAa2a@@zBTb6Xq#EGpB`uO1fIQ5tTym5GRJfCNA zzH61Zfj^M^!8M|*#ni#Ju*9#|W)4k)y(d23`B3&;krbUGMl>#JlXg4a z`AWQ5e8m3^$5y_GQl8hnRo)u$RRu1#x&z{r0XO&Q&0wBK#Jg@)cJIB!ha9@?q_=f8 z%f!u{!k`VSn-ZCFAp^Ne8xQXpaz$5jy^fnu%I-XlWx|s)x8;V@vRv;p6ml1rdv+b? zzSmp5Y$fS8#6HJXYs^l|j2q+$2cgM4bZx>~5FW?(`d25S`D?-ZoOQYU4a2w<)r{Ht zQcP356VAw^hV=O5&!u1$^*f*(7f|$iEVM-T;Dys2wB&e{HUqRUbc;!Fiinb#!SdjnA^(B$a}Yt;ABaMPX#}@S*W`9L9WK6y&BSQEh(35g&Bvd zopE0a$gLa2JcJ)5l?Tx2JZI7xNp*bU-pj*>6Md{Yn7zM6B}I}&z_A{S?wT32QPVxQ z#`)_~F&W+AR>FU?H1KlOcyWho34dy7pl8*%XOv4ZKcO%XmOU&ZflydBI-*2uw#!_>J=Bn|>~c66@>$6af6QP~F$tm+AQm z0X|u%#%;)3bm)nG&ueVB{*4c5ZJgm}XBN3jAG_w4bueTM`GZz9BNq!U9HcvgKBF0vZ zg~fgzlG__$Aqd7+?xXKl|8v`_VI!3@>JP_DI$SIGQ=0=l*Z<##GP@<{)2_Wzyf$`} z_-@0lt>`y8AWj_XW0d!@JwyiFgG)W$)CV8UUKY@pL~?Fv~T5?_U=K zx+^0;6Mt$HUgx{w`qvEmvc_*=7k=U*?iH)>=jn(bc?N*1K2mr!kpYQ68&xK6R%{2dLOEUAAt-LGTvWh z($OUrpJ!B$Z(vf}c&EI~Cpm1MBG(Dl$>~iGkRo{gANJlno~^BG9M|4X+G@>es39VR zpv2flT_lK56{<}rw?v4s=wxW!wuXcl5)pz@Gc~jlV_Vf$3?Zt9Y7L!?Eu9QSDgA~! zKF{ZQzqilxzVG+<`{SMy&OZC>v(Mh^th4soYpuPO-`K%*joC)n*hW7es~w#@_gADO zYbo(mVJl@B6ai|#R9GIBF0u2&?q1H#^@XWIzefz|%SGaYw8VTpkp;JA<@_`htbn`- zI_zr7v4XY>SMIqny~yO>9Y{C*>M(i&XA*qEWX!Lf(3N_>OTNBLepYXs`FbpSYaP8q zS9D_cEWe!!k+ZJyvw_82a{VR9`&)(}C*|X$h4$B-BKehoC9qu&$WGUuN>PMT~ zS9d+}5qG%V0QOjTfdtF)OufIF!?mRG+n^(3dvuAvfgcop9rib^*t)sg4s z*f>W)5{H9O>ar-_;z)B--xP}gJ9tu2H_z=S99q z5D7J~dGo)Oq(}{>FYMZr_u2F}E5Al}`5}}1ye4OIpZ73vM(|YVkm4s+l9xF`N_Y&| zN6=S1jNE+_yW^|!!GeP{QR3JT*zWj2Z?8G}%-y#NS`1JIU{U&4MbV7Z6w_^WYE9 zA(jtH6=dxLYEag3HTxpGx&&{b0DAd3{pUr_`^OjP9XsyjvCTrt&eE4|Up^R{XF4@$ zK||^Fm4l(e0hm*GitK6(9k~~YvhfjL;DmJb2#k80*<3jj-{9sqhVL><0_v=UW?(t| zy3$Kg(R6~!`Q299fK=VO;=Wuq1S}Q1|BiMd;2U4=z%RPc#Cv^ayDz5ef2#YZ#WjmN zmq-fE7;TD|tLX78zYAEo=C&Up3~{C8e78*#4=x-*7R(o0UEG;K1??Y5$k~td?QAY= zW@*c(2*+uE`aMJ#0Sbj77MD!-_S9%$J~#>QsRX83Q`{YdTD)5JoPLVU{zuBu$!`pE zgWEfa^3cfr{O->DSfH?iK3&x}#pNwo@O37<=wG-*j2MKgqCi{g#j9dRp&p0D+dBYa zIPBKSoq3&kpIFG`^s7w4Kpo---=#1RNPxE&%+I&2TU6WaAHL;4%*(*9%*_a{oiiyCcL z6TkW1NgrQvCav4HuZaw@_DunpeR6RE7evCZgj|T1A`_3Bdghq>7LQ`f!PSAbkNk3m zp1qkB+hy;#M_bdbUVV#*P{lB~--|Z2m0YF40iWfhc^&8O}F%;qtPDDEc@U6XnKyh3te0jT&F;e*TmVZ zGCNffkQTEoPseP#o>#f;dQ3UuP0PmJcbi^LucUQM|AH;&xbX!$m8h?I*m64A#JNsYBJ@Tx5#qVwN_+R z`;i#_tqL?zH#^5VZ*!Ml0weaqqSoZC(F5M;@n5<=qtglM^3?3#2+h;l@`t{UV{elj znV}53XJ!Iap?`Gu`sYz+CAC|iPpW-$DL<`XBFrt5Q_?FWd6lEvWix#77*zb>^7%li zS%BT~p#wyuQj^vAKzUE?sTPl%kq0DFLY$pbrkW?yQA08t0F?vS|s)27NTKrl+BQI(ou<2zW zQI_HP{gP71*of;mH&K;Dj7epzZ_UsC^2x;?J)4~`f(x?6c8{IwJS${lS#ZlAdMLp9 z%;X8(TCb~cy&jcIk&%seZ%Ka<`3D@43gj=0&)TrS&;@#1_EAa{(dPfjsk?}V?eXM4 zqC_>i%M6 zn?eoaOKM4O*4HL_uH5u}{B-)&uMse6PlXBZ?A&wG+2Ya&w4|J!+M*bhiKL3ksufv6)+i@Cb(O75Hj@(D>tG$c0D5c*NC0(_UU7V3N$nb`l4gCROusqr~97p`rve^ zOp-V&A%-`fORzpe&aJNLmLN~g7nztO=2u^f^Hx5a+*8f8R9%SQ!TtIR1*;9dt#ZUb ztqjm;*jk_;>pg^2(p{LD6!%-=8FSC98v!s=dRm+=XMmIj$~h3X(88lMz}7xYJAh~4 z#GAr)ts6o~yBbE^|IM0LQf+(&+7>xo$gry^^60;vXV+4BdEXp7E{%HlT;=X_JPZ6Y zk<(+WI~>A~XNg*)+O>)&;be^7>Q~Pmf~y^-^r+h!lpmNgofZJ0--EZj__>p<=d3Td z`tEoSj&+FzV}}(}I)LYiVPl`p3$~tRndZGfBw!RSP*NzAij&^`-g*J<+Aks-^y>k$uwc&X!&tGH@&|8!Fwo0Mq4xCQhrBYt7w|RMYQtT7 zpFV^Q0sxvkrx<^>510Ky+2;%r56K9``i!G3+uC~hX{B~J3{EDpBZg5eL{HRNs(|{~ zsq|2hLL%`B4>^cUS6~m(NC4o|FP?}yudw^$Yi+ln8H@xWYqb)Er{dPX<7w@nRDZJeS0O=GDT3b|&;B>YgF*p&~ZTNgAAxA*@=N81&aoX^$+$x+VSDEMevnFnL@*_5+=8t{~yd0Iwjx@ENb!Ww%i+95jKsH zCwHEUm!I8z#Ba3iE-%(D-XBwSwGH}HZxQ8!k-}~|-qD5;387<>y9%h>XGyl=9wWc9 zfww#i0LeRU}l#HQ1(u|v_+GPa%XUSK%vs1JlG+=e><6|ok-F>aQt8WmR#Kg!G$|eS(6qCLmV1+V4xUnT zb2(*W>72o8bM7^BvSuWsI8$Y+2F%kJz@KrL~+x~s#@wQ~iPQU!Gke50|NV6-cRBz1jx){sH1Cl_N zh@*E1SUAmUA2P*f8!cNSrHG~``HhY&lzJ>zEysB>Gk!Vv?ndE8TERG=D{mI z!@AYWak`B9{6qV<=-S%%2p# z7J2mbn^pl0L!!?ihv+e=J!IU}D)tc__f$6U9pHgh(DIJEe+q0_0m(2ao`JObK0kNp zgjjiz&I&Ii;h*t%IBlh@rT`HB_K215lg$s^qiGdp6?&W!jg$8nJIu;7od`!6T6LZ2 zw9IchPf#S7t2oZ$8($ z7C+@Ka$%g(VaX2seNwRwRHZg)iR2N~uP z6`(Zbl!Sd4=3vKe8;@rMKudC(^~J4M#64YJ*8QrBU8&KQiQn(9?@4@@FU4>Xi4ohO zZ2v1|TpYV=qlZ_lDbYyp8$oKL;jQ`EKk$M?S18aJB#j&PFNXxmYvLYuR{QkH&{NDG zOJSJZ(T+CZ2(hbC6TSH(J38)fAQ;nKJjVvBH`8bB@k~I{9m6eeNs2PayABmiwSAz! zFxV0-%v7E(!(?`=H?B*8-f{R79`+Yf$DcEbXLf<{{Zb;BdFvIPLgKx#%K3SAf7>q0osA>L*MwKT8zg& zU;e|R+soP`{=nuS;sA0NLZ~6>=WCFpK8kmCTv~;xUQ{eP)w2CA_nGE)j9CFSl|QiRKGap9@glYySYH#xN# zWkhQ)ks;L;s@@T-WNfO$;qV~_jvb2Clh;XJ>O`57;OsXA1iu!89zcfBiB zk=z!6J%M-XDzbSx9`zb1;YkKgzLpQ3wgtP&6E^yn0}7fN>zLz_No zsP|U(BzFQYsmva|y+TX8#2J^W;;q>6xOU z-1}2t{y_}*=m`_4c$F7nNNc3hh$S_0KHsgh>r8okfMtuXjIK_mK2b=@(No;S(qoSVZ;Aas$cPsA@=#FD`M%GXWr|iYM^|I8 z|IkNf{*U#sBj_vj(M8tT@GzopjpaGf1>l`zpCkE_o6k%a8PqBaXhG)@RcBf1+Q{j` zDpHMtIj%48=%v5^x;kAw~~*q!vApYbAOlb^-KBFiXp!&_0ra7NOR*S z%;)~|4EL=HC$dMq1A+{I~yYr`>Ve0oV0%y{%qOUsb^zoeqaZ`N3xx+Qg4JJGZ1$LkT5%7 z#}F$W5t+WY&HGc(D>hD?}Iy`Ff34FOuR;Onq!HLzpp!H~I*ECXov);^T%BlD$pNo}b&%nGcddD-g(e*Ry_daIF>YoP1(Kl4N2O z4sR%c!+GnQ)`_P^g=!!EoUYwY#ljQlUEZ{EOVguNz^6Z1@bFBil$V7_{q)`S1=Ry5 z)Zuw*rANmL;tHspUp9$=^g{CAzZcDnM|-Hu>6Iy0&z>*+>D`yE@b@RWJja6iIS)A} zoo_uMFC^+5ayR;znct3_IO9^~=ep9-YU#LNec-jSh(hSh)8lpWI_Nu_#xv)y%S%6tQr#yeJ*_d<{tCu&V*Ppxk*nW;3tl9N(J8 z44#;;Y>Qr`IP#OdO)<~v0kG550V8RFOXMXrf3X_qjaTSPcf4WsM9r>JD0&x&OKf^_ z)D<@DpI)EW$!~?mNUSd}zWB^83!_f3I!d+Lh=Gn3W^zyk<=AR4(JpV<+td*w^=4Ye zuEhCLzC~HozB!*?Wa$i^liH79evBkI%`Oc#H1j8X0;Vp+t4cZOqzy^K^@x6gg9=q< zUeVnGx&M6Xj@&3$OgP$;Q($Hlog%P)+ux`E6*P9|cO2Ep!vD`h$P_Jl`X%7p?Nhfa zhYI&RKXC5t)mrQQw|{!yyWKzS(3uC{oq0d@ZTe%i46M&6_> z{~9xdkENYeUd{V1Jlc`y)$$$aCWRck{vFt9!VjaVze1h7I&tzp0NS6xyY=LOQ*>wl zf~wN*=!F2~{r7w;KlX&dzX!$xyvVZO0TM|hB@Jy0{p;7Em)!q{^5U&Rel%6elJNK8 zKLdfJV2>G60H~AnKXtIOX6}dnQ1H_k?jFYF-UA2m+pX`vP2*)1erJ}jFdUBk>lZ5d z*Ny&boWOlg-vNJ(Uhuz!-)^ERRCzi3--N{p4VUj}$zNj1cOV7N-T7a= zfVSTy+h4slB$VIyMlCjMyT9>C8RdWDOXtmzm%2B?@O}uWRzxTf(@HYhh zhQR-yA;9yEvq^pX*e_&kZLb#lYTAeiH&A}UASqbJ(l7xi(<;2jowWV$3x9*;Z)EuU zGx(b_{7n=89u59_fRt`|cCA1-$)!i@I+K~@r}<$@f(}ZN|0~!X1>kaw{F?S zzj^DH&6|JV+qC(IEkc6A3R-p)>Q;FZbTZ(8_EC`^-2-!2ruILbIvsSmvRlys>h^Ok zbDLRGk0?#&O5T0ow?V!gn>O+B8}ohRTm2D)JUPGd<*3rE?uIFP*^KKrJGgu;y;2Lw4JrD@XYP9H%Yikep&MKj zp>hebk_e2>=hUUqod>8%i*KmDA^YeqFQU`k+pR$0d|Kws zPJBX?1CQVs?ii5_CCyTQlHCY-4u22Zn%Xdqd)dkk2;u~j{nfqV3bG8WC#d~CX>l?vC8kM$(>1|iE!)QIM9XWEI&;k1u{bP+~h%Bbc9!m ztG8Z#yqfk=CRn?#jkRj>&ez8|t3M{wN$RP-2olhTB_UejR8WQo2|#G`s!<{`74?8| z;)G;uRB-lSWnt0O4D^iU~v-s6DD zuX737UX>ykILk-2)0b0ZTMo#5f5x{ zeNBrHz6*F{^m2<{FJ+T2R+y6uPO{?&FIY|rgAwX#Arltly%L2^xcCaRV)f0lntsW& z>Z}oUsMFDx%0(^ai<>Rt9qWi6}67~@LsMMCr|1-<(F%olS}7lBMHG1r7R!^`}xT8RYiNJ-N_dZA7Q8c&d%_Wicpl#x(MQCSFtmggvjn9&t<<*2bR_UQ6 zY|m-y6v(%!OFRX|hOjV5$#)o8C@ivuN@KZ)vh%A?tls;W7MW>%$WE@7Vu;ey%Qr-T zEN58{lKidvMM!!hu$q8<`0k}xNGERTx_SF<1!Z$?r+P5bHUDKvTO`^cW$ zWl-oqw?z6Xr3dMrjoCB#*0S8E3gL01OD_>Ts(q-L`ouGHMqjsD@CxOOFydA+3>R`{ zNnO)7X)cJewX9pLdKY{FLFp7k0Zsg2gFr|RPWTxDPnqb32H^|Y-t{^mT_6UoWr#*p zCjitSOhL{HFgRAe2Cz%rF{Cx`p#_a0^UBv7$a-X6QTMv2Syo%^2u=b3W*4t(0lvWr>p1+H8teyqXE$Lit%n$0a_AT%o}(J)~^NLQ9g z1W#P#C{bkz+6Q5K4UGv8_!|g9oPy!mgy-M*?w(syq-U$amcwlg$FMNTS5+6F(TUqa z&Zy_oV>_v2$qBdKhDswxu%JR7*WV6SHp3XrYq7WjD8y;1>KSLRZ4Mre&XcUuXN{?Lt1=yW@1mfoEkXjkzurAamPjXietSFM> zcN*$%uUK6!JsdgfM%nxW44Akh=UuFF<(@E$!?+CEg$7xb8OFH5-r(;0FP>$YQa0~@ z+3hJHJtXqPjUp@s^T@mWx`-QcM$4ZHlfTf0g$a#n-uN1^+nAB4_rh;c0en~p!`eig zANxu34Sw@l^nd5@gV5Xcss?^$hx*=kGt&D>OE%-czC@d}-4=!1ZHm44Uki-!E@YB< z85Ca0phLz&Z`W($}_Mj2UZMqR+-s;#~RTv^;LV!_*L~lVy);5nyo+&tBLhQ!kGYjjX$V zW*4)B^SdIi5*o@}`gtIGt@Tdfd4ku&GP0_g9X32BtrE^wZ(6X2Nx@Kw39)RHVf-_Hh)wEDlXYlyI*n*yLpGex28Xb+O~t>L+zc?()9O_HnLM zkGZe4c6n6cywGc)Gs{ln5xf907Jg(4_6WSsE)>!)KiDtvX4gEaI4zRoDau1{<{@by zC8!HF(g06)mhWn z%o)$Yr*}*5=z^bzH+7b^XP$8!J2ggk8%`t^`W5;VgB*CLR5xDr6O1#}20B092pqbP zrj7p~V4QeaCIeM3GY9pGV(fJ5jKjl&7?N5T3dpf~=?wy^Y>>-9(vZOJ`w8}<3~6m$ ziX1`xX8nG@Xg@)gf;G1HF_R%#6NQH}uun(xnxT6^8F*QOo(0$=$Fr=;{2}ylEw4r8 zZiQ8ssDNRF0pKa1X2kq-bokcHVar-!ad<|MrISn~q_g1tPC5ikW;%P!MN#j`km?Iu|1YIWGD`XfZ`xH8v9ed zm>E?;_T;m|~XLIsSn<7U0!`kC#A$H}URKm-7s zVnzkvKbD%B|gpKT&3hb<7Z5s?$dy@P`Gk)Q4P_=8+o7BH@=dt{;rib-}r)$uc0On zADNsw_3Nc&GD#R{NddtBKKxIEK)>B)E>!rV&WWBnE?Rp--o4TzI$$fgB zuL~kl6FUKIf(q4(K-LHUSc9+G_dDL|_{VBXR72U+ODmsy*Op;YA3kt0U7z&IMpreK zeCk~;`NrqJK7KX47$07;8QVA84W#P5p%T94ytNLMYX?%Xxb$v`oWisg5c1;j^&wS> zK4GF~CyLK0Gt;Arz=PeqqFYQj%-S;Ld173oTUanS@G@**`wbKBqb<5~B&T5Xu)}M5 ztW%u(;A0jA8I2;q8mL7&p8VQU?dF6e?f^hCr4~fgNez;uJR*FMe?^sLsZvSCUc{`% z&3m+zvJ$qZ(J_EpAbF(CbN>PFEi8&dHGi11ag635LvOfQ6nvzxnU+52lB|g!!PBXq zWbF{KM-Fv+lZb;Toes3ei(ZHoNWK!e7f3ecHmC^qlf2F4>4eo#{*+c76Kx?IiTsXU z+-w5kqy34j(;e=bniiBS&)I~7u(COAcKNEPQ?ggX9cg{zu;sVk_%6Z@WjO{$9DCI~ zf)E~H+z&Vg^_s=Gpr*ogz9EdVm>-tQZtE%3B;?B<2J z08@YEO&2I;GX?@vMLF*!I8L0qX>-X^aq`c@&p6f!AlQDz*^>HINXbW%abSk^~z z?O7`c2)dLRrJOUwAV+Oe*>;mYAhcK~@T|EOx=C5!Za z)0aPREd!qdYcsHMa%n@Q3SX7eqJ12$oNUf&vB2MA`YTtlRFU~8d<}8J3}hs;NAX!p z2JWs+IYP!n z?wfl&-Ck*)0B zT}hXk-rcRK9}Lb*^equ)@A25N4@)vG*)JT&`WTnpmklQC6VKT46B0S$vZQ<)nH`>0 zIf;@K1Ld@I59R<{x4?ax(60P@Y8jLsK} z)GE%qH9y%iA$zr!YeEKq3tmIFLj3f~aTk7^^U8WT0nAuC<$KhhbyxaGJ9@cZ_dNpt3Tv5P;=%E}57gfWPUn4^__i8Y zUvu@3bSKPDYl_^&9m1jYRh@pmb*yt2yHu4%tY;$RNBsLO1Y{&9Wsg_}g)k;UBqt(N zkY(+;$7T9#p)l_33U6Jh?aJGk8^%MtHb{JS+3fzAw8#qd3vw%as& zJOalc`LJ2@PJ)aM(sR~T{Pg32`|Cv)T{#9&d{u%Jkk!4l?uvAu_49POXp&;^auJXF zJ&dB1fv2)%V+%^sGRs~ayK!{bfjAC~{mgJIS%y1#1lz4}YV~5JqnYA1Kjzd;3$0w7E^3vh;o^kwq%6B(`AY(H4;8dY(HQ< zqyj$z)-nX|0$V2ZXsXDnl&^~82WZ|+_iaZklCJjkLurF;aVRbP2zg`#u`2F0LvlKX z53>h9agmdE0R|^!p0%u3@H-9Yp|QuQ(&X;#C7T*9G?TvCj;%b)T9tKFp3yRT=X4!k zP}U_EwmfZoFI(!=>Yeqk-rn5+N^Gl@d9(%I3wYr^xK`9u-)fuud?~kPn%m`EzAEKO zvrz&ell*r1Qe?)6I^E(!P@AtQesGsg!O)V-J&KCAULmS{aW2+jt{nHwT$6INh7BX{ zelj!&C-u~A&~c62$&HH-$=WrQ&6{d`(S|#wXU9qyaeE2rRpQoXU8krWiXDFF^|Ch z2X2U{+UP}9=a%D75y$Q|%JeEE)rfim$W?Y_?Wr#iC zh8Dq!nHTn*%lBVwtYGo*uIcIOolME*RV%|>D%B8Bz(8)Pg0#o>EEnyWWW1dXYwtbq zrd(YV#MK6)OglwEN0XSYpv##3Vkv?hrfLea9_cF9P5BTCni6fkUx?#X0^Lni`s~Uh zcbD3M?9>@Q5JPyE?#i*{6(0B(KCh2bd(-?a_Dn{xoU^jk*1qwnKGz&HUY`*@PFN~$ z_W1WU`~qt=ef11)>X*GU_fDIsV5Gv1fA#NV^NZDs*)MIcq%KC>f4NSKdwdRW-Ex-S zNB=WFu8!_=Z+1A=YWs~AM~nOU*RMy1EEH<9|34!p~ zCR36tNfX_xocBOXRt?^x#=WUf*qnvfCUf11H|B|dZI}4m0-uqTX{OWt zB!Z-Mc%tc$<837>sB3!}G5f&$#kp^NP<~XkWSP!Kh9dGp53ls)-&sKH7Jq zwe#FJO12KKGaTHnLVBZR$1>Zh^lwCF#t+u#sGm~W&FU6aDgzElk+A^A4aO%n(tu)S z>h0!N1IeR^vFgXg37iy0aiLL(tb048H(3qgVAn8f7YwP7Li4jqJ)1SY z@zLfEPl~j|sFXnOZde>e=V@?4O2!AC@SE#|e!LiWiKu64O7LQVoT}n3b-xz+fX7TF zy7Q#nt()2DAeO$41#Ey{h-$mAk{H~6ftwX{8u;0vwZ;xIfsM(eVf6R;NLZZA<&Hjo z6&P`HG$#(~S!X^Mo=8k&<#7{Lzeo=^*YY$z)~|HpE4fZsaV{qeTSQKfQyMv~SS{!c zY$%tj$X@KN2?z!BAwg@-t2wf`(;qKYz8y9GnjM7g*JW1Utv)6P5$r`1)Py;OORM%j zvqF-*)l8+hHm%SH((Y+hjY57ADi#b`JHZgi#85@v+mERZr<~U|?^95i1RR12_PF`s zFKA4zk39HzMq7Gd8#Una506NiOP)LcPI~_EC=t+24ov((e27aA`Ef4Gtg9eVe|RlJ6umjNJw56$ldr6;6 zgF;d|02-RmFwz9DRy?^Atk_Oet}4JgCcD-So7e8Opv~pAg>->Qr?tv+xg*YbP$5t* zvL>xZHjDRhzBuUUi}AWR24AwfW6O{|HmkWMBtc3)qqTnTspf>><<%ydd-e~$pRMxgw`!)ukm`Ycc53O^;VqvBb?;=M>+uEm(PMbc%{BeEvO){| z)cv%4<4(SL57n)gjKiDiGR+Nvz>lbQYUb5wbr0L~xK zW6DV%*yCKK-WEv@__?4BJr-_r=>@30Fg<+hVbd(kCpF(VTZbDMpS-qXkm|PgM-`Q2 zmUh~$MK<;YDk;mf7i93h6IT&Y^86=*#tHz$`UMCS&}OU7Pr2B9*XfM%1}Y2Vq#ifq zov^kIbY^w&9>VqQ7k^0&P=pXsNm&@l^no3(Lb7O|PvomNYFzOxE1#OMP`~zpC(vsq z%-OCaKMHt#Whw2m_os6IUJ0;16^S26P9NI2bXaq$xL-)TNB)b{a8!mG0;ios)Sacx zDrmqxC|Q-|NojYtG()1Qzf!b?$4s3g=M*4wufRc2MG&#--l&s;p2@6kz4Xe)fS$`O z2|^IOVm-8C)i4yyY1LSIEZwae9i(Q7$*rop8+EH(nT^RUC|?Bdv&%I`cmz}%>~+N# zF5D~AR*>TfsO6T=sfBlr*{eE7(IXu*Ow@&J#3~Rzlr5>kh7_dN6`Z|1oj75l zE{O2a+NI-AFILz-+U8nI=@e~ltQWPQg2@rNYG@o9fjX@2RqhkmhVVwKq2MB5XNo9g zD}Y}ewnuZC0=E;(Rf+8u1*pV|r{oA>d4VKvQXp+gh5SjDu{`1KF%mjB#xOi5cf>lifRGElbP#i*bZ4edXHwaHq?Y?uT z24e90)BYz9UoD*+;QyL;_*eYIKjdAy*Y&aJ^XyuisrY}ve*95<)@;hL^I~UO$L#@f z>SrX~)HQr3IK2C6L^xjU)MD$`eeF-@Jmo$(@y2{e@*mvHUsPQ6e{FeG(S`^ez#>~w z(5eW_5-~u&L+pQ+jOSYZTN|(E-?#CA__gXAUtPq&Is^A_ZBaQ23bMLQ(-%5&>wNCk zi&VUvj9K@hzIkO-;Zfsy8ofNRq+G>oxT&dNQc_Z6qyqnUZ96vl`pZqc`~GVCwbj4C zTZzCE_t_Y%nxm|HEE^=?={|RW4bO>{0yreka0i!c#JVzz)1_o}MI&sR~^;g36n+_(|dw!n2sBBn6}7;~%A zC(-@+$0Z&cC8oTx#(|sqm{8%&~T#$}`MT`7gQ6*#aV#w?dUEkTu6yL}cr& zTeq?zRMH``URj99g$5Bg>zC1uj6B5Zk-qP#$1L#pLsrg;`(-*Kyuh@4>7=MNR^Gb z3cK7bl>OQ69P4CrMq4L>*#jT6p*Q%Fe64KMQhG@4i z+zFPp7l>f<-Tc8v)_3o`)_B4Z_W?A^ZcT4%1b@=xNZ{w4bGb-Z9^EgEoSW4v zSYULrP#rv3mlcS(0Ro0{=*6k{y0rMbPH~mA6o!#orvs*r#H=pzI1N6e; z`3>3)%GJ;E+#Dhy(m!}1=e^gQ%$Co=kRb}FKSCvp@~K=X1RDBmz5{3-p+A#r{QPY- zxTJ0h6|72AT3Jcel~WuNw|L_@@p4mP)swd$JiFNQjSr-?+H-mS zTm*y}L5i%_I9OicGwg;N9Z#)_lXU^_iyo^jWV#Q=(3@VzeQ|GN=+oT?y9xfj!)r%s z7zK=<=3p4@u*f0zi|bmx@Z_HteBzoAsFP%ON#(mWSYmRgIMN(G6e8Ym(yc!eIq{0r zNaDqfLCIp9o^NU-&U{dxObfvLNb7?_a2cU_5kjwpTarBzT_GLPnE0}8&`R7X(JIYt zA&ff?b3(SKsGME+%5mwyIEg)Djv-L)X#is*tI1Rt>(Z~z#9okfZwq163%U(<^}w^R z54q7ZV?0BvoH!pdcbvUD>ZckXp-;jVa)XUvApMSJLPW?JXOfqD7(;(X`zhUNmmJ&Z zcGOKf?O-=5-GUswz|L4|t%g@mO<*A1+SWC$<{0&|5DvV)MFa7kn{gVRE*-i)oskGU zFA?${cE*CoEFYUyDeKZ|GGB-+`p(;f+i+^2k>p3(|K9>4(t1`c-atB~e$jXm3fkGjC}Ym{xaKE7{CXzmj?FLZg~$ zrW`-$PQL*vRyTM~DH-Bw^;NE8A4`^}*_II~(F(sNsJB0{dKqINUGY3-OBZ8*k+MbeyHspqxKLy1AKR$75}89ni!u_I)n=vK~@&M|s# zsQJmK)ugd!jqo{Wdk6_fg$8mHYja(Ol+u;nkC|f>bWVGwy@D~#{S7G#&uVg^dRoL! zB=sI3Dy;kdoMKx@7P08ooXqZM3J`k#()P4ZSZyV`WoMK2;b*hR-A;%*3#ILzH^8nEwnr?fU~sM4R?1NDy057tp4qDkqc`9%SA<>Kdz`BAdf5- zvfyh8E=WI;b>4%IwjV+PqiSe7+tAqMn`y7Ss~?cezMK=_XctajQVR(6*H*C!x$Y{V zsWzbD3dS!4K5m|kMiQu<6sJV3rVXo4YU>aZB!XG! z(6?u|?I>Xsd%@=~{hXDM7f?xN9MM`)qFx*mBWllzrvpWn8C1_vCYaN>f21>Vs z78|XDtuM>m3mBtkKW%(>=N3BdMSABxt2_-=wW&(Q5x8%8jpJgRf60-%&@f3j{gULw z(Q%3K!7oCD^0$l9HX_Sjr?Z}N{TZL=A8^UG!LFbL+zuE^|0~bI@F2H@lxxE-uQ8dL z000pi;tvkmL+C);6{OHJ?m=#jcSjc%-0lj3e7kT}7J!8WTM%>mO29dg@y5j)Bef=86B)E5=gJ$B@XjkSSd9eLb0 zff;#}I9BDDA&#=K%n=gc#5NG^UVfnXUmRO+hJo>j)Ws_rm!8Th|TNsDk6%)AHb0G|WM|qx*NTff7T2Lp1z!t#tu$P7H1&gr>o>j&;w?Ul0j{iH zj6-t7*59!xAo6Iekf{pdKTDcE`@eJMIsZ~x$zy;OSDPEZ7#SA}Miu;5Mb>Ms%JCXC zGA{pPe(_H!tSY(pMSe2;x%R6CcFt7DXpK>a5`TFoESBY3er4@V4Kz`d{a-Xuoc3Q_ z*qD}lSXbdr>;<~Ya81>1UtnpZFc`|AV75LV8|R3t8l=UfKb}Pp(}TL*G%(`1m^UE+ z%s0NrA6MccW<$eI_pD7%9u_w`eBo;)DDB>r*72nf(fX&$ZGI;^3Y_Z-9g|mmQSJst zk2H-3vey}j2TS5zzID`WZS)JHJWHm`1Zf6)Z9X zCor<1Qi!ApofeAD+T?SBNTSj1%#e6tO9GiHX)w312N+G#z&$k*5OL;cgaSzw7YB5# zoLeEeM$+0&{2dSueqO7CQRZ2G*)u`+ykA8g~O+vS^HYurRC5 zJM737N#9uucKmyB4gi|zBwqRi>V$k`cUULUVAgx<`_>cH?EZ{Pz=>R=5;+k_woE)# znj7@Nh$NX{!(Srpqy%9w+@1Jqx*-goKnwN}XIo;187&_)=7SL7jgetC_&Aw!iT=fd z7-}-9;k+L*6*Q>$ZdzvhjL-{4bC$~04yZ~pIgR=ZMz0Kd7FUy~n|HZ6TSSH`n$^7| znQy2AE28-H^~+s$M`>ef8sDH+J9+4MSl4#a_=Chk=!K?<9j+z;`@X8LHe+~i?R{e4 zs=9G$YRqtlaCUsqfYOTkx>Z(M2y&`cQ3BvkfX)kWPxM0m4}0$c)>O7G40A>u<)9)(iXaRj1W+O-^pSFgY7B^ArO5yxfOJq00%TMa z0thC-KnTLnML{JY6lo#^2!s+*dha5=By|3bo^wx`x!=9#-t&Lo|NYNhY}VdcdzE*s zy~?}Z^%lLK;!BVVSpRl;acHx4k_ff$)h^G>MR+*LEhh;}{Ynpth!2v3*Lr%Gp&u=E zf}X`{AHg;Be*bWPE3WDf+8@OaXXJ6yOw>z`ZSezW%yyTKiHwQWnf-u(gTfL*XwFB- z!cs1oD)i9}ALK67^MqpkeozQkd`ol+ANwj7kwaA%>|qOdS&RO) zqT#zdi&(9Nq7z|F6Y+IELv=F|(}T5%bh#j6uYl>HL8p|GY`9=?=e}FYKb++c8Vq?|)?>37}}I z8-e2o7@qBQPRdH^CVo=t01;uvmI;EvS#P_!p(MK`P-I>cD{}=2!F_Q>z?a=ekV?48 z^qI$7NTje;w5e5=%w0hX=bpOSXlYR0jb&#tXlYpyZv8xk*7ku#Q*FpxOAzW1G-8a8 zlSzao2ehL(ye}fJmO6yIn&2*Qei6FMlV;x8wO*l(DrIa<)^)j!+Bd)aL|gHQt&9B9 zKI{?b=Bc`D#&4~c4}4d%3xZaRoFw-?Y+>e-%60{|cd%E}>gDm*BJGF<#t1j;tr5p+ zHMaw-ew&6#_z=2L za#>_vUY-?TZNymW41A)n;z<#7yL)!M^|MX>2Y~i5XR~G$GN8!F&z&`GR9-a=Ptz<< zwq|}N(alHlNvIE;Uw0I^yF5LXLE<|DRkMAy@1vYHEV1{`DT_wk40w9UWrtF9ItC^{ z_E_l3d7Ec=M=JTkgM{h>MgE)kE-{KjU9apvVt|a?8izU6vl2@=laF94>^T#juTP_3D{dw_5 zUuylK>FX^fJBdkg(!e<$^hxo7+m*+I8~Nu*$(AvLHCIF`2zo0!5C%{%qD$;WT3v44 zs7Q|7Vn=(-h<2K-3gLH7=96q%eQ4-=Y|MN#3mnf?R!aiKz-pj)HBo< z15uC85gA@teV&u?xuDo2#AmVN{4P(sx^vx)=h;8|-cXw)Tz;K&=Hb(37xC)sBzAb+ zpogIU#veb%2Necj0aLqXCO2<0jKp$IS6w!>Bc9bsvo2yBIH!0)ydaa%T%^Bs2fuCT zA8}c4rMB;GxvfQaNx8CkW`2ZbVx--bO7ZH?&l2Y2q@16^cYE%V3xT3#@O_p@A@^(H7^umvY$OZw!GyeU$?cFCOq zKk7ws4~OZ!io)aaiwQ_8SH_j3Ak{IPqQTUup29+cS#h-ty}Pja#i?zl<%W3o`#X`f z^+f%cVL5KLonpJA_dzY)JJeHm%LcNJg@mvQ`lAXao!fhQL-i~$_nTC1FwzceuVd<#|)ac3O$9}$sqnbJ~o*d71q<}eoeFUM&ge3K~ zYhK>viR>XJ!$Z``r4=+vuc9tAbsiwoG!%4(*8qBL#}KWY%_c-5uI0Fafv4SGW+AnPL6Isi*Y_N$utgDcb9I>=Dy5jXd@ z9i&HPkB_*yx|ej2BKln2O%v{K(Sv zCvNHG3KgCm$h+896I^i4;K;P$?BTCLJL%^P_@`wH6}}kj#uhqF0k@P4X>*IXmt^3I zeO`af=_RZU#)h%SSbm?;TDMgs--4a=X7Dj~La>EnV?B_V$O5In@jH=kCX&sBU>}l(^}t4P17S>I$>v zaU-S=k!y@p?fBT~znvwIPo4d;({r?D&AwmLs}@Ul`7uM?;Z_!6_G-0(uJz4p zjxHwvYh=kbAcD~az>sd}k>lnbcS!514lkaXIX@qw2c4t@$nr*7uPSUEH*Xx{%8DQV z5t8?s-*~Ju$;qo+^6K&Jd5^fYVyhEr+~zThgIR)l5T2paL&35q)h z^=gt9H+L)MeVA|Kp}mCtqqFZrUn^sn6*%%#2WT*@mf=OjWGj6nng(@0OnyG4d3if> z5*l?n+8Z1Yd#X2+7=J2(-4P>4eRlbBG(bpJRWot@DU?kQLOWP)Xgn3W_Hi^d#qioI zD`(RCKfW!veNOIBUV4tus-Jqx4eQpnEALO=|D?-TpmtqvJU&w4`l07_iYS7i;9D{J zwJI@$M3Nkp+%Nt1EV_H-Rs7D>WV{6=H!0v|=k$=pA79*WJR8LX(fK|nUwys$v=Z{M zZI@@~j7$ku?%CIq(&%F&j*!ki8x7$QUv9uH>LmR0DcX?sctREjy-;s%M(Z?`KK~-vJf7tOu!jx|Pb}$zEI&y&b#=t; zSH~e`!=mr_DRs0j5=m)`85qONbaZd~kUAd1ez(SKy0TWdWjOvq=dF}Eh?9|r^s--3 z=3hZCCoO3#H(*s$rd}!8h}LeQ)~Zs*ukLtjEFafIF1Sa1=$rEP(Ayv>$~Wtt!2V@< z&sp&iU&e2gVx6|Lg7vygc6n4*{iH7T9kD`&6HebAneG}@ZU@ML+LuqobZ#->f-l@} zr)e2wh--(5hg`Y2oMgYmO1abQg&En(+vUMti{o;*+P;sMVjs^-d;4SR`%_i6x2>@Q zgS$NV3a4L7qt8vBYgZ*Y2A7r=KsJ&$0H# zbP&!CavN&KM%vA-t+ipL%eeQcGhvmlx9~Mar-kB@nhjQdE@91*KU7_Rc%d-1XI3k8 zjVzXD)E;Afu~%}*d|vOm@(h*^NF4H=ys&y&?j_1u{JpK5Xwo?$(G@0mJi>x1c-EZn zK~1ZjvFAA@@=(zkC9|6g*KO3QS=+W3=$RzM7gdLk{vMuDl;9a_5AUdT=5soU7qLl%IWg6l=?H1-+^M$Gvo=BNJEN)z#aocw0kI{ zwlC8M)R14FIGm>x?ZY*YvLI&eT$s_!0xqGB~)T~0WZ-PNzQE?U=^ap;w_-XrQl znBt=8#oNU*-Pu7w>0E@5)5jt`N$qQKocI)DZ1L+&H!I^A?dh>)jS>X^aN4zihZ8pTZFTChCTuYq$u-ei#dt5B9H}F}0 zk5|u@yjS+yWy1~Qyp-}u6g>+P8pqMIzrJ&RC@jWiOnbJrU#n=%gZZ=Xr`CsZzp_+-Y`MTY7i)t8q<}{1o&AP? z93ywHu?)g4I47tpC}-TdG7MTJgm^ga^57z$<|ZsNfW#Ty^+))g@(J^Cg5tyYDsyvrdMof zLuOj8HfrqsscZsA7Vd6y{g;7^Cqy#=WSLt2P-OAp=8YV3GXL47F6}X+=?R@&37Tfw zoY7}^Fl(q4_Rgu9stjS?V#prDxriWphm5At-si*W&^Cn&+VxMCbwucIC`~FW_~R)t z%RltA)-J`lMYZ?2gz5>!j& za+zYDfxA4~6vc)+@?%F-Uo0Iwce$X| zrswRZt6nD<-%opA%`U83qtiv--#i>03&Q<4`(Pj$`9mJTq9}Juq!!pYt?Fa*?#7SU zt(3eBq*GxxZ@l`>rzrR3>$eh;?vb3j-W=2NrC2hMkX_Mvq< zhSO&W!+FkP`r3paK6=<2JlZj;v=+HkTg`S^h8AeJ8!fp^)w>KRWe=~AfTra{Ycf^a zfzzk(c*^vy)3(l{i-)y>3CEACs zysT}>oD_Pfx0d=E_?}=Ny$eVDMXou_J@dCc;cQXVs78EY4!yg#4@^w(CS5c7(^H>h z!i%J|g${D%B{wl!y|y3wWSqUMo2J+ss#jj@=wA)hJz0FfLv3hTVJ0^E!a3RW_JYqv zm74A+Lb9y~%umZei4TU@l5e`0=bndvcN9b}l*!2bI1{^u@N%6g*VVX+%6piq-+eXo zSww1mu3lylay??@!s}Z?=JMZ{UzUCLT8(#y%6EJ4>wuR{=KFyoee^Bl!zUwhfwOR3 z%KPVv2?_)+aTw+diWKB4D+*pqRt;j0nd~vfIi9#IY||P^jip>crVr?Qx>Mwy+oiA} zOsU&u8Y_+*Iaq$*c?J`fC5+IW{En4IM%`H>L6#i5^KQ_5MVcMPA<+Toi;6Onf|kfR zNME!xyYME5RCI&Jj6)YV_UYu&MU22!<&}oZZX)9+9UH!gpqC_xt@oTjQ+P#RQTw8$nYw|YS8ZEK|HBPSFRI_pYwQoufBO1h zh0x=>xY=TUy|sX6&v5UXVt(zD?gwA=C-#fIH%qh{Iy;~-K&99({VAI1nLNnQ@^wDd z=n-rAK&XDGoSbzByB*~#jPQP3*a8)H^gS|n^|F?5(;x0{YbdX^+X|k(l>L1AJ=p)% zlxC&E%%*Sr>$O03JjH(bPe7;X2WUOh4etgcuJ<1?x-AL*VAmufAuTpuC-O?@+?fqO z?4r}j;M9Jwl_Ih+4bs9YdNHtN3_4R{NThyI9}KBfq?Q1J8lwtLx7_e|`=qBO8hfH% z*K`%X?->_~f{9V2rasvaK?^1JoZLz0)RqPXeF2LYOD4GR+GMDwjk&18Uc1nmw)0vV z>Mb5UZfu$iJz6qdgS=yZt;Z{Z@qIvO!iQoEUjqu}I&9$&9%PU{f`26$yURJCf94UKB&jeOti zeGOpM_};-+lkD>%7v8$dBY2A+;F!x+*5F;w4v;$4QFQt&d&9LA-z_$MD&w={Wat?> zUAStONA}Pvlrb5v_r#JqYde18*D(j!&6pTn$m!^8!;k6OX`uxf0@Co5iJ!(Rh3tjp z>mVX`x8VJud|FxWedINfO$taAn(tk*o*cZ1BI$6&+PAuTa{4^NNQq!0X!jLyi#pt? zwj?wAq{T6T{ltr{^V9i`kFxPm%LRYL8oRuLW`=?Iuir3hy$VvcC_t~me^^x`A0E&r zn09IyxdP{E>X8_fe={l)VMK-YKwkW?%33{-alO2uq7%khJZcbhEO;U~GqgZGhW*MD z(4}#1KaE}Pecd2P0PX6hF`lhNoKR;UXozCPCT=#4uKCui@c!~hO ztM`?-;%u!Vbh^@*(Xlv?R2}M?8}?)26_}*q{tX{eD zc)10z*N*z6EIc$_Y0tk@6fp0y%d>g*ocI0@OLpRw7K(R# zgB!NWLijTO;7eh5``eW#a;=v_A{B0?e-aMM^(8K2zU8QM5@E7)GDY!8BQieWcy`F~ z0KHjd3di__-!?kkG92)9!Acyd}QG-6L%8@(f{73DtUHR4ujA zHH5FV%jS!MT^^TBzC8l}&LNqXUtj7q$-PBJwd;A`@yF&=BRN8QNRI`;@bf?Je_G(r zEl><<&it^{TBnR7y5A;!K6BbY?rFhI*4EU2w}ogXd;I3<*@{t)iT~sMPaFJysUH~I zmze3mgBvajGhn9wIuH4^%V&JI|Io1?{&equZvVe%f&=6~DA@7eM@cF@XtW5Hiyv7w z4R`WTw>f(FzgRs|+*fo0A-&5pmG2SeJdUy^c&c(#J0j>F@gd+6*hE&Pw)DZxKYU%w zc^!7r0V)SSd^D@rH0j!(2=Qo|nU~uZa3%^Y=37DrKRPdFZ79c*mD4C3X_EQmSA}5! zf{>(GhsaJ$Z8IxAShHgX-{rC9b6T#S9Q=kpq^=a}ogPujI@s)M4Ib4*Xwnp#J*e8! zt$X6TyFAr~ewA4>dhnszc5_I|V|tS_egvmzj8N^ENNxSbI#g|XHxzCkUf7DN8mi=P zTK+1UMYTcl{a@*L=M0~1|D@I_2aRMY2el%;jkYgUe?4kR0t8g?NZ|TR2!Qu}Gj9&vbp%_i#i; zi7^vh`>0*1H39}Ytr8GPKGyT3+~^Gw=JBDURMqUL7Rt+b1g zVoSzQWYatZS^9kpnhezUkiNcE^v~tzQ7oElpAACLsriu2{&1Sedo8M#EFi7_q})(0 zu>vmu@6Z*ljm(D`8>(meic~8xXh`cZyy^vIhf=*)3v=LhD^+ZDieLT|(K6ah_Xz*? z`Au~bz=Gc1+2tbf9%H9=Q9DPd5i!pmVGPOR%gluuednNgDDt}zACUr!r8qkB_c-Nl2V zn@7Wa_v+%yt{pPWr$PfkhOy@p8E;JXv3!oLC~*W%2TAm5=Lj6?@4G1VJ&;T$qIY{dLlb_A=@lOwwtWBkcKKqA=I~=X{@SEIUr5B?>g$;>F_aM$OiKrAZ+#3m5VG^ChHPVPq z5T+nH2%@(yl37qWL)nfT+9}iMLv=$CF+{dH42X_XH6x&a^ky-r0UV4AW>U>fyEU?i z!6;@y46%(_Kt$oxSxW{BnlTh?@vF;NV1*6qrP@enr+1UB zTV*^tP9w(D^1N6L7Onbl;oC;;!1!y+AmdB!J6?d8=A+xn&rd`G^9o9nj}iF~+?xND zpD_*US6rU_hjM5Cn6*Il)ISFORod*|eG(vl-}q?h-+9eva&)6vji|rNbMfXUZ?2AD zqYr`LQlmMUFh8{8xrbu(0zG?K>N3kmE6{~r;D|he(NqT{7$aNok7WCzm5Cnkjn+XlSFvt z-tUxovF>+rxlH{n#0L(@NkskeH_k7i)T;lY|0A*ot>^W6<+pF)wcqOGg9U9XK>qyb zh+`1HyMSo9$pcMEb77;%(E5xpdnzD2%8`!J484ATT~F9&-5e0ONIkf;b7*ua?9k|{ z?m_7nKHSsWr)kLmwpQRX^Ig@uJy`2sAGQ8wEZi0uqyqci?s5eiijaW@3)Fabg?vFP`J6oSl{ zwe<~X6384>jeZEQw| zvvdrpBPmc{rj2t+w-REd7%p@D8%V)&c(|1aiO7m=7U(j46YFli-?xqC*iZ;$>H6jy zOhF0en|7lXwErI4jw_gtF+*@CYnjb&@>}?Qy zV}PWQRWRk@Z6Fo#W=OAF3J|L3q=VjDMF(qAc&E@?xI-jEnrNqH#v>f6=^#a(AYX1u zF6^qO$PtV?BJi-lyJzNwA_DsG+PzXi1nCNlB~&i4{3tkJDy2GK+oGmwT)UsygeOfj_^;47;gx~N5r+{xy^&%47g z^1!0r*0lntjM&rMAdv*d8QL6`j~`7p4IS89fO*FXb;6%?I0nDf&N(UQ1k6*LAA+Uc zpLZ+p&`efk#+e)(9AFE|+6a`vJez(=d0sRY^mtt&Tn2_okx$T9SMe9@^VJyh(v{JE zNPjiI-*+A%WMJ3aG|le-R+WF*Pi(K2yzSF2pc3Zt9a8-QsLPwRlzdwq(BP!=Sq1lw za6$v+tLf$hw1Cpg%if5U4_wTht@gj5C98w`|Kt?>78KQ14qy!o2NaXtup zLQ@1@SL>^tKCoi=$XZhp6Aip&Es-k5A4dX+V&oI1+wfe+)#fiXbHRH0HrK`0(k3#A z=22LczaX01f%j@L2a07QnRC*=Y?%xpe`X3chXzJz2KF?k+o+sqm6;La^4}6y>e@P2 zE*gldsjQ#tmPt{-%j8Fns3_IHVX77`njAUzD8&_XWXeV89>~Dv7#BuH>pVha4WiBB z3`|GUQICoxP10uI&9VVNV`TUeyK|tDyo3{dzTzZrW8maGbmySJj7VQBxSV&!G;H6Z z^gZYUFjCcNIlhYXZ|57|05cSJeP?Xd#`%x+@MlNj=ix zFRkg%8wI!9UIsp-v@j>1U%_ezIPiVV+T)MjLIEO6Z?-IIrprZ{YZ(!ZfC%NsHNAud z6KNvwpSz&BeL13h2l1KY|LIfevNCy3m|~pJ04xRnH@cMIe-d&=?LYrV8#c=Nt;^*6 zUePHZt$*vxp;vwzXl-ro{yUl{@yz9Bk$LCewg;tRCZNPc^gZ&Hh?y%!$$DY4lU4amUhSqOGsL`>YTG2o`a91a zUjHqCz6=d%vWGMMl@b6Cc>afoaus*uYWmESr>&%%#8E*6Q)m2ynckOG2oMC^m&C!q z3rNC1lM{=o&CIlsaxR!a=n?k>n);TgeuKYTcIUqVV-Nq^=RZU76_l@@^jn}fgpMF2 zwQnbrnYE1+g>3?IQKGHqpLi2X6#NkE?*UeSt=T+v=XapC$qLVTAb-lh1 z89vN1%uWwEZ`Eb5S@HQ8G0NRdWWr9<#~}XK?wV;m5gXn{0W|%Ih}rAcYceJEQ7}v5 z&4Y~ZI)x;3o->%4wj(SLmPaxfGQNZwa9;LXdP+|K6cp-?>P{@{&ZI;XhVAlrbl*;^ z7B86~c!Y^Rt+-l2(pZJA3&zWkQ91iVZf=e!#|z0TRu}BxlEQDU*eGU<*h9=3otLAB z(08|uFjtTZq=e*Lui|BC038kigja;*o-7-7I005zlA5OotRT=wZ6*p(4Bxgy=|ifU zfj)YgKC*0UA_S50(PhcJ<8%^48}A57ND_7MCPpDc0uq6*t!MKr|dS#9zdq193wh=zc zYb1`y_Wq>bBezg6(}9KLYsr8Kn#sBu3oS>r8S!cIqTGCb=eF)G_SbH!>rn0u(a56x zGVsbN=nhABxiG z;t2kbOI=m%M9okW2HvdD!!232YA9|kDAu}R@DCnNB&sb!FN3IkiBsU2$}9&ok@EQr zya;VQt+^RdXjflcTHfcq*ftQh?HQT%`uMxnsopLh6aE)S*HpGqwByaqQM9}5nvHg* zJ)0S2HU4g7$CM*e48uO($)-MDwA^{=#I7vO^^@`i#x7Sc@vD%b@-4ZvnBgo>DYhqg zR0^Wv5KxE%vyA7D@Vgc@EI>wLE_**p$cQ@8-#4UFS}@UF%@wQDemUZt*b^;m(-2f$ zH5~EhdSl-Op**dURedzMfm0*8lfpjp3n(hdqrgk(BT=+~d~40@1>8_7-2!SgUPvme z%#!}4KoMl!OpEAT9_-nYYA(7kEZJN{!vTD$erJ|hj*wRED zn$kt4h;nYdr%LOFP8_oL@|~)0l^2l}`;{DPX~c#x4emvmRzg6^H{QyzVaV$`3^p{j zSg6nv7j21#8qOY2Sb)a57Tgjwaky=2`2faDjHGrYu8I|x)aD{_w=cF`kUXsK0i;!q z{pe(gkG|YcdDmG-&8ex0dTCHA^so8N;Hc zl4e>w72}?)i866JnXUF>P3lwfd9nIKKF|$gC4#+0tXpD)wbI75hXi|jt8DYBF{i$? z8jx=903&`ak@Krg&>|aM+saSeRQHADcfO0G@99OA+Ju;*9+@UCw?mUOh~4uY9Zt3m z?>I9f$g5*c0~xSp6~UQ}$4S{*nE}Kx`<0Xpt;G66qM?c>$tar@&%^|jg=7M=;Kv-- zN)uQ02ny1DBcVo9vuZlz5;1zSBZAtXs9dRcb`PUxsYp!Jtrt{!cvJot4{D_qN0yyJ zx(3xXnjioD18h%J*E{id-u!J`O2UF1X{;_S$KND!KnN{!`&Du{mzp=`I;r+)T_-`y0NWK5Z zpu@j0?NBZrbHOa}zYOkQYFlhAiTDoz;&=GR)_nAjA6Mo#bx-&xyMTCaf4i`}H(xRI zi_}lnD76$jyi-p&Qm370f6j5}zkV7Qx5J zepofYPLCnUwbTd*N-WX_v}^}^k5^vPDF1U-O!#{sD+EbsFXuNvAayTSy?`ZSkRmD9 zm2Oy}u7`)OW!t7i3nNFmc7i0wSAyA_qja}~Ev+xgZ|#-8j_9O~4Dm%wd~>Tg0}2f+ z-mLHId;CQoJ(&@_(WH+#Hz+u#yE6u%1ZyaFxx_Oy#E(4wj~%hw$tB79&D zq(~a%;S8)lu<7S!x}RE>q(ySl_9lXOYIs5~m|cqdlL4`8ORG)$pM z((v-ny8xDD;)Z5HldASaWia(p5hApErj27~69=vOR_PD{`RDNWK}2T3jQp$!stGZ{ zL`5UexN%VR1P*mWyCb5=p!dm=5yj*U$%ACjBKM&A(0v<=cg_?9x=`;s^J~f_OGafT zG}zeJRAdJwwotxv7WL@M0{_FCxDxXH!!+16TB_)K8CsfO}?b7JpL=HMi@`I6e4CcgoQda|* z>DgdqY;M4LxH$FFF8&rob!5kC+(kN9hu=XNYwbaUC=F%$nBV~Y+FMb)#7`o=rhtXE zYeA{4*P7g8N*`d!7`yIWOzlr0zr1AD1BaZOjG9C?RA4WIK$PrLF<;8?% z89e91fL=IF0d1z3Hi>`N|Gkd}S}99l7Lj~2(X*W)d5|7$MGFW95T69!@jMf)@$xXG z6a?{NkWdRWCf2V3BcaPLAP1XaFEEl1@5Je3UvTO&P%kSNuYw1?I=JtasddgDW;~y? z*qS}W6dp-a^wZE&jcL1uLVYA+29$+tV-~op6s}GpnY@T=PcVe>dHrsnLW8+A>E{% zH@d1gqYY4(mU;|R-*i{IF40&!Mj$O>BQ%Bg>yO|{-jX|RLB*El^ET2=d)wLNlP{Ff z4-5F^xfH8+JNJ892Q#>Qj^JWGCw7f~kUDbl*mgFQswrtq!HIQ2FBDP1p6jLt8J}f05GF6*r`MhHHF(*`+&|1=B&YKY& zq(|ErdIW;3$GuDHLwGxBi_4Yib0TO4NLjCsK^IT!2R|p7&#O26T`wJ6Xe$Z~bm<%L z4xIx?z8JjP$}PhoDwqt|=_-Wg#>wyZ1W+5+sN9y>8Xd8&!8X!0Fx;Y=@AH0(fc*huR;MtKRUN$78}Xyk79aLIPHLYcWxE^Roa&2--i$H8vJX5m|?GK>%=Sn^foKnISuR<$!JGP1|NMDoraIDzbNZe4{*ln8Yn!9b1k_*nw;)Adct{Bno!U7c2Ec zLzkSJNnzgux7YZ9J|JyEs_i9Bxdn?XnMAlSjXSUtm;Q|SfA;^xwV-h*4NDYlNG&vwmCve$>K!6=l zcLF;~#vR9N4+IOK)6ix5Ol4A#Rehh1a^*_XAVVxd(0ay(_ZEEC7nRVEp5#0SUhOL4 zznW0WE4SSLA=*r0cyDJbonx7RTn_}6d0hufk6$x?>(Yed|G^0hM?=-njTZoCLb!L+ zV=v9$$HIRy=(w!-Tc=!etNET1*?n5C6ZUqiYmE<=7&GIAuNhDOJr~{8yXPIHR0{IKkmIJq>qN4u$iN7;apGMU+C^6BpITJkMO;*!zxAi$>WM{Qtb zzUI`noh#T}hy+{Hq~2Rmt@s^o88q{$8ptPUy3!#?K(&s>^Hkq4AYyl7lZ6snH5%}g zqAx95OLZWMm|%bgq=baK6{kzw2K4788FX1k3k547NO|>d=nyl#p`7?-y}U&e{@&N8 zHFtUTtCy5C5v{TMm*Ymi!N-_=QWOVaZklt6EhnVLG+t;t8F(r2NxIhMm0q|J;Gm74@BQd^9TYYiatQ2cdEcer#DFQ>24zRsjXYCDYk_>kGq%cp*k=BeRyFD;tDn-r%WU_s-rB{ZifCf`_5Rm+G17fbEaq}?kL z=LSL$A@U;Xc$`v;HMm%Uc*3;IfRk9%WPnI;NlVLzN{VfnJ;6k5$o6zCy8vcjFs5bd zu?L!kygAQYWWVo2{hX?@e?3v2RjrHWT|R40z8}I8n)sImI-iKDyPL0jnYFpe+N7{H z^QWA?5uWaezO1Eq>hLC*+uut;0Lq@2jaso61zip-pI2vV(5K9(-MMOsy)op<^YQ68 z#Jk0BXl-j*YJj;xk6svsqLl0};p2f#*HSPd#y{b_#zV#~TA0QsOGr;Wer`m%VCCsj zR~b5zgkEF5vetIs^;_RFp{MHr$d9?7FBQo+`69-vzz?RV)P#>TmJtiLjW2nYHsjM! zs!>~;|8S}nax>$Myz9&`KGM=TrP}X|u_DBYp7D+@M&Bn!F_uH)dnAswbvX*TmWlx~ zB#(?fC-&c1fVmY~Q(WopqM((V(QH3f{iZe?rbxkHwlV13xDH$R8Dl*#5V5MyF`n$#6=oKY$v)vY{#B8EPl03vq{{3&VPO)113Bvw?9)xG4*c}fc*w0sv}6HIX&xj zE!|!DJ8=Um)dqQjJ_76+kMgls&38v}Qe4tA$7>7Z-$fMgddsFD1P~Ia9h*J$*r$yn z$XzhQDP(%yGTwSpRNxh@-8y#36i7|LkL!z00Z1KoW4+Q_M|$(=1-)-Q9`w^PXdNHY zP>HgKE0aZ8(Gy1hZor}cIMOkcy$Y;?_ir*$8U7`u;4k?;`CpWkSR{S;cfn8zoYhE? z=O?UZeqAuPP404J10HV!3+5bPhRGGvmhxsh=7Y)M`ey|7(vZ%^R+To^vUGvEmupZn znV#ZmBe?GJG&wAz9K-)516$?P;wR#_XJ@!|%=;V|y&N2px2%`CLwK;uLw8+PYk`Io z?`<4@?8Bi~km`ldxKhdVR4j%|<&-UPBGD#L80R*W5Zd65GLTO{(S5AZTFUst>z@Z! zl*S$s+bTtKMos}X>}f%ZPci(aMLX^5BR=cO|3>{pf66-CpXwhLD+>%jeqYBv=Icm; zw~X3N=V)KL@%gZU7ls{0D`d?$wPmD85F80bn`t~rWutEtOISZy@&b3%U6eKZie?UT zi(XAEdbe$Fa=KN=&wxifrOe<#09J|HG>VQgO|~fhd8wIb)(Bc$-{tviA)2we`pSE} z3OLVQkGL1%XJq|WrU)XQ>Cts*BFgr*4pkRo*)wvf*CV&y_~f)N8%a3z$=%Rj(eISc z`A21^K6;l9Mfp2hlPRVu_?sEQKR8f~pv6O%mWLerEDpD`C3^)bD4S2eh=pFys7?%g zSvvsa=Fmqu^~w3jE67PEHQyv{4s-D&OT||f|Lzfum2=6OaYW2B`8;|}xX>ZV_V!%s z&y9B)C2u=W;)GBo$0shwN3C9UANS zJZpxzd=4Jc!b(;7-}Phvmlz36C@`6B*X$8X!JczE@a90^Ogzj=JqE)}>>%R;WaM-q zTF)1Bau?5hg3Zbnilb?x%Nj(qRwm261Lox#)iL5^je`b>+!Eu&vYlUfe*2_jo@^+; zthb+yYO70C)s_0f*ftcsNF-D;23Y{oQpVf8aOyE}g*W?I6JQs8K?$u}x7>;B4Rxa> z?6={p@l@Ri0x-lHxkfcddp&LgSa0OYO$1K|gcqyCCeG_K$2@}yJndS(>!pa8N&b-@ z)pyfnA5Ity278~!Ttj~n&8UtB6ax(Tf+~dqJdi$5!oweC_=kQh^l|J-qy`HLwuKk! zMcUj3_ktp5szxD@i4~~iv687iDyUcj&*0-&LH@O8M}K<`6{wv<-gb%74C@Cl-!<7? z9^F*2oTaa<`*pgVee%y+zFV{wX;;ISV2p~aHF-0;YJHAz#$1RYfEAa04BqDx=uZE8 z3+UQDv(J3Jt@rp{bPxW)&HReDN^KtlpxfvVtmM3ak*6o$d25GrRCGcfrUeEfFQ`}= z4_7!8wtN>{iYqL8X|SMSG-d3ruhMzmMr!zw{?HkaNIjmCSSh3PWo_Tzl4Yx<`KXg8 zbyWc&S$@*ja}+TX&1dAb#P4H-&go>cgwC4I4A#zYVoo>RyN@|61T6dA-85RyIh`+J zqWE82XC?**0$fIZK5_O)#&;ip$efnuEmNVWvw82S36l8392$+Q6Z4Kn!wS(%`5I=p z`SmLMSwPk_S`zjyUBV{v3;5@h^Y07s_tCtGkN|%dm%;#y3pz~RMRjMH*6V`afgH&A zjR>VdG7lLHgAK4u|5=9! zQTUgE0MupyEu++p`=_1if3GFtro%)H%%`2cen5Z%u`SpQus9UiHaWBY;$`hUrNSrw zEg%)%?GH`(=KVGFF9~cqBe%}YP_>(6StKVVTjt>ce@N*jGxJ7ioFUF7jc8lH#0$Pr z8si)dApUUo#O-Au(kmx0-f==Nph*;tm?9VgR{Iz%;6zl3wDjkq&V>90gujR6ujT(O zRDVtc?wzN)C+-!(e1+&?DkKLfm!-IBtcpUP6Hsw33^p5r&>vwL{vCe^jE2Yn# zo^f$TlDjP@{wqIzeuh2&4dc&4FYC?)1v;nAe#QAWna^pWU^+RL>`oE!SB}36I+8UK zVhp)tN=dfS#Jt|GWemeKjjM(r4O6I)-ZoC*ja8fVgZEXUMjYjo%K4+d^Fo6x78^V# zmdsKVFqTTUie>L}o3yCwKf%3xSWD!(z2qt*ab;$#+KakcM+yfJv?j8sn0z_KW5F0u zz!+=|sD{LY-xwkF|7B$NPGcQy)&VPC3XUM+jS4 zt10$5u^UljwhhURA(+ulg1jtm?)ZftJPqnDm`*G;GD`fMpjDOIK=B?#UQO&4TNf!c zg1M*{$utVY7fW4T4O0X3q5ujp0VM^Lb(g&zh|>^qTSo+hAOIbPl>~55I4K!`iNHVJ z@xv0aPrDa*ka~}Z10g}RH}*PI_RTts@r}}{ARy6H0mu!n;YzRuN8lY>W!BPt$*X>%EJSFPR9Xu(*G$>aP1rJ%hlk*0XqN#wTL}@ z1KY@yn}v6|hBcz4RU@-t>O{j)QDM(pCI{w7Zch+2Xx&8ptlAr^;*^L2nPOX`r2|PQ zVJihD?m6>GGYyhOmGP7= zY=V1p2`&4AWY&&M6WoM?^N6lk0S$omK!mIkq~9YINRx7#^>o)>F~BZdToQ)jki@&_V{Vn*o!cc3VCbwLQ78H_k&tOMsP$suhb ze5F2R+=|u~P)a9zdCyCIOym~K;^irjWy1ldzDKJ>-Isqp#OT8uE{pDi zKDQAe?U5lWiwYs>-C7y~o0m)k6^kCNI)lLzAHbt|p5f%0{s!|Ye{GQ2t!rz9*am`O z5i9;q&j=#K)NSkDp8M+cI=W7cm9HmW z@AAmyG%3%0o3#?R&bsV#gn5cRM&Fg0)&EN32h4gl^k+PZz9WHFaX`P}M0>;@XyI3P zbH&CwJ_SKYqpsw9j|E7;zVpyM>$OQsuTaHUIzS_eElABS}U;Xo`#$54}6{LJW$#k@DFe7rW!K);h z3JnG5wh9~!BTiBd@5zwCoW7FOEr@99FDDo-y*eE4FJB>+BPuHai9sS%jEdTCnVB}&VSn5EW^nTevDGVzgKX7gwKyXVtawXGakZmp_8h;dtS1%P!f zV7ur>GA?Zff+KX{wSOJxxNs%}k+b&|{Lb-88Ula?@#{`(D-W1K!;9R7tftdBF}JD4 zGP#fOlA%QO5ipmSw_hvM-nUuN;ZzlPFCB-R_GWTV|7bo zxy-~Z9WJf{Sill$%|cF3@7#4;s``dG3SBUYwl*qI!o^qs%qCD=u!TpF+#*x79<(-Q zb21E~cFPA~MG;&Zi_V}Jv4awf%yF^SS)Zwl=QbxF7AVJ{oQSw!kGH3c*Z}{@BCAr1 zIz?TpGgi|ix`o# zBNkc!K^Q_3K$@Y7QhtR15fA|t0|+C8&_TdPzg9>AOoBiFVQ4mr1EH#bg%$`R-2eh& zKt!ZBf#BN#^^Q92&b{}4?aoWY$$2`)1 z^j?c--pTtwbq#avA4d6~tW<1`GKX*--9c(T@PyU%L^Yc}N4q{Fgi$Bb%=$r>Q%`OD z4G~DlkNIfe;=v-+t8T0Bp7!+GqTNFal3P0G>C{Rlcz+jCTo#8VIUysfwrIiAz};)z zSb8FI^HzlgeU=xNWMUTI?kLWA&XN{kI{BhXF|kvSZVb`2w9ZSNhDT;smabT{^miI} zR;qf3r?R!HGDn*3$2JDweencuFy6 za*NxAz)W8}?M!yMfP>e4cba3yX6uD1geTe{H*cuYVA}fXKS77sR@b^cpAJ)4QBjH^ z>R}it17e(yq9~BD#4is#sWQKni(uscew|M_coomzX!dgN+h8lyPPWzN|JLrX;PU9J z&sEZ4`{(aGe9bYCR9}5I_}X;iD}xLCmu3=Qnm~MMBk_NyLeREOreE)a8YM$5KV&^Q z%8um6c8Zf0FBKW6{a1trQv}MRuJsCf#f0S@HJEF>GI(?~kvNE% zrvx*~vAtX~7lzKzi!nGw!BRBXO40n4GVExgjS@l094sQBmkd5Mfu2$bu9xH%2m2Z( zs8#Nqf|p??4w_A^Sj)_T6&+lG4f&+)J2;-d!8H#$U!<2Z&yj9Go*T2m1~+3#PEUDycM8$`NC#k zjY3o4|I9SVMn(yndE1Ap@C+H8D1Q^EnXC&?2E}7+pCKbT+prl=frh?RR^}I%^I{9T z@-6#o-YTceTgx;IapbD}KPZucd35#yue4;-Af823sY)}Gr9k#oXu_Em!~&YN^aj_^ zR=k%&ZGw}cVi)kbe5-MNFIbn_0{m0V<&Yzao!af5&KXlr!RqXx8j2D;L53O#j8@_x zINL(Nrz%ie62$WsPJt(IN~S99|7pGu%{PSQ{=YvjOY3`?ifch7PzXAikP{A?asMbX zQYAq810%OMaF=x!s844F<|fQG9+(2!-gkoj29_=NC%N{#dYm7i1!sF5=2ll39A|57 z(O8xmoAHWw8qi+w+;bbJV^8xlRCIg!F*ixkMX?i0aGJh~o0$@fUfUPEGf*nAw*Q2f zZv#;wycmjktW&8H2&US;Z1$z3Ckg=`&`Nf_&gE&HQevPC1>2Hrhkga|)*sha-Iel# zCU)A3bY{zO#fuaQ=Oxn%exH?f-=SFI*9I`#*`Jix_xao-1L7X*Shmu!MR^|kjRR2h z@P@Y*=oJ~244b)>&B`9HRi8@XH*r<;;FU<}QuHJDQCoDLF&AmKSLTSAv-d!(dZG&rC*y3^n?D|7BxoS z-rF_${&rYv*yy>3q=;+{t*RDCRK6|&j9bX^c`%7iFl|i%H7R{+J zfgl+rPaj#NMj9G%r6uMP_uLlWK5uvx-HIivnYpAIsaO55ySWcArs6Zq1oRtV@Pz(L z+ufAEQ_KOVAv05U$u@fXXnL_6E>#SFXT4uy?=L0Aqs7TA-56`dvC18s{$0O84(GOgSe?6+s{Bu-j$PT>6-(~|o&g&f`>wj+J{vh+Ao z@?5B!$Tg!mk=YJjVtvJ0iOCn_us$boYhIGQw_eG;ab%8?s7Q7vr>gf{q^})6GS}fL zU9J9foN(xRoy^D5!a1CcB=hOodymiIdlyLuIu=RheU71e-HxHk-Hv)|g>Emu+}61w zR8Q$XHZS~Ux!d}VS`&*>C(k^MT>y$~42$|^k4lIO&OCdBF>{TkOQ*}U|97)+>pHe| zeb8xZ48`KlIIkEaj7jV_m}-ZTY|jI0U*)8;Y0U0tR71H36|Yqw=+8CQHZEghfDk$U z6$PH1ue6|1Uw#DxpOjDH^~Y(&dc+Q^ZXJP`0C<;7EtABig`MX=tb;$wW}$!Mwf8q< zK=fN;d-K^Be0CAJ2G&q{vQRC7jq-z*{+oi)0ANkkD0qT%7fkfW^{3^MN)`1o9i!nZ zi{oKW;~vMh5EnWg#x~v_UAR6LGy2YGeQ?0rg^ne?7;jEgucpXUVAugG>gq{`Z4-qv zDT8Q#SSbaN17YJ-Olbe60L+ziU&<7lGTg|=kwe&NxawGtWX@K-rs-mSro1tu#Ks#}+ z5eC{RH4cC|T2hdxg!<DX&w-Hd-5P&>t2Mp- z2EYJ*_4IVo!seEgz5k&s@sY^LB(ASZNJlCKo=KI6^^q8z0}hcgiDF){yQ+|jHra`% z24^=_J&5%`SDK&yoh{j;H!r9XXc|?bT`V)x+MTcH zF1oZ^o6qT>Da(bwMmDE1pDGrULA1G}Q|bTgh<+#a<=8;Xbu^o@0? zuBkzk$jB@S(2^=GLO{_2v{vfyoX^D-SxsTYJo+9iKLgbO#&voON|{l4wGX zI0;D9q`sxyH`yP!OB|E;+UJO}TdATh;$^?fYuBEdUrb%_@zn^uKIP4Gl6O8V7|-$5 z7=;Igol5Kt0tUVOIJB6p%hjP5nJUJBK-!4XRPH)&+kk(g<}1NQywR5II9PB(uOG); zCe61`;m2XYE(8g-7YY8$i?L#adP#4BHnf1DKH7hoVvM=X_9310)+Y64tH2-%Tsp zN`+LG^+H^xUFWCo$4_(BH;Yx0n{jT;`Ah-gE(w)g$|nKX060wONhzbSZd*v(mDvn$$9~1jRlfv@uFHv?7_s@0ZXCp? zogUv_+^x|pdG79(d+U;;*0&{U0L8FlXHA*F6N6IeK>bcSSlzN)N0qEZX*}h`PNOt$ z>(D55FlwwFkLLRKYyNS6Pj_g=2Tj=Xm+6&3HKQ(hl0Q5xTD=8b%0UEs+Qvq$AFTJo zT4-j;NmnTcP8wPoTDW=*Q)YjxHPXgwu4f^BUWRf?Pbki+!V?yNv%Ed*2u7?hN|rE> zqI&k}WcR|ymeorhX+87~AfJf!_-WFTpkT?|uLw2E;B@Dsc}g@36LF1vavILU0vAx; zIH5=4{-f_OH6;zz9Npa*s<2Y!}F5G6nU#`d}X+UPKI60bgw>7YL)mlvQ zl1>7|ZR>vH91Z2QRU?p=xgpM@XZRe?6?<7!Kn+p}t0GxYRb<1bmLTz{isq=_fc3=W zy}_N8e!=Whta39x?`gYD6Y1q5Fz4#P154O9Yt=NcD_^vdU_K^~nOOdIe9U)ONKk|H z`4+IoR#G6f@dTjyojXJH;HxOD65j)?xo(-}OE>PiA5kdIDzbuD#wTV|8qcl&IRg)) z7&NKHPuag7kWN&gx)L#00;xc)4c)X?<4~fU)X1QbaxU;2^i0_1mbPW6Yn#6-aldJl zml#}d@35iKd2P(&-l~F#Of`LucGE;P)B~Z8XoAo~M*}m`2J5%dw_PwQV9R7%k4#{# zVlEXO19QH)5e+R z)f*4AR>zT_U8`#VpT82{E$yANX zG@xHF!V?DAjy7%FNS>tIiR36_xEMEyxKvVh5 zw=hcsgW4SAY)8i#9(-a18A{n_rUE-@)MYp@*6c=xLccT4h`Sfnj*v-!_}1e2JfQ|? z_=*C0gW(G|o2~cid#ZTI23Dp9Cl$KQF9nq`quON}@Ph?4T}|Sw(xBSwG=5ov8(At1 zWx?9A3Z$du!% z741=Q*}n7y`u{@<_2sBH;k^vk`Skx}t@>?gyb$w2E^eLwPI=lnJLV6A|AO$yGE9YN z%lFkai1T#&<|0I5NX5u!{gu6BUjcd0wpEV2ABZxt1*o^d!ftWdxgr(|MRQ(HrqU4cQiKkOBjl`pv`a|}61XPH|UKz_~klT%})Bu6N(q#EzA1|t3 z*vXUG2{~FJlby>BT)htMY+j5Oba#HAzSBe#@8ph#{A-zk**(XT?+Ao_yMFud#M8pe z2agLSq@ONJhxu=2N4O{bFq7<=Wu+s&<+8#vid=`(O_n&!8k z;Kpt+h324>*4a(^Ilc;(iKD;*to&YA!HJgp6B_xV%4Y#)(ZemSblZMkqi^Fhj@$9U zmeWWSjW?=6bFNe3>%B;!0)$;cZ`2MA+nER^zEgprh7o5&%of$E^!GI!s7!fYw)A*q z8vU}su>U%1J>9W0U*cJMrJX_OixFVkMr{%*85eL0uOY(x0fqVf!Mpg}73X%5ZK1wTi}Dni#8}hJ!MJZ! zy|W{7Hfks&UwUBc7YOhh;XSvCI=tR*=VW}kl6t-+wkLHbo5pjwPm%91uXX`X zw}KP6HXhZ>;rX8SoJH_ZK!;vw_9O%(Zgbg^JFd;_1CJ1a{C@HnF)>G~Y(T+Yb_OaZ z1?m)J{0bXc>vjbbIV{8dAHRp|-xEYMdQ>*ImKk8dvzuVwzeNt|ygmZTqZUrroRN7; z+@muVKS`#ZGob%C>9r9?rW)|O@q24kP>~g>rqQj-+xpn=*QDvnF&Lb&eXK(&4h{K4{UHk!b&D*$)2+j3Xh03{%L6_Sp-* zQX_1h-`TCmN&*#H=Ne@WRg}`w;;Sp5dp@3cWCF_MAox^vN!xDeGQ9y==!LrL2uZ>x=BQ;vuB9xOEwz;@fK=6GHxn=ST^tpmxUS%|)8J_j^D!`Rjnn=hRsiLJP3BrxZoQIJ=f%A`RuU~n?)Bu(eD>+= z((PGF|62!!>a6M2>3oHF?N-R6JtzMM*d3gNZU?sS-L|6PX7Ps(#^OXp4q2uFpkQL4 zo6S;a>g5BbkJ2t?L=2L4duA%%IheTf=HraxEjS@T*?gXKUP8>t)}+{1le=5Vmkfor zwxRYLit?e)03Xm^%#|MvqMjqWx}%+e$um^6xjo9RRe2lOJHn=jSsg9YXbcmFk%$Nh){Z&JAKyH~bC!)!#v0 z{SP!HT`J-_hTDet7vHc@nACru_mAgwR&{f->0^U`^?m-|yOfv4lC8=yVVol!H(r*# zdB4VdOFVbQYQ9NbWCCe{G_H~sB<)AaR;Kg+ors6Qo!!rg7U*jbO`x8m`napW>3jQJ z-qr;}F!fPnH_JDmlVvG}LQk}fhfR7HE&F~-zQdQP1YG&7Cq=WHj^IT!URKUJKZwG8 z15CoDZuf@QW>REN3vwi!8gw>d^0i!69`uR(nXJsM@{oAX=CY-H{=E#ZLaiue5JSm2rRmwfkh`MDze!$;dRGQUg{FFn7Jb{&~RF9I{xOpUXFIjiPI9Pk~vhSeqrv!_$nM z6fL+{C^eXX;d|m(XQHp_+qi2kIQwPy^X_9K_aeF@dk+TSf_?NMURTgnTZWYpPYbW3 z=y7rfj%oj6To?h^ntN3QH%d1>*$X4Elyx6;fCpRTr znCj)}jH$$!+CP3;1l20i?}V6!Hd+6o=ZUg^c)v>}`)8fInwkZ+mhyF4S6%q9OQ`Hx z_o`@|!70L|DW>+0VkRgS`u$Lu(BP#kne?def~;L)2$lQ&`ZB3+rADINj`&JbH3tum zxL$U~7&r%1Mwv-$h-#e`8h|MDpu&8ue>owYt$!FfQhPZc6#&)Bukg&0U2Yryw3-AF04Dqs4! zl!hhC_PkSr9+?5V*bSWpcmZG{q%;O5HNzp5KAN@j5hDu}7}cP~TSj;WK{50r2BC_F z?KgC7U~Kezr#(v!yv0EQV_)3Wn9h!r-c@wR!9CQ@6MPq$sWq-;8CN(rQ+@Q#Mt6Jj z*Gr$i^dc?iH0{EVfQXXS-FI+s3deU{AsOZEyqf}6|1U=l&K5}H0Vb*@(BArcc2_F$ z1=5l>H4q;d@p(rPX4uD7jschgoe_=FOCHirwYM5H4&R*i4J-U7^2KOx03W2%dldNG z`WBhaUY~wPd*E8L>tQSh9+{*w^~6t%QN~1L3F0pxr#;ZpyfgIfLoX(`053HI3OU;S zyTVt=?eJKX2UHFn9Lc7L9e!1a*D4!{@{wNiN?|TuW-af`**WkhKH76_!9w7L;n=NF z*UDj$8@PudDE5^eyMu+9S7 zRk8U}Nvg68&Z91}30B-Pkk5+Q=M@#mXN$EV1PVBNsRr-wx)M1d@0F$~g)?&B=cVC; zxAo$4;|stApeip=JhNotz7f)>bEZPut5IWHFO6RXNWNR!iNQapET12j^SnSX?L!sv z7p1(lYwveWKoHZJ<=Rcb0crD7sEI-1%Ld_^1m$Qo2MO2zh&X}LzKU1!e8s1u$Ax^q z@ovEl?mc#T$}K*iZolbcW=`5I75u>W57PAAF$ilJX&r+WG|_MF{tq`~4Q+YVN(C9X zy+So-zP;n3p-^7YXN9oPruQ9&p|6_Qy-W~0AbT;x(BdCOOL)~yijMdz^}29h_95$- z6}$KGW2lAX}abCkh=aPV`rK@F(t+Z^VgN0cUNiAv0S>VTx@(a!a zvNT9Uk&(=#_d355#GTC;LE{N~&cL1?hxcm^X9k@qOR1NntyoNKeF8l4*Mqqm!BmC$ z^W(QW2gQGWly+fD!OxFlL=GK1T#%8$J>E>agjy-JpLd5G13&_Z96CNJxAR>*mcYA1 zRu0T4*~ja6b(=5zK++1AmEAcgD&o&e+QDt@XHcKYyIMb(V5*A~g=(44W{x;#m&U0K zI^rC!|9fwn0a>me*c{&~WPp?+-@Z}B4TKddP}4MVf>dn|v?M>mPcB+Yu!byH#zFdw z%7#O4-k5Vc-xyu%Mhx>c&=NxNsKie~V+rZCx$^82tMv#b23AlCSF=zOktT0&umCvG z3H!Pc=Ek}CPPJ&zZpocnD3u65&>&CH&~?yRns`J;#C2F4V|b-u!J4>MiBlcRNqX18 zKc1Ac2nwad6WqwvEGX{#N}>3r#_`X!i9p-@?@dhp7}dY1Bt{P(qjLFRov6O7GjHne zBz1;tEkDk$xKlO7U(eT`{&5$-m3v>*#4Z2NI#s!BB=?v4`P~5s-wUvH$=f84J(8j8 z#=Xxi@CR8UipLS90(SUZgAS+%S-m!aZRYnE1jXYL?G@f7Dju-;f4ws3FFdKjW8m5$ zmkpd{<$X{5DI{x1N7N*F8p3F5Q9lmuUS3H2{@g*>uL#gxsf)-#lF=@ooM5H}>s>y44qRH%{NO9+k9QAq`P($PVFAz+nkv_B%dc2Om0GgyW;z7wYBe3p-a zh+6xMwXVb_M>V{5sg^KrA*jP{r^^V#yd9viMuob&wX-pWh$F>Y9Jv6Ta}rNRD9sU2 zohREgL-qx1?0lJq(NM(IW=v|j%!sn#a=y@*hMtAMQlge`(*w-gABzk^mD%ksf^$OI zlwFCFbNNqht48-K3#YossZsh_<;W-Iq?CqGt`c3iFhxK!wvZp7f&5RO2@6Go+-D31 zdzKE5>#CU?_ivLd2#+Bq;wy|EC$~7&7VjE77K6q$ccRm3WRo_YGO;5oWY{J*kNp&M z;QI@#vF&o+6zfn4HC52T^ar8OCSyp34_`rhoz9&$PNs7z zUQ9ZCQ0-1`?SywXN_mZ<5?K=}wvt>^)S7&A*9Z+;Sy&0bpIKtU+%onAq&5~{9c6*b z*4NYgN+k1vSJAXaKl*0s;Ihd8u9D5T-l^@t1?+sm#-Gs+iXdvz`>{nKW*OvCq}M_W zMRfrXJ-a(t^#KFVJx@ICX9m2Is{);tujy@>TIyO+)pn*m*(U!?U&;%;#q(eh9W1F= zzdQ{n0o05%Y4+7pb7%P)J>;L#A!b8>)L|F#v4O_cdPVI6-%AX4(d?NK>|hJ&5#>I~ zPsjpuBFqBy%%S>{i=o z)Yr#UP`wc`^|rP4jog!YJJ+lkVliUuRimAOeKjLPG4>gn;%{F_gq1_QEyECT#lR`6 zl49Rq`>14$Disuc4F!?AQx)>Y%8!>EgEiBA|?}B<-n>a+;-y18O1+!Yi0pd4`GEf(zUx8s6Z`L~BI6 z$z3m|JRFP>32~mgI_w@Ph6!iYAlZ|WiKGiUk}Q5dNk1mH zicL0(!sFRKs`dK=#F&$#ISG!FT=;|2^Z=FX^jLhM^d`AnE%FIMP?W^th5>4+Y|aM zWDVw5W>AQ|QXxb?QYy!j}zqwO!(u)B8h4<39mBcjo{ zlivsbk2saMEg@E*wbFP|ETPbLpI^f$ivOZn{yXKhn_r30>1@hQOJfW=cQNqF<$HG6 zX+6i07wTyk+fZM-L&5g(BT>FtgDdoP?=G(7)treQ*ny#*7>zxC2EI<)Z&(zQu6aaNo9#pLs zkOhUnC-AYbB)2dq2uw`pxdnw^Nr;B_>f0d1AIJM|KF-t%=g!VDr{sd`98}_%eP8s*%* z^xQ_c#Gb>222k3!0x8X-d~>x(T)8n9U|NcY&#v5DkXyk1r5{Nxpo@){eZ=Qg&Lfsw ztHfucD_5_4j|e$<(b7SaYaPbn@o}y9=yzt;)8bT>aCXd6n!kDg&0l5kGtuXVKK(uf z&fPv{z7PIWrO!+JUj2TDLUBMWc)scVnmzB=gFGkzE_xE84aYz&{; z4g8dH`jmlff&y!yKXRWRcW!`v?BMeO)UzT!3}wnvPQLvTk#9gxVh_kH_FP(y(aDk=<+mU(lz1TfS;}o0%}RBRuvxvt zm6=t7iQY|>w)ol5XGUs2!J1f8dvsk~m?Q750R)l3)4@*~Y5%?`-kQgBVg=pp^5kf7 zoPQ9UuHU%=%s93zg{MUGMn}ODva3xHB_h=?Q@$CTd{89nqcTn0=>ao8EUYWnQhBZZ7(sNtvy^>zf5j$JCEB_M;plvG$AoiHlv_~&GKK+D@_+u3{%Qd00v&z&Tw&(C(zMmCz`*rRf^L`EJy0{ zmYcYc<4e)wzOL0zl+Ryqo{XVPs=Tt>#byz%rUct4Q0SMlko>uNr5a8y@Fmcp9vipA z67$Xm*}{5pvwq-dJ*;;!zdAGJYQCQjkox6tNBX2(OO+3AF8C#%k$D86@_1x>h%sT+Tvtz9gS4?3~P>6PZBM#k7>Rk*W?TzY~p!xji1B^4cYi z9FK=BZwLLNyaQBN>NNOA0CwcjDw21z$N z>#p*y7}RA|g~=oN^L4eZ6R|0iDqfrk*P{I<%SUXLF5BwvajaI(MY5CIHZyCpkM$ut#{ufK0T$! zP&903dfe0xItFRIJ%(DGer_$#V6?f7eBJ&h=Z~D^r~iEQ+IQJQaF@OEyLm8AKMKu# zh|dljV4R4;-Yo*Z%*;|meJEfsi*k1W^(aS9Qa;r~%kM^Gnm-6Lu3m$E-PmvT@K53Q zF2*CTw_lT{XPiD6^@Pl7-m}~2pQ7o_Ux_}JGG;K|6$u133{o(WgZJyD1z#+c(zlL8 zM+L1@*XyQ#Y_jLv7fpVsA86!b{Py+sGU?)s)6-Es!uYejGa2yQXkxB}J1#`OAkkq2-$R8BOGsrxT}D1Rrn z#9+am`Z~}&^R;eV#&0J(+Jh}Z)8b;P>U=I1@loQI?)_2e-)`f`G@*xV+bkc5@-fbR zEmQ_A&iJ(`=bs|#YxNY7IN55S2i5z{FFZrNs@?CyBM6a(Jcg2_=;e+px?Mv>Mt62Wd=d?b8?HDX8nyxu0L*Yw?GhFjOFR%InRMDAr@4mB$*C=^HRe{^bxcprAU{hotXluq zLX}e>q@`tQ693#agu1%MLrooKmUVO>^FEnjdxj zk1~KaQOqg5aZu!cJymeZWC_yLraW$Ibg1H?*LF)Vg8y%2FBUT2uW2pb(x$weSrU3H zY)0|%jLG{ow@ypmcIdksYq!o64SgU?X z*y70_RQ$hR3Y-b?<}2v1RxLQYj|VD*{@QvcX{gFy2*Zb*tMV7LYRjYiltEiVub_YX zz?0j?jl_RBr2o3ggz}Bm0EC~?znee`F2kq)en3D|D$7?wrPX{qAxwbJyx&o7$rPoB zkGL@b8s`@HuVq>HJMI8|IdJ`T-d;k1Lzbhe`rL4${KJ*y8h;_FIPKgxq?Bv9q*Bu*vQ zv>FVr?wzVA7~U|uUN&V0x7o}0veojVr=4zt3C~&p>$*+xExoJU#RT@!kEIP~e!QWT zDZ6)+z>ogQGvW6fIKGC!_{#a)M*^dir{8{qrEASOH&e!-O<2a-OE7EXvEci$~ zH~B37)3~{E$B!rRp^#(T*q0-{!uax&`wLxv*$7$r_F*BfAiMib&6AN&Jr;5*Ff0F)2>Kyx8si8iydYikl3WtppYic7UHz_a*Ed03y-Frl^?H zWSG=J^we()07S_sjLWmAk4Twm!U90^1nSe9jtxdi2V9e& zx1j`wR=^}Vc726lvPiocuudK=U1V{=7d-=FYvREuiU0%ToZc-o^x2eTIXF8|yJayM zpX;(jM_VWj^9tIVc3b>aYADl71Pi4^gG$tFR z1DvArNXae28rq!>M*{Mk3tse&>-$CvI^IA4l*Db43#3GdpKJc9G`}P6fXy9=i&s}butNsalD7JS{ue&OB!R5Pm&n9((Hx8$rL_3&NSgY8GPn0^GWKO%dERno@6yTn zV*oqFfs2o5zJM<`F<&ISUsF+%vf!kMrkEy}8?-y)A!%;WT!H}vRZ+iz-?(s#ew~jm zl$~K$2xMeO9~2&f0JtwKn!BHe>E!t!LmT{cG<0Cv8K1|t!Q;#jc7^Ecfad@>6K6dz z{?+SmGfjSkijzw9Y@!I?3*u1%yn>?&P2UwLw8$IRYeZi*0PG)4=8Baem*53=Y+(@@ z6b*)PUs+d|A_>z#uR9cTAA_~6y>QTM=&oFB7034MtSbI-MOiAA4!Bei?Jv|t)%4c( zML9l8kZ;!~ZH*~g@;BgbdXRvcknnh3v6>^5@FPXV&*dsnBSU%Z>6PW+txtScZm^Vr@G@pH{8=Mjr}zGRKCHbtEGh~SFw|33n8c&5Fi&X+Sx~KQL;?<~Fr-5N zv`cLGguv|kHSuxd!r^5vW}-hV5x*P-n0R76*M_g3Sm>w3lbWZzne!djvdQVZBV~tmS+gMB9aX zSxK2E!!&{=Eqh_OpKBDcCY~YPb1EkqYVhh4QmKoM-hfR$&tOV?iwf6>ryCg*IruUx z>hjcFB<%7$Ah?{?9=QVODvch{l6`gIV?EtZix`TVQh3erL5;}A`oRnni@aBgR_Z*+ zddwD|)&#V)j^Qk^D~Q8|NCXyp(L2CR%p+`~2FqF}nNni;-y3FC*-P060}uiJep#0XKyVe0KNI@C-Hix6{*Le9X?+)Jf z;l}lHJpg(w%>r1KJt+nCM+%5!Pt!osS&=p<+tCseC%qK_G>Tk2CIomT6c4OxYVUW1 z7?+7$tZ#Lxd<(zrC`fZ`RkGbkK4}_g(FcwQ2VGpRllC=A7YJGqtXxZlGoC!PAwDS8 z!rBxP$q|69lY;!gs^5;ZpHvb*BRj54pdjB!^V9s0?wjJi&(vJ{?gDkE z<+Go#zxjqW?@@8VnT{~7(NyV()7U3W8jJeZME|7k>^5lVhiOk68${kI1=N~=a2Xi& z_&rC9%r-^4iCi9_0zkv4=3tUl-o_(O5IQ$c)Xu)Dymxr}&&_*KlL{Sik^$QJPK~f2 zfqti+p9^nPMzw5v!QYqxP+n(Tu1s~F7|U*vnf61D9(+NT^r;$}K+$gHYmFce6xfeQ zQ|uSs8aj0$-$Dc5rS+zJR%=y8nfIJc3%Hg4+)AQ(4|)=S2WUEm<~W<+U0f$5ZFJTP|OM8g$8CUW@j zr=eQTqZ8f*PKmBH#e(x2wVdx)?=mQUZM>+pLJ(TBi@ZQ&6gYOexak_IHw3+710n~< z=dLvx%phO=hRm6;+4lEqUQUj2otUyXRSxfzCRJ4jneXVjo{foro-qC6LVu;HlyN?U zwS+N%Rj>;HXuv36HsK{hsD>gR4f`*MBaA+ACN+X@L?bXqU*cc+)#x;e+_}24f-RYj z?T`T^5#Wy__3P(^zhs*DJC7<~&BFif#{TlNS&*U^k{CcTM2b{8@%@$PFM=u>*R1@0O?h-vLL6Y2f)|qGPHcs$WF_A!8^GB+d0R)SZo zhry(wl!kVbHd)7ctjD+#rP8J-46{#^EDw<86SM)Gp%#vDt#6Gh5j6=5RKV?{o9ez& z0dx_CZE-j{KU&8(dUl`Q4(=0Qop7;v)l#%sbFQ7$j@;hfaXOFVVuG{gWb`|^itBpp z+spCq*HE$+oR;_Bd5tMT5H(1J;1R(h?7M zY3cmwlL9GwwWbA9^c7ZuVv7EU5T_3oc~^sSoB?s52|C9O(pwi`j*lOZxbgdeG# zW(c1)uF}QF-&sUBR*cZVgghUoyv&HN0LSmwjF5@P_>mrIhKeU^t8!@~g)P#MyI98# zQlnv#w-LQt0^7r9piaLmXPA0P ze7-q@<4>E8YgJ1->DX#?7(`a>ByM!Lon&^*wX*F~gaSv0TS=%88 zT8VFlQBOaHUxrb?3=)qwKprP3M60bJ@dI4`m&~L9D&Pmel3`q%1%1hmWGltL@={Uru9}|)3ytge}ARV2@2t}Zeha20fTS=Z@-06lD(L&srLF8N(-^9L zLybZ5!@L2xC``Wj5MA54Ru#?f^(sw2_MRPD2dx@}m)p@ISuu}CAL)5G6hua3br@X@ zx<4ge*x7G3jHbPUY4N*DgHFW6%dhyrM{$$R(KIa`j4wPUUk2)Pm|o=yp4MX`U%QfJ z;%Czg0~kTmQ%yw77ti#XK;*m%Gvq8yAn_{|SZEKnuz)$+su2uE$H@a>Wr-t!`4C}+<|l4C_y z{XiJk8gbtf6{4B1saXf&xnF<9#cb}~0D+!Dyragca1|!?aIPW&-Vke&sFO2|E<;%hTHDX4_`F`|F%LkU?<|%Xzt0*~V=;Z7Zi=*X4TmRPI(PKB}UX{Ml9+NI`Zi{P}i9uiPtkzwZk~ zr*eMD_{AjaJ}@?zqgTQUxgu*}2~m;6;}U#{#x)M$tMhSl1Ye;M@DThfaa6-hv(AD;?_i5lNkV)LZa|iqk zd`b6kzogtAx;SW&`Y$#ju4KR0m4k62*)$=im+Cp3dKbI1drR&-$ki|*HB*;NQCA4v z=^867%J@u``HUVoth6<-;#oBq`^U{@YRbf85GZ&8uw4d8!W+sC&x^?nP7FGZzFDcr z9nQyXWmv`FI{w)PDXwaui-z5T9;m7Iv0aRPa&WS!Q}J3DLq>AMQIUH!iExKWP011N zwfW6W8OVQUb5slqW^sokgN=P90|;6L1l*&qnq}B(lxWn$?L!S;a!Ah08J}%lUmSm# z|69jq`F7%6GCR6@`e*#vj$V|$L6(f|%kQ&3Z~d>fe5@yf^s9|H;uA&JRljSm%{=zp zv+DV<@#@wg4KACsFn2p+M>_W04|(QPZPoLRFAs(M7YCUr;waS+!BX1nMLDr-ePt?z zHioo5l~-!QoTUr7+X=FW_j2Oz-33vuA^34w{wH@zqeW(n2_N0z_iGMBRs^T4DlQUc z(rc=8Wr;=6+QGVD#{VEj{Du*PGQUoNisUHVYUbEx{v z4+RzRBwL63ks$`saialI6>k*6t-_w{+iqx6dr^fmDR^pm!pL?^@KpJvJZ;BJSUh1+ z_Dw~P;kF8<>_~r=kn;Vj$6T6bwx#$5T)Avcis)!H)CzqS|7JPAHquLpU;R+UU;uws z_Tho0%G+<$?J^$@f+Dhjb$IvPDtm_~vZWzxk71z@gWGTT{T6FM)~%4m@2!ufC-&7G zad_fh%IUvzv(?hh-l*vmIjV>E+A*hF6@x+nO8nviT%q1wM}p@y9hat4n=^pg>Qu#D z3_&z>?n)}<1@!RyH5hD&@X;*L{=Tf6hfn>Gn|io)$K6ZT2X7Ax9s7@nqSJ*(LOd2(jk-IPgfRw?Ij z2W3j-(5d`i1#tKW0a^1}asHIO>xaHWAQtvc+AXSVm)b`1^flN(v&VGgBpfJ-V|=dk zIQVM0ETzXm87H|`jE3(vO~T$mbWN#jv+4YfW`?e5T%XA}d|psS)H`ru=bK!F=&8!b zN+t2m9ReHQuL(9)=1lCYn0xRjte3ycaL&toQP5-WXke2;jOXN-dLWoPzh9%h|B$ut zE-ESPcGxptO4tIOWpx?^UmcZwD33?Zhrjz@e6eF`C{^gV(xw= zWIVKO{we46PV1BL@^>-k?`48W^!&ZlPtk(t`3i8vjaqO&08YtxF^-mqxX}&iwP9e3 zm}dXvE0IJJTK?y@eK{!t9r6bHO!KkYVXcrR&kNyGiWV9rsjrkI5E7LoC3!dR^!`GL z>zs8Si5t)Vao+_9WKA#YC2#8G~uAyIwwB z9oM5>2iUjMvZI@Y8QQS?0loR5lxaZoO`t53%D61!kkIuz z>}VQ21_`v|9&EsP9y>VCK5EmlNHPTlQ_d0M5XTC+9h6m-^TdZM4>6Y4?=V?V0cz}Y z1>|PMalkN6mze`J;?7_?vv0N{9cc#cKjz~K&j9T>-eWlUuyeFOO6=Fr{~r z{wM-;zMGF3{`DYK{ec#I?r4FIvi@k9GWU^#nO_^k=Wkj?=Vy7~@i;i8ea;*%y|sx* z_K&@+Jp}yz=I~E)gKhr=4ulY;JKfSxr0(39p02O znJTL*CtQcx84y-S@OX_9noc7uScGS#iUi)}y9^@tPthfCWE04D>BdTg^5qQ6iIi5R zG{0Yiym%v3c=vMuE0><1UJn^=jy{0+;luX*me-XJEnZhXc){5fFRph(V6D-wx9g-$ z+c!LDdP-715$q&Lvg?qcAh}ILHbc-Nxcx(g>x6eHGX>85WmYGw^^HYFJ#XK0 zH~fr+{9U|5YeeVryLfdO;HKgyn_KvPje_MTw)f9D+dq)Jf8bzWWn!mXJV*d6@4xq& z3@b+dWs-KlZOpgt7;qPI{I#Pn0CoWY2n&0-Dwz6%zvT-2e^0iNRqtj^TxGG}A-4kr zxzzxYASIj^`|#K9$C|%;@YxBA{q6}BL-$yGY0|Lb5Y88*@GBp0$gdmttToqPmHMpD zjk6oMYk}35$-AaxKBz#VReT2zXftYP{}GV~fVvJyDIqJd@ow0Hl~t&FZo-PEy`314 zSedEIb}`{eN9#>OxxCcA&|?h#W`?WN!nMrD4Z#VOL_DIxqa3WCE&ecRKz|zH9CzBy zEeh+mywR-MEWLnT*s-?YRWrb4KhTl_AlqL9$aWdG#tZ=2e(i=X^}m~i%=JxlS$6}R zTnI%X*7*Oh_ZDDrCEFTk;{=ibA-H>x27(jZ69^8CG)|D<5-eDN;2tzcaChm(EjR=S z?k>Rt1lQMO=A6l#$vJ24x%YnWefJHu>0NtO?W$F>YwfC9`(Lgc70wqkFq0%}O)iFZ zQ6_M!v;r@mVVgZL!AQ(WWU_?Xkd6shbaOrwXkvl^>QzSq`Cw)3Tb@07`i05w$QeU5 zZEd_8WK97_$9Ixc^4N`0GAXH(;`f? z56k=|7z>OmBTj@XfBSz*@g=ZzrSX?oD{w7|{TQhKt+P8MV z1#-dyuAbeY_(BUTS?Q+8p{MW|zg^*9!!YFPzFy`}#67f%+!w$CD;#4Ol2>%OVh`ec zkX(6|OLVYcl9$fNQ7M8cN}1TToR-}gCGS<~Jr}@qFo=`U_6%yF@!`?4L~QGS;3o1r zI^oGJa%0!Qprcfp_lT7?p943`HPZWPuzR^=1bn6wVO#ut zxIhd4(h4q(D6VkTG!xSKeRF|b^R)l}zkALVFI~Q%@&cMgG{cGP`G3#JjAhUh6 zGCb|&ed+yRe25VY*IFV8uWvPy()ATkE1(Lu{kx%(fPg(s?ntVcxxQ`D^Ehv&nPXa6 zY8jz-r<4Q6Y!mM}-qEG}S~3}9Lft^WNdG9-uP`i^L~gb?+E46~B$fI`r}2)FewNYv zA?&j8j`~@r@h66B-DUS3j<%= z-u=>p27?Nn>h32#)*V>Vk;F}2U+M9o8Q3rrWsgHT*#E;5+l~>K|JHDU#}egd=z2h1 zu+`gJEeesmcf zP11O#ye39>q5U032J~KOMWqIZSwbdKX*Hcb^KbsY6aQlm`lZu#%(^sv7sTSvc545>^|SsfbhGpmwOh@Z=tSd< zyRBuJ-PA!zzWLXggEA2i@EPGm4{-=n5TV6H`KJ=Cu!1w8${s?(?^-V<_9Tq+mG9^+ zCi=P`at-=MqLAek!ho7D*4|0TiH^RehGI=MDs)}9eisQs*c8#Pn1<)9ccnOhWy1|b zaeMi)c%RxT9(UBI?`LfQr%lg0Dwp_DPfJ2B7BUZRrxYYUqgyGo3&=LjnAPbi~A%KzHcsfy+On zOYVw|J02UiQ|79SMUx;NCnKJ%5W5v25EZ{kbl&?|?g^+x2KWTh>Cn z!b~dWAum*)nDUuWZbR1%z&AdO^vvRULLcR`UMYm|?)j?6u6Duv1II+)u`hHe!Ido7 zUQk+snCkWluTIG&M#s>ujML;_O>^wd`Ob)PGs8fGzh-}vd?06ZpZ8(qQfS$yBBRI( z&8IG|RA%+Zuuo+bzj`W}b4hTt7f|<;>B{qmFlF(7Vh@zzAu^1wqQH;C=K_~-*RAZZ zK|YAR4*ZTVMowWx>R$?el}3ifjXr-VNuS@nr8zg~%KWGZ^I0Z$LE?D`_<2jOdRh@k zWx3$%J`mK)xi%MuLKbCX^dL!}3U$0(Y0i!+*8CXndr{e%?I@7_@5?=M``}j^cNRxZO&Bu zzLlc8rvch9yw&+2BgGZfZp>$uBAeOf?zCE{LK(6gv=UoFXV1^vW%w89%_)H`WtK8q z8yu>n5>LIKAC$Aa_}~kQ0b=elzT*>s>ZP#5kakl7Cz}Gj-1_@2~>}JGx53RaAIl zR~+yOR8$CIqb`#z@*l~4wv{q_y7P=Aj|xKVm>D(_IrWZD>3@J^ND@}j^77z=$u6ao z_z$qPyL$2EPrXfB+q_}Gv$(W`)ONax8W|Y4N^xDO2~_U}m6SdQVH-&c(G@*yZ3~mR zttoqwT1s(ma^Kkab#Z}9dr4B>2pI|b^0)DgIhuB&-L9(%tos&4;^4ddU}Ibw29}jA z4p7vU->-8_@qdpr8}Q>4>&I!`?`Bp1%>dtjiOvcG-s)X4Vxy0I9`r()^8LfEY>9ty zG3N{U9YpHq9}4i#vABMmFaB;;iQW?3o!#>%^8L=9MD`DPqyIPut^8*JKd?uEs#~fH z+en6euJ|OQE1yP@Ay7p+UG+h3jQGE}puDOpvinmpVF`v)(z7gb!zLI)r>3`^;0ADy z?0b%j8MoujCC9Dgy8-xx!?eHLC1GfSf$4w!{8b14$NK^Ei*Ys?soQCH#uUr2*I)mC z)xlqV;IBULS0DJR5B${!{^|pN^@0CpACMm^-0{2tw8+Dh2EJysfeT6mREdw2f+iov z-2gUV+D12R0Dde0JUl!cJR&k2A{;yt0ume?Jj^Ef14QhHm^hS=k;o}n+1M4RID|#? zkZo`|MaADxiz%W=DA}e)+)M#b;o#xmPysi9%lQ2Pt;MG;RL#|x#LaIn$TDZJ56RRO zyyBUVKfdef!9=eXd50Oz@@-$JB&h<+%KJ0qjgiDQ0bWeuSb?@n{|(?}{G;xXO+uwl z$82#5#lm~I*tX9c44};yxDyJg$fXQw*VLF=& z=;Y#P{kXJxc?A|x4w9exod&_2%Z?($_j$~lXcDyS4Ml|!6M83)R33qq zoet$kB|_??`>Y(|NW&b9v_gaPCyk6;y=o?oBO8)?z z){VPq5OZu{eB0?)OcS=?$IIawWx#PXsmc6AW=o|eKl01VrcnN-VE)_R??+uIe_i

oGeboF3#PkRWkMi-D)vMDQkJkY|nCfv0|0i%QhqAp;kGhIa`sMi`CrGI@G(2;@-G z^lhm!P}oZxiS_#@Vpj$8*gnm2%_;y70>x^gBZv4Jdy4CG58 z2TYx;Uq7jae8N)r?8Q8#C8oJzClF~6mO`|VJ8!x@b`VW;?S-j!v??e_vrEXg>`iF1 zwJ~O4_RWNLjH}E}WC=YfV>gGNizmk0yv@nE#l*GfzSqJE%?j2%5^Cc^nmh4^Bv5R zHFJLMK}MPCDS$Y5s1biYy#YYt;0HAO(>C7jtteHa)7L~wmnmJ3zRg0tpUG49dO8;+ zqlSPvKY@-y24o~w$bkH1vXlaF`rvsD`dBZ|xH*{O^}Ye_8dv=*1V4D&IRH3{w;0*B zg;1eGv#7k<{B=xvPy{8m5qcAS)(*sv_GR76m)u;S&joUHt$w-c2W%>+tVw!w1htM( zm*7Z^*t@nI#B>|k*;75`e0E?DR;n;0HxMZvgwgZ%0^zs+ET=~2~ovj-XVH8PJVtfo@m1$}%lU`n}f>iQ(rASgDe&W_!H zKZk2nlPKODO98?i8yjVA#QZ3_AASS;xIreZ9XBlSsdA28g}uVGQg!}pK0Ov*b=#Nh zFB&j?&Oy!ub3R;0^0M}}pouX2JDn~DyKkkL+a;lSckKFlC<-M&_S$Bl+I$*y_Cf`r zN;~!(oe?8y)!6?kWDoGckKB-wMluvSDWC>6uC9~BSqA+YrHcs(Y_$}gU4JiD`XQahK&wJY(p?xzK1pP1&-oze+`c=7aF?{_hUwIW>v^w;V;=bh@l#G5kJdZRz zZGEI~S$_@&(_07Xp6^-*Dqeh#sQlYKzjy`Vx*G=q$Q_L*`lhUg9TO{Ovv;^()(LA} zkfy$=bHy@EDZeaMi#gi8c4;6O_ zGdO+>=G5o{7?LgWek@CpKyP&lT(7Wg7Z6{;T{^!=uHMuQD;`-}_JG6FQC08<$ASo| z(|RLKF!J-f+MgLlzn-##87ZJ7R~{%s;w{zOpSF53#Z1sx8iH_ex|!!&ew7|U@NDhj zP*yA*S$H~U(hKlPy9zEB^NqsPtSF!#a$W+MPOUr8(iMN$-LO^9K!r zI(WD+PAAV19x3o#DPJ*Q|XP?0arlzs?kRhW(hS84_AjB??vTy8W%jl^e9$x zoolDMUn~SW$m|!L&M$<{-)UdmUB2$6(Qki~(9B{e`bo|Z+9_nRDk`)QYq zrt;z9BTo8*tp_SCr#;!Dv-on1mPO$m*T)?kSn3dhk>l;`a8>4=R>5}z&o+smes%<; z`AM1#E78s;R0llk&{2(5JpNvZss}vJ3)IL-1)4vbC&f~hW+&!z0z=zZ5E~|wgZv+p zxN@Uhb9kgHET_LT0-3-osY+4SNGH26&Df6O(2MdVJ}X$?{aAP$$+_bNnuer)P@f$s z(C1Y{kW-!YpI`EDs}Y0K?h=iZq6y8h;wHjdP*3K(K3Kk{(Ve4S@xUNDu`x2?vK#(# z+cuAzX!q)_+*7We0hP2Oh1;R<`4@$E)5kG0OyHW8y^aN8imkDB^+H!dLT3T~Fqo1n zL8`tpQ=2$Y=MpiWi`r4%idV;?YNrt9^1+VI`-x|o| zn+PTk75$N`P0(T+lFXC-C}SSLf_oU=l3*{k>V}1@%8L@Jb)NQ`=b?>I6wT_dgez2f z?>V>U4Pm?HIj6PrGB~Sai54b82mE)USZSY=JzscZ{QMZ-XJfm0Q}hjf_87@TRMa)# z+yo!<{dJkp7_Dd9F|YsD*Bii+EAizG0R3`j&$I6msAL;TXgVyJz%iH|%JDLzKT*~q zLC~JF+;kXB8xAAL{ymiUaMGmp47E{lpWp@{w$ICN?lSvwpT*aHeu=n4_t9y{L3qHx zZzo;vUMipc2mr?3KoD;)U8^8NO7JE3QpuT%RGUe(o8(VVZWxO*J-qA3 zoL1`nF;Q7BHZ-1q#chZw3qJ@(I#H}DLnJ0ka<>o1YOQ}`6eHjnncXhDV)K<8|I%C` zS0Ij3LwU?*kkN?;v^3*GO>gKmr5nu?z7=zcN?>#&$$3UBSwT(_{{hMdAx_kv+ z9NczGl1IP&Kw4O_yVLB-YYO+GD*6TxJl!MTThoZQ`gY<(t-T_8nX06FT74!=G>P*tWrb|V6&poi@e475ML z36_GvelWanF7}%lkYZGGiFRVkX<`2gr-&TdBbw}gded(_gm==1zL(sj4dwx$xXCEK zhRXhdvjirbJaPmWEA*1E^1-;1cH&X&qzUTpTMYns;lcl7Nq$$X(9TC`LAJrgJ(qSq zO!daL5$1q}{LqP?6-v=`XFIb65tZ8s)BPU0%v*Sg!5;n}`Uf2I!T5b9aVt%{x& z)bJt^vu3Vjvh9&xyR$m2K#g8dtod4B3GiT~==0;12Bip+?R=ZY1|_o=^Qyfs>g$!8 zMKd<@t~Y>+eETO81v$FlB3zzC2?lhA4qFwUlG^&dS$Jsx^o3@ z3_KQg<@%zM5vfLBWDpaq7NcGfGjlX8_ww48&vwAN5^v=rR1S!B! zc7f344fcII`^&HB7scX&9k$(8+%yZ*5E-MwjIdaW>p1y5gVGhCh>DSq>WU?DY3OW&9u1-LrUF;*j6rf&HMLAE;)|$k;>-D$h=u6i)@E8rS<;2_o*0|%F z=F^f=UvGYc?|qm<9JP-^7kYJ6@z%k7i}T*p;&ON99K>8-jvIfBg{m^&?(6GzO*Qve zZJoG43bTVoEz^9NYAd9sqV+u)ILzux};WZITkZ z(Xx}s`hITQ>;>imYjPJ(X|P2UW|@eSfJ+tWz8@xC4;Sy z9)%p@*rY1WLL)~CFkjA;!U2&NXndsA$^5P@uTcq%u;YavdB_qLRnU|j`iz)b#0dyggA zkHPI0&9B#+c^7ch76=x@U~)>n-2mo1#`^BizWDg;<-sY@z2<4;ibx`FTACoJ2wFM8-V&AnS9)bLT%e&mw)E6e5S$1v9e4F8l2FVFNV6a zqGax#+LhOtP`-E`7|BK}-t`{)N3X@*3EAv5ORg}XmO1PWiFL{ zE6O(f2qQ0Gf}CdHvgWlzo(1In)tpF#-q3r_sgH~4~qvCs7mZxTeIeljXZ?u8R{oJ zf53hm47ZD{kLd2D8p6iO+h$g%_%8SBX*rvRbjTMp5fo%jt5jSSr%Mfj`-Er~R8&)F zGsSc0;HD)J6qF2O_J#aUHbvl^l}FVfokhb3eu=`LRE&8*Fz>ZO1oHD108Emqu%4Z{ z1v40-&&~2p=eWN5YL&b*+)(ROC3n2>1L?Cp3mxFVMVd`5sz*O!rdayoq)Kk<9p1~i zS-hBT{m41pB(YER#H2W1?OCl7`u~kEIQcv{KxHzPKh#n2 znt8(_(8cPrgY$_UlY>ZaCD>VA;+0OOZE^V)e)$2Cws717XT8bG9I7LHRS8Zkqr&v8 zr115rTp*zxLoqq>Zq&VmF^OignH(~dfRzHc78$xxES=u)=fi$*K(sMraJz^KiC4iG z5GY7-Rx+2}0)8>JeKcW_$!)p50&Kqb*;h}d@lwwOXVv-S=ChX z3$}v0r11cxrl9__=Sb-zxE_z){ZFGkEnd|}%DO5VK?Uh3`?KD*UrygH$UmsFa1{O! z)qAd9^={Sq*mScZ?jiwv-PEcdLup$G@1L~=a%FYSQaMnveOTh~f%}-!#*|TbCe>n8|}W)wZSVQPg^5mTv?D)k_&PZ z`=;B_k&}M|01vGZ=Bpa2ZdBr=DSq$=p(DvpZ4pSnyT@WBnm=)`#pq2Du&UJ)2BUyT zZ|`L!XDUIg(l@VWGrq05;i}S^2VBw9ijB-yXD!0sCtI|g#Vj+c72vaNRUu;QZOO;R|CEw`+oUj8lj(bv2p5#|He{jFW0T5xLcs%8>>%Apa2JOHX>cK>9 z>2Ah+<9-7eqo6K@Ar=>y3e(Zi;RkW{3&g1l2zG9Y05^Goo8%EsgE#tNZ$%vO?8thb z2z*$L@3#Ev#YuLrg*Nv$wkIVe&m{F1ecqOP$|TSryvEMwdU^YliecJ4feLTmp@bLd zy5Ai21S-X=eA^&?`d zJ~*#36bfF)l3M$h)?JvA649zA4M}`>o0*t4p3QgFCgZCbJGGoy*5((3iSOP`S|cJ3 z!Ew|zG>r7IKEFn}GP!go#S{mmm_AG~Ks^~u1Cj1|3)}z}kyI|$qr?-a2WbO2o~6q^ zF#RVN!l|w=KE01(Gk)Ivo}Ko;>@{hB1R`)Y6H*y^3kLv3ti1k)SYCw7tQ4Fao^NodCNeH+ip=wjdX=KTIpXW{Cj(};6)#la5HHI16b?+ z?*`zdd;S5?(14#cnYUsk=^WH?q};jGH=!A{&apN}W2mzbegm-3=(-;Ehsh%~;JMv8 z4KlB5vy-bskgyS5eAv!2IW~x!KbU7!vmRj0l$2`{bP{}Avb_Agp>CCKD zCFTHA{M_Dp;C>z6yVdG;X*+S_@vu!g*y>^q<($$~3vV98p{ycJl~c`xPR2QZ9dckM zVKx)DQ~@@esek?2sflKIeCQQtS!w>aP1+t7E3vJobfK^BGeBO=>4rVIbS$<{vVeqN zVC^+coA|diRgSMZ5yEYntI zBq=Kxk#RMTlWKL%?$Sd)E(WXbPGfgfdqvkn@-6Vj-qz#R))={NSFFzuB{E=k!#?`} z8?qW43-~iZYtw||rhL#&z$Pp81tS2mDEqv-S>xyuUz&zXx&-d+!2Ml{_m@crt>L=|X+B1DIG zfxUG5YOEc2CL!h7UQi}PEotz$KTVbKvo}9{1u=4dJAvu#d-juS5siib@`X3@uw^Hl z{EqWHkg_)%9iRZgTZD8=wde>0QuYg04L=?H=qiR=+ZYoPXYi#T5v$ZDDmOC|6Ru7z{B441#!PG&Tbo*aa}vP>q*k=z)peZ`!N zo+ElTJMt-&SX1{ifeW2(^~gUH|O(KzCF1& zoS!3S$z0r{`d7A)z(JH8RCUwH=PHVK+GbPb#i^!h4!5Xo?#I?f4eV-y9 zHrn9hlH*W_$%&BDvM9@O-i@_APrEx5x@n6_})YrL3neuml!O*pi#7=%u_L zN3QuUE<0i3gEW=x(BQ``;n_2C^cl2TSEIAEC!8_aJq!hgJ>q5$K0l6(hK3GRt_YM9&PTGC*E_h+)0M`uEKarR3Xv}QY(hI(~dF^(+a4oqdVHFyuR9U!d} z+d?0!wmeDgBts5P<`Re}9(Sb@A<%Js5vOdc22$~p(@`M=iuQVbyU$;Uu+Ke!|KVVx zeL!+U4%c6!>$un+UmAvw(n7PVRPfZisVTFUeGTE!CGkgRkRUVYl zuJQY)i@j6F6INvp-`=ysa^Q5r7-_)dVq8U-R_3XiMA5Q5catfPsS z4J96@5sj`af;G=!fY7#?wx#ErF9$iE-N`oq2B*usd6>T^`Gmn~CU4#@$Gs={D}z&g z-rPZs>u+9{?&L4DPD$_Q>`Y+Zd0Hp8_p=8kPTl@dE+^C}o(qpwG{lTdSJYmwy6~$s z7-6V#92N~PRz&lxcbV!)5k;wkqso_!Vy8o^@GSORP;1ndY;l5!(ABjjtuZ13>wNFG z7`Y{|q;j- zGl<~*sn+WWx>HNd3VNX%fTO3vBj9G6VZ~P*2qKbjO?%3Ss!|&yPhSbNY$`7is)vSv zOO!0yDZF3|zEboPQXOe3c|Lh1`wYbRUiYx?t+0chiKm+fETW4E^B1M;Mk7e7L{*GY zL0)l3kq?U9w)&_cXc8sa7N5Sa22atNp;rwAVrcRAbc2pTp!BX;7T&5o(5w-G;;%Jd zt;Zh}%%!)fc9o|~PxnAaM@D;~kP(6YUE)dmiN)@<88uzxhA9XPA#Nsr`*l2d{<2SGq3)TIO2UcVKExa{m6U{O!rZcp?i`TQ_);D~Ftv7d#2B>StEge`?iU>-MQdg!-GBkaP{be&;+j+`G#K zre-NM1*zGpqbBcL5f6J5MEu)$E^-t--z|Hb!|XQ1U1y+_UZY2yliCP9hwZ#-2i9>A zSu&RgGs*N>oN&hB#AtOpM)bU?h`tbb+UujQ!%3%7yv4XFUF2$3hJm|e?p}S&%cZV3 zH5+WZYYcukI96R6cLb*zY_4YKj=-Eo+QGy#3XiI* ze~Ev+*mxo|S6yEV@5PH}Df~jxYJ#BC$&86M43aw>Y`(kRGj_nF#|R!Nhp1NA;fwC_ z>KlzsoVr)Fo!wUzu&;w^Se zUl*1FRhGjGbAe!B^xcfe7DT+hg|MeUJpl<@<8HetUeFO5K~LU$b6bdsLN046Z049$ zYwMidS^?)3zR-Dc@1&+VwwUHwZc_fYXJ~Pxem)@>))ouiSgUBR!A3^aV}he#%i`xs zW~;o^*q@L!!_}yASsYiQRaeq5o+dTR!rL}U%gJhMcH!9RWDRbWUsxitL5M?F3uh8B zSr`h39(UfeY)O2tIID$R6y&>-x24J}(kB?xs+^lA^ZBU9ie6Ey6{+?kC_P)>ga|Pf zcLXS!b$Sd;kmH1pxfr{yIuj)8ntfu~n^B~Q8A7(=Jm1)~=#m2dEV&p_BL`d^jj8TW z)W}`S>nD4cn=ftWrB~#z0b;9%Fd^8v+#6MRvdM6NcKsyubx^IBi&t4t4Sc6jXg9iP z$!RcbK~3VAtYy&{vDpV+Ps|4y#eYcOjkOV<6kp@e2lI_FVgqpEp_x@poDBf*oF#nt zROG7F{cGC($4{uY_R-ikV87?WFweTla4Wi?H!(f{djkOP4x>8jNowVd6K5gH0clg8 zHK)j92V?b1uCqMkc%}Vv zvpu~Gkf0r>;V7N41j)Js+wpvR`=HeX#}2g*L)|S1SwIp}>H6jSSp)jlWRd3yXn63B zTYL`5wf(auRuxqm(}g=@{~^K8H%5ho&GnCI#i^!y|0Ii8m4~S$f6TWd7ai;8tZ0h_ zfB7Sa>M`)Ubbn;MRO!j5pOAkoqK1M}{7(w14GKbCXZk}xd1}_U4$R3kB;f4JW+ z5m5WKYL+Lc@DB8C<=ql2F?g$GV0ALm#`^5Ljx1RTBu=y_#ZP44T3uJXH`cAC0cEZF*&H=CrcB6Jf*a&3fkA_7w&{ z9#Ip*En+Z4z8ezH2=0PSEXRYkkm*;eClnpBdiZnZCLPit zB%l+ZY%5iDrqEghl#_eQpP+3<=sD~JNjhSDZ0x#9Nmyn$OpJf46lm3@8}muACUHsn zmsQn}vHGNf$15s1i0ZzMF?Ow*&5+TYTFvm&;KJP?IjIGH7rAalqoq0lVMvvFeT>5H ztPRafDwNV!uLm{Gb$o%jqL!Z70K)rl*3fn~lrF~Z9ny)asnp8B6JY=fYiJJP7q@}~ zA-F|P8lS_@VR}T;Ky%C;?WAA}2epbw5$&RSH3jFKIMWGbhx9(CrXvpBb`!eDp=N+R z>Xf2=snM&7Nb}NPW73E$ebCO(mmLe{D4&OEc`)!wfpFBBinQD$lbLWamQP_r-pV3+6 z3X_?67|%+WB9>=me`4t`HwEQoEuSzK!4|dy}$Bi^96LY||+p?pjw4xnnrB$dW&`_qE3z zrg}~NYMh96BJMgn__T1CxuP^pX31jRHs8=^q3j>NZKP1(oHKowg=QwOiGV1HU%$=`jmU zA%B>V8X_luA^_weXu1)!UY9xA;O6=r$S-D1MRndqD1=Lp+Dicp5@B^ zwv$rAx2J8(`?VUh{fz!BipvK~&1IOBz6ck7`zxQ1pWwW>r<0uklpPuGY%Fh9?t~WD z;e|Um;mSCF9obaVc8a@ujpsVP*ps$1tgLQU$tXoxs>*Ze@j-@#baTg8v7?5GDH&2= z>Y&L)96CU?N6Mct)e}@g2rW)6vL>01C?*Tr>AKHL>`F2^)Nn}D+px9Q6r}BwmJy{l zdQSLR(L5(k;p6eR=EAfSiKPO0K`e4cc<07yI4mW+{VKh!;Wey4DWa@*YT?~QlaYBV z({H|n`4uPK)&>o~F-F5L9i-9A)Vo-nFo@*j)uTKyr_=`q9exp|tZS zGFRZ0^*2@h{C1l{0q3Z9joFG}Kdng1Bis^_pVjo^ zGaMrGf7Sv$H8=>yKW!%iI|f|!f6{)Y;9$~!#{S<5)yu2GEBn)wjZQ|o9{;p-FzG67 z_|v|k>;By5r=?@tm5_wOxo~XK{jsYVB_&9+o?Vkz9j<#&fDX5X!sNT$7w#NWkzP|9 z&R=6*&!GTB3CPB|RuM99=NC4K>wsb>eZgI|#G@XoEeK#al|bH}Dm>Rp9T!Xz1z zlh2SI87n+3>PwI!EW@UCukyx}E&5dmO%S;?YofS#Bp z%jc~tw*6rhF~ZE}FH#592^-8(N2)EAAj8HM@HUb$a9HN#Cik>cWo`h5!jM;R{&SvX zKyhUeI1zFg0Df%5f?agkK@v6%^Hvlq}OG4#SjJ>!SXIOob*)O*eR7(f$ zCTL#}Dr%HB)6w>&AcQUIZsJJ4guPZ2YfG0Qy7mig$P<;CTTE!@7ph;7>JmS)(7~E_ zI0wRk{O*uVudxT$WDhY=Y#IDot#JBXJ<4H_Y!z)Y^5PPmt*3M2c5?FG7b%qj1ASf8 zDr+R~f%UYlmJOb!tZi;)#EkcfU$$8>7_^~~aM zS~;I%=ww@SofX#1;H9zRsu;gh*p9o)4xB7< zImkj)13IHt@3J<=T3Z^%cgVWjf+1?`L2abV1iGHdMJV5q%e@lUV)TaA##F8oqCVc1O4K){BXwA|sF+_sJ#H(#uz& zKg5c8HI`yh1^;^f$!X8-%xJxZnO3ect~C`7<~5InRYe&Y|uD-|o{KU|YH|4;(jC0u+VLoeebU#t-}wpgXY9?y{5 z;XCsSDK(~zCRE{0LK4CO65aGRrrOL{^9x^Kl6!Mz60%YbBE0>ZtcFJ6OmBk>q2&-_ z(JVQPv#+P8*j`Tx{)7u&blP-w9|)p%M8m+b5#~jCP|WjUb~kfOJnvp;pb>?#k=aq< zW1ksmA!+A2L?yZH{K8`tH7zPjQ?UwmR*6>HkFY*z?QkJ=Kt^F-Eg@Fs;FSa~xAl1w zhY4+0@(wBb_4VfyA@keuM_F=Hqc|tW`ys9#ifLnumy(DyoGKH&RdHl9h+N*^;|35j ztp&JGqS$SfCLv19MRnm0gP+i4gr>?ujMVHt&LxbAZS(&!reDxaT=^Ol7UK9kVoyr2 z(>)!z^ba-Eoa|AHW|oyEATJqND0(WoGJ;O7lYn{tRz#Eim1kZqCq0N!$fYr zFFF+nAvGblO4)R@>upqrdH@%K*ChW3}biUvVI$6jC3p8S_~^mK)hP5QCp zQFWl8u5E3A@aEB2!m2r;l|{*OtZU_KL5$Osz45=xldF$P@~?)zP7TfPn8Wr#EVY)a zrOtB;v(tM9dsfFK8Gjkp$nl$JUg5Gv!!w%SL+dDbp7~Wd3Ra2SwO1Ku7?JUGBSTp- zQ)8<^AYM(wB67hbZOB>}6LFMuefyjRQ> zi%m^y%E9JbpYLBb&UCd;cHq9{bTvE3x2x!kf^1= z^ZDDx^3F2=)DTffxV~kuP~&NTo3MvRt_G)P&aN%ttNysSjO}By7|O`9q_ptE0!9)D zJ(yuD3QU5osXmkV*hrPOh~VLRm-Zd$K})G~@{LI>CN)q{n#L6EITDpsgA2pMI<&zz z$b@}y#_CXZY(|g*6@}}aINAxy$|r1`(xZ@fGZ4KBhB#1Qm1@%4QdUz(I#yun%EPjF zTtI%MgpmxQN|}bHfPSE9?uH_J&Wkdc(5z><79&|qrfMpBg<&zicfclFrZhMPo0&b>FZuPuI2E%1yQ5i+5*c1R#?69zK@cR>+H_1vXkCTKS00!yKELH%h0R0; zhTsv%3uY;~tiW14_$-{UUYNjs`HPV9)tbT2W17pvUqRu@-ZVt6)1HM|oU+thh|OG; z+=?dI(ZfDRZ97(R(Cg9Bg00UO3VgT*MiL0#y&k}cNlSzBJVBz1Yc)_$dGw}wNLzKy zj0(Kf9LCOZ;*}eekr>B_t9*OacgJ8P4ZS9O=Qw2_wnkR&9zJ;rKDT%_AY0vcX?87Y zi4eIn>hhjZr@j;7XK{GuOXI#hy+lE*FrD^@Q@3_K;8u=mXLGavfydbzg|1AMG38y>1%i*^Sy}g(}{TA`}IsHbr z{IMXWeTS?Ze-8s53YjeS1@AL!Z#rCa3Q;Tt=(57Qm)ZyVaGHvcuByBG(oG}dP|d(U z1%S96-eP_A0Z=co!j%$WXBMYoZ;x(ia)>j_hdOM_3DZrZ@Fc{;34W$ks05@~5HIln zt~kX&A2Tr;Z8=ThSiKQPo1#2BFI{iDw8z2;cKEsS&fn#PrTf4X>6aZhwMoIRt)8A! zp4OG~TerdAUv0XNg-n8`4j2USn4uFwFd^t%b-0Pn(3}~+n>yB#+})Mlt6v9q}H#%#B*l#Xx(* zmHKE`=d&7o3^@+>=o^g>pGT`van%c%#VW_&f(Wq=AY(;iR5bNfZ=b_!5!fRQZ$qbO@+X`d^OZbC&AtS4GeX-rF_sU*@@^eb z9w!!K;lu>4V*d6$%`yCzU!Lh_&C%Sd0U@VG3jQXa{f&WdTeG)*8>;7ZQ#;cL8Do)r zo&@>&7-Wf+GCbYWwLkW+xzL3vp1%9QTP8!4%c<9{)CM;R`_e%K(L2d4ms+W#k17`? zVEwLP0(M@Q+*&gO_jdvo7@qp+o}a1{6Vt|9ieva68p249;5nHB9jC*}*oF}ITiRHohsjnY#aydN#Wk56YUAx&8!yPX2SGyocxe|gg< zCEI)JHNm8PO5Mj{FG@$GTS$hxBL#{$R}9S#{Um{Zvhr{w=RwjB}fPeGn8~mHxkkz zoilWIHz)|w4blw~l0!EFN{5tm2q+Rtseqt>iuX5QerJDspMC!K+-E<}{kvX=)j6}) zdUG*${rbwvp1Sn2p6(OeRL@Ff5?NZm_ad9d{#UJr@5mR(?dHW-zUsCA=HRQ;UQgKb8F!MR~i0{FVZOA^%y&vwY=Cdu< z&$xaQy(PqnxDlOPC&Vda{=RNRsU6AiRX595_ldbgNUfd|CEW(s-V(Y6j1+q zYAF_4OV}33?wEyKqn8G7+)J;eI7Z&Da+JJ`o{(VudhaYGxs+AsZ59d{Y&elqFBEHc zlP0%PjZ&kJmT&zMw9Ov3IKzKetXFL9Oyp(Rt50Gs=QG^!<5u9;_;c1ici?;lEZv=d zI}z!Cx+TEJ0PfXQNY6;D`_LyJela_fbgFd_zxQ}Z!cVgj`c9KLXVfPYFwo^{#3ghz zw%Y#sHj~hiIYBk_9gFB!r<+8xC_779exH+beBKz9Eoogs)0(Z&`2>F3a5HLtJ$jpB zxz7S9f=*NWb`DOqBl^{6^}t>;VGe#p#(c4*ibBTv}zLwIj<`J2!M&M`xYtJ+mtQ{Xk4-WZl0mY*~ThfK;%QvA8IF z*V@_P?c1Ek_03IQAIDxSe2*g3XQF}zy!)dQwdrOKe~GYA{WTZ{59!|Ci{ z_{-o{6=qTA{%rrxE(w5J4O9P|40F!jg+Hdsob&WAo#DY&PW_`L9%O9nKL$`!)AiZ- z%GnEF&7(QQN$|zNkLLi5&f-o&oc|mB#m*I#$2`?aJ5xf3V?R9w%9Bn>9$AIU3|lwk zTYqI)Hw_m$>{?C> zJRW{9i>YNOlCx1%x{F-g+k-Z6KMGDVd7MTcCKBo~K#tT+L84bt2xIjruIVrUs5j3J zuO_lX@X3IyvTuw_VXzeuLpMIO_ehJf6F3L|u22v|lc z{9r4`K1J8%$)a*~%WXJX=+dnFK;iLs)U+WCZ(}Zk+8hxI&8A6l(kn^4y*1N;(8SCCwR?;-Rw%a8u&mRooxF{ zoz2#!LfvBqEUWV;xLzNt;oi|fWlH=;8gRnj9=*?e&Fsc{X&iza zI$W&bptqt15X&ienVb za#7p%(7-GXT zC8qOd{sxK*K4Z8+y4vqGH}?Ew(OB62jic||>YT=XB#ipsbrpXckX^xP1mjF zPG|ZBMX}!9gR-}k!T2XtZQ{wndw=O%{Kua!tMjY z%pRYamc!klSeYoPWlJC6XW}Wu?L6?ZoXu}J6H4S-XC$=1|JYs^mW%WCjDgAA(n%LQ z^hjoaT7H;*mb1)*Ul8~yKk;X;k0O9h2r`l!^_42voAtgYbs z`s7~buAXauwJV^K1e~2GHfYN0ZJe}(mYR}&uRe;|zv{?)7I{{9#^q0a1K*L^4WP)n zeR$*z&|!^ka|oy943BNR0V3*t4|oHF+n*_aW(BCZzm?ltNJ{#Hr1>ZP^50L27~%SF zlV%-0G|g1gf0AM&bS!?S+yZ_X)1yCz5V7}F_Zd)&HDeJ5;S!nzxM7#a z)$Pt{*wH}4`g`kgG%fjdbj*{G1h2+T=JKJ#9im1S!Ac@`0ft(`i=B^g>!S7!81#kO zdc5=b>gMc)acJK_{s0#ZaScZ3*$&w(EAmZe?nwsqB0a}70Z_nXWVjA=S(!GVLi{Q4 zh5rU(sZnPcewg&gnmICDtM?rF-mt>twi_-_s^ussKBv2ud{Lt4+08Zo*g|_v?@b@> zY(C=D@2`P0xupaZ%}=Ayflsr+MHmK|5*C>Dl9cLtm=jqKzbc!SDb(sE^L*7!$xd?H zKF*;-L(;2zhlM&&n0RM6Mcm#i=Vp-wG@_{{(r9SRq2jt025)70rMWUtV<}BX`MO3r z37B!ZzX&8CBY8>L)bYAeCDF{6;lCk#&i_gHROW+dRcW)ga^aotK`CQnjhGQcIt5jE zkhQo#snDPJ#E={)O*4~}N;rd2DeV#|Zq0tFXvbmx~+ohioePY$P`)Kg%GyHOo zY5~*?OT~Q8^9f`kh&y(pXJu(xSu(jB9f_#+tM8Kk*OAH~H`c|t2irXeBHXX*^z{LX zd{G8>H{3OX0}9Nd2;>ciP;eRsbe>fp^{TyqL7)L@ux{oiD|ImG4uKT}naodVA~7CR z7WepR?Vv+iMW@_dT3FyAK=j11lhg@0)yji|Y9DCnQ0r{IgINyshGG~OLv*gCa8D}V zG00Y}N)O5I%F(=nvZOPwSge1N_QjWMpGTAL?|>5};erPct2*T}RV|sg9jkuDs144y zWlgi;2Q#e&+G~bNLV(TPM&u3UVabra#v;Z#}uq~HC|JQG=4e@kU-c-@3Ib(BLg@dpqyA@8Y@6D{6!>{bUy*YTPlvo zN^{hO3OuEM3!*)|px0mmn$W2V(F=KR?dVEP%kf#N??WB^z_WRkup_doLr{jHnUD$s z^cH|<^8j;f;|Ri3_QGKZKDH4$qm_p@Z&ecx5}1kD^LHk4gr@5zNC_v+NJ|UW7d!f) zkK=AVymN7ryyPfrDcw?UWworXxvc}X_KT{e2Pd~(Qon}gfbrzb#w|bz(!|D|&>4Q! z^(^m`DEm4XlMKSl$v$d=G(G#4-z93d6C3~hZZS9QE7eySY?Cs6tLl`c5{1paEi_J* z{0f#i<7G*^qEK|WhJae{Wq{nUs)EF2IBF>OPRO$kr84TiPhdoH&M<%jL<*pGzMtB@ zdMTnimES`@sUdReEc$thxc8^;b7Q6%Az*jIVU_%rEsP0fsf{xr)O zOmscj{0hF}SJ{nrytb3%T31_lER`A+Jm(bV>(HQJbgNP_LZ&j6PJhw!+awO<2WJZ0 z*DwA220{^Z2hnRZiZ=_nIwp&&%I!_47jN2qs!@^2nzw|Y`oj;0@W}C_-kNQ0m>|e; z53oTJ1}eFjWw!iQy{gB*$!#k2=7y6!OazLIUX8?#X<%2QF?J&n>~3y427 zw5nU5?AJ-vdaC1qESCxm#VQ2kB=#Nb+=9lIB*j%kB3-xjH96QC*~L|IYi` z;eFHz)+j4DV1_-8qRxz(V8QR0i#}sx(z+>a~4zT%l`w+NmF5k}> zjaqGhRL`ZP^DIvUzcWX$%+{WMbqAh`tl@^n5(n!Eti@=}5+k@PW>&+bZn-KVCFg83 zYBx|*GaVp8jF(?mBG4E3yd6}9EPjoURx*F6POz#mcN&6B+BCgZxTB`V)PQH%n0ka- zifUpnSv2(tl2A(z-!uqx?HTVS}Fs*P$i&e{uUh3hcnO&H6z1ijv94Bgb$1;2;Cy)(5 z8G4uHVyf*zy%ro~rPZgmxg>(4zVa4)M-$N(jg?IkvIh(uwX15t&%5)-xkHhdCu~X8 z%Yak;AYi3|B`S)AMJL}N0bUxsbo@MKB#BjSD6C>0pO8j3pkfF-AD4%ak9pN!*ZPwE zqpLxpO(TmHXS^|2WvNgy(SFyGaGG0xL13U|2V~c=k#~j>Ao50%pvpin`z+J+67aRz ztLB($D%?{UyS}#T3uSAOvtVK7W13a5Yu(3sZ1HHAU5GthwSeYmGwO5wR9o+u(){B+ z()7HBx<28JfZ}KM3)S#kxN<*qr;T z2dvFRrxoB})&C333I41#Mn(FMF?9bWJQ|~Muil)W=NBLe{uTfdL}~K79Ve~l!p z$Uge7o-P^vy5Gz5b4B+4(PTg4*1t%{873^-_;V1J34*{ zA`Bp6Hq_Q83hvQ1S8Ap5qB7Mv7kC=Tr$nn3Ppyj_SS`=DHVvbp=L?ZsjoVJ)s2b2k zkm0pPX7d;~mGWa#<0ZUW`>=N10SP{`wi+;JjV|JcqHS)6yuyOd1H6NdiDux#qELtat22S>_r0#qOR|pC1^KGMCJ**NCG_Q$yMf zW1;4@*YfBuUG3zIHgxczS`3&8im_zIf(S!uNc?wg@|9Hujwg3(q;x#XCo4_ik5jT+ zuVYLVKGsSp0*=ZCM;Azwl{grUIlPEerCgDGD)x>2XUE54D^rngt&bJo zedm#=$%C#NaXZMf%BOw<*&B3xw%g#xd`YiY7lID8Qm!y0525$~a8CieabK*d0N5$o}@)QW7EmXiw5JG&#!Ub1kiCux8g23*Ft8{(&Hbk6a_o0^~DMIF(-XU`+`TA|YX z=y{w&Z0(*}sFW9CmnrGNaClTXjZWpsRVjK0#y-EK^|gEJ+0`!&GEY;H@N{Rm`?}# zQ_X4L_4Z8U`3gm}wRnnN;DYvj{YJVjDJ$G25)|b8Oj)}(^ufG+U3aRu|4dMfdL_az zAa!;`9HWY`Tts>ew@tegDL_7)6i*xJ==uh}b+t=Z`RO&%c_^WW11gD`^HEd)%VoXf zE42C7@f|7~p?WjZ+-ao=0aB!m5fufG!a?T5tUb53P(wrqJB!_g@6um?>O5yai;A&Y zSJ&WSWfK(V}&#GI&*QH-?EY!-@{^j&G>w6YqMRY z^Tq9&SlqhQ-6$8eW$NwrUKjSPpfSK~{f>$}FmEXdvGDP$`mFG$b#PDwRQ8i`gFp3( zdvK`sl_~=sb8rlEIdh9fEljH>*m!$(JUjPdc~cuatZks&oQ?*0vUGOv^W`mgUfy-X zP&u4tIFPF7W{IStaGII21AKwS8}iQKk%ApUoM#>Cmk>D}m}2OJ%emTbs&lyw!0yIM zcg)+3%^LuDM4Qhn1YxJ~>5nMzy1RFDFh8~QSLRB{t$TO7 zY5W0+#0=Zi4DYo64&*3WYb^YpvwkJ=XD}5}&;KFV^wn}tvHf#kV=P`^Qn5-NWy;j# zEw)vf%qZefxCkO^G7Xk-{n3jUeS$ygBW{u&R%-YKlKM23#d^O3lXJzdWFV`!KEvTe)GYWz-s{^DCObu9+f%JH@*dXMbkfJTKx)#I;mQL*V5L$HWFY4&*v z)>Z`hixz#ISseZ3#ur~=0Qu`xyULhBr(cJZqbXGEskEIj!vnX5j+Olp?6Rf1kcfUY z057J!%cAbB>&P3$uWJZn(_a`YgR;USP zO;*e8l$xf3Rp8{hZ4CqGZXb@0+$s_$Cw&%tA#l#hk&S&n)|udT#Ug9HlYqzd!A^ph z>n1-RzJ{4~uK?Hq1+I)urfy^13ihu~d5W@iYsPWD zd{-%N*MZ>&L)m(%4*t;Ws5Bu+8W52_w$!~{bHKW#@%D?)`N2iNEHTAFqQ+-&*xeXX zP+XP+US`bi3-Zx|$80gR;l~r2*`m;oI)Alf_=q-`!x^f@oLAe`fM3Bbgke_o4&*f& zg<>;TM=HzS3wu6ZV>7me53^^71vYZIp<+)+7D9Z;xVe+kG{bUi$Cd}X|nyTZ}3*LHMM^bKHVaMI1+ zUG-~x0EzQltU))O-!LIIP|B>qxulM9JMF}d=OrVp;sIDHl8=&E(_+hE_G~dItM)(?iQP;JJ=oHKs5Mr z8YN0X3BhSYRYY2_nU9zuv=#l5LBo$jW8qC0LyFX)#0%|pH80fzUM9|R%hzI|f!Nhp z@Plq0sGc81xIH?F)~OA8I@bw`r~Zi>*XsN(TFCU61zC)tSy1G;eT9B9a30yTW>xVg ztjum8qprUaXYET*Jg4u)Mi^oS5HnZQKv*ix#UZFvO_#vP00BCARvEtU-lP*Cfh59L z@MHB7(uclMOJK-$3x&z3SM?HEvASP~!XFfH^Q1rNB~lK+&oX}n(5Lq*XY}bG*+7}9 z6Y{7Qy=yA$4~B+c;JS?HM)I}DKGn}~c%gf5xb%WZ9Y(turOB0igvA^XB_8+o1Dw09 zMm0|m&_U3~zBNHuJl}|x-ornDAP}A(KN&l$o8yj6I>6F7;fN^q0xV*unnn9ZfC3-2 zi2K}s1h_W!9z8So=g{nwWpQ6rX@J5!j%y%&ZN&Apz=vzz_itWA1h{SpZZZ5Zn7>xq zzewZrrs@~G`b+pt75huwod=J8L9j!{uK7gQ**10BQF7 zv8B$)g&@_4>WNyw!-CMJ8Lk^?3lCjgCPDvz-${vddfNc>Jk=X{DTkL-VxsL<7rh^EB-V=k$7K40i&;A!UOK zaN6SH%}zqcGLXaTW)T?oC;GuqNw8W$t@*H&k32s`5OH~1;I;5ZEwI{#LO@D=v}=(Q zMbD(XRD2Ug?o6WuwMyqqRjw>+>R0b8UbH83UwkR|Y`%fAe6v-TL=QfH-+`FR?2R5q z=Ty(b+!su>8oA6vEBJKWhsbDd!h7_s=%duqT{Ab}kbckw181H&(bn*~CO&8Nb#qHC zE8wjE1`1XXtFMB!vgECSm>a&6fRaB;SL=-tXW87kS-n-4T!Yh2wDdLq-901K9fHLC zWaN?80ac>Oljq#w8~*lC?YSt7cJ%yfDYQ%9K#H-iU~8BqR8JB+DGFXtA~<9>DEHQ7 z&1q6st20vi^fsY!Uqesm*2?g|7q@B9G+G~$~iEycRflxdH^v+NTm`+rwe5kg`kOx&S zRQ<^F$|4z`C1CRf5DAY9#tx!BwxP?|2=X?0phItfq`xa9>k+d>GRaeDEjN~sL;Evm zQW|uDe+F+_`?w%ENw5-An452=rC`(hrpin&-qnxkZ%D=>NF2(OHS4`N7KY87LaqF+ z*Jw!y5JP9oKl@gNMx?}o2$Xn$+sXCVbAs$^y(831FupCYKY1kGdf&OMSqgkU`*RtZ zeJ3a>>EakTbm$qOGt(Zl7^#n+HPgSX7U}r9PtDT#p%q(2b$i{x8pZiCu#}mAq^AU? zPGeq)2#)wW=h!p9>k^@QjZpJb#70%-2{+93RH7097;xW@fQ5vDbxyj^J-fc56#0)( zZU*2$g1a7;JN3rrB@MPL+lw8roLml1_x?|So!BPED$~~#{{(zC+B_ENTTXbKZZ5|0 zuZ`@#Uh;0Ha2&{T{q6~DImkYoBSwtpVnYp2zq4rO^LwRhjtQI}aDTzx+n-^?p$H@p zIal3!{=xHh@BpBBK=-rPxIu@ zK_bqjHOI)E-`60viR#7A45n|Y$oG6jNj^U}!qPOk<|D($92arGiKbxN!ai_<`XxN7 z%*^$pI9&iH`B6-fJbLd#RGbyHP>p+@prqV1sj3&OQ7qVE2+5`UNIA0q+6DCwUYrd5 zQ2^NkU49vUzqJ-087AlcRA$ET&LGKIRl!gbBp?FsLhnLUOUqgvzwxm>m|@r+&!q)H z+PGlMTS}Gl2&b)<6X@Im5hQ+B!aP@@NnzH$rTz#btfAIcc~@Pm&|yoF=$2&!_-fgN zx;=sEFu^N;F7~0|z275aIobxy)m- z{YjDNkW_ng0vsrD*CH2S!pwQAvv6@EHv4R^nO)K=^x{eAM0x7f>9AI!0ZvU-M*E~QVfktFGCpO2JLv6MCI`|Dp6V-!ds#Pdq#GS^( zn*H(D9Hfnuva8TuVjC%Q+ zprI>(mdcOjek%t=@gjQgXB47S{@r()*ZiqgRL?!|+ z{WG*KFIMf9B|ebq_0?O)jF1T$7(U5Z(RR*K|?x0qjwta5+?!q4Ybv|ERqM zP25XK--r3VT-V;|4K|`sg`n><@~ggI6#z3r@Q=p@ea5~vBrr3sQxe+_Z8`mN{t`59 zkB#W8FIT{jkcb1UBl6f$BBO${#`xZ2o|fX%Up% zx0)lD)Pv*DY#9jvU(BaF8$6XXO!Sk!EIiZ*O5yT!kLW!!zlRwq+o=% zfeW|q+^Y|x_b6}vxBl$8wX7rm!(LKvsQ<%wM$f+)}}Dy_BXRt3M@t|@bZnyb|hf60*>hW_o%AAfg+R4aVNS@%qr_z1;rp#cgNd=A6Z`w;TM8vF8(T=|^7D>tecLK>2eB z2GT%+JQs5WWI6j6@Tiq!NWO60GKfH-2x!k=UOYbOz1 zH8>Q;>LR2HK6P2AYzVfen>bzYCsEVj#y*5E;#hHvMQAJ4LA^YW{ z-VKlk+1wr%BBUc%>f#I%8CA}6z9b1R+@5S;mqW$7*P5PEA4V0#P;v%B+~l*FxSmkk z(5Z5@ddE(UI6W};_&`=dnfS4c@#n+0=P%p>&)w#EeZRnTv8xvpbr-f17)IMtwID@c zRr0c2QDBm;aZM&VZ9QThX|M@|;Cc^yWqRc$F@Jz07Ml)lWbwi|yrgtrP6iBcT-R#v z2}1yR1Z2HlZ#S#mM#j@#Oqi~d`EK4FH-F;=_0+5JXk+LRNRL2#bXg9Xwj3$?5NYO(jm;xFn0=5{kLQNk|q?HA%W40sBWJf^9=(>`omt>$}=+!#g-% zJ|hGhdHqM9I1%kQw|tkcPp4s<2G5?}ZWJ#mPttFcuHVtuVpG`TwC6I?(D+IkmW;3-4jo|)=mj7{qyG(r zFDR6F(qgN|e6Ml39}uB=6&snE{y>-W8%U#Hru|AVjluSkr%AAp2(vZ7L+pmfh6HM> z&m<1npxBdss_Qu_QohYTtbawF`v9lPQd?{SxrN`Bby%aX1R+HcAv9psGzwLilB$Om z3_EcQ&@H$D45y(1P{si9S{B3A<-oPXWlKQ%dhlgOoFEcO|7>DRs3FTc);`pu9Dr{7 z=C&|1^YscmT7<;R!Nhj!9NpNBk8c2NiiX_GJHDDPs#otp{B2V2H3MS1s8go(nTB=h za8+yGjy4g8d^x)?h8Z7oU43L~KCn6#REO8PER5Ptfq6uoWZN{TN$V0#qj(ZI+}9G& zO~jlowT)ubYB%GMQIX

Kv+&Q)A)}m1d=9k`B8b8KoggL1pV!GR=oqu zT!b1g8W2$mH>JzP1vJBh>Zu2vlq)zjQ|#DL4p?1~?ivmAwjNC6i zT1$}-2rL?3najRx2@S$F4<&Q#jUFnq%Q6_Um!AUWObWkD^{nQ81(uDtQ)lOzrH*)^ z=#^qStN#e#&Q?~M9{r~d*OM>^+t|G(2QvR48>QAFyI5$Z>>x9h@L9* zqK<(E=36ZqezkyPE{O^QVt`1wj!K~HHOg(kFJuk+I5YPA(W17n-5W=Px8*sF?oCx* zGks<1VXYZunduUl8F5E^oJ@lK#dc=FN0~reMp=6A^a#+$&JqTo3X=%JTn95dE3s*y z!Q)R{Ew<_p?(B>5xSxsI4@K`sFYY_X>Xo4SI`s=s*barSrJ@9N5I+tRKVA-5rHq}w zg8Sg+F=KC5%JBI1`TU!77JkN$^HZAcM<=+DC%%NnI3IHtNCk_@BbrA*x~#|%k0$Z8 zpHnqLQr2%(%$-e4crkUIJiE|1m%`6>rkcSY%QR+ZQIAU+jeDmMCe`j&<)>`Ids1%- zog+g(v5Q~Wz(v&GAd~Ym!lWhU&|SNnSj}3v7vEU_qxm^u(l_P?yY@M;?zL4vq7ZLb z_A#0z)ymHo?rL~30gqY+sdQPJ)z|3Gv+hE?kpGLL@j|%Y;|XeVLUtKVg;D;-LBa!i zRl4$5xbVJkq}{B(fQ*~fKOyU8H3A4;W!Lx_8G0P-l%yHoY(3eSd&d66+jGxXXls6f z^3_Lf&fH`71hKt0G?c*ylBKG&8}HjyLk_|LgFlDwsnauzJKt4uHv1wka>^JV9t|#V z?6E9!>aP$bV{{xlod7&Aj+8G#y)wG<3&LcK<`!Z&4f9nF$9ETO%-XRa<5Ird-CYm& za?&&A7jTh#&a*h7RTQG^&0!#mVfIrh+@m-`AM)i3+eiwvQP!`mqd*HMsIBwjSLuKH zy~J;ph#Ew|dzTBR{^Zx+LSUe9)Xs?#Sl2vKNI0D?XCv#1zOO`>x4 z4J$ft$FLc~?mP$CtFa9?0SH^v@J5L>&|68NguQM&j5}J_fVTJJPMyAi zA}US&_bAz2#kO!G_K6!kzu>Nt3qzj!Z)F`Hg3EKif#ep4p*)e_Kr(JNk6CYgL0P@O z4w&;i@bZsaB#cX>_e^heEY7^ zjh>vNXK5|9y1p%04)*In+ShX<^ybiKLA;U6xX^2}tl&!YKNrKvet$lJ*I_M7Me zIniT%-*fC5;f6J<)oXXvl6*j<(RgtP6a7fP^YV)Ir)v-}jY{9E6+wcU^ESOW$X>mJ z2HYck4odYEso>kVbEOFx7p?vfDD18OjKzDy`DW#tl=g$>2U;J7Uf_l{e|{JaL#Odo z=$wW7g9kQrB~G>XNhz1yt^?YcH=s{epAQb+fQpPpTvFBODBRXQ%#l7FtGsi`lVyxi zuWYuOB*#ZSY&*O|>(MNn%pOEAQ%w@IecyGi7>k9|P+frBu0DcQQZ8sauBNrXRj9Gc z(^`NCs)DXp%3ehVM@L;$`}C&@=uchH|AFVzzoeSs!kFP=^4e8y(8(W11SPkFMP03;%%+USyhHe~ogzl{;Tl~5}E{A%{41)8F-46A%C*9)N_x(JB@YCxd zVtoL1f|qBa`=UgU`G})lMERXVMJcMT@uai%B$>Tw@MCEtEZ{;@Ss8Y@E)ibO+h5m2 zOf#(>K#?bpW9j&=N$Vj z=kq3&jisGz@`4;@+-oN#7gr-NL0y3tRAne~L0y=c(NcQ1G$#d!;<%bDNKT*gn+wXn zP)G?{wu?a?QBiDr!msU#ids9hZ)GLOS&xUL@1P!t-jaMT`2;hpUl*3n1!5YU;8sEh z0hf!uWX`S`Q@X%QNM^hSuPwf_h~f*95})KcY755j6H|+Sq|3e2@qS~%O$jwXoa&mS zyddY@+^c!Rm}F-b_BRA`{}tE%naK=6f75A!ky#rLwHkj+Uq!)AB=hM(hcI#8-_9q%m-7oz4mzRFdy{8nj=itGKa@-*U z&gS+^T|``BvbA$B;m0F8=^We%nepfSWJbkGNZ3Lrkgu>jRsPv=bB^g>0aN4Bi!pT$ z;#G-EU-~#}5B7WgbBr|{)4xV+-3R8(vX!2UEW)=fdmIa6I^B}qWZ>Z~z_d3_m?{wn zYnAAljNF^4Fy6WtK+U$u;i;89$-ShXbEY%=_WLAK-)d2c88zpa{56>*_rlPA&T#0x z@DqKvTOh8+Za%1)mIglD zg1=)SW{6Rd2-jI5w4|a)`UdLC-QRQW{o5xskpw9&#DVt#V}yhak4M6~%4@Pn?`&%) z@|RJ#if>C+9GN_iE0w;Gxc9Bf51&nahDV}+qB(zOJ+o2^;G$hv+Zd5e)v{(}=#zii zC!?SvBL17nsKM}}zIo%F{A>Hud~m9U2e(uVTIajjyIVcC0?ltWI-pyf3vURBlV|Ur zJ$6T^!F9}y;dx>`;9?kV|G_T>OrC5^9Z-PRN;BxNE+>DkWfbw?M29@rS)a_Lds?leG8j{KwDls*y0cA`C^;Poj>--+ue@8c5KCuxzue@4#hi|t zzxMS`mnA!-q+-7dtOrO5eYa-EQ^TPpNV4E?En5#tA3lx#nV8d68e z?g9>e#VmW`A)}>GSPhwHDl(HJ0=FGg)flDfA}u^uuzX|wIES-!4f=ys37E+`*gC;Q zW5%7UNblW-#YmVr#4m+YRW?>PYqY=iWFd)mw0}EOEf_QuK!e3%>{RJJa)TC|qE2~x z%(SWL(@q6s_KHMPotsbN8_tB>W0o^f^le6E>woD?Dt!UlEEs}_7io!&x;do;P|>W7 z&2;apVADsC;F=H<1L}a+zcL-9Xt;@k*1;NXz$*59Hx`#p6L}U9h5Y#r$LH@x#OM$Y z+Oi0JzPi4i>hTW|M{Nf+Tk%;squs;3< zB5GO}F!ii(AswE2S?<-QvN|XTQ4r^&&b*wLiQ$1JVN!O&9QN_hnm{6E6xEU#5q%CB zN~<=U*yFP534hE3Ug_X@dTA6m7!SvK5jNhSR{a*J3NBjz$BZGzWPGnFGlEyN50rU% zAHug)?P~FkHK#A$*i`J+-6=Ax-Hi1$pwBEXdT1-1TuFDJE1w`LXceDKHW`9!7=rNN z+%VYVy1>Rj6lB>T?igj%@e7cI)4=N-c=1Y4zlRC2Q!vj)@NdmY1X%r^@jTg*nDhG2 zfklDSOUET2q9b;{h;qHalzi(`JTDs3Z0sSIVH2vWE>{a6-NX8vgH%DczQ~+g%hiMS z<}rT3{~;N_T52C=-U$kPakIb;@=F zuf4%bTtAt_B_$er&B8Uy=Io`YMiC7Zb0V1R+=|dsQ@Ri%P9zQq=OPyla-pp%x4rwJ zjuagi0@E33Cem)LQ7Ls`B!oO@QcQqV|LdI8di+KcONhRCDu29#1ABj~=M;n|+P;Q7 z^W1Q&$)cS7qKb@+O7!qLatDkKpfkSY=d4h><vnB<0?Hj?0)?mxtcDt3@-?HFZ!w02=`Y8B0LAPiy3OfszO^dYoC`q zC}-tf%3P4pXLVa(<;VZ}#KY6lG@kr6EbjB{Y@8{CcseOhk{o0Z0GS8IDk3f#<`i|QN3ygK*$!utEvXD_<62* z{`&f|+G@-vW!!er0pJT1G8i=kY?Sdv!SgS|Uslx^1kW#pZ~N?^ZHwg0+?SOe%pjn# zP>TF@8~$JP(&ASPhF|)-SFbPL!!8_5yVo45&wx;nYd9-uKpLol;F?wW9om+sqXpTF z(^@EqX(0N`IC+iIMLb)#q_%?x? zCgJG!VdLS~{s>Y{D~&|%i_0lpDCp%wNWRKvnQC*g#5o$_n|_)o=?NtI>UQ4RrU}(u zAE3SavfmpAdUXlZI~a3o^1MODNo-sPc6TIXi(9mR%rO^fI!5o0c^3_MZ6PU(`?b9D z`~ld@fry8AF5ZHDv-iXMBNpWw=p-^Ey~^xS)N7Xi`{)1XQ-B9hXkwke^@4=)LC8qR zXvnCSP>?`Ks7NSiAS7gbE)+a!^@OVuRGi!zs5Ihgrmm8K`6ey|ngO+mQf_&)JZ3@h z-=2dokdTosivgUo6n7;EKXn-s;r8hc%^11D7dbUX? zIt@=Zdkww#%x7K>NiX^baU|lV${ZjZlbh$c6Ldp31?gfHi`OdB>t=Gj3DLCRJ+mj+ z+Fen{T>f2U_<;3^)fex=Us=Ap^~e>Ixt*-w-`hXt>Be;JQqn;7OXcEwd;*le2t> z-!W&=GRq;BfTAx&xl!0ARDl_{_MNcK$J7b(6kJ=%-4t@wh2 zf%YxS4VEX($Z_<=8rW{-e{HYOwP_a_uPPllm6^0WRb7p>B{Y<7We+!uwyD#*p{bBL z6gKjndO6w%o;&7Ku&Xy2{JuaeD*ss5kjpNNWplVlVy6B{Oe^$;r&%RM(ImOCLsgDU zXOo_^mz==()t`F2lz3#M2O*TWA|x2usS z_40H3lg~m#@EYK^yqs*c+N++n=PHR2`D<-XEEDNfe|hV)2{kXjr!jfGPI0qM`lDFo zTSfp0bWC{bum5h?{|wV1&i?eJmww0baTUh@b^j4FfTlbe@jvPaYP7aNVoUsg`IkT_ z!Hit&v3c2N2}l#4Rj#)aDRjvDcBHh&CNu}em=pJN z#m1(PsMjLA+{(OF=Fd`Wh0@PvQHI0ivwFIlugrTPca|{G)#;Hie9tUp~$cf$qmYwSqDU znh>=gbM_?8e0trWH8t!p*SJ?2L!_d_VLywyhPraeBhRx;k5=xnVY8WsGDWgJTEv?L zoAG5+%<_=UZJR>{KC7~hwEaYQ8IDDY7^+Z~Ui3x=Rw_U3OdYk19xq3#WI@n$kE?6_ zH&D*3rZ4r`gbeXgJ4NYS8MD9Tv^`_(c2rq`hHXwxTjZC%1xvz35p~$psRw9mfqVvb{<>JNyRve2>y?_#4ReYM~F259zA5 zmT1akmQCSQ<6UoI9)E`288V14?$F}XI+$60CB55QIIgZbKO5do^(?%vwZNFY*CPu~ zQN`M!$y*LKr=Gecxv{isvuZG@7A#laW8us&MNwT_2rxWO6}xz2g&a@D>}nMyZEfJ` z+Xb7-%p&UcILrlp+*(!~nsluXN!9K>B-gByPBH%S`aXx0+$Zz)B-tp12%!9;^J&f2 zYy+gspu-?kw{_anC3Bl~Jx5*>ju|w=ti35x90xBog40E_(bSgXSj}bboKpi)qY%N3q<})fic;#m!jHO-*Lr(QK zp7(u1G`1c>jUkB_0#z!FiU9snV??{zOZ)PUFjAEEaD*qRk~+Hi@;(d8*qah1weC^s z?vv}xvfxs}mNi+WMaR#@;dxd3d-}0$I(LlCU;>SF?JoNukz*Nb}TcuS5&Vn zWD-~`@GB?%{=onTzU&K(k`769+scWh7vlj2g?|-QE}pgw2{F9$F;ZiMg~-{kkq(hB z;Qtm0B+IViHz}TQeUHRPrjwgVn8Ev549Gzv#4UtRCH<=^X++(~boc5eq>4za$rbr^ zb!H}xNLK}k(%kFD{e_f^?-lAFTQfX?8u43gRu}11e$Ih@0aw4_fTo`&LEybPySE?N z@($mUH0Id#w1(jtyB#C|j6W}lr`$)3X8<*5A!XIy+7HJk+*2=2%W~?(ZE;N3X4L4! zInBE4F2_R;x*Zl$K@na0>ksA1vuyNoZ&_Z;(PUG~x#|6XrB3v~^E(_B#w>cNWfrB+6n)4n z;W5!pqj9F*H>6Zz)*B+}UJulAtO|4M;Tq(S*78l-lIUb^mf6JV$UIy!Qx|*6yFGAF ztWcYR!K8kfk;qJ5g@I;EQCjE*8@BPM_g`NreYBk3kun^xlpZyeQb|jFaTg|?m}p)R zmLpqkP$VsKHSfrIvzax1b0!kj#M^99cEV`Ld&=J^)jFQ(I;KZkH@CHB>NO?iq)=U! z`M7R2=Sw-Cq+KlGwil^gq34b1I%94-D|KaTV06nvEhW25YIs|1Wq-1|N>y*t zXXpbZ?>=sfac71DZ~55u19Rf1V#moZLUbWA2^PP9FySXaWF-?2(H0D0T<4ql#Yg-= z60osUUjG?!p7iv=T;j~~Mx;!gH1IV|j|(RFLKh{r8%#5f$VZ`sI2nFa zz!l^D!w(!1h~JCimQH)ghC~CKTtmowCV|<*AvSymWlMCWf~_a&4tnt(PodG$B#^q` zyeyizWh2D_$1hPj`I4cSgxA&1|E$Cv%XW;HeIBsK4`j2OR<@Sv)&7?VqE}3HJ9pvIWOfd7L>fL6@ zo!nj=_l#w=og5Vc%e>Sy%1|fWDyJO9%D*=Nv+`GUe-SIH?mNM|ZEX!ZAsS_=4F6DQ zJLNp)TA+RP#LTV@|D@b~*5|d8?4w(+{hk@A7s8(HHo&+i;T77kx`b8B+5k{`qz z%}MIv$`sw2BMj*{+`OfAXkGbO^sQI4pxSK3jQo|@dDzyY?br#sr3p_RsM0KtRg@N_ zV&b7nTFD!>_6?2caSu;&H8}f;b7_a1_9?wV`VLF|3^nv{O10?hx~_i5tiu5;%6!h0 zA@1#+^$C8u!3KrM=MS%1B{Rvga17LhcZ@kvMt3f z%(V_o^W^O^Bxb_yq4|OB^r2Oxf6-~id%g;de2*DbH*)&%(mtKZje^aC#j!eCIU4`* zGqYX2IVN1`=p)-hZAj@Ea}oT8`k94ng0XzfGWkH#_@Z&;OO6cuf`ckHbs)R|$kFAfbhX zBB4o91VNgG7CIsd3J8cuZ{CgV_@3i=?|bj}J^yq6=lN!DrmUG+GkeI)teLfDO)1Ld zVLa8K*KAv?+#2UWjh$pmSMHhCZ!UN_87+#BbTYAmip_eJ5}%3se>@>LDA*+vC(}9g zL=G5y1^bMmoJ(td%js;ZVaO_PlabZVd0!pQ=alC7LDtY_Rs5Xtu#JbqGxzSQ4%Z9i znksfqE;+e)cjs+p!IpSXf$UO=nsY*Czw29ylU0GBf_iT~|1`J8`x-@?C2dchOfA8) z+IU)}Qj_V|i^jZ+mOc_|2`Mb9j8OPLSjrkdbt<5Hz5UU{IG&svPHg?DlkIl5McZ|k zKf9e|tVp?9W&%t~ee)Co(5>{XZ|?TezvSB?Th7Zx^s(|+m!P7#SdEq=s64N`J=DSn zQ>!j-wHftfUm#XlL$sk2wa0oqG{c$Ty3|vor>VtF-7c*)lFTE%YO^?8hdXPu7n4qr zs&|$>I8LWF8JRKRFf?_X)_M zi`4op=9d?|WBdFlV>8P!Pkm=4dZc4^7;^8JobI2qVQZD%gqoaL{-B!b6olKhVFM&o zB9)z#ouC4rX|kli6mf!GQ09_qVV2N_%2eKzXTCebP8?hPVsznRw-)lLj38iuf!t#M z?sE!wKn=84FL&HJYRcjM>T%M+llN^|fOqZ3dnUgjSe#yjr?|tijoqc*Xvj8p#38xf z?S;LK*VM%eXXy;OXD@QtPpSGpW7I7~d$xuSMl9H?=~aF)E- zwxb0Vjl7Fw0$r|)TC`9*1R-JvLK>Ui?2JID_H4-daCW77igL<2M7~9Z!JJ$AbLadYw2nbi=F}_FiDvL5 zoYJAkc|FxP^twhX{nS;xE-g!`}z!E|HjCPZIVv}zv$Fw+Al6mF>t~hw(z#?m|S+F@y zL0k;giHuik>_OOTYNxKFcNo&3pJ^H$Z#v$@jw>x>u32Kkng9Xa@Ev~kEj5X?D0HKw z#o=aKQAy*7r-qhgtjUGD0c*?F=D0}lz^0}7&=L=OkS$EeFjb)1id!IjSu4)_UN5Hw zApl{sLDEftn4Rq+1n5;(uu69ZoK=~L7atVBdl28V#Lh8K`_t-_b}{LABsxSr$#qdo z_VNpVE)uV4wk%XKp4zhw-LPqZRX)Uh^fWd$s+qT&R(a5&*i4v-MWPsI9D;}BM@k3# zMNcM0r+C_0Tw5O#Zw${iVbIUrADLvS9Ii>LU&G>FPVqek&t5n6=DDR4s7?|Op-?{4 zw7EoeYff3@->cWdlDnieliQZ6v>qY4wpLu%jf2{wGHUNI;m}I2gf7GC@X4nN_dA!~A-r~b&8hSw2iULRd zHn6r1ah*t7b4Z!;+RPp3{Qt9|B7kM}f5r3&kxI8E9Ui``2Ns`~ZP*H4Q*YY^20R0; z=((nI_BO_`)p-fpZ%$_4QS8KifDj$du>7E0}4 z%-U-8ZE}ftBBA@3tT{2Hk*al#xj?cr%|6!9a@mFQL~FsSgyQGFw8n*rHOJ}Z4BdUN z93XO(TqZb^0y(7YsqHQJd}_W4q7DsT7KAOe`cf<^EtiGd9>C=)qg>N0-|};LNctk~ zz1KP$ASfp(S2tI-^x%Z8uQ_?%WE&rC{h8+N>DG$7wbo&VVvU3`5VBP+_U-AJ+XZlY zzBvx(MoSDXd0NRIF0` z;uIJfX&>jI`dXA1#lhFXuuMxm?kRuU)#_NTb!6@O@O7Tjs;L@kKnIpm8}BI|)GF7D zdDvv?U>4^_Og~P%T;t*pCIgmIE7_5h0Eyui&C_TFC|a{SV_8}=9+rBG3Km^+uVy=> zARz46i1+5XS(AqIiO-uM>6t^h;xH{7Vj`g$^xx$Xo!2zQB?;uViMapl!S}oWvX~0L zUnB;ytFQl4jk^A!0QO&hg@o?JU+eO7?Z_j){C3geU*~dI{bjW@-&g;fyj8tP@wJc7)rOj#j3KJO6Uw?bYiWcx5O0C1 zZ*~B>30biM1qO`l#{RA9uV(Fnk!^@PK6#r@ygVbLKnVg`7q=dS>*KGj9*s(GE5_L+ z-s&mkL-B-G+fKC@D$qj{A8)^#Z`;c4<{>t5J4mG9cEY-{M<^)kur7iZ2-#8EMYq{u z)!VXtB$_#w7Ip6aRPc7%b(a*|;GB}p%@9DjQ$)#2OC0DLL&svrktSck zUcGb9&K9CdlE|!TU{yw+8L1bmY%Jx;spW7HeHb{q!fGNNR(P>3BGTzWM?*MNvjpU3 zGylS=R8D^*(mo!g&>@wa7_pY|dURrKS3c`(&Ku)I;;xbOD%wcpQmeEgXE5a;4gOnosi<*+!Z( z57CJ?H{q0m>3hZlC7w;ZMV9&KWs?elpoeEu&RVy{3u^!OIn2L6_7rKE&B{S+Rs&1I zBci?qpyA)j#qDT(FJAPA55fxjUM-N%cbp*K?><4?^iQaM;ANEifk1rf?@0fI@qPd5 z&Fdf7%ufX(5*NDCZH)C&*~TnmSiufIBtF~2eSIalk)n`C&hRL z7>d9t*hv~F-oYt}zw=DvXoEA6d@RL_DCwe?0Wr}!a8Zqbz0hS;dUv3*`YArnIRX~hrxMTeTWYvPga9v%DLr? zW|Hwu!J4CtX0(7(o^h`YvpSPWYj0?LUm;$BtWb9(BJ$=aC+D&PNBO*5aY@?hM2-LJ z?8xj6>;=@)`wfKvIXF ziSS{_mh22ts<($EB52&OeafnbE6@Tzda5m;!8j)KCK-eGQ1(*xsNriHtDrUT=wc(N zrXn_I%j&Jv(xI)jF^!%Hq@bB_M@-VJe^Z){$clAykNfXUP3O6y-H~oD zT=!0UWJ_O#1wLc()QEPNNuGK8e&R`KJc)ErqiT%Z=U(#0p&_lE3J*sbeapM%NO zOpN%bi?aopspnr~i@Z!d8dedCshO+_MjL3fU>Iwv^R*F+R>%i}DX!yn)+vi5YFwc@ z8EFx`WPiUOj!;B@^qklcuXim#eCJaA;8$^-_{yb%;cPVVU}OOz_y63P$k6z6OI{i5 zr1={zRv^1gc=1=BG}dpWw0|q9`dguB@b~in8iTYCY*WXJg~oc)QSfGDdP{6 z@4kLkN&FW6=yY~j{>%PgdtBEVJ1+Qc(c7%U=Bxx(cMI>~$Kl4}gL=6~3!?D)%K>G> zkBG_fktkv?imRTC@+g?mEa!_}g4$b<@qBX4li{D{5(-SL-zUCgH5_Hk_T@zt8DAgu zNn1mic&Oo7G1Ls=Xna2Z9IH4 z+k@>*A3XKtYniqgaUqEn*RtIng`?Mu%`te-fqSEIA7m6%Jng)+iyVN1F10b~AWyCW z$1?vk9sVKN+z#kAa3ILaQwI%sp>uq;L-GL}gI0bqZ*slr`BOZ~;mLC8FrHJ>;!GGFJAplTnQZ>mSxxl$+> z9MoL^msUrJM^7~^@lAzMj$KqR025`JhOO-5>=~_aqm1^fB$$y7s#gznHx(yJfSMP? z`AW70?r&1(`?bEh|fqphlS}F*NF48j{&X*>|R?GtCdbp6bOnr0mVN!KoSm zHOXQJSOjDJ-?&S=zeGAnoyfA3*#JdBRJ1lJd<;@neQIFYZby>U3WC)JL{b86ciamR zJ)**tw+Xpesf}75JTAb;sB{$QQ!^<9-EvkWl~V!nNp|6ZK>V7hm_p4O^|0(b%_^VHp2;fnLHvJp(Pa6cx>{d*I zV%kQ@rIMDGP0itv%xvF+eBzCk|Dj?2yWzAb`;O>e@d{?72mPCR{yJ(abCS(Fax)m$ zW}O@)mZ;lmEJpS{Tq`fuQ)bylC&h1Bp&M$0^WjxmE2^7&7>})WUP{}}98I!Us(Ohj z?E(ft^cBzi74KUzVu|MMI9IEs$fdHf&Ox5p2Tvck*H!o!RcUc^)yni%a141?lbtAB zkz;N%u?`B8L|-~M8!T3>P0smZ*HQ8gzbk!D;-D7LxhKI{FFO?KIPKwv+TBo(=z*o8 zQz`X#NG~Qx>XX`3Nklyw%uD?(ucopcSw!*daAg=KNVznU(GpxG=df%s%7w9rnvIMf!E13|ATTaYs6hmvrJ9^ykI4g4&18_~;FYRd1HQ2qAK8iq>e4Mz z>eGFBy8QD>^(+RbBgsHV4S}7fEOLAHL+TV_q1=wO5?L;>KvyLkElQeJ_m{P}=Ldf& zI)CIPcQ9GXGVf;R{fe136X{|T2ct5vup)lUL@-%g)!0E`sT0QT#TSpr)4bUovJs~N ztHMtgJHiiR>hL=Q-}$vbj}og~s81muGk=^*CzetCCOgK@mehQ`lWKsp%O*iRUG=)K z=df~e(${qHnh`ZM=g=aC+R;p>s76bLX*0PLU$%Si(ZDd7>&XvwJOMsOl{kkzx)Dc^ zMj)>gkRBNa1fe(2bnTsKy;-pT;&G_PaVX<{Akod!VT`Av zq%Iyu+H&#%Z~%DxbhP60oovf*%=2BxdAVfvNX|F5I^cl8KENfp{hKNC0MEeuz$=S| zv(PRn9p+ujr@mFSG&Y8)-4?U6n0NccxmT-KjcU*z{L08*YB8)wtZ z;AzR@UX?HRgOjVKk9Fe~lnjybACyF8A?t-*^QoH}`?*dnphDC(JT!pD29nUOHzMiMuZ( zhR<1A89jGVu2m1ISsxVqNx9K;M*9QkVpoqvUBk$&)2(Oe0ZY>Blgx8rSX1VboZ{Cm zG(mimF*p(}dd)m2jsV;fS(m2m`>emQg6}hpm~VNYaGS)Xk%Z6hCCln*(=0Lzf1Fv`~?InQ>U*P-RkVZU55^K3zpqM5y(B%$S z^dR2lC9zsb`Q{Qn&iayu`H{0Ng;bHm9j<(&INnU74`SzMmlW^ioFC`4#E;2%`~Iz8 z%KYZF@8U~;3Nrm0pH1Mxzl;_qeg5f@+58mC|Leza^PSH*@70P|F^)Ulu17)EwKj?g za(QP_DpX)V42P?t0yVZuJ)9^WSR+zL>FzMihtd<%OLNNC92PRI{0Kf@qmLqxfnl0} zbn{}xpstW)EiP?kW>&3su@T3#BUKrwq*%3(_l$p1UmT+tp1Avi^H*%mRXpJ~@nRhh z7|pzRaH<4Zhv=TXY|mUx>g?IiG>h^-h^b1y>t>?f6tR26;6+bGJ@034U6;6|Su8XI zpHc0X{nlhb>TKpJ-oW5&zJ!&|78`%-`g)bGI|7z?6?d7FxY8FblILOR`7`db$ zxg;Pom1Weu!RWz^un72x3THF9?%3Pq?eqYkfMSi(7l#`wAU*lBC|#XAxoWxkbJ)9P zP8=*T$S=W7)^;03;+yAW7oHPS1q8XIo&xa(OeAu@7L&vJc1$c)hufFE2XTwa7v6* zip*B-N(itC&PV91^+i$JkPo<&$+M9ai90SaQavjW<80-1xVJ|$IZ%1sa>}blgtR+F zWO>_yG)#N4y0YwAkW}=I&UB1mkHDyVT7jiG*?OtNb?>^4?qQf&v7}U5wt6lYUzjGFWu8;) zVoZv&&&94mqCX8!dA%4;Dtw^D*LrV;Y-mUU7AF*x>%I3PunRmr<#cURFSc9PmP491 z95P=mOHH*n5VI-$kgZXIoPX%`$`px-XD4mcFmmdv6Qb?JT3eDNjL?lThwz`$9PxPub>v<>9&{zdMGAjp=OP^_`ih*SfPpHirdk3vim6`ic$;y_+@BlWb zWs%rgTRP~NxIU|)MLM7QnMSRE@^#g-C`~{?KGS3`W@fTYt?<6@j%LY5eDbi!om@f6 zYzBE~=z#l(Gg!*e;tBJ(tV3Ds#$Q)MCwg0FmaR2vA~10t)@C#6P}QzLDj9o zTO_>3!@RJXyo*yrPi#XL@1IK-vC8Kaj&P;cO#KQk@xGMLG?oGI(lH1{v$(m1@S)m{ zq+jP0VGquxj@w2&%U)~A%e*;l7i69~S)X!k9g)`ykW>8Kqk6*%W;*LEfJpr@lp{z-SX$14(~`brtEH#HJ|h?*WVUjnQSF@o}PnNM0*1-H<5lO`h# zy5q%i(HT3(v^*_t4EA;jVfbsZ)k)@RY31gU(>t*!;d&l0P#{lawGAhKxqtm6|GL&( z7xO=CA$%7z{3dPqUvXHaB;%r)IR&M(?UK7B30BZ2;a`K+;HfY2j(|8L^cz(M{VPBt z>|0I3!oEpI0=sEH;rJ6JlfyqE`8(Eig}5#B%OxK#vHCaof0+pvBp()Lgyts7X3hA_ z;pQ-@m9fqUo{$1?DG6EYdwp|NLaj#%)}59rHMKbQtQ#W7i@o9@J!4lr)t^b|f?^uF zvR9S6Q6DuZ3+AeEPL&JxC(sf)Qao`HHe2Z|T8-U5~|Tm=v^sZX|lJ3sFJ9E z)n@SIWwgnW@KH7mbhHk$a&`p2VFx0|*A64N4nff!N$uR`HH>MpFXB`XL1NlU4c=yP zBkq%CFq%0cs{Tc4;Pa8lW@sEwVlruny**gRu8RxC>+1wQ5=#oLNFO{BsA_E3WWUM~ z>)q}A>i&*b9h-s(HKN#fF7ZiAndoadKzqr=6b783UO)m-I0||o?qknZIwXL-ym;GK za?a9|3M`Z?s9;iw8_kclkZ*ZehVrU(!Sa}iZ&Do0jhcACVWnrDgjYQ}8f zCk(g3Jz6nBCJ~FeuWOap(G$AM_iqQi-(;t^aGP)XxwkHWlbwQR)rd$fkWMT0$>3bP znb1efF+-x=5O4@%%W*2xXY&M2C2zH(z;Lqo{>9@vNX!Ovs-z4AunjsURNPsQ(u+! z=N{u%pYh)yKam4JrkuaRW-S%z)f>XrBu^dWf7RsA5qpbq;b#yE`HxxuC8F~ed4GUt zQJsG+_g^v}R{pqZgA*&aa5KmBHu?&~hBFg*SJtE$PnAr)e+CvpbqreJbxRN`FIKBEvXkrdpPC!%Y?; zmQ%*ky<6g8Xffl-kd7n8>bZ2X8?Xr)q3EB!gaOeCiZ!*7HhRO8@Q>duE{HiuoJhy4O_2O9b zysDwQA&chXmn3x=TA)QqI(kpE!u>Kl7us7 z6TE$KF`04AN`q?s6K?slZm>XgHgdIaUk3vI@SPrdHo@m4dc|W|`u^+wFOi&D73ysD zR?#B&-+T&G=T_p61u^HniOIylAHIR@JO?fhvx?=9&{{lSV`5ROkun&-HaJe5zs!L- zUd@>W7sE4hR$R##tT_gi13Ne}VI<+#M?+0(#i~B#=88GsK#P@j_-OkjM4wvT^qQ3c zow9V~EEqHpEquASXc5&eW$Zle!4pl5!5hktu8Y5|b{+TN9yKPAuo~N9o{JD}W9yg? z^DLV>Kje15iSPa!=gLn~zTc9`{MhLGwzn7gRR~yEKM(mWN&7d^;FN!i3C8}sW4Mc` zrt_Ob@jqfQkozic{F`@TVO{;k=JJ+|kMSBv1rRa{zOi@z;q8NiEd`}^PwA78$pz-k zahy_95@`x`XYD+rP}Z6~_CB009aJ1aH=OQm6mfBEN?_ZW9n`zI&75PPyd&)Ci~@+N z1vx%hRxjo30hHPijZ)6)bKSwJi7&ZgiqC3h=OC1#GjUV+$c8b1eZp;O>s*m&Q)ht78PuJe9O!%1LY6q6Rn%zzP+hngFatRfS28DWYgFoSR-_D2NcHx-My{DLs;40)0KBE5hey*M#ztgbPvb(1hXLg0UKN~ z43zki{o*L_TbEw6nF03s*31rh8!9H6jc#)-#XLOPRyNeU*hEn(=^sh`uL!67`@9^# z6x``5rFB;}y`3ZgYNI{=#r_clJc)OIWO@?v-AH{ml371YG{ZMTZ};8k?1X9Im?na% zdBrupczzB-}+ugk~pfi zNE{fLkTJ0=xAADt)j5Li2T#IFYbeV<`WWK`r6YJ#qXWim4JK)%Z_NYZ}y{X#V2oA3o7A@NgF zBVkHiflq6&_N(dN7HI!{4*f4sowB0aK2zWGZ!B)$z?}8&s_}N)w`D8+7h={JSYxW} zLcgIs3k1GE;&`(E4Z1V+-7FrvDWT!?-!Q5Od^vdZE%%p0dp`h+nVw14xARB*EN)TS ztSQQEHV?G~ynW=u29)K+lD0UNca8D)DaAR1+nX(o!(J^(mM_gRS0}hczur}W;){ZF zDkjMG+Mf`Z+>{P=qxS1His!1n#`59WC$N08jz<#}e5WFPyh?(%9zaSu6prwBf!kv6 zYSYpaN)yEBSj#~9cImv9CC47HYV5md@|8vN0|pENiBZuu2q{-#u=N8yxIYou;ks{q zm78lhFj7`6ln~nvX_<}pOEYWGQd6`w!lQkW2~NZT4u+G6%+2GTS6W1D~c>(h90 zLfv9TdEZrf`FKfGo0(a}mXRdVAKqLyPBhoMhTMwm4)sgl(!RaKF{>p@TpVt|oNA`p zU`L`F)lmWc|dd@cN=`U96DnGB;g@8jAA^({rPOsV!c3+bHAm6JdQ;x`6 zj8`ppK_4YwttBt`YhS<8^f<&{`}{8)DChRMe-RT1XL1wbhR5#XIVi=dMBnnbWIB1k zb;DMQ-pJEc&9dPfC;gLPN8fXthg(AFf%lFF^tGykSt)ycwcETNztz%od52v~QJxMx zccta>)fW*#<=xx-)P zTxlJ~usfKppC;jmpuV7Q3}j0IOM(7tjBww2;6(2SCc9Kg^ub+;!uz}Kt7cOU@-5b@ zj*yoY%>iVi+4kn-uqJ3XPz%kVI8Xs7OIi(vOcf*o6Fm+9Is|ovGijt+Q(+KV!tT^h ziidVdBkXpmogY-tpG47LX`o*u2@i|fC87TJbklB{*sx!dERwGV{}f{RB6|X0&162R z7al4or5AP+TlV@id0mn3Wby)b@Z)id!H?(tGZ~L+Uw8M{JtfpMzG&GJ&-7bz+(c8X zpqP&&zZnVO7qR^oZyFyfDBvT+1N#=8I&sHi3rKe73k>J>&mKpdBTnnfpB7F7ClC_O zOVGf5Svqh$36YGI3FrF~JRtxqSYQkR%gY*`u5(0$Tue48)G%zOb0&)l^+e9F5QF)N zGXRu`=tZ0aB8l$1ff+fHC%1B(#lxoWd(y<+Q7g!fu2k^+Y$+lgvaCe`$Q!OM8 z>%e{UJcM<`GnvLG2~4(KaMv|W#!WOO2?|t8g4)8xwPEg-T0rbyfE-`ah*eA4v_*<* z8@pR}#IuzC$q?xy0YW4Fc^*1kA*KLfg*494$$rrFX9 zef(<8$lx>0(51@@{!&U`0se}|0C;1RM~#ZruCWez@;B4Quv??Qo9!9CPV~JX2$a`B ztQdTFr%8SDII!2)RQl)1S%A}}81Ft?T^dM`6I)pr0#fHYww6^qK`D z4o}5x?x6;^W*xSp78@$gGQ=8>ERZZvLBj!=D@7qxBSA0-5_31urk#{Rx!hAi& zvo)nv>br^%;snx`p)r4#GF7(MBKx7q^#F0r{F=-}KKb~h((o~}OA zwf~~~MR$Sv8JRDq`M|p;e#7y6t!1vYyD=8^?R?Ms}bjbtw&wQ5} zez^0EWrqDsBWb+`kiGx&{7(z~H?{!R8{h~*5umc~w_TNe`)T&?Kd^uAo_+iG9N4pG zFU`LFj7$fZS$L1L@<|>9)b?FGC-u8N8~-H%<*U*v@IMeBsG7muuR8no?b&k}7}vLw z`%dO|?7MyJ55#4T;76;gsVBY9oEKtN$@_Tn{CTMO)f11d)+=;Q#I)Y+5wlNphZ5N` z_7G022d95r**;Bs{sb2*o&|KKfrGNwU+N^`ZF~|UFj{KtjG_YtYjBgLd_N;_!+b)o z%^yi~I5y!&d--M`X{FX&X1&PsA={v-DnIw^QwIf1h~Sv)J0=_&$Uuu(oO9y5{t4}zonMMdn*xS3mSut@4}%8t^5bGrDgR4ADzI?4~oZ%QV2FOq7f;b7v8eS9@4U5ig=y; zhxP08npV9H%LDM=#%zW2jmCRz;h$+-B=rgDsxsDS2AAL&ByYP&AM#}~{l)!zX#`qm z^~%l!c(Lfo4n~MHU7a~6?1(aY^e)xVj;v9u&w#d-=XFM<6x=ryKEQp~3Ep;b=l1-b ztD4z~mLYdBR=sx<_a_P7Q@vW=FQ$SYgg=fw5}pe>Qz^3d3{z^^c#0N8aO5?5&&dP) zHth!PPm%XAR@4wty!rrMmM*KY)Rc&M$FlB}W*wWW8BcWrU!7mt37x zR3yMe^&mVuQ>0(+Ef@}SI)W*c+IE?>pmm|72A^Pu_U<*6Nt^y0<(r{_Gux!rd0}Wy_R~@2}bN5L1?{)#r*%>xhkG3EvsU&?bmH<8d#5t$x@ts#X z*L=dg4ZK*Wf8@LBsGh!SZN^rRC!VHBE1cD*cF`Dm#mI z#jDqoVlYHwm|837jk7U&8k~5E5Dm(?0TsVBmZo{lUe{UVS?-1Me3^u|-FJozzJe}1 z%fC?mPUg#woGXZN0_zL1g?2<-z_5IUDyQ$^RK%Lx~!tIks0-CcE;l_Ruitoai0Cvwr^?M&H@PLx0RlG~a!-8ihV$~(8n ztl1$=7?qS!eU$oqt6LDh$M*WCC=)oi@$-vZkBd*_Z2r* z=p=x<`EmC6{0>_@N&0t2fM6*s7QGBEJEEy;S_wwbiR{t19Pdq*c>a_H!E1cYO;1{- zIbfPnl)XqkFKus0yl%P(OLWaIMrH4GzDGT|fx39)oVL>pX#6E5ESfBWpFVi?J^WGr z4F?XBRtr;Hbi{?_Q-=D3k3{%OqV<&uy6YMU9A8_{70ZpUSqZH9bZb z+2X}}7Ml>$+K?EnYa{LBt&Jp%tq*0SKW60(mnKQ89wucW_blz%d#jyh15m_qDD>FM z1wenATK*@eqjoAI9Dth24UxwWXK+>1$Q{>X+iW4S)qspwKEo!dJu~k!&9m{boE?T$ z*)1i_Pyh4$ztI9g5jRMHl2fZj{M-Ml=N;`)5hMc`6lnG4Km8!gr~k9(KgIhk-ABVp zHEd{BKPXwEzEdH&U;(RqNJ;UrWj#cl<&l7Yi9SDH=Gwsi#z$D;y#aZTౙKUsL zP>XSl0}v|SI4L_{z%{V8&}%sM8_58#>0Y3V5^2x9fXoLcOd>+?r)j|nMtiyK3~25- zBCcLQ=Ji!Ku@o@I{YY}>M=q~0agjX)&C@gk!OVhRwS5ag_#$*>4UF)|PTk(E97;9w*L(@Vqbc;||)NX?ap7Py0udu?T{o%K$zwxOg+IJr^;Kq_H>KFHLbt*3{&XOS9S`70#Pv ztK;4D5=(#A9B1H<@buEo1XLLuDnM$F3pEuYeEi0%6oE7%*kQsLEwE7;H zVU~f;-g8ItQmTla1vN-d0+rSqiNRGrGXXBj;$o`)Z8GQR5mo_+l=hpWHwyO7w>N~u zOs=5N_^Yu*{yD}y(y1xhNCDFMiBBgMBZ>p>321H?z+>1lg0}G@Ax~T!4queNoaTs9 zYPyPfPGs@3$2ZIj8S*E&64&p$jv`Lk0sG2;YKxH#X{=^W`S$*#fxZ~W3by>9;%7yi zR{6QbAh3T$OIO|Yvr|VbGWX2~qE^rL&)S=;vYZwc7j;T~& zRyL$zIw%#z9M0cU^@8b1!xDtJOBEa(x-cbGB~`^39}lzFk{k)@qym;bG|npfQa>8U z605w2r+T(N(=gRU6yocu)6 zYeHiM=3qR{(u})Z9Xqn(DPjJ7;s$$Wb@sT{r&j?l+Vksjd{n#2p50fzOByj8xFRaRcKeaS|950 z^WvADUZ2QS>1K5^bMH{D7y7OdE1sM#vJ(RQD=ANBir)Py`HBhmNzvMW zERopk+X^m73kl{-^xjF0k4LyW=;~;Qpm?678_bLJ0gly&cJc+!sGp)?KXODAiU_Bc zQ}c?X?a4YAhaSV!a^9#tp_QBtwmf#WKS8O4y-JBJnYMD9H;;8H)cxKTQgKEj5^gbk z`Dr(2Zv!6)>i+w?o^ZH@T;uO2_$to2y>c`-$gW?j%KPXv5@DnpaK3`|7UPS2R_b>8 zO?t|`ONVXg=D}I#kIp0y^ylx{zgOu2R+-GPbMr3HJ?O8#m#_7mGkeH0?!fP_(AcZC z<`+ziURb4r0~gt`5o8~aK%lOn_c38($F5c|{!=p4t2=zRK}CgY2YPA{HKniELRp=! zWB1hV?+!fBc-y96XiEX{=62{GSMQz^9bBOE?s`G{iV!OUA3w?S;LP+#y<_DR%*p7e zfoH#Z8z<=F&7foZ0Da!)8IU3k$Kv9ipJ>`Yp{#5B#Oar>6^iyl>60txuP_H^n!(4- z?_#KXj@@e&c%}0z{67`ip-SSoz32QntMkU7nKiUfy5Zjouzr5^Id6cPCY52<=mriv z=@n8FRtO8a^AnoCd`H`zuF6u9<9vn6$%6$Y_x+=8>Jt8r_bY_$v@JwuJC$g0b(22E z{oV102X_m~$(-!B((UKV%()bCQ5fZ>M|GK3lS7g8oprO@PgCW!QzK@BN_3v#-OIa) zwfsrytY?`LDVZ-pG@KQt{cz19S=9Dgg6CW6pwIP!qRKn<2>UT()5QB2x2bGF&=W+u z0IgbvwA4Wz2SMs`-um6@tgDN+3}|Nz)pC)!RT7D{1`Ra@xtE_7C*&41Sl`;Nl0JtL zIjL1&neZ~?^pk^14{EoI4uh^9FhNBJ-*<3h-M9s-hu<;CQ_=Sg4u51r9!|rrw&R>1{U zk>#`{x6}0~TknmlBlguBgoAD{r}DG3=yyXy0JR%(JKs_Fi|2TN3NRKYIpFFPIUU50j zJXn)~yv^AZA+-N4vg5QD0(tO02+Tcj_wG48CK6e$2f2ED6X0!+m4n&d?|rkJi0~Xc zzy)f{F3yNwiG4*0<(C=7=Y`dl!S`o}qu};IoX&ZEoD(E0q!)D;!FyO~P@_VVHK9jt zh^m2IS^y~x{Z_`0Lq-uQsRzXlvwo(r#@&BL=MLs(O1o~b*_1a@Q$c&71ZBCir76sl ztCN^|ny6YK?cigrs{I zSD5+jp<$`ft~ds?cWNp-Er&FC_H``;$?I~F7OLxfhVP!ueyrcs;5p(S&q!}gPxe#J z=6}GP+Y@-2KH9+HbcDEJW!~*(z2(JEibo!0U0c47-xkFfyPRmU?|O~)#EeHDh4l7~ zZ`L#2ugSH4qN;_dh;#$1M|&cMCLKG~%|*L=a;OY`M+zQu=9F1oYqIOj|5#N~zhDTT zU*<$xpk!%2iH01gayPcHb~Xz6opg&c>?I%~xK9v$sg=bwVF~HnDLl^4wT9*upZB_Z zn1O2mdm=8ixIyKU`LXh~tMz@@Bdss4!3~E)!Q-Try>4_tr1pX(hvKD(Q2%ZuUJFb* z;u0CWH;w3onb@nt^FbfK8alRS+;V-M!TsYfebJt`XnN*tu~(gleN2H}TWpt-pY3Ho zUFP!6hIqkA`OFF1!goiqxY>^|1NX5;1&AFxd5r0t^ci~E8{;@eA3TuZAPXY z;Mn{6k@#uyW31E%v7W)=StIY6*^jq0--YJ;eDrjXwjZ{?b;g!{_sXtIPfz^p1vZkU zlap^a)xQ+%EpuyBF9xiu&J$2S##YU3=?|fyy~jFjQLFnIZ*$W&3GBh0Fd4XgP~&t| z*a_Iz;1D}%_0Sp0%{@^K0S$)+YHr=4ebi=Xc>X}=$>TFGdpw@=o~FM&^Kxv62KHzr zl2ts{OA#xG)LVPwg+($O&W{e`H;<_f<4H0YCsUKhR)*2Cc-fa5pVs%{3Tl z7XMnD)%j8a1NT49HE+F}q$TIUH{IxNpH-Q#zNY53?_^`k?zNNu@Sf>ypjn`3^)5WP zS|xqS{j$KGe@yxV#Tn*XGUq}iWlw=jNXVFzAGz$`8umOby8D`~(*o1r=@Jl(xiZ{9 z>~{4kz5DXTW0Reh@)`}TeK#GfMlPJ`eX_?;pz$AO*RNCVWp{;Uod?x~BPlEYc3ypK zz_WSB_FB-$n={B46dX20K2H2jk%I@GYAh*g8_|sq*c*;_)6EvcDjV3E_oim!kXhn; zQMBw8ZaVLodn+N^FZKP)oDrGg<20hUagj3)tehrM-C{cDiF{#B8muAzAVY&2sBElLS*7V>=mllOXRvSJf0OWJuafV4o+o>6=l4y$(4*U}3x2D) z<^*Z3RO!&%IMd4|V({a=`JW(|$l0nS(b+q?_cr6hd(IC^6q!Z*adE`~*gW$zXLr<( z|BX~}+RaUu(rW-$Xi@~&t|c1nWcoyw(zH(Dr zZ#a@Rl(d3eNy%%M5iKzLo*5>h@B5B!EwfUku8+S^kYXMcw zFZFedE8F{PjCI-y^trC8$|odl&vEmg+HlVeg^0Y}6AwndMe=515@(sRL+>Uu`v$X$ zL_lEfVUIDq{CK?%QLr4IYz$&NZ6Ilb|xhPt*@ zqb5dB#upD#ZSprBlM&nLy}6sRF$`LAAmf{hP1SQ=F)DkSOxusxqn(NAB(wYXR(za{ z^vR+JSSry=_T^uxp*MG+1H-=8bzaaD8jDQGn_%F|>PsEyNOX0!;}bhnm2cMl;DR@e zby;Bh!p7^DMF-64TOZyBoqY& zDIy38BuG<=6se-pl;Rh#Ts`O9``r8f^}WyYW{)^~_TDpV>YDXiYi9DH(4{U9cV-9% zxP3iO9+j&FYypNB9Wzwl@T>v(J>Z=L5k~^F1mQzeuZU4{mxb@6q5&$;&>1jEssO4< zI(+7$uMpAsdRE*{;{eBxRzQ0&v}<#Fp^`WW!#Mk0BDfo&lgDH#xXUVV-j@qGDqVVbz49&!Aa7es*gRSB|ETU%%GudUwz^07~vR>>)s zwz=}&9i`>mzRoZ*>&x=*E>pON6@hWlOxrxv5Q8jKRPe{XDyCpbNQx|)8I(7{3YjoL zljP?zUJb!Lv@ShKB9}(j?w?|zBkz0`Q^J-ba@G6fBwoY{^S*z?h-ZbUhv%p?x4C<` zT{mhDaLSY~CvjgN&$>JyVhdN<7NUK4w`nAkuIm0~Kr}~w98XfhNWEJKuF22jxmsm8 z*)FjY3DE?R{D!j2Av-9ftrKSl*n3~AT(tjgcaN6VlWLZbswbO^o$QbSh8$)yKrZ;1 zNgis+c?jO9*VtyPL_Yd#H9Bf@WAA6vh z#l`lYVe^2aSLAQS@#jDr$p z&sXR$)f!rq$TCTz-b0+*sJbhO=qkV#lpWsTSz8etK4=4*wB=|I4TbOyjp|x}jJrp; zp}yiw(^J+vAW`u-(=8G__M=%@826siGQAa?dG2ifX=o6WjCs!2I%7g)29Hd?Z6EM{ zTl9|P@OaVLX@}EDWTA^Nb%uDw;jjTm6B56MdHVjT9qh)FgU|)Y;cP+l)VfgUDIo<; zG#8H|QW%wlc7uXjS0K2OsY5cYEhC2RR`(GN+RJ6$zLmx1R#y5YaWRC9;n{-Dx~=ti}5OoHM*nYdCwUUx}imL0KCtszV+<0 z=o6dF=*4wt=-GU;GN1bMX&ca1I)})F&aK6u9@yYT*^;Z@G)qY=+W7N zIBPDO43xnneJLWuHO`Qo&XAl&MgwT~={r*PtOC60ZpDRWyGz*=M341%U73INutKZ8 z#3tVkhSJOjcbH)U&nfdauD(n_Nwh()Ke=Jzzh`mk_PnXRM34qpaA}&UwhijXbgfIv z6O;CO9Z+CT9>%z;N=D*}^|Y@nCnhu?FeM|7P#nqE+;()7lW@geU(xJG5<-wZ%aUDX zYuj~oc*%605|a1uy#fbDYM#Z!B44H@kp6Wef8Nao~*tWZ}#j;$wq= z#HhO|2$0!-mYI^U7rR2?7;bb~1+DWIH1_(DxD~KqgY$AU~fDe#*JVuFfEUefE1rWPtnG^WU$>+hJU`Aqp$dlxv|7n)ukQes-z zPJrk_%8rIvqTMZF<1)$D7xc}iLlxeBT(Yw`WvwpSUySP$7UpAi^Bm)*v?mF?HG9=h z-fb_zH!kgkj=`=AOEDVVWBV|plEs_5t{_?}Azm(J%mAQQyXGYo`t?)C*8CEF`K(+M zer8uJS9wbonjVvu69H~6#IP|xE-hSv`adG|rX67zPf;keFhmQ;-c1}1q%lg*KvoJ5 zH&&W7qtwRJAi;9q0GN5V1VM15=obF~hD}k^b7n{mZey8`SIx&>mkHLHv{qtH zslBRn!BTTtOa>;l!a4Nfp}nwIn6=9lCd`;h0o-$x!4T@Y%cNx$cJ_UydL~%()N^k) zmxFYin>Xj!b&Jg(oXX-8`apG8B`hkVfcl?Bu84;*tv#+>?OE$aI3{lA<4 zKbJvQMFlbB4ca@>CSgR61K}!f_J2@swD95V|9Abr68KdDSsC|pQKIO!%KQ(a3=8)u zAqo=4zaIYYO(mTdwO z%60iGC{B7YgwNH+ZFfK7fueJubc7D}%rb-D35BS9HG}`l0Z30yZaj;8Lu!>TKvi*sR9$sxfUP^E!^)(I-HDT z2j+334YGZO28Aa>HAD46pe|Nv^7O-c!80e+1{tr3eomlHUem~M-X)ANrBiMHirS$i zv9DwURSFwZokv`6={oGK9-aEw8yXOc2Qn@{@#!n@iya4p1d5XBT}#xM-)Aztq6o?- z8a~VRI59Y^le0eug%C4J8v$z&2vJ6}sbQG-&zOUZ!Cf~vgk#9#l3bT9;=wfN9CC^W zIU1*4KQ!Fba zCh`E`!FH3#H zS{<$O^lo~OVquvsj59qlN^OxS)yrEgYhCwTwPDY`T9llT3w>VBWu99G_*110iwoYK z-ccSrT3d2Hl(T>aKR0eEGjVndyzxm@{>+PlrI$-7(>q@t4IG|2j18qZJhdM*a8M+j zb;7jJ7I_h`e8W>?gmA^0kF4HXK~Y z7-LQra9|b>-&UA#mXY#IcGH^3;}78ox6o`V`hKY4xm{1(&UM{0HX7+&hJL3Jc4CJ&?I=4n)`yu6ZoeB>7&3t|Oy?tt!5$uF?-cW}Tc z^K!^1VqjCwKN<%lf=u)-R`r8vP83ZMduu|C+@78WP zRKid9d0A}vp@EFy`Y&sZ*j1|%9@-Z)e=H?30gQmER4yBv4!Tly=wHJNYz17&X`1gVNEyRu)%UJXDd&OlcxS zUYeg+%rxe(Cju5}SB04DG1TYlK**~b{7dqHn@??{N(tRpo;$>?py*GoUZH^)gRDe_ z!e*nzCl;adomJuDYDS=3xw+a-KU`ew=CeB_R4-0Qo1{XALE$*V+%Z^2*sXIJR1`XG z0=<&KjAO;`>~id3nmiK4vUJA2tKjhVx%(h-;R_G=1U~39y%KRfcq`ov6}Uiw*kz)( zu*$Jzavy>}?yQ5!Nhsz%%@Hit;r4_fxK|`5W zw}H18yJMH*!Amh03CrH}RD>_)v5!yNQVkJg)< zXXk2di|Fmwv2U$zCp>e6xaNTA?iMGkShNSnx`%Z-w;$ZIe3!%T{+Y&5P}%OfIF49G zFb3A$n=CvxtVc5kP~}?NK63@9_*}uiQj@){TU;*}szX>;)HOL; zdWVD5*PTwXXB>W@2yKwl_qmDICpi^<+NDSudD@-WT8v!g!3!56`m`$_==QSRwp)}I z=*AbWQBdeB#5a)ekIXzUyVTu792vcrxiGVJd)a9=Q#SqlHuI0!LzL3u3dk$E?h1+* zuHi?IH1=bMA~t)|45`J@289%$du2?~UvWww2n;m{@22N?5Dik-%bY-PncQ$PqczH% zNyKWI^g|QA&K`BPb}L4U$mY{R0)-&71``knW(JkWN_sPnwFsD)sFh3eD)4LaVw~Wz$U)6Q{m(fJXizT` zzq?o^SHccW*XZ3)y?|Fu5gdqRA`T=r0fvalGA#!Q2w+b> zJYN-Z)a_vUlH`FrbBb!~RDl@kUb!B}64l27m9{xcH_eO@Z z*O3{BVV0)`<>2$0d(aP7Th2KANZTAYf0Cz_WgQA0^CLt{=?R(^m!C#58V5j)Lz|KK zvoLSZf2oi!H#8TdDoh-=df1t=f+PgR_ul%y@CwM76pu+?@VWorUKC)e_tzKIZz`N@ ze)VP`X8pzm-=atP)RTV%nw0Jt7!UmA>MWbi{#yy*(|Ln@2zTRPSRB$aG zfEYl4Ynst#5u3XQj}%r>IvL^*XJ4v4D4b~lpI=dwzhx5*XEa31MGI|x5zD-Rw8jw6 zmj-InE$r<0?W>##lj&oI+-~V!eMDGD(#KF;5xMx9;)FbPB-!H9ZQ35zA@c^Xx)!LE zymd5!RsLy1hZ5Px&6Juiz0)fM1HnqvfRW~xqUZ1z|2F`0k*kT3&8bdwb@q@MR9a95 zzaIE>QC^M}vK}|Gm|z5lz@^mzc?>&L6GccaLsx>|V$kaC zTf*xGehw&}1Yb}o%`>@|dorgVH0P!gB#rWrJU{h(yo`wDCDff0sC*4^HAh@3PI2}g z=L@N6V+r$BlbSA*D35T#MQE7w5bZuy(5~^`h&SyU<&Bia=<0Qs-cbA9ePhrUU$;)d z!f6wU4(`L4@JlvpqN31C)Bbt6*WEr&05Kl1V(`F~8)E$VYnCQRqmibjB7@>5<3mSf z?7HapbXizlqph*&jF`(k6I{2xRZc}cw_=F;AVZxNpTsLH4)G4}?xd{nF7?IEdAQ38f^X=H>5ERVeD64#nC zYYU!cZG)N1YnUr5i*h&h-iF<_c?2nhl-^jrL^gy!m_Y8OH)m8Swv7#-`Z+R!s&p1E z?b<20Vxqj&zcx+7qd>^7o~~cay~85C=aCazb6RDdIsXyiyuED3bLkDhb3XrmT5Wmt z>M|20xEC8e5mj5)tqAe8%LbE^&)grTuKN)f#<1J%5vr~#PpeP0UsUKDk2jjh4vh$D z5e@a#G~Q!4_Z9yBTAos3_i|H^X$n>qJqKMKbJ{zBh5N zO^n#o$}75NVtE-MVc=sVD&>2rw@pXV6jvZFVzhjfs1AY((i1E{DzscSVKKX;-^XvX zZ@pSYFtgINnlU?qx!I_07WX-tP~i3SR&b?|`GoaID{!m4TSYX2;L};D$y%_jpipr| zlDK)ClK(RS5~Vx>vc-8d(zY@|Ae7{i)m6FyG?5@2xuI ze5Az7=7D19*BF%3;RuqQKQcB(5M?7M`6Uk()uQ*oMA;SX|LcC&th_Vnb4eb%tPSKHLSGUnTgKj`GO7*=W5PglqjWg>L8&Qqs^bt2v}7Gh-uS( zMFLL6d8o~W3*J=+7WxVTJEZ5O9!--vO_6*9;F_%CpHIR>2#B4i*f_Hd>%kKK>)K9s zsRl@h5!tDwy%vNvAfcdiSOhKwT25arqcYN2pNrMjDw^l6<&`ZATQ$=z{VaV^!igX& z0>vE9f8|r`ldv7`4yCs&Pnt^v4-(&f6!)7+k&8e~OFL8h&Tp#Le0V1I`ROC?M}>0p z=_8GVFtbON(Ul{aH(9VNIi{Ivtr&&y!;#Dj9CQEn`B={QPC=a*b9;b1zk4LTX_Pe%_ z(_g;Cjz7(HC@z z$Yjf+kdS;hE2y#UX@XD}BB+~=J7I|Mr|PXyXj7|&o#Z3Pgjv3 zC!_zUt9r|QGj7Jp6gk|0^79PUU%MCmf$A~*77pT-eA09jhqe)gK{H=MT5q%8hKU)$ z@)q!&G}KNfNlz(WX%(#hA{c07d%DYI8N<4Q_4x{E3GV zcBy4XMOsbjZZ87gvZj`3OFD9g4IP))u1}2=xW*%LL<6~e%D2r^1PAzzL04dy@GRK6;^A>O z6Y;Zpv5hwsq@#1X+{4Ar_zjR{d0-c#y0OMIcauNbT5sZYr2}%YYXaPp{h}wEs6Ck? zPMeF|H?P*wkD-LwDn4x{O;Y&*eya8ibI{LzW%VlJ8^BF>>dot~>PxgQhxWP4{xxhI zTusWrPe?YkhPVq#zxVkGSr`;a_AS1v4%7kGawNh#fo3Q(>e zBW2li#wgf!UcyX{Tqwz~)0W8S>Goo;xj^CI9&zYvhVm&r6+o4WCs;3ltG82}GehEY ze9h+2P zV&2WewxHejPBAY3#zBLB%nQ3`A6gCtrd*l50%0|yDT?0VV8L~9Se;8WZZTu{`cdRP ztL!Cf0L8+-Tqf2$PB>;b-{Y-q#4WT%Vw6z z;;v>D2I<~VH(TLE1)MO*%=Kd`rEOSn+#@zkaJCBR{rS3w3rCz;NYEiZDMp}4dPfx2 zj_;;H2d6hpX2K&!b=wmY3h-4BekMrhVVru}8};f2bi=Edi+V~rIkLWrK^_2GD)KQ> zyB$%QIooJkUvhh$tY89W_A5>_Z+CqF;pUuOG{uY{HjYw(Zo0)csuY8UHInL$kGa(f zuLI~K8=GiI0h(l|BWv1m3DI%161v3p5V|hEuoi*t!0Cz42VwXz^4+fU1YWR|c2uqn zzAcCdZpO@#M}~u*(VQ85b@mzVnOL7!^%ahXM0dtpgS`7HAk$W8U*{kQPME{LkrEOC zHrs>P9Iiikes#M!a)Pu><1BeeFuP$iurLlkNjNy){)Kgt{2QPeB4B*is!>^lytK5_ z+N|wRDQ%luclzb)<}U(Y56@I!3d(0G3!l)R3UFJpVBEi9K%+B*mGT8Hk1uZ`5K9I* zm{=w>R+M7+9S=)8;0vkUC8T>@@e1&b#?^_Gqv3X*IK@3dz@e&MKqPd6?fb|Fzq|mG zk_+py4XyO_JoQ>GDw_RtxEu+VjbEzfIV9VjQdWqqlDx<0giEI&I~DoaixHb`QDKtm z__a)7c06LQ#LqEiUEsZT?L=AwU%uLGl^TkGh;Tv54IE`k>_j$}gcuLw4N~hgq2Lxa zl*ps%m2+VJ*x*BWFJnL(b`nc`>LYW5Q@a<{8FDr{y#)~wg7EMcG$%Sm2zUv}dk*u0 zc4@u;i8mc{tTPTj>m&e;XvGBj_U&Q$MT4m~N{#=f^1y=pmi5@kc%u>yi(R=VoZ zHV4R&>W&XfCJ*7j?sUs>K|B&x37+2x*G}Z9cs%b8dZA-m|VjSU*38MyOQs&;9 z4w5tC#EOnid?Mx%S6Y-)N<(6YcBQt~ZyTKJsCK=Y_{fI6W4!{~^srjFXS0k~X+TtBuZy9}bdtJZ|Xdowhu8la87nGi6bT5)X#iC%o(uh8PjINOr-3*9O4(5*5zv+fy4@_Tq1Aax$4XkX8GRz`vL2aN z=+3;@#AUk|x6E20K82f9COlYpyycosD$a}~-t5kvA(KDdcIB8i%rv9b@jk8PJy_5X zy*97A{0j#AnQw!7eI9X&Kf7K+E$adEpjZ;}zNac<1SFUxqU6VXs zS|$SkUK5(h#n@hHs!~sRto%Te_;Z*&c`0+K_5At9ui+o|gN~-~hh1M&zKfgq5%s8% ze|0_rNWNY@64Y_urS7<+XHaELtuwU}<1EV5u*pmJC*98V&Nv@tI)DYmCX|zG*6mU>c=T)d_1GoG$B_$gnHx zrf@$eS}s~t)@l1`+-G#a(t*y{ZVeyptv=U27gvey8%G`od5|Gd8KXQ*RiSu3yWM>i61Vs|Bzzm1G-N!>>j$*Igc<^roN&~`1yccv5< z&vVomjs@T%lKcL6DL2uaS#ovF*COUudU$~o@cU9bHi8eo$)Ms+G{3*uo+TbR{=3Bb zl!o~Cg?0rLR)Y;FE8PD^)i2UL<3FIQM8K}ozY)~-NBUu0pMPH&i05g)B@bBmowPRE zp_+peouLK=TX)v>-S?xyKfEjW5c?$7mjphz{eHb%%TM8A#o!x*uTiX_{O~%A2pQWilwVZIp8Ee?peRS0i;Rj3+WQ|5K2&weG8c? zVSa@2biIrXy7-lqx!E97S_qE=&JCw%rfMFEBC~~eiEW9*Gunf@S7k}OSVe$M#$<8C zsRTCjU`tmMpUqxDdw^&{(qp1y@q}_o#8QYL+B@m4IN(heC(>o-1K?=1sb=iKga> z&YY++AaoqNCqGh%ABUPk-)DD*>L}xf8;;mD&@(G?wy&KNuQ;TZA!K_ElV5d2Zeqzc zSuUn(T0~Tc2Qr?K7$rpKe{SBimFK@K;-gj_5cNPx?aBp`2~$<(cqij##gQ6LjMU+f z(_z@F+9^;H0P)O+yzi7rJy*gl+h>kc=(}HNfJKR*dxn%dr&W6nvB!9$Wq1$#=Nbu3 z!$`3w-j++;p2rBmVOLZ%aqi?tp-g64A~>*-!sNDu;VAq8#N{4#vu^8SU)|)n!S1RI zZ#)Vq8m`rZ6pQYxYpsA{fa4>OO@?0}q^;aQb6^(n4O~2B4*$KfB!SvW9b|T7Cj+m2 z!5&8{R?!rl4oqjbK~Y@T)vD-ib>qa&|L8QKYP(6r1hRrd1^5xOIsblsc6z7p9NO^e9R={`t z2GH7?iwLf}mxEE_JDW)z;$rpYRZZEa-Wg$w;cHF6?bl|nz}Mh9TpbC`RRZAe+#{ux z0>26#q?`X9>|nNu?nJ$v44}=ahBIU#m@5Y9KSlfEp|p~3fZ$T13M?$hguWegvMqQe z+GwFlUqR1y=gWh>(wB5l{+BDm8{E3Fhw*t@o9TE!=cD=qshlhkv>=Q|kLVzQZ)Z_W z78=1|VaRjf-X@t`V+%`GmowkJ*2y;J2=Z6R^8|(-_$sg@zYXJ^2JkgNJ=hlDd>4J8 zY^8;iLUt9i!tSMv_aT)77)lLdxJnQw`J5E8Hw*vy8Q|l?^pvfxoD5t=l)~HdERcHevozD{bXoYWcNn=hjruewh$@r9* z!c?5I<@q{}W_260BRgd=9w@`vN!@f!Oc$51qZe8|X3QoRxdW>(YH7tZ!EbmpJ<)&F zM|nMG1jg5S$4(_dW>@2?2*o|w*M8MTt>3590eQrTH1<@cBrX27HmFct(U>7Ix6nI2 znV?AtVnJ}1dW{C%?b{G{rX4-Q3G&DcV#JuLp6cgyzY(zfWdIeq;vw{zV=-ZvZ_c7K z4IW~}w}tTIw$QOAZl^b3Gyux0mACiloR9BgymwB-0E9dJTuDsf> zPgI(Ivcf+G|KIq)f9Yi-c=4a#Ji=cY^6asA{M93h(|=UsT|?h$%XM5x%lgQz`AVCM z?vFc?C&*iTjzefJy7PJG8kJe+ue*u=9&wo7Z!6i^$Xb4XmL>P+Qu3#YWxsPYzM4Ps zI^*`xALEvZCq)%ck-{`<=FAZPSS>+(tFiU z^>5sjWAF$1@CXVKgAO$oZ=I6cb4MG>Ur%_tm*^w>Nxq$rdYS9; zG8Hzy)m(QJSrn?ujs%{56Q3@*UL>n%hF95->GU=IB)wKmZPG7;mUh1cNfnu@W5i_O zbe9I&u}C+@`%J4?iuICV>3T;>gL;mK0bItfc{T~QJY2l57FNs3i_1YX-5hl8dR|R) z1*Yl{cbEy1A&_poH!(kAYY`h__^sWLY|^)q48CAt(T=h$A`$ ztfbQMzOYHe-gBNP?eRnnMJJvyald+Tlc&lWqvj~XLm)R(tXD}VOAbn z`m&n-O-{UcLlLp*MP`|cFqQro3L*wB)=fdGIhNc!_DAY@)50ujD#0~Gdubo06`yUq z{Fl1Sq<_9YnFk?9&FS^p^L#ON%5C|Z_nDX8-Bj^LDPYi=FsL0*D*6z zmL(JAV_n&y$!5g-C)W~=hg_y^*Km66-?6h7AtD)FO0Q)kbPo@$FS-4JgN9sXFd2V2 z{E_?$h~2r|<@jgLAWM4| z)&L}@w7X5END;&|tSx1JE~PZ?ZPFPk2YZh%&~V0(JNbg{`UtwP5f#OmNJwTA-#Z_% z2Xs^wr?tYzu;U=H#LIBuOqn4K02lLQG9{E?{U0F8@4#hLQUK&|A*p=(d@AF*@n-<{TcK zR2%v_dxTEHK01}+(aE?X4Z&od%(IgT7dYAXYhB?m*gG51p!n}7NCMLywu4FBc9`9_ z0dj{6n*4nS3AZ`|r{@PI}gIASBM>Kd1C>bXn4w(6~!tme4I)yuh(l zCy_;Nml|ZxKq~bOK*4ngxE9VD=}ihqIWsHuTrR0;=Cx@rN7X-qaIrtJi1WJ#KxUYr z)s!eEQ*nR$YYu;41{4kv1XqG}sDe`~CriMVjk0T+`mC8C*uOz{kSA!6hWA60Tkg)?-GzXiEr6aBIeI z41&pQI|Ax<3DV<@DU1Qs>|>8eY}?I1nnW<$!iCc!l6L#SmB?_Z3T7}HY%Gj@zhm{1 zq3ZK93`r|X_1YH-3Xm?9At1wECvG{m5x<=&^;Dv3`W zxP=6r2<`@6<~_aOp7N)dj7UHq{5H8@<{A;WMl|>%6^XP{B49rdk%97z$Z|>x+YVE z0bz^+34zXN1Dx%9R zZxX+fb4Ofe78m3GUd^~Y0WBWOXWYw^V7mcBA!;E6b8`J4S@?c1MsvT6nax);32d|q zIOl9kTk{c+9=2A@0i7`vK*sm#MALcra@+3|6R=y>gV^e)(WYlkjQhKRb!l82UL~UTwA<^gA$Frt< z6}*IkrjCMFgroh(?+|fs_Y-rA^5`ZB8iO|#(WBho0G^QZHIY+uMPDNzhqVdnU_>e5 zsUg$7yIGO%H|F~u>E0WORzGmVvmcsyHpi@H)6)@h)aeshRQ9y84DbT^9`MEU7hGfp zGa@H7y>L8;!cGqZzQ@3sEXhjh2Qjv7SSK+M(xFVE7$%j0PVbL^d*s&OTe{05cUSJe8fK)X|+Qw3Y{; zIYEQ4c1+*2dK(^`$_95qT0*Vq=>~*FhikscdEt8lx+GT!K9#t% zwc~TD$Lx3Wxjr!-9^{oQqhihb8?Z5Wy z12?Mpr;rP^a=#HnNAMFIIoe}_hp6QbQrV>bAX|;h_4oZI$k~32h>*Wx=Tgyzj$cl#a2dY!NI@nVnGi0y)6Dh=pS^ckUITd9RTO|uk;0q2Y9|9QAb_; z{?rvd_JsBrRk_YHVp97)Uf%2xNvS?k2XQ+ac+kq%0Ww-HrBgcODxIT$HvM0o@}Iiv zDXWu~PKc8U9|I{enb9j08T4Hr7+c&r+??A3(2zA#*zI!xBN?)mT>So-!3o>1Ve6hk z6yD!05vGg0)2DJ)gzpH>n^cvH0m>lM+7=*YB$DTgiGZn-?X955!V{cKUR2x#@LeSt z07OqioFeA>{xb_>4L^%1mlZVcpn(bZceAN-FgOWreU_LSSeL^+dp9u4JlR=<+8!oitsvZ7LcF>xemw? zJe0<>TyL1@%tsfz2v*To0Tto$D4cuq{yFHa+s>Z+ducS3hpvA~2}GAfXiG?P9bE(w1FSU%)S7**`Ap|pX`S_zvp zqWyrdm%=fxFR)}R|CrN9?8V_#Yo=xgg<;MNwWNir+Efpip7*gSfsLLKmXO*&D!_6w z;gC4J<2pRIje{#+yYqFc1O^Rji-v{;)tNcy&Hu1S09z&9JBz9y*Q#lUB$pjAQRQ>o zmu%3@IF^#8!j8V1@Rn$a zHZ)(=A>1&gEGImS7;gz@-1ngO1Dw@!C3m8O=cd5hxktiu_DVEYuG_kFa$V!smGwwKBBrQCM*6Fl%WC&M%j-P=$o`ko)ZcJ)}FzhP8()1AdB z8Jw=8w>+K4<*1n(iXIVYBWepqPV)I-x$c)y-77I8{g+rbrkHbcDice2j`7_Rk;f+xiwJ5l3N!sW_D1`z+7M)N#L**)^ z;rg~Li|GHth2t5Zp2*V|zZ_Bgug`uT{(om2XMZ1m|6n11um~zA|NP^PKK>ZK|Fyf3 z<#x613E$4ARV0fnL;xFaTk-$aLr@iPzx=|j3o?oRzj2MoKU2T?+oLST2C6>@rF(}j zpnts|%f|To{jSA21Nyc~%WRu1<$wq&;D7Oubz-WyIw{`#mUEuY-_wfxBPq7usK}yo zkovu>sDd|Bu?Q3Z01#XDw0=_M>B-tGdEY-Bq5-|J zee*S0G~B_VGa&J!jsC4$p&>TAE)5fNo?YB>}@ZOwdB2iU<;6okr1_x^mCqt?{dcuvy0)SD(cSjC~u0*D!J%`cT=MI zf{ObkkS^! z4);m*Zpq)se^Tw~$-1Rbity^K_0dI42^7oQLLKIomt@;pt-QD3(Y`{YmMtD0mS^@6`yt<>qc1_e14uj~z#xpfA) zF4jKxvg|u|l1jT?lO~5)usb1m88&?ds?_=$M*Fjdj0Ep5Fkf2a9>Z%s_C_oZqXj~e z9v$F9r+=xrHr};sQ8hm!#BPk^LEA6Fnm10}NhwdZj+wFE#SPP(>lk02L^L%#)QzIm zsA7N(mUjrtbipqC&}pRB!0Elkl)dT-O$Xuj`amV3d9a8>jTgNYeKAFA729`>R@&{E zlUvKZVN$4P!B!<4F5E)&@nqu1_9p^FC&l}rNZ{Panc=mXjU$_fV48FIV|8A8&U0&Z z!er~Wf>r&s=pkmZDSB2L51j4YhG&?^-^C6FX10jU3!9;IAsO!z`kcMJ)eiGnzw^F6 z%k?5QveIHR`NGJy;N=pMLgS1} zc_VP1X0>0LGQQ_fW8%E;n#Z&!baLLG>@T_b_8NogH0YDH#qWYDoF;VgP-tgp5-PTy>J58{sbKyv#Q`e_w+nbRyM`3O?jc&0@%KjA_&7dIRS+!6~o zDFcOzz89qs_+bk>o5UO*71349$(VUDufGm?qEEJ;te2D6F^bxYfRFwF%)Woj)_N)d zDa&Uf+LrC_a@Gzs51JW%M}uKmlE{v{B)(-|X1|xQM+TKMouW`&8AHBu%m;xH=+m8W zncHAPyY`WRd?Sxt2_W+lPMI3ard6aNU<7mxbv0_`f=qhloVTy%&pZKT{(^D-Zo4l? z^d`<-L+Or1T_+>izzcR}JN9lKJbi;UDP$XejfSm5|s5F-_&g>`8<1% z?xNe0iXGnB_hpDarmr<}WWO_n%h3@RXJ@St| z^;-^Hyu-hLejLY@=sT}aSIZ~v=r>`flKPvlwB1)4CZWD^ofCJ|_OAu4b(c*-J-W*~ z%j0hFA$}x$^d;%Je-(<0#BVYFNfn-r|4KXZs9LP)^tY@9U6k=7;Soc+o7%xcr>T{! zIlg<%BPA`DI?MoYZjOq!aVK)BUDKSrfC_uVv|twJyo<3o6g9o-b?!kSG@tmD{$HKI zPgsQ8)!aKV0k%wGWx7yKUb*J1`L$Kyx+_XlhV)|qrfV22M${=bjtOLL>cZ*b4d@;` zY-)JI1RXQ0zUgOF9r+ylunzX^QK~Zy+e4+&epQ>7)2Pbp_qfTFjk%_)O2FLbs z+K`0e91kNF8V)fpDcW~S+;*P|uWDzgI<@y=OjRVS-a8-nfl$-geD2K+H`Kzc8B>)U zYz=2Q4S}BRS%Y8kjAa= z3@9;a2emWY4F=gGaIQ^}i)VzWz#KlKs$agCv9mX=y3%=NL~2>_9Gh`1>Z{=SkH%ZU z-bk`OH{D#56RZ6FHXf#)t0yPA4h&dK>}Mc{5e`*gAN>i;h3CiUomUG&d_~@kyt8euDzIv zaSQ%H7FN~DwSLQIB_XXCB?9C0n>N^wG+bh97@5@-{$AsZE>(loWOi_sh|7cT>$wg= z_^mw*a0$=c>zoR4OS7~YLA_H=5?di`lh<00EKl%@xt!gb5~QmD4O??EQlmds6V-o8JZ#h@4pip5;iph{A?2O)a3uN{U1LgwRWhJ|3G|qH0G%z<) zb^WD@&m#kH%j>5NQvbzQm^CS-7!AWWxD^l-7Fjt-Z0%pZRNbC%wcJEx8)IrCXiF6j z{fxRVx=Wj10-Tvv~DbP7Ws=Wb{xcm z^zyeOYwSqJ=Q zMnR;ME+wSFBOnb@N|zvYh(kzsOA8ouN*qc;IuCe=14t;{C3z?T>28$r-+=dC?|tw4 ze((2ve?0&H{KIC?%$nJ2X3st|v)0U7Ykn>>!{bb7sr}R`SFpXYg6zQ1M_b)Q&QqJO zVcIcddMAQ%v&9^4u9#^?rI_*oS)j!7u-+><;DX8wS>^$?pJJySVFjoht1f;e=rTye z{pb0gP^pKadG~VpJ4pa_LO{f~x%AZ|nnSrWuX*>NDKspH!S7|u< zG%e3?aQ%Ga`ZHrpKIz7)I3LqTkRj!1(pb+uv%6kL?`?j7ZD@O$w z4@XcQ%{+ZKLQshwrhx2QP-~}WrXR_-95g*^I{ss%{ofTr=lW$J{cEA0zw9qt##FWx zgey^Ab*xg=<`>8LEXhXSj9gZ zsl#`Fn@Y~hdi`tJeP4e~x_SSX(cWU~!z7RPsVFGCM}sn{NbpwbEoys3ey=JWd(3bi zpgKffA0Eza*E(Gj;R~NA5)@%jq(zA5{Ws?hDhk2qNpK_`*)G2euSO4rH{$p)m zL%XMaC4lq*F<6{c?(JOrz<(vH8?cA(Y55%MV1^AeHuP14m>Gf+3tiFr5-iocqN_7l zY5tRm`L5;%=I|fX?FNrTy$eM=zYa+FXMGdpy5EtX@B0A@l|&Ud&EZ!`Yxb3iDTha9 z@~?GulYhV%#44a(%woSIW%-O`YirznK8DV| z+NDJayMq6;D7JimHnk5KmboyG=OdpiZ&1Pf}1%}aDD@`taOpyMwC zYZ#GU5m*TN#g6s;CJHtnf{D1NK*2d7IpeY-8{j)G-muS()xN-#EWmF(GH9N+Z>!qT^SgT8hx!IsBPuQ?f{CkReG84^?kL6UhV@SL6fHZU zk|}qSnw?Jf`Pkh~*2P#z@4bru5DdH*Vz<*~F?PI{wIT)bZy~wJ4d4cHBc|MKYIc4> z@{dLShFkx)13~*z{_SAwc+>lL;f2?4*Pvi7#zptCGpwI_j-f-fN1Uy+VWrBmhiWVg zJQ>d5ux@$33|Da2ki6fASyxiE4mD(n>;nIRB9B`z2^F846odRN9!tTB-(T~h;_}Z9%Y3F|*70}N7PAL>U zgF+hz?vrb~)uVChD%(Y`bk*f6K9K6j&2EIKKJ|1^V{*rwOOhrCJoH=pzO*LDWJvc)`NpwlKNc3g=S zkpi)~;dk|=!3?665NNnK$i>gcMhG$HZd3M`th$$o{|bg& z6ut6YVis>)YMtp4X_b;{^igeGzS^}wqE61Z0@y;mIJpaPd2-kJAzc>I*r<^~F1%SX;`t9*QfWP4UC&1s%miy%xx!5h;@%SRZ=KKIEAN|)E1Qq*?xM+bTY6~zg{QjLmxUOZhcPJ(g zstRvPtaAc1kg?(bt?{D^lclAOE7Dxn;MT!vT=w)f2WSBGse3WmxQ&A_< zGIrt_Vzs+wUHRs4d9yZ0y2&BlrnvQ^Y!gR3tJ_O*bfAhpLAkmEaP*?{H$TS-{Now^ ziWdDsmaVJ}V8kOi?==0^kmn@=^yaxf?)i%W{uOGukeGa5#XFUSxcfqadsFJCOkr!! zHCL)q&lMc60Gf|mZCl_`Q;YwX48^3qMd^02?yo zPZ>o0VS0&x@;F&}>Q|D|6T@MjQ0?CB5Upl6XV9%SK<)Lk3wOW$5RGI*jticjkFR-+D$OGsV$ITjA z54q36JpAxx_Y>B0Ikp9eG+{be%nd0-=*(gxdC=SFJS@?8t5xVhSdhM#TGx34uQU#u#D9iKTrOPlmt%j3x%#9sO(S4JJCQGzG_C?m|D`%i zDNtuToJALAov(&IwvhbdW731gWHY(E;_~Ln@7{GV2o{kvuC}Z!OW}pyl90U36BM2t zy>}>fifQ&;tbM_w*fN14>V{RJ&Y7A;Vs~LruVhM4r$(2m*t3dEKut{qMO22I?Z8~u zdv2>)tLg9A0@C-7>d{$xx&{Mrx~yJ-a$X$C9u@}>9OwN&QEl`di^^H9u``}CCnUSh|F4@qB#7@*}ICo#DkBQRgS3<+=Fv${`(ShLZLt$Nrk@9q0;$J`;JIgZrHC zQB>?Mc5YYY9qR>Euhd`D`i`CW&hfPyZZgr+QVt#rMqHo7itONfS9Q*6MX&5dZ|dJ< z*pxp?x#a^E9o?>t0F+$sIOA{m9sEM0h? z!K&`q-@FZ&i(m8~1Lw&m9{OtP-nWb$E@M@dQ%O$7;<0?7WB>N6#jh+e%dXX{_xK0rap$dazf&G z7`|o`6nLgGj{QORQG{^6&QHEaJ9&*wc+s)nBxPq--NBHO@e6u!W#;0;>hz^KC}hd$ zUl= zoYx!byhKWMZ$4ZO4mRW>g6bNO--#D_V*e;?#c_@U6)!XiFhE4(a^J<~HAS;w1_}@t zv7cknoJxzhvboDwpi@BHW%p#`&Sk&-fiiZM6To}-K?^w;zh38c!v8WCkL&*Txb3ED zX$bu%h%`?amxa6G*RN-Ixg-naG;CPnz~pb0_2#*GnUQPExH4CBY7RYL?E~K^q@dbR z0{}N|TPk>7c6If>5IA6>+BM+10+bL?*5>=Qk=9hzF|1^NgsZqJ*{f@H!%W}l!EwUK zL{Hs<^C4$evv$VFd2Ld00u?!ux*EK)O-)Uoa|&@XntEa;B*ZHUFG%}Kbj?)o5n(5a zm^G!%K9|Ai<(Vby<`3t(PBhCj-c=d1t4DL4aF%IwTZC5lq&MhMGk?&*t_TDBCflm= za1nse)PVmmf$%>0c}W1u(*=pH>r>}&Q!}7~s9ZnY7sC5gyBFax)Ko)<&3N3;nOXVo z2!lLT&$6N7is_Zo8c!Osu+&9%8`pE` zDfUTp8LEr0~Mu8vYKO!N8l5huX{2v!$Sqbc@BeH8}Z|vZ#_wr z+bX`QG55s0)(p9reMhb@YQqW-C)U;?c3=`?K5$N5-gWFep`y&450P$=SC|yM zX^y)5j~^;p*?)j?H`ACoBPJXmZn7IW(f8dp=;Z0v~hr~Rc($bL7 zoL~u|x$Zy29?vfy`n4lpj)YxaV2<0$u|3b53TsBMd-NTqar+Y}kqkP6KPe7k>;#=GlfNNEun-oP>^tSq}(Lg?U-^`?Y;Y3HX+^|c6D!}t^%RF z=^4ArCo59G=eZ!wGvQSnm8ywZi_jVhR^YaCnZl0!^bwu^Ae%fB_Omb7{RG6w>~lW# z0?EKHVW3mn-Km$&eZE(yYB5fTg8R%|dmv*%@y_(1`dPkTw;WT6ejnW++j{7V&2%+F zq-A5&NLU>>0=qP5XdI^p;G$z|bJT5;6pO~u&SNgfrWM$E#z}y&h5?LqlDMn&O`2*1 zDpNjicJ_Pn%YOvdgH9dO+tp7wJqm!swShdsN7dG*085^ac(pMa`qI_f>jRJi>B*mR z2JZro0%gL0W49mtp9KO-2N2*ju?w8mSZy)Tp2cxxRwXlZEwh=)Iz5n2_^i_tweT#C z6LvR-&?EUV=3w7nZ@M**M4X3L8+M+NMkcEV0|yKhFzzk&7wFrn%kfxn77T&Y#|AT` zVD^vM{C8MuO&wpp6swQzS&re{({L#0S9!F;teEb*!u&`t=zw@BGIH?At8&8i!6!*a zgsDAZ4y(Ak?TGh?3&W(vy*-2;8#-26G<7EUF}pslJtSvQV^P>CO=-TjWey zP)+J^N>FqnaAN8H>_lK29S{6Hdz(4QxXdS8(mnjgQ6v`()rB3Q2pABSJ`}jBQJbTH z7up=ebd-ItC2(^0L#P1jN^Yiqjj+qHP1w86=(6$#qvq1H=tk>h4jnTM6b zU_}ei=B#9oz;$O66Q^(!EFxycvST^$!C<~%mN%sVxM=M|E{edd3v+sJ2)O(hG@f{d zK7NZLc12)|>dqTS-uozAxb|0YMw?nMB(%Syz9$P9+AKA~BgnZ^N`}s;K!1?H#c14> zQ2i9cGZOXw0cExV{j@?tH0t{vY>LO@DB{tfafTe|678`PM>Sl;Vv9JaIK)?kU!X)` zu?TDl*Q2=rC-Mo9b1p?HAvXEktGlPLplCdIsU5)Y*7@=Tpm*|AobD=`$aWV9ls_#1 z-zr!7D1zX)p`GoNU$0%bsGhV^nyl?qpy+JT1H0xi0EAZ`>6I-GCmju>0^uGn_d$*1 z$8NTup7a`0;@t=5_j_|lOMYePCRmQcuoz<&=b(gxF85Frt1Is zx2M7je~Z+lA|IfH{L<7@WQC%rh+Y`O%A-Ys`5(a7wL69bR#avN?-sSI`VC}q?iIqU z%wpZVD)Ty1WU2k`pzDU&S^;#+Ihk=2_qnOf1toMIPe^!i-1WOVxTHAhFkdVXNY|Mf zhzwi;xVY}8H2hwt=X{Mz`h$gle0nfaXc78Rj%t(-pY)`v#!@fpu+hZMJ8 z#r3f_4Bz9tYcGN;`>N`jt3TRAPGb#c`daF2tm-V=4I2Z~Vx@}$?i(N508|e7MTLM{ zJkDj6$VJ9oo4U|{FB$ccIy#S|o>qIh#p%ovzCvqjCv^6Gxq(4P=e&-I`h`yS-BU%n zN|kh$>owv@4WB4TY@U>XZv-}3r&Bf3-?y_FIl~b?xnB9JMB5)Cb^sKQ<2O|pA@9<0 z`$dz=_c?Zr=DG}i?Vb-5A2ZBSn0^3H+YXEZiZlh4hVP8^!xAY2u`q|*;9u2RHG{LBcOYCAoa^51E8+Gevk;df@$9I zwHf*`2dlRxU)A--8ZrXjXD8j!y-9ArZ_O+K>-4N+=p_wP>F|Tk46P-AlUXkJ>zjif zrdM7u|8}m7Dqz$(2u4xKx!j~Vb~)HO;jZUy3kxHX^D%koSQB}D^+v$BKH3$ z1F|#~(Q+2msmP$vAbE0gMfW$x<7En#3}U=lcfAJRweq}2SvEY)IKw(`vorF8t)FJ6 zr~_GV72kA*gv?dVl(8zaTZ}4~S2(G=`H;a>iqXI@AE#%a{v7QDxd;Hr6qrKTveF)m3yUz#DrpfL7qS;k2%IetE1t=>8LqyXB&W&o5*h_Ug{< zaYoHF2T<^=*f$P32v*m-Iwq+GjL0c@M>K%@?8g|xlF@{;KR4qI7wB~l1SBr>N97P^ znk!xG(=MP&Oi?VFz6K0r^`PhKBwYl3GDR!w>`+td#k}^dU-R(0u_R%rN7TVWA45>Y z3cdEM4J{|rH0Z8_TbS;><~F)od4Tb0?v`;kgzP1mr{!o9)t4>h&97B&6aLu+zi6t* zgS6elw(mdSzhW(n&0f_`hH2monU4*lsAZQ~u;qPdk|RPUSVEA4PuIv%KDp{%SXAo3 zq-w1}d-*Z~kTtq!6s?@a`}4IYKU?F*9dK38DxcPej=^=STw<1iiflguD9BO}%ZoKI z@54q(eqTO{BXbE6ckZ}yFS~Op$$KFIZ?A9;Tpzb{bJ3jlOkhZ~{Y)w9N*l-&Q+6!w?R!T~ChG2nE;CW9W188;|d{F(=opYVLjI|m8k z+9MOVW+2)cJXXO0FSW1WUM;)IceV7Y+6)PI9~@COqao?XI6W-q7pR9}>G)~-K=Kjs zdgbHm{k=D4I_2Xn?0cxSP}8QtFO-7$ow4N^SS|{BO+U>6+VpQRur?C7PxyP2#mj;R z=YFg3Yeo*xMl~N|vMu44EI_TEGF{Bb7l=aTUMMP{{Xnq=^a`m*0u@O)1asdOndtbT zNjvy9-q*ySI|H~?!s^0W33-3@Gt6K5dqJX*K!@&Ve_DgNh9b3EZ89mJ29c$M<)rjg z-fQ_g{NHS23~bH&KN4GL>W+WT-7mr)8sxm}>n9Jp+V)k5s{5SLW+$ORW_@zscmTt^ z-zZS28 zmN`~2<`;WO_@&zY0dSQ1-6DMX#CN+-fHe_T_Tz2w!NOa}a3V33VzqM{ncw?eI7^+F z*Qd`%3X)UT(1+k|u0#nOkNcLW9eBxkyhT!F685}Z*|K^+P`0mZ&M0kaHHkj^fzt4Y zz0g+cvD()I+9TO3En!i&`=7=lx-}?7L)3~PuR!Xve54?Cf^=dhE2-JTXsI-acU_nw zksj2K$m~*cJNP~rZ2*-`?5fSmH8j@iH~e#CQOHyyuI!e)QG+>>FI!zoNp@w&YdIV! z`>xtO>A3Ui9r_^L(g^!fQZnJ;JjAT=3;A<9)kXWe3(Qa(#qhzLVsu<*@Tg zF>YPS;_bJca(kq=wZ~M>(co+*fCx$V^$vndpuc z-Z*-m=^Tk!N$&ks@DMs_ZpJl;I(t%|c5#Pe{l=^K>0TOqX|V6ALZ&5)GOD}(a^76K|?`DMM1f8 z6&0U@29My8awHmXKA1`r?foYP*9gU)I=pmDv!{EJ4kzLgS2cY1roR8j7zzgPG^QxZ z50rh5`3cWw$mAsI_8}y$vO@_~dPxY+$b!ku^)#(Rfs-V91NO`rpNQL>(anydS zMQmTOuBGsdvxGC4w~A*g5lkc-#19PT;0Qrkuo_B5+B{ z64R@hNcZI)5mSp5AKiMB=(BBiL(vtvY{oRvy^lPQCX2T`#ksfk6>cy(+r?*eyKp)j zlMaiQpXx0Iae#}j@nTx@WcZ;gNlx~H){4m5?1o1WWKHTofZC+=6~AQ{d9=Xjf`bRe znrVyXMsw+2K@xEnHn_)(*TH%gVURX8+bE4@5=EB*=Jz=z8%het2F|$}K73yi?#T&7 zhzOD-lGS!;&fHEaG92fxrs&n^==3y>7!eth#cd$rAtVDD_h^|eN_fD3YcAljNm_T#a)9$3A6Vcef;SooP0`0TR1|E$o`Mqk|Nvxp=k0I zKm$BFKLd!|OsYc*Ev!?NWT&cBw|1ebzsyxfC zadD2SxF;HpvIxNzD=8Bt=UbJ6xjV zlHls&Kvz3-rhr3!KBwEmK{K{3I;zsdkuy3C!eE)L3OkxrAr&FcMoQ>Vvz3#uRfiLV zioTnz`XsJgd^wZNs2wfL7arG zZ{IZ0eZ+#nP?T_1*eKFG)360$?h<1US}8JY;lt0jGX0o9-<6j(qm^b}nL;Z3Rh{p4 z;umY(Oi;lj)_8mHVSV$&0w}Xwg4Mu+3v^9bGGaV&QY&HF&(G9EZt(|-3Jd$3hNXs4 ze+^Y&cwY%T9m;1U6)jeq&)b^ewnJ5lsg*>DY^B6OE}5w7sU{-3J1a)&|@jw35c z>H){)dM&US_$lZ%|6Hq26ta6QO5-kV`X3j~rxxo(4V{uTq^VtBqZ7`j7njPrmOOXxO^n>f`7 zJVHG1M1X8NGQt#{W6npv(FGz37LjCN%ycoQOuTOT68Y}$0z`MBm>U!YSRN6*TXQj| zjiLBXnRty%C+$Y3-lA!ULT387Yel4Sz`GVsy~m-E?bbed5nVzya|n;ro;NKVOY$AH zQXCQO9HGYkq5^Srsw_(;bV3UEsL&z?J}t2ORg>9?ixybcWyiS)GjWbgniRW0ObPII z)|w1k44n39EZK0%dolLlM_PWqJR}JA;-draj3WV^foFQ8R=7t3&mqG44{Rr_S@9~C zE5}`#8XwQn7bf`K2+meG1hHfe>BR2U*pBRyM#>Gif_d(SeYGsDx%(^)m) zxnm=bCS^2218Wz0Fak!tDV}!O-t5?D6~Y>*D%wG=d~dHj4ODU|7!Zrek$N&9ACqLh z5i?IrYDhRSi9q{o!ob2{lC@9g5fv4!Z+JtB=yPQEceZ;okrqS-2G|rBD^qn!ccql6 z1LqL;x|8%$bQ9{Ty#xtu+7s)f0!LgUI(lSQouaA<$zP|&OtW5dD+AGkvO&7v*_aoA z=Wo%j$Ga1bEX#jnf?Ml0e}Ry$B}RrgeqJlSnFR>BH0J41%5AM^1gO+JfX)p52^hTh z5^b`g#+8d`HfGI$luy*ZGz_R;V-+}+_TCfCvm_MTCiU^(^^wa?igI&Da;R6WG{ z1;qFHxGjI~I}21tpNX>|`dC5rkQm^sShtlX)Es==!yz??0gNBpYUd_5Hs=y6TM*^* zTJ6@)pD$(|-q!D%@0(h(dq#gmj0I<+svaNEUpWo80fUl%&=_FT_Csj!#dgd;i#Ic4*rgIRxmNxsa_&S(nSs!aQ@9lcW z!Sz_8MxqJKKO=R&xBHk#N!@!bsa{hlj4sK+kC1)*%$UM<>!jkv)~J+zjC=hlh6i)f zNl}4Imk%kLeR;2P+k&6hMB27CRdin{w})1G)y%8DZ*FwFhToz-t)-$8Xxq5F;-_LV z;vI^ZHE(QNZ;z_W_}ofS%1YSh56Fd}WH|KR zqx`!9+@ZQfO4AeNtXe*l*ex4&Nc|rv(UH^fS zK|0XA<0&jILNC?6@B;;e+8<@fYQmA%xFK1;+rgMfn|PdxO;=M@%rXNHXXKg(Uvu`t zE9aaw`N;m-A186#Rv|IMR-yL8_-#W!15jY_C_)k=xUMZtQ?sSnD+p`Vkc5{NBaIfc zf<#8+G72V)r)78Bln%=hNJP^Aa>Mh5b)_k-r_*3U5-{l79!bsXmfni08{2P*bo!DR?;guc=wRA=CrF=)Ctr((edAkFtI@1ejISOo~t<&1u+JWZv-(0{y;Hn`Z)U0 z(CL2GyWPksrI#7uk5wq<uTib*UqvpZf0wZ!cKYmfJxXgN#Ea7eILq#1rvFU4`lN z5P7=35O^yFxQ^FDO0Ze@CZj5MkT8E5l2$t@ehW$RwadMpq=;2AzxRZ28M&!EH?UE2!lH9v8>HF$(pQE)<{K#SA&i9XsSwLpjq=^SN___ zngn7~ediLagFD4Wr0^it_*x{fd8C}oab(RH&DQcWN!#=X1^ZHLlB{S&q4y%S@#SQu zPZFCRvjuo^L5zJcThaAVeYJeM)z=J??2Y$IA6r|d+|U*Q>?(Wmc$aw;T)pG{T0TPJZDpCoT!RP4qyPmp{JyI+ zuSX9~ZDFAnce(JrecVswhSQr)(OfnPP68I?NC&ekD{F3vl#7OJJF`;j91zvWS>s|x zaYdstuvRO*_9QZE@<23*41N@(x5zOiNIk0LY}r-^28@WB_KWVxp905oNc=$Q=QM7I zVx=wG>Lygtq`cjgf{6LAZV8e-0T<4T8AX}%G_t2F*C3!9XjiHv& z^pMGltnMwh@y1c`ScHp==Vwz0eH7(v_!~_ zx}C{p$uSp&bsOU8v~jPi=nkZmJF0_p>trDgT&1p64F&t(|G1`%%#cmm2#Wg=-Mf(YpUANQC{BW`tYM>SF={);#D8GSoMJ{xiC2a3;u z*=gER^O^pE=^2S-!i?Kd{_kcm|EC8$RewL{=YLIL^bfn8|AkP>NPbH*u)GpF)tYh= z7unh`aPmFv%g2}Fb!(P2{?9{zCi4R(LbFaoJeYxQWGO_iZK4(5Si6MJupEhxSB{Wq zpve(_!*WWP+B07f?+e0O5AG6MEaBzn6x2MB>e9}@(55Bf=j1JIzkwqY7&sZ+8%*3` z9aa!WATZy;M|UakmP`2wc@Q z4_^t`##P=$(mR+5mrx=zZt*8X^GEkRSI~i`htj|zR9rnB=2GCTTPBtttr=`$-}g|+ zGTB5a8C5Yj1<`XL*(We;K4$J7>Gu20eyO{U)+28e{>8lY5tXCTRny)=$C_K(gHO{qei3ngPYWQZgUu6 zuPg<<#L&m{n*!@DzDt}#v-PaIHgtsU70D+LQDAuL;M zBFA78?HT->j8x4ANym|+zU+Zw<8Ac>4+6!$`O;WAZm`~?O@E8dkIwtss${*eySY=lxkZIfJwhID%XG7&5H~x%lo1X|9Ev&9V zcpZFdZP%bPJ%I5#j!m`Uic?NNtgq)dr8=z8%94u@_LsQUO+mb*63MADN+=H;H>5Ti z;D;NI8~PMe}1xPT4$n@&P99pf+EDb}>t zwi$utCVOeN4XxyOWTzQE*R?LJCGEre&3V2$ipM1B17@rt$`tY;k94v1W=V4JIm|(6 zR;8&<3A55S3LaS=?2LCw@d9<+aO6+2HCUf7#nE1?EawjdOS8rs62~@e!m%s;OyGiR zVgiSiTsO#KKR&rw8Ts$uXrH8t`5qB5^`(jUVeT<2rHOfA5ib1+c)kQ9hUfR`vasp% z$OYv5_NQ3(+z9P|fQv~se71~+zjrOr+&R|P{NFqtSR@fos7&qealYKWS?GNACMn2WN zE|K=D)`^AbxahRbQ#ZFwAAnAngJ}cPU+1YtNwT)La+n8~Xb4h3LF3*{>WNjz!$abQ z@Awczy{y#A0j+QJ7u|K0wmp8q=W$lkjg8-Ljk-utQAfMT41?xowaLt`?-M_BfRK=P zEYPz1C6pf+(jvP<{D(aGoc6Jm7mj)4QNL{-lO_rP$NlQ54u?bB(>$~QI|kKY>F|sx zL!0Jol^E*z4M~xE={X-Z!H?sk1gI(|TwQ;ln7WpW$_?Ru6L>Dlr0?shqV0ai`~ z(M$6OikR4O24J0dBxW(1Wo@oHNMNkZe;p^oW`U;oR#O^Fet(Gt*4|RBhJYgr zGvDn3>wUHj9c?LB8>563AEuXq4x6(*3svxuq)NB=^rHkUVLitFF`U}co^JC$5})u)nw8qHYqFfW|< z*bKc2EJB=l_<%Fa&gk6pvjWIiX7KOv-@uotK#afp)P)fGd8;7C%9C8G0)Fm^0Uqcw z_IKW!+?1Vd$zqsymQgUj=qRrKo&E2dA6r-T${2iUFtzAPZ2Mvgvl&c-so$!MnETJo zWCY!=p;vwqtpT1>Rm9tt5z`d5tK8^Y8-RauactPNZQH6aNDA{O!dzhBX*mHsL*vzS+GeTHZdqKUt%J7Ns&R-uZx?l<$D)mo6Q;p7nAL7LJ# z?WFWxhX&_ls3frY!|TW|NK(q>YvxWCd1Py5mPKwx$F5QOqRdfBp{WrVal^ZkZVNMU zKb`gp)hv%4r_g$Rn?EIk6mq|-7C+AjXTG#)uB$eQJT|mA&!fN7j+`z=p>pk0F>~4H zMZ;*{2|n6D$$Z=W+nv^@GIJhZoP_XWHw+(qoYSbeo*DOch{>f(Qm6BAqG{`OJJxnr z(PJ~3$)pHb$sV2zs~zIyewT{tj8ZI>dc4RL-3=+WUhN$%c-Vr+Na{@5iPxi*mNM}B zs9TfT5v-aX{OQ9A9-8jZrhrUo*Z>E9aqxnRu#LfrKg?jxsDm{_TujDtM4?oC(4!{S z+#@5Ta;X1p1}^jL=>7+CGx%uvX5>r+b178_m}3dq&4G+9lg_l~Y}c%45Y#0pxiwX7 zWkjXH_5F-EN9B{ijzjL8+jb;VQKbs51$?e>ZH~_v@;j@-`WIcGwvu{_ zmCc~`1_Qp9q?UV*g>Zt6_3*cylQ;+1v38fmaN@m9PlAX!7QF@9Lh0GqIPT=bk8p;n z8^BREgVhC6VGuAC+*M(#n6}J(2+(jDxS#wbb$Y|T^vDTm*c?J~PZR!!X9Ks1{Rv<# z`D-GOby^c{^AFoaf8Hn>{w!?>3zs&4tqb0;vlzAVRBVKdx!jr>ct3oQ>|ar~##5W~ zOJXyGB8;6c;{pfO#SU02{2xm=xM()c&=p;F%>NMOFXbg>iU_si{Ia!nu|f3b3i~hx z^XKfFm9OdNv2B9ZnyV8&K=h^r-Q&#{5TeMsGRN;p5s;%zhFvfD)#nHH(MR62h7Bd= zJ%>m9+#braRm;*v4Tx;56=@Q$E{ItcnfaWdAeWI~+mL1}DxdVdTbgHK&+1U+f^0R z1{jAK3Y+-eD=6k(3&-&&m9ny9Z+B&R0Ht1*pkShC4sQn~r^toxSF~nGl8Sa}yqz;_ z;;;<(oRv*4`~26&W!Nf)QHnG#XHlC2a$kfM8GtpaeA#O@Tp} z)?x%=Vgz_^pdsdLv_KNUY4oZzYh5P0%>E>DMubH&$1udVf{!)@!op%JI2heMT657U zheN5T7zx?~3)p$O7K9bX#aXr3fg18ZoQL0|it^35)n8(+kt4ZM)s{o1$5P-3bjD30 zXrYrCW--I8m4rt^gVhpMj6=i_hf_j`wWqtQL+N!wMhImc$ohF1hfNqv0m0j&9RV_` z%i(%6ItE6D)$nee`T=#TT#&rW5f>QosW9^qAM=>9*$)&>J7XIR3pCXlkkAgbA4LRY zLxisq)}B}e(us{7)OOE-b=$Vu@JI#UZF4o;nTT^>ksCIb-!*+N)&1pJ@ClTiJTRR! zx^Mf7`zi89cbn~bAF3$>sCLDr23K#{$wcmrP`&k2)X4Tz;qCerE*qSL*d8;w+g-Cg z(s>jJk8u3K0qL{@WIJ^huvi-8m(DMDOpWGve?D!+tZ>>SUdDq0*_{&WD9orAVrpyH z(Q;E+py`-gVJ_Tm_3TeSwIt->kte;3aXCGwI6192d3~r6Jy*Ca&YKoa34a-2J1L4@ zCKeO;ZMWmZt>LiHR$R@$oBpQ@MCRn93oVLNCszK;rLyU>nv(7D(MWW(%&ad%#E*QB zxi?M93yW(>IaMt52z$Y!A7jRzhRTooJ8e{`V%t~rwd{V3vZ1XfC+$1IEV=C_+^YJ` z;l1A-%h$dWsZMqU0=v3jBUioJpMGx1b+Nuy|Wf7LN}Bs8nyeV=M*;Lc*LoX^@V;B*|1)9bxteN#^GDU2{6X>g!zfC=}Z5t+BERPa^MJ@QBbD z*y(~>LVMU6>a(ED8HU3n{DRohVfiEV*-Pb7*4i9;;~bxKZZh|$nVY#&;5Vn~7N(?` z9~3ZJd|=gWj)r&{B@%36z{|hV4=486{bS#^thtp{68P_Cir+2(Fl9HU#-SzM$C)s3}y zc_u#)6%ma3%~lzA$u}489PdrSW(F$?Tvf_9B?pcWx>`_nhw@2|v5T`xVY(i%NxUNx z`E=>tM6jGp8q3}OGHtQi2Z}p7^KI$xChUk19&t{e4M3$w0;RqqZC&L?jrX^X&tlD6 zk0Nl}wdvS==-4Go`|8Yc_r1hly^p|hgxZG1yZ8P1reW2AO^zJYd6xE74GVc63!OkME6nTof)a}Tgk=(!0sKh; z-a4R}!kP0_HvQT=h*QyBo<&*i($u0wy=Af6EZ`3wV%+XDW>rjm>BL+mR=Vv-MUq1| zd@${*@qt^F#}Q0LXX=-!;fmUCfGyGWMK@k^=jP|il6~VkqVoIwZ!LBx3k&-*4S7s_ z*)~-AT#ZH|187b_7!U#0=(6Fg8*REXy+A** z5iCeSXZ5^SRajq1<`G|n+kO%PX z4>3J^U!+>FX7Zq}MYX_Z>(c)j{TolpVzaQhxX8hJ;jC`|w0>1gQw$FpB}f-WF31u) znD)J#)g{nYk*yp5@eFOSZ{mjv+C=+^U@?OFRj;*nWQ5k!*`k_-o9Kw0vltqTwC_;; ztG^R}JmMbX^MyklSeA)3ND3JKW65$)jQyg6yfh@Au>nB)*$UF(;x38$>Fu=G-YvTw8Jci z{0nD8v^WYht+aGxJS5CWgr*vYte>+Qtc3E9z8?-ACeX$Ob9d6fhF;F6!Au;ADZ7=e z5JHOw5ipAC@VmYyk?fse6}}ajg#(l;-D~=2&tB0cfqs%?bsIRFRwp;RL0BE2o^RUl zVmj6@osPQQBZ6AlTEmGXb_T6GL^V>Erl8l5BMz=K&Nd7$nRko%02u}ZWCqE}@@G;qLK zw-m!8!H#kUJUs+Hv&rG`eqTztaek{B*?cPc-Bg=$ zOhXC+4=jCE<=-QH-5|%sWC`J9dfO~_wkWi%^OlD$d2Kj;HAl4*X?-(wrsYWM8k<>` z&Hi_4Z2@bbcNh9)uMqq|nTd%m=?>M>+?JPcTiljS2ziXBoI6uRl<*-#cFI*7;UEnR zZi4h~hKW+HJ@-yQY98d>hh>pHz2Ajc3ewyP$B*4_TI<8eAM0Z8fg)r<2`R9I%!4E%E)H1x*2?@I9f9`G8C*VeIF0 zLmV*TfCKR%66!|J2#)uA6YqzLgbApkOgAuV7fmHn}LTnpkI~K2%3~N8S;jM1At>YmH5NOCoL6Tw!d30^h171gX_@UtFsp0~a z=9W=FPyLatK`H4_3VoqHSc=GIhud76m4N4%JbGhcjGQ}0L1M|Ix;81cCH6y9=DQH{ zfdu2hd+I|o*&6!MK5I?N3FgSm*oxyYJ&ws>VAQXQi@8@o;g%9xJt~@k4w2IFJfkmU zBjGU<%yv`#*tY0Noj1`+I@R7YJG8|)iEN$UHY43z5asXsUo%kjXE=HM%CY>JS^0&PAs17BrcL*s z#h))ozYJUZ8y4%=*Nm9k;b$+}=Ksjixib6>IuZl){!sxDOrrGM4$WEbEJv1h5Tb1? zlQO=J@w0f?{EfN3k-0|sT~DCvSG<G64Trqz7&KtrL^MO0o2p+OZk?E>b^GMHNH z?6+QM&9D<66r9xQY;SV?yqp3Wbqnj2Y|Yv-$j}`Y;YUW!%?5bZUiVDY>@@md?p~Fk zw~&{%^wlc~51`#~@3|fY0Lx@$H8}wBH`cDN!n@WNTj&NxzLsTr2H7>CY|GtQcr3;3 z2#aMkF6xnntshgBm*VNKHK})1_(X=RG=Bot-JbtILG&1&vfSLBoZ=h~X&02lmMDzO zEWTWN)3={9!zj$sb|%VHTy=grIZ<$1Zt+$0WB?PJ$>Y;+c1*yWkra-x&7s$`z;0S6 zUn2I+DEu(9K}x$%L;RZ>%#NkC=}hCAQQV*-5(-~#JAF)M+1StZW*4;9(9-&DOIWpX ztI$UZ+-2HIHrlctur)CqD!aZAkj@XXnH7GrRTxf6Eu2*7ASII16#{uvasHvl-omy8 z4MXJ)CbzvhzQidPa6M z@9PGZhmoUSBealon}YOSi^dT(YmtY^Q6jq~(o-%n$35-T?!P2Cv=;VnR;OJ&y!K1~ z`n%#-SgJvjqyGxqp9<imaiSkhp&Y~9a4 zp<$!rs-mHLYU68fxl|uP(>L7=D?;X%_tivI8-14PY!FzRL#R4NH!#dhb7xs0w0cm> zVsyii#NKGdAj^)ok!iO-R{cQfPKnfa)PR-)toksB(a)91SkzyiK^MNvc1#>ik`wfi zss3p{%x1^UJX~L;VJNAHFN{2PO%z+a7TOw@PYDgvhWbxVWt(KT@WNhNIfQ*v_6;p- zwW0{ecn%IAcK9M?VeCk`FW&QH&581iQ4n%HE8@j^TW8zomm&8QXz2($1Hj!Ug-gGS z(%_G$Oe|H}P*Z{NZxq-|nq3orHESxb3b2~prhvRaZ12Oh&!u7&4QJB+M|Gy0JtETa z`z4RD@#?d!?Ok>rNZw-bHDHW<3#@Y|JvE?B4_@d&GBF$WKAP8s8et4Yv^t#JkDU`u zG0{*~#L`~dXFE(gXAJgF;>^>uIU2s}Q2vkho&>0=EL*F7``cyI1`McARqw(VUZDn$Yz8<01>EG)Fv!SLPYjqQ$j*m0tARatE>S*FzlPMivc7McH!UP zu01n<>R0`$U-eV>y>rjG=dSPO-TTh+UR-RQ7!P+ZRA~~?UjR=Z!jBx8JyFeVkLXs` z+TP8I%TK=dLt|HYSx{VQ0zN;r&ulCA$i;{vNBoe#et-3Je)V+3Wc9oVr()U>Cc-fj zRl+!kl`G*LbgAc_6#Nx6KngJif_=C}6l}$`ha1xiZknn^YRiGEY3?j7IrU}EqOd1*o-vz}{(BcdE#z}+Qh=t&`@>DV>$oxAj7e{1hv z){k}LDNCTkyhCS2{mBGh?`N?TKbK#%(WZA$r|zJT8SSwXd;xA0hq3@jHs1y6fHsZR zWWc9^lWC-QVdX4HLS}9936emjtoFNr^?f-X5-ENdx$GHQu(L{gd>mJ+_Yu8WX+gm+ zr_2G;>Hx7oEbjr^t=#3~H@Rh`VnaCgP zn`r4Y1!-}W>R8QgWnvU;Il=35ns?%b;ghrpxju}wP~ZxgLO`6uM1xfhjOWeUX- zAEQ-n- zN3mlWI#sa5S~_vo+N=8jx0A%Sl`@bBTC%OU|70aaiX>VVWT&Ul6>#Y#UE5B%{0cc@ zlCP=|S=Cc}8C+ZMsvXB;;wV8$R$cSrPqginDsZAdFIDBuY0H;A3l#LZ_K0LoWI+9t zFwO+smz*Vyk2B50IkmYBUIV@$D}|`4qhyyu^=)$SJt)Ddvske8!iArSb@lUydk}sa zO47xJ29q~j`(CcaZGD6Y^RSw?vU>H40NZI*@q01nvm-?OMe-8>0lTpE=Lv$) z(bH+dL`2o$HwK4CCFq&<@wQfy@AL!N+XuZ1sf34N1bWhd{h84t@nFiw66jFu5aFq4 zI9edcd#h_vTC6vdp$_SJDltg3rAx6Od8yLHXA=5Q*A{qo@)|k{5`_=u8lf5-f^je= z5tmRh2W8u}gqt^T$OG(X=t|e~>~VQC?BlfOKGQLJoW+_Ps@-*N-sZds=0(|K^{ePt z;bEbUv$Fo==vIS+_wa=C9ry&n;jpiV5`^w?`*_%`0c7(8D3=BW7>FDlZgUMDe8Y%z zATN@eUl{j%J`8%A+l@2e`qEW3$@I80?@NVkY!Ss1)Hk+>6tyvz7)5Ohg*0hqhgiF| ztUdZ&eBfbu9Fu#tXI10cG<4N^=lV0SMEAXtc!2bAe;dHiNM}9Vb}T)pdC!?TS2-D< zqO2dy0{cns3HUH91KcG0T^{e(h)`zDQH|Z*nb*ewu3DLXnGhFwn`kJBkM+ZJm*afOBP&1QN4HIk-tp zz95fz<9p;%ZcM$;f!l}w#0+tMu;(w*|?6QtD<+iW%e=rD@O4 zO&s-ADDQdfRpX3rMOo`J$BDgjEr-ukCwke=-0c~4{jH`qVehZvog^0M_@^3O7GXsw z*cSwjkH8}o+3 zZ&oQ&gCjyPjQalmYcbfy;>xjUt`+(DqJ4W7E33{!Ua8<1P20TedCAmF+EL3s9zvmPjyS{DhWRMV$ zKfE;<+SwJ||8Pl)ndbx#NqzY_UiC5>FkBa8Pz##oej$Dp%4#UgfU0~9$^%2+w+d3F z&`WOKEFknlZJh-Yzzg^X{NS3<()9%?rrY|qsW%@g2O`_|wVAFA)=qu0P5HiDf#r%) z>{4!$^L(oL>rlBhx^?%{(q_fpLtI4{v^xpfL{*`&8PF!L0oeQ8H<^Ono%1bwVa&k0 zseL*Io=Ma)`P!kPBtLofPq&0!4AjIj#1RdW8NU4r<9JJ;*N<8Nnm?yzbkvwqSOcP-50QKc+>z1~se@o;&5l`$5pOB%}O2iN4bNYo??Lz>WQH)E%pFTzqog*+@) zRb_I-o+L-_0XvI zE5#?OWSX+GT&NWbSL3{|X+?}1^I&afC&^&i2W;P!5&9zVMIy7!*{ z51;F8YfU1tnVogAGcNV`WcbnDb3n^7FracVfKeTpf1DDSSOawlq0ai{^75oM!#M|;Y$++h>;pH}hSzS?S%o zVRRWP$JkP!iUoS6ZKs5V3xW1EOymqN?@yOgNMNHeeh`7t592p7Bf5F#*xa&>!&(*Tk5|0oS2X-J6=KR=;6<{d z3r_y--J-+>Q(nb-uVQ<3LNU$2x`xH&)5lDqy~;eF_47KYLk;gVmiszds@eiFNPj-} zzcStWZ?U)qDwtKvJ99&%EZ1z^HntpHLp_**XUqoj!&+V7 zNn1*`<2_$HLs^Ql500`;C*}P1ez#JCjm6zj&WAlq zxMA#9p*|`6bD+HU=lU8@C20g&4m&T+itKobI$`Bv{Tw)aZAOE40O~xn@}}dw)y5Y6 z@6XtOK(~6HQx35{l`~=Gu!EXr<$DyoMR(*}YH5b9_nDBP$agjSRtaj_HTzSBqRhO{ zJS+{%(DCXQ3D+Qf3}i_YI6@_ot$J7!3(rj10fC8E8d^qF(vfl|(^T<|EhMjB;wygj zT7#~nt3>sb?SlrDcvlGv$EL(Ee=v_fgK0yOTnx#Qmf;%xxo9N3qm?XG@t737qX2rE zBAjUy1Au55#My%^NrdXl5HnE;0%oMlW}XiK^$F{vN}y3tIj8DjmM6s7m;JevY(mT` z*~t{<0(KRaU{_&CmI`u9Ggp7hECX=a$o+WME8Z#ZvrM#rKhD4Vys5MFBtI;3#~z#mHTF9kl)f$-?CF4B3dbN+{)Bm zLcsQgU#mGpOb?9<(luH^QDXuGTO?a;qgH5jt~fd4fuH>8+=E${`f`Pfu97o+XhyA* zs5{6a0SLDR+lmYhRk+CLIg^J1LvV=?xB=QK05qclXf^eJ0mRbSNIAnS$ymZiAUS-{ z^V^y;?Oa_`^%yN_(g|!AO(U(gU&hP1Q-9ou%nGY1UDn=acK2SKJ=-8P%vqA2T8k1mf}zjW&th(3R1vj zc?X&Kfe1LiCbo+RUM~<{mjm85&+USr z4cz62nga7Ex}E*KW45Ek$4=N3H;NWGJw@q%VK~L?^k7LoBJkwv^F9N*`6#dA(nyJU z1O{mzvsLT}{v_;xx&@M{0+lCr?@cPSK*p&wNP$PRKF`o2+d}lY7Y%p^)i(v1FpM(S zGniXZ+Ed%0lbMRdQed3KNmBcmc|p7 z_{k5L74MJYs-`LafwGVbJsv^Ly(ryhdc_?cQ>w)%<28VyMpa9!21YCK2?GoGgf2eA z&Sddiu~@R5SX@OqnTB1B5=cd+p={kI0+G0Ch+BjVEGo>l^r2!M2QcHTmVl(5jV)54 zeORpKvC0)*#6pBd(vQX5KNkMxzpqhG3M5_zDrOJH)m=GE6IMb)`t(n>l4joU^w*m5 z(VTX177m()#J;k>I~@;n&5M73LU1bK`On=y=lVM8nLp5D3+#ZHrax8O+SsBbxBFRI zRdeM6zmEDl|J;(IX=jJesBpTwJkUAMb7lt{UenDWz>AN!U(0?EB)RE+{~5J{Ndvz3 zn4Ko$N0mkcQrpG4zPBm2Lwg5`e0u0S*~$JR;$n}8ifKsL*@(W&^#pH>!nQZ+N>Qx8 zvco}x7GS$92xnN7!DjCpx|W`9EL;Q@Xp^hkHJ@~ftg$ZDycAh`GdBF8sMPloT+QEyX2UB@__DO{vEHMfh1Hm+8%=)rDvuhm7b3q#{Cqj*kr_@c|LP^ku zV({tNhL+HKa|hlv;Vut6xL~rV;pHe7sG#)QJ|5L;-gtNQ!)eUJY3I~3Vscdj*+u^1 z3(P}Mj(xz^+(=4DdTukFJ`s8l&P8(Hm_9zn~;nhT1>#npelz1VqjGl){Av7kM z9v#>%v{Y&QHY3b)?Uqo@ozp(9sk{x(Rk7~J5-G7$22H^4U zD9;XLfNwzpTW5tFUW2J)LV}4+#ASqJqVE{PY4?eg9}-;D_FM83jgQ?JOkCPJYXkPP z93Ov`DQAUCclO>pTScPTa@dYycMaxUy8nV&#c8}5S%Wpas!Y^W9Lb==ZqX8Pzs&6V zQPT>m?~$o=Go2WFPlp>dE=SQV6zPjPA+TPfwf3HN&%1%fUL)UtCoi}yj0vnswGtYl zM)?iEv`p3zQ{`T=_AnRX9BEJ8on_+(?y<}M<9~l$l0O}O68MCRTz9-k$e%Rb{%G>H zDUi9NB#a8`R6EvL(nb24+<=fj`K$ZJ7T*wulq;v=R-h*ptxx}bW6Qnp$8>AGhvM%* z9>jyijV+_yg8P{n`QppmP-AIeER*F$%EF~fPzKs+WN~4gy5+#+grNnp< zCRrkseHnX6mPD4{x%K{hAHP3(Xs+d4=Q`Ip&$C?DedD;vv5nl@xDf=|NY+1m5<%Dq z2*R!W#6U>16o+{#6e zq|Y2=KAFX!HeCdtVBCg5@Tm>tTT%g%%v*zU2yYA)%gDQI@LGdePPCD2#4;GN1mx4; z9I<5kLSKfyr^g9lgi{}bp$Z?1chQ=va5I?+q(4qpMR;RjW}tN(i@s%bb)MYY~?1&HEiZZ2fcw|lJYjmxX1)dX?c7IYA6HP6kzJlXiyRd2*RlZLoI zjE)yO$C$KAVMXxxiz7!5V=(>xXX)J~jE*4fhG8ot4sA)hZ0uQswQ=*KJ8u0G_>alg z$_1|m7B6i#_B_w?l81rpA|P@a2_u{Hj-1_|^*5c3=EjK-$?{}R+vt~JL}t{P;1GoK z5ODsvYPPK`Ze*VVB5ee;i@m*aa+T@9r4hH;NVkDXtFL*dNczi>N8}e1(?ghMWo|A; zp}6tu(yH5zaeRs%|+mI(`woSGlt<{rzRImmzGQqh3#(`wn2>GFcpnU za#DapU#Wl>(?e{>VIxWD1@!LY;yakf=vLO^SlVTDxmnU%@${E91aaz>;Lo_Eg!*`~ zJU)-q`gqNgFk}kE*7|C15ilLB#+;fEK)m&U(5a zO`C?OmY>0h+;v!g<3diK&1@pQEFm;z2y^j7Mui9_A8$cat5C02w@PJw24aPV7!1C| zl|1#7Pbp%Q{{1;0h7=?uK=XK~yn-r$BYpIl9@4xWHdyvsy7Yy5wODTks|KA3Y~Wv( z^Mg9w9oaB`Ha7yv_t#slVP|x{F!Ib)ujUjpnW6Y_A;P9GFawr&!S@Pjl2&`C&W=Ps zrXev+)=o9udL=uVJZ+K)MGls*f+dR8tFc;lStGE7+%4FJJpYAYn=YGJU3JFAm>(%Z zjJwuptnLYcy{f6KcyuB!OcX126axuq#T9NwUXkTK$Q&>?nhlcR> zl@mKoMU63n;=50PY-3N5kVw~E4T4RHxe?y1dn!$87-}Z$-u9h3GbmTjdyLB4g5fj< z{$KoXDwZ&tHL3|HQJ|4Q+>w)0F+rdLKgj3u_%MuMbXI5L$jq~+Z*@4wk%%lsZ3!EPv1Ock(PH7RCC zt{##f3JU1{-PH5E&-Lx<$xgku@YFbT9>rjW3f4TdVH{z50LxYRkQ<-!eYVHZH7#Lx zMW9?OB|9TWCx4xy&jKNLPi`*KT2IOamj-4Uoiz`VN(D(ZyNybzofNktP3e2(C?bJ? z9AhsZ6BjI^@R=QSmzTiiM_6w4tt9hXnFB0^8s^tf(Q^iLGf=GQ103v`HoQ$+ zox|uk|My$RH@np3`iCVWIuCH&48mR-0}B+k#odU|NfI*AljPv%bA5xV409C77^Pvc$0z6T>3-ukh+EC0kfePutv$r) zXp6VKGhM>y^(k?7YA$S4eJioF5J>e1q=?e?fyiPTJS?&e6mkNlxDj#KUnt)GV_?%9(0i9CZ0%H#PN|lzXvp-uptQpUd zDTub*`Y>JA1d>pHNJ9#L9;Zj=>g8uo(#tA|NL5(p3ivn5+tk$T*5Ud_(}(qtFx2( zfNPnOgG`?`NqkHcz5A3nHnRz26tAr5C~QbRXZZTDIv2@iF`GO8?K8UA6TZrRK;;`i zJOoZW&*d!rU9O%Y#m2zX#D|Nf4Q6BR>&M%4zwZ`N0c>Op4!pnTw-kUfd&ELH@gSVj zm?*TRCD6r!CST^CK>b#~IIQURb~m#WxQMMHYo7)#OrfpB)wE!Rc4Wzpz5sSH1_#{l z>L&xJ%>JlAYaR8Mz#(7!Zs_Ub!*z7BlIVvHV*~RMN$r!U^6H#7NFJ?6jFJJQQiIyfyhIw&MSotU~Ypw{y(o%I-YcMlpq{(c-Vh4UV# z&^17Kr%sS)PtO?4ka(M(+Q#u2C19~eZAIkY7E#pKjixjAVbT_ubkii(ao_QuUI4|? z5NlW2pgRXXj2cSGFTgn6N)Ix7!27&~<28G|T=AvD$^!1bzcBUm_2HuAtdP@ziDqdIc6>pale}}dWWYWq2RaK( z&HjRaqkt>897Q{jlR1uV1@vMsg?elRGO-U^Y#g2Sx2{9lObpN3& zfkAP(HJ~;$ze4tflccZ%rD)Ok@8Ie7s>v|7f>p^~!D3@7$CWf4m(wAng|m!338Yk$ zFXZvq7ppZ8LY}H~F^&SMW;CFk5NN(5O4kJULfr|h)*X;R0bl*MC%qMjeF85O`8^w- zuB;UVCd!+H#qzejAeNX%(RO6S81jdQ1MLUJOBBRx1&I~ z2RPhT<>lXH=#(D8ricf5sgw}ao~g6XRZkI{P&B^=M42y8)u*KgXfhvzJlfH9Srp!; zfx{{2x^U>cAC9=K;QULRIz_h<@?lqwrVG(o^9i0x$c~QFWq3 zW3h8R_mwoG<^xrjcR*8Q06RncR2rlxjLrj6i{XD(`R0-oj*~L1=_m~2lXjA|QBmyY z=4!TpAo;8~mUH5RN}>XG4kD$wHbA1NfV6)&ya%*STV0uH+$Krw*G^c+VHpsIwt9kt z7tne$ER*&39RJ)+1p`u_RWj?p2?52;#~_{+$M*XJeVMcN{(RBD+wfUzTA))Qo@eRS zK*|A)W?_TiJjbFTm<4u@P7Dw&U_bgo0+~9zO%FiOB)30@*yk#T$$Y1yXm{ReHari& z80;dDick(;XeNSV=Aw4O_|6|>6L5!uul6)pzd}CB5=f7=$d{i$%j^R*R70{s)Vq5m zY@#xq4auRhmzNNsU$GKTJde<4pXo6UTc@%>a10foeQiC6#Rx9kBL;zywSp|SOkE#P zJJlr;;hjmtV!d5W>66eyrt??F5@@$zP6x27lhC3m8Di)oKvgf>fV}l4MvgWg+$t52 zr_Qb@4uaTH!6vrBCU}D4t>7qBpZ)`2ybg@I zGN8s=aL8i*)63$;)Hq1_KwVyeO4UvM@DdhT85=H{&h z@C9#M16%KWt-#z5y`^ObnGNvQ105yzSR`HHG!8TJJHjcwk1hW=a2fe5z6{)3z9bG% zs1On~Vb`GKA2`Ken-~dcga@!B+ShMAU}7hD zn{3O_cr~BE&6O|PQC&2sXg(^l=neg1(7(yV*wfL6EAw=Qspn;A`-8T@oMjX8Oc5N# zG?>`YAEutCVT|Chp#xnEPP7G|UNyIlIBYO}=LXF+hoE1h5}v09Gt9-7lAnpT&ABKxAbB#9ElD{;M=&`PrTD+{spX^7lN}D8~fNnhrAQ}1U7cC z7Jk>HucPFpT?9o}$VGD`GWXoBEr_JH2ni$=+be0}-WI7b!49IBCrQ+|d{U)Pz^up} zQUUPyxE?0lX`d!8_x;_GMLkBfECEtxX%u`Fo!-ROtKKV`IZL#$P zvgwb=#efX@v)U{ipl|#`8l&)EoJt$Aif2K5h9=F5;sB6n$jG4}rS=F&Z3I$7?SDA= z=UPQjevXr<+Zv5L&AU)g)^FIw##%dnzPYY!;>+3~LA+K5OEEN&Seg%zr!GdG z82~xI6B59eJcq4C4qsDAjK%JJOk=$1Np`RRN+RD4W`eq;C6e2eS%z{$NI;2LB6E8Q5T`B4jbH!#1=_K+O0k zYjQbM1JES7=DaCg6f8onIV#@D4BEt?ZI}{#j&11mE~fLZqK!wZWRzoS0em5Xy9gk> z9ij@kNLW9AFY`UPuQPLP>ktVkF+;Wc&U*H-xAQ)$6qKn3L=YTAx3Yl{j!nYAQxB}h z9yU|{cgRa5De|#O#9Tw0E^RTO6s(aWTBnk!}&6Rv1&Vi_k2QQ}ccj(>c9}&(d>~ zh2IO+(_)z$bBK$ppnzanp+Z zsiA^XvKK;bGueKomwR%@bwJ} z!%0_+L6x8~g~<@9GGKdjar!DeeAxO>wSq=X!Pp2{L0zJbFM4 z`B}Vt)%)i&s(A22#*!5s4O5Z1_B%ugz%LZ{5dS8=9g&)GwVvMz>k5nL67tj#ho%=IiCs*H%D`oHSI9H@?)vL-Hb zqXsB$80b29SEw5x)Ix26gR0>~ZZ5fZI@%J*MJOzG#JfD@!?u+TTw&>>u`r?-xK(P= z--qi-Hcindauo3%|AyKi&48QB%+E2|gMfJ3u2*wOQXE%zb)~T0f+&p||Hh+5gIrmH z(R~p2>2uM#>Vm@!Tg`k<)7ijRB;`Rq4@t{z81T86=m*gbb*B6-T4rtD4|LvYz*1kj z?yx}r(1xeq5?P%R7C#@HJCD;6NlTXm8~W~fQ*Ft2pIT7dMk96 z{YFD=TCpr4rfpTFX$7H4stf1*iMfmY4=<9=rpU=T9z%!!Tc?b$vm=q;p==9|AsR${ zAg4y_3kH8X$3CvH4yHG}2P>m$0!(^Bf=+}L)DEIS1wyTyGWLXgha$vr^%Z4%IvWEo zlBK*2821QShhLImqv6ac7yxonLhA%b&Cm5h0psW{LQLg*r=x+0;)O1H834us1B~rh zqoHROprkkJw~CH`1h`rJYh!frz;m%@8jfiH?Qf79T>Rj3)0}QSz)){$ zr?9R7Q1EkHeehNR1Yp$BPJ9Uh2#_W4ehw!lg0j*6S5>|6n5L)#L#B%pTQ&K4IQ1~L z7ynfXkh$vhQUT2pW-;s$%0Y=1BpLEYpMz8sFc6X{R3V`- znZF%4%vS@_`3XOv(#V!cQ)E9V{S9mr37kqL+5i$cpCFCBYXv++Cg%^+qXDLvvV^&w z&niRe2-OuJGTi~{1bIg>51QolJ;~r!@JW;LWl+XI+g|=F6Cj)uf6-eKtocJ)vjrNi zA|pj`^#xo)`8A|)Ps7S53~f;>9Sx)1cW_+QhG3Ky+m#B}8Jy#DH?fEM#BO%su#AUR zi7comx@*D^5H#&W(5?orqRg#A0!u7_Nw5jpoo{I@$f~IKv4?EF8+eWGL8!m9H$`{{ z9>P3On7R$7Re0V^Q!*|6IB6^*nl6Sa@lHQi6e1ChtC!BUbo*{aF80kj$p=M3&AIKe zvFB0PRnqkya{6<=%EDcQQ~#2AgldOgdHHZbX8fS#vq~ZrgY;N#&kB;z-w-za#FGqA zm-!I@GMBGX1!jGvv&vD;_fW_x72Br%n09=i_zfElIi<0a35k`W7B`nQU=D5d&qcJL zs<;<^{|_Ar;Bh&YZ66sXN}~ZVGRK}Jh_HKx$U4`B+j)JRA(`NMX!OWxEIC7myyC=&om zJ(Nvr&W0iZj`m>DlimaMLyB<#xF~Q*{gGV+jQ|bH(|@Wd*Y#- zia`no-RZR;H}IL!5MKk!2+dq81*s-#8J=;MBPV~DFdfu#mzO_2|+57l)xsmI-*J&R+F^ zmVfSVi&ZEG+}ZvG%v0Y*$g73>EmV4WQxIJjfCMHz)~~k^+Bpp!X3jIc<}hw9=YQ8* z2u=4-FmH=x1opo(Xr&g(*M?B_j1Sk6F=oKww@m44I2c9QV?)I&kR$(hN%NN&l9VWu zRj`}mYMa$o*g92v{bK7%=t&ZVc?(nx5uIJX*lO0{=Gs##({P;^p`Obj2E12iUwK4x ze>jWsCRZcw6ly$3H~qi20Qnohvkv(GD;yw4hl_|^z^DW_SM57Vv~+;bPJEMy@V@nk zmhW4J-_e))c0a7dczftJw(6YA9@7UvM-knXW2}pO)$1*$uhuN z;g5U79P_Bm1nhqs$&IMB8~wM6)>olrpQ}czSQHlV9#%%n2D;)L4xLkIu+#kfxsrZ{ z3Wvj62!zW}d5}wLs&2~|V(vqZgk*N^aZ1;#fjqg@+n)X&WtFV4e!B&EvO}QBZFJ$4 z>BDp$*w9{RnKD#f#Uf9N_cQsWEpzz}`3c22l@iuVn8+}GUp=i~B znS?+Cyh1>4X&KzViHlI>di#K8R0TzYl8s2SMTP;2x1BlA^cg*b6{y+@wrp%UW`Yr^ z(EHWOj!^M0OlJUe;BHx@q`}EV2SFkSozciiH%KVX;~fh9jQsCpG-fS4h7oybO}-4_ z9HJOyT3t|o6lT3dLsle`NeHQi3F>!Q55XW2QFm+lf<+Ydmr&fVU)7)xauBX+D#M!r zk&LtPXe5kKG4TEXj6oQPBr3OdFLJ}E?S`I~&;%jlAl8dSYEB+5Ok-dRROp!Lpuc{mlVwYo0^$}`!qyCJG57zi zEBc7W+Xt6iY)EUqrvAcqU&eC1XtCjX?tolD+V?3mfU>(_C`%=Rks3qaWKLUFeLYPVFniJ>QmLPjlV zWHXn|Z5lV{INR_Pxys8Db-^^I+8*WyCxhAq8%CRirV8`|B2H5-aL zkmzD%H=VEE3A&4N6{|r`26Yne=fl|KIxF;N?i1Zk;RaZ#G~TM=6WX*7XPqd$!Vx~1 zu8C3sD$KqYeE%`kFyj@je7G0^{9GRx1|5GcGIu8Lo8gz5I-l>`?#^!#hz7h>+m9Sp<_6|Y%khleRqWKVOW7W*Uu65 ztPCjkSju?PnjqRG6WbHC80aTi;~|^9COfb<$Z97PtXd`O1k5Q=%HwSH>R8M-CT^>G4JQQ1@2c zzYw>Y)24e-6*Hc==TR{7^FX9+z**k*@FFpjS+?GabK+Mc1>;t~Ca}CbT$P)jY)fc* z$S*^X*+;>d&pd}ZPv0}XE1Lo{y2Xdt{DUZ~)EcdILFLoM(I*eORZ^4{cawEj_BdN} zz0199L2B_8vEr1t!vt{6pJ9ZSh%*oO0bBSp7b1KZg!i~q+Lw3gA8|%^Yy%d6n<^*n zy4$C4_xH&Vii&eY(lgG8vyW8^pffr*)ZO51w@ofjV-1m4t$pI2?mP6-$Ko!361Hk4 zbRQ+ksWY8*Z9>2d9{s5Q^L!WY*)F={^QsCplUOqG%fUWzyF53T$39l6nq4@B!<k%X$-sS%Uv7j^tYF+Wi(`v4rG0V|{1HC*iU@ML{!E`a?*29zLXWa$ zl!xW^1e?^6mXEtcX8$pj3QWOH&BPrHVw&Iincn5cM+im@o9&S>v(M)ng5thmn`Cy4 z6r~3W6}eEtij?E8SGXl1ZFCQou79PXqrZe})6M=5MnGKApRxi~wNj(=6m6b0xow=2 ziot8rOc}el-VMM(>4A?p-aEEx&PtT10r0Gj^ksM0nLD;6)+}CAJkgnP+$aEM$`JM_ zQ=)8_;#Exb59+(!7mT|Mb$3N5Wt-*Kw=AoOj=a*O^xYZR*dXy(O$4*_1MW2|<|WQ# z(F)zd=zGA`$(*N{fR5Nw(42)1)#!Z}1MZ0yCX>)_I6Q{9!ud;B)i)VT<*ETH;id~<l}K?!b_tRsh4SbfLB@OgTFLk}_^De3nq?wtGZM)D)Burgn)y_PE8S)#y% zf?f?{LtV`equHp>(_+F^`N68Gw7JAe^}?ZdWbON`wOx%$7rE zA}gul!joI$;Z=lPT}<=A5z<}$ud-F17h#%QJCt+uXA0VMBR_7aTRtGO=mMd%E;W<4 zKB}qWoh?Wz_V0VJaJSPqksUkd7JKl+Y$LW5z9KmJp+@oy*p%KdyMuNP*yG=a8z=24 z+9oEX8d!2<_C3**xEMP@(0fGtG^$6Iha`ZFO3}W|UH1p<&LvchnP_LRUvTH#H*0}m zwst!TUzI~XUqPuPGlCqNtzH+Win$*RUo+=@hio$RPH0n|lbfy?+Ee&|zZ+0XJ5GnES1o=fr1oMp zX1vq(bWSq|O5>&F`~Ci$lX1(s$+}Atr*Y%TJLigeHV;QQ?UTb@u+8UdXtGZkKSW<&b5i(oT>aHlE7xINO8RM!gwZ}sB>C8>vk$F&&4p=@MWWHBgPc~N8+Z$ zVMQGo!l!y_+Ac+X8_>6pmv78es-~&RS!jdPpERn3_dGB7J|8n7_5S#zQqnVD6Z1+@ zE@!U^i6Ru?Q!^2(V$rr7=yB`Z2^jE*%m?Kl4(Nxfi7Tw_5~^jqA>fhfF}FXv)-kRXBf>mx9R4VvOoLv zN+oeKsZS)KRYtz@VREIqo_*YQ83I}P%W3T~jVe!?pEAYq;w@r;D)Y8E?y1VWVBB-3 zGfy&ztrn5PbN2-WmTG|HpQFjo+@v-1GnTkkie)9{;%(I!-+`Aa*5veOd?%bfx?O6# zIiR)zikOe*oSf^aLJz7?UH{rHn=AAB$@OP4lWo=XhBwPaR#Vf;7e~q3DI54&assiQ zmUsCl;F!E?p}kbIL6{Ym$JbJ{E1l+IIOCoC$npu5(nwLo*w*p3k4Lx>A^MOwg&S`X zIyP2vY%w#^R*eLv--=s*V05@6`#0xBxVeE;aaZIpvT`Bcq=cm+GF;PeR2rB zu%T`SrNJgrmCQLOy?-2}Yu>qG#i#mMFmBJo;AU+Q%78K@$9Zc`soo^uXUnyxsWg0g z>wzlI?79tHX14hzTg&ffUk!e*uHTit?@-0gkGLO-ayYzBgwNZ2WkHcF(}9MT_4tN* zinkt<&7`IkhY*-x(!&!3*JSWUw;zkJRUH*csM089=izO)EDKBf7f5vO`z;u^^Mv+S z)hbWK+&;hYA;dPgv9L$#`e$o`v9I?sM_a_=|I_5HM}srQJCVEsu08{0{k4TQ-A=`k zO-t4%w3BYzsv)!cD2|)pRptZr!)I%jYW}6ein1USIeMkK==^cIgz3!f+z7c&ibCbm zVYCd1XRq>1$}r5Q9^jn(G;uIKc=t}xtlPiXS-G+jc@6nuv=?Aw&#K7VO=tQnaF$uG z(r7NGv(>ZWZMtK7t2`-UGK733&dI#m61rwGYXN9~{CafE@8}}+JS;mGTd6+zYA5Qk zg`JGt{`>u5I@RwCJc&yF?^im!%+B8y;nP0TOI$Of!|S=%T=u2x&bu1sJx0xO54Q5w zKM<9#yz(2L=k>79WHxj`qfPg~B{>-a1QZP5?3W^C^f0bfC=M#tuTR*kV!owAKHlqY zl4z^;#T|?7QKHC@|6ha?i?8BZnUa+-J5S+boWkeDLxnHwm3sBjjVl|w%2g6=l*EBy zqx+TW{6u(W)?|UZ-w~%!33U&qzo7b-$l+!kU?x3f+L72r)Y^ZzclX{BM z14W_Q^S0*<+$GvP<5RjVSzg+efd(~lci}kY(kqw#h#Pxa&?{`j9fbAv5DdvvVUsU; zGoZ83Z5Q)a$*O(6w)RWn;s@S~aoUAgPuFBYfk-$uTyX3ZRDd0R5J`R9!prBfh;W>e^LUw<8t*Kxd; zD?J6h?fO&=WFxDnA%CXGUO8VOf_a@FDHJz6pjJht@F7*_^R-=GN-aJng7tXr(~~81 zCf~G%H@6EO4qazx7#1GdSgD| zg!WPmaHvT6Sjp1}GEGH%bo+WGf_ z)gYOBI46tFnauFV2R~ESZ+VIJT(3GvgIXg`9P)eLhd6DYTCq8eBQF(TzTF>@_*gta z*jc>OcwF^v=oVAz8(`@O?6k%Y43@cOEuN*o!HRH_=dk<5TOSTJcg7Bpypo^mLCiyb zoeetpVf)XZY_tbT6t_NzVT@)f%p;#@W4@)b3gB`s62Ga+GtFXWVLt@lW#?EFf8T1`c`_`c#H0T%IB2o657OdJ}`s03@ty(jVo9p-oYRJ$knXZuC zFI;ze=N!+&;7=bx1evz^Ms(cWqo=n_?kD zNQu|H&&re6{tDljut7A+j^7*n6W{(J zS);B*G=Xi11rvB8=4(XB+Gz>6aciNt+t~p_T1O&>8A*NvF`fEcn6;C!W}VhW2*er-~Nt5XU&EWQX)2s;O>xqe=~fZ1U%Ou>J-;)wVvBh zm!NWNzx_8|kVjtQ1}=t1tVjN8EXZT+&6BNGa}YYj48^_$TR;l74N*fZ=n4um99sjh zp62ijCN6B-1&AI(O-P8zWx0s?gY;l|=33G9t!EuDiF&DWH8+h6L>xYH$i#(4G)vO72@cX@3*F9Sh$J|5_f9IUQf z0&h=e>A0|t2rC_`(5mv^=>}pY+3Bdbv{O+va#=|tz3etM8mA; zDEL5#W=0mNJg|9$@x{d$K3ozRucfZ&kwbSg6`E#JMoQTyA;!}<4M#G@4;K|*CaS0_ zXiOt=vpEkuWL9?YcjJPe=!wyeN^nj>Sff1EXZ6!9X_!50a{ZJm)Zn>)#?8tlqlh_6 zaM{@@GaxernSF}S`)M@uUtrj;K!r*u*}p9v%tJj6B6qYSVm^w#>`xCXYge%PDMf*A zr>GGR%)!VMjo`W(e@mWovf@6=jJ!JMP;n7}Pzk801DU4E!)gSgjP4LKqY5<@ho zVYi0pgZ2x2wW5nFZ+pc()@NcxNv8tE`D&XWDcEKXuz8=Hjid6dhz1@o=H; z23aW@t6YKyXIX1425Uo1`N}1Sd-Y&CVo zJ((@G;`fWKHUsPqL7;+9Cxbm;l9MMeAwJ97ZXuTSQsq#^p257z<6~< zz@QWbY9R%;wnE;5(8llkksRb60Ns+uYUwUnP zuuQ<{hPpP((shMJ_EV%pz`du^JoYLLBA$S$_`5&DSlgVpvkRQA7lBOn*3m?H?~{= ziGY{3M)e)>%ZcRGrK9H@HgOQi#Zrrh=(Y6J*VnhQXD-02dZ#}obWp-5dT`Jqh2kgJ z*DhhnIZyiv>b7!Z!t)}UN02fTGGKY8o7}{at=6Q3p8MI?Q#)#+*_z=_o#DT7nZCAz zd0T$zS{I0H)_9yr%rNm9l|yQdpdV_v$t>O>hRHXiy%2uUfPMY_yGqIETLorzu?`+d zgAb-^hCrx^BU9!Tts}UJhj1RdnDt~npLux6e-F0K2fX3v%Pw0b^6Ig46;rb{N-|C) zy>}SLNrk5`G~2%y=uq+9fV9M6@Z!oInj?y#8%JF|zUg-Fr zhBG;xT>o1BB`=0y1(OFBEu4D8)()MfO#to0^C3itvmAvTG1L{b_fHiuOo>-!aN8~NuAGiy0ZB#kJDuZ75Vnl2D z9eLG?j#d-jN1Bu9BPl)c;Cn|JEs-zq_0vSK2J?2-E{U)+spqBjs#v$Kb~C-D34!slNv`E_A;JlbbK z>lcvTD7iszbDhyhu6mf}VeBdTw%@%?3n4$}&qhDCJL#jav1s9a#b`)xV<27?_eNTy z?zqYW8mT)w6z_3o;3(6Q_*6((fIJcNfpNb2QqL4iPOlxr@KJTp<4gFThqB}!7ch6S zeotUt?7SuZ$*8eqpYa~Tv$E7T#v!%e3G^>in0zS%7hVv4_H{(z88aTPYD)V9`1gh- zNB?pd?R~$XP1o6Z4OO4naWW8D9^y&VfZ@TJFt3kuJ{o$Iv zOg-f(OwQfIbDg-c(X(HMQCb~4a%5K#EpNuo?j1uLr5g!!RTSSdi2bMf!&!1p1`32{ z-%UUDxZXnvR|DadgMz9Oe=L3DT!iBsd2zScZeePOj(4)u^J)4mZ})P9vIp}~5>g*; zmLoJB+^)*wujP?=o%qxZwsWT7T>piB73xvX1cO(!yl>CKZ?kn>z}?BZ`I@GGvM(Dm zic~Q9P971CD-z`t!vtS{(|nvh#|!*wb=mdr>yNJfaAhKbBP*6?Xp39qQe5@ho{c0$T@%7%-R&ZR5PJr+Fx(PJ7Y8%~c_yrn~TT;Gp~_ za;^r?^(^Tzj?0`TxNI56T~|1=X3rU?@_#!38`*dVHqv9v)`$s>7tbOJ$B9+Z9^Lqy zw~=0;-$Dh3+S=^w9#3t(5zW!2D;#Gvbo~dn+fIWU#I_sg#5v?3MuOvlwBxP>j;w9I zGMCNzlu)WP=uFepFY9}&rlCJBM`-)ZA;y`C#2AANR%|hMPT_cHZdxmeZozvP*ppiS z6S*(B4eaRD`5wlWYT=dure)za9(|u5Nbu&bJAvx+aG-j+hbNf#%^r>G=}p*^Avl4c zrw1GOc95G;qWfoQ(cy*#5f>Ze2=j{DRBx#6+_z6Hn)uufI=AehWo#}&{3$vf_YwnsX5Ahzu1(=$ch7H}A_Y{Pa++yPMGQEIcqZ;FGX0AJ}M>P>(#mX6!kA{1Whp?<9tCV z4s0}Re8`tiyX&~Me~57zG_Wn5<8aIIo?})of-QUnd~R`MS>cczwiGbiQ)j`ZBlh#Z z!M{<_xUT;4SxJeXAl1ZI;4z*pRX=r;$bHz_3dnim7w-PVYROp+rsZAxt{1(%z0bof zHl=WmjEKuY^hc?e#SEs00Wv^!gChe9IV zNb0vs7-!Ob(Ia%?{!em)AvG9^wt)&(b@LxJ51pQ(XN@%8prwkhSc<;Y@;E1F)y)NStK z(+-YaxjTxHMs{fj*rz3M7BbE;MW}h6O>{hQt0CMhJR)PYsfQ6o)2W;-q5jxVcD`t> zTkq3k53ih?-^tT0<%c(YQ`fkj_3;%=Kk&skBPZO(5qIL|3C7>+uV1ZR3R~OU|M%Id zo{h7A--hqgsTB)C(`Uu%celCs;|Di1K!RAtN8m9Y8a(chV~c6#{R-8UMnz15|Xw=POFHqq$1hdf!L7weWNs=KZkV_a-&BRO^P$MO2G+-QzgCyX({-?bke0 z?XEqqyWA_X-~0W`$+NU)>3JTj{N0U{4_|x#KONf@1yfrO^=mLJ zD6V-&Ka62}jZ!yluSl@*m7{?RiwaMZ$D`-sZ(~8tK!rgx;FGOfU^!f9C6L zn`a~6t^qXf2SMKgK@Y#-S7k#%;$)0e_PJZso>5v5EuK=JanEOq0L=p9Hs<(d3*&IV zZ#V7uLwUQt*<<0x0C<;lc&>j5{vU|Qeo(agIBd`0Sy~J#=UJZZ4Aq4PLDhL{hD(da zn32sm`u1&%pC`OxFeb#+?ij1um-kND2n#$dHAgDgwJ~z~pjYoU4Vk~&*uP-Jsm+yV z)uk}uhOx|`G-xzy5V8eE^+x!o7oLg~vuSgb?NE!#`VGj?&}!J-<-W~5%u{&yYs?$p z0fODz#}x?zqqRBDC%67Cp^@^ew7d~Xb4&6kTF=o!r+cHu)!kzwV4y{JISyY+uw;ye z*B3;{e&FhNA6!0avw(R~KYAnQ!lX(Z7CUWDy{*fBMKv{4us8c$?)>$fi^njJ;$i1t z`CoYJueW%}do*16Sit|v=;B}9)z!)C9?wHXE@DK;E+4ji#0)tdu9JzH-hayGtU%Bs z888VI2iS72dFM7Xk@*?i7B@Vd_QLALs+ zX`fRze>aJ4DQ@K3;nXZgI2oda4d(oF8bymEM%iLb$!G=Zu8{R)V&fPzryP^6`Tf*KyXV$RGRiv<1 zDv$nF5B=c}5sM8W{$g)_kB6NOIIy$kbuZ(sLdl&|;=s3d;PrwxIoR7$V9Kr#g8VHW zo9r>w)D@YgKdlsokF{wFt#8>ryl1?xcAYRhGY8H&XfrN}GYBy_>1avH3QRJ{`%odT z7Uh{|YLpU8Ywu|)o*RFu=A&2vcYO2FbGE{tzeqS$b(qh` zO09;g3H0^rpFWSdllxTk%@usf{S*L5U+HWE&Y+N*&hA5H$3(qvTs#5?7GoDHI1Xff>hyZy%Qsz~v*y!$2J)n0 zY;Qf|g|o!W))?%}%mN1H;@4;(n6fgc=)|j3* z4}M@S9A{f?7H9rl=v?Bi>czOwzBf;f25flMVBhqeaB=|jCH-_sQie&4^;1m+c9Wgy z!G+G;PWN^(UNK&q2fs2$kL|`RL9g`0s|s_hAErd<`byQMt0kLt{14Xi?bz}WyJI+M zWAOGrWK`jFyKDXSy|OFmNf2BJ(QM9D_&Na!=V|A4B1evR;d7bsd!tE=gf!pTScArO zVDf4AeCVBOXmvJo=DS|Z+4oryeY2C*e@@pI!Y7+$;{KKz<PcNL_@1iRf zlN=|0c=vUV!xJ&5hs-57R_SnJ#nSD&E6S_-7JU0poe4f@^Nzbt)=tRTMWg)BnK^+q zTCY*C0jzLL=+1M9CpZ8Yek`a?TlVXq2X=8#YyOw_$n~m;kxhI2GA_<BiT30cD5`DwsO~4QMVKuxbQs%4JAeZ`&CHC=^sFF>o z7w}ypM`-EqF-s2$RfH(P=7oF62h!x(3Qz{9wTW!d|x~oJjt~0mPi$M*ciGYxIDg3 z5#IU9m4RDw=-37K6!HVp_Jd zHucNe37)NWfI@`vjkdC#`^p1!_Of5zpfaNU*fB_~t(8Q%S8`k8QMulB!s?9d0s%>j_=2$4AC zU;L<+ZWa7szxJK5GTp@RQ!e+ofC*Qf`%C|XtbEa1CY9d*b4qXc+ilq$r&o!36DmB{ z=VEHZn=lo1d=G^lg)gwx3YrO>Uce2GANwf$^*i>ph2X#63qjcWm3+4`mfEq*lLY=NbTlYjSrIHR=d* z9G9hDynI=`mNfB1eo(IU1_KHbStbRvCo2ClkEmR^Dq6&K4eN`e0S<*qM*H{h9mBdIs^M~bGNC`ZH?EUAlcP-t2CbW zy=j{$=eMGZ+uh6E5+~p9ZWra5_MEV7RqQwS^;K$D5jA1OysS+`gH8H z-D?b{W?+{8ld$83-9g$OF@W*l{XzCNFVN`M@N}w++Yw7m3B=iV#n-)O^kVdW_?&U; zs0R6xZ5>{B^TBh|Fanq3t`Y2r!A*hKvcmt>QG7U<2|4b{fx-)45EFBIkZncS?ax=4 ziV(WMurNZK%`<$0m_bdBvfguCWBl5^6W@4Pqv<157U?XAN0|vUf3*cps*`&~8%S0} zTAOEB3RkX~UuJ$L^b~Dng-~bE^WtnP%3UGuGBfdi6~fjN6rvYruWMu1O3tE4k**^d z6K_F;;$moHW@Gu+j9DRHs}=Z@DuN3`v$%`BdYh;gEL2-gsQr?hOl)}1Cc=6Rs~@WP zw?u;^VtmYe?2j{fi!W}mt{H?8>dN%cJO-WLS`TU%@oJs8m!dO4e7=X3F-f%ECc(H{ zg!Kj-e?q?|yl~ll*~D`iLim${2^QVG=GKH&&h)LLF7Q!swL*|UQJGn2dNx`7Rx)D5 z7D*1I8Slx#hdJ$-0`>3M7(+jmpDT4Ik2y3{Lua4K@z9(2N{jGOj6k#n%4fr~kmWa_2_>^Rr`K!aj2=vnUc+woXRP&H2ci_Q5k*?-{tXDkHmisyxWf^3PCB8`dlyQ(gL;a88 zox>3)^SnQg(wmT=XfElD2cz+k%>5ma2NAbqwE2$~{eDQTA;~+~XF@e`?;fAVADPp0 zl4!gVmLkT^5uPK{#dhRW=wTsLE-os`G=@(3CX^)qYQ~X)-NYstq4&XZL48Z3hzrpS zy7TA7r(=5#OUhbD3#qmL)Bg-&nrn?VB_5+BEs`0Tkn#Q!D(KXe+F2o_#F4MeyLM!u z3OTwrsOR;f;dDO_qd72q8eR0=j4@Cjm3o6?e5|AUY3j;@nLbj$6FnANYv?iL;_c4IJ<2L2?D=Wv zWM*IRncVl{96|7_Rk?$1KbvW+Al(CDgDRU0*@?j4JmiyBJ7c1CH1wsFKuGxvTI7AY&T|ewIqv~13nFK|8eZs=V1??>b&B4I z>x!lON&9b~nAhk*>{D*%>TB}**c=P+L4U$U=m@mTB}Wz5-AiEevqr!0aO`S4Nke?;L$&dH(L8Bw20xyISa_rG3>HQ@qS!{u>WuJGE`6~M% zn`R|PQ{Aand}!GZkk3**5VIQ^BoJsDMhLqQj7F>C*KXMTIm+EA5V4~ZP!4P1AGaZ1 zl@X#PLj*<6+ulTI&A#|_ba8E~8MEdDC%q$g658P8WztFE?zpw%mL>dwtOe^JmZ8tM z*Y*cOfvb2hr}6dH;ZMhW&PxP}u?i#yM51FG={_4p-{pJcPZgL*q27j@gHVC$HDiu6 zFj~Gx7}pLgj3O=~NA*sWX0?m|y`gEedBNx6R`|miNE$nfQ>r60?)M3X`}dn|3TY-p z6dbJR#uQ9B9vg9wk*)dV{4HA-(h4xjX3h-J8XEe|=~lW;gzFY^-E3Cp`r>OIOCpX} z8SL!_@Tb^b_o<0ojqLJHk^X%Rf1vWh&{w`tWu7&mAb;Wq_`5YYM!#{3=z{VW)50!p z{^$(E|3Q5dSC|Mjb5t#UDRvtPnRq!0PaA$t`}xow!^e8EW2cpX!{_6}L9+4Uq>GSH zllBk! zi2fTe$#UjGCgd$6<{jjh#PCXZd8Z1v2fdoFy&mFN z1}VGFNdLcVwec4njv|k!QWdEe*QV`vK>_!p-Uwsp?u7`%Rqay{Sniz_VqLBxH9XPt zIQR_DLN^u{MI82o$fKyHA;PEP7m52Zl$LYms>qI%T;#Gza_JJ|XR?vTh=m`!^v@?# zsgUH$eA!sc=niw(k$(Tvb`DJhW)=(5Q9CnFw0Fr)PbjeOY`g(x9&OGr0PfeOBi=0a zY8P8-@iO>djX>Qn!mV6Gzlf|<#3t-H=fLwe`O@l)x z+%=oONM47bErY+{5Hy{X`BZP)Yn66`;Nt>>Wfg5MkLf3PCibuuplhH3AVZDbt+VM^ zT|+*79O8=>De{2y_!rGC%+KgtR6Et)=oW}QX>@OlYWXSAc)@?$_lPPlGO>2QjKAOJ2VMt5E=!Gmp%su`B9~mLvU*>Lcv$&hNEF(-Z-Jp>hdl-K~k*q-J z3Et*o2$hdYLt;azK#@h4H$ml^4V+UI(Y1g0xKfmO>5%pTe^Foup;kDJP%Cn%L;gNb z$Il0^X*GD8o*k3Fne9*jVTJzhL3uUP=}EL9rndIF&0Va=Ts_@bKL2su+0Hh$b|#ZL zDFuU{T$_qjpiYzzdXHB%u@Rb3*qb#=IHT5T$vTDl=n?nm5cAun)@)VI0-vnodF&3L z*HXWPT-;o9`1SGFqC+LP2K%Vzy4lK-Z=%@%h3CK37GBTdY|o<|8aPNFNYE!+R)IK( z?B^LC%oXaw9TW>D-_iJ64gPBmdo*1my;rBH;_XJ;4Lv0NTuzuKZy5AcRo;Y_pR(wd zd?HvZuWUvqi|F;zp9xrV(E-zS3Dr2Pm>~##P0`sHpl}u{kJT@mU%#i9H5#{eDJ+Fp zi(eieBb!YV??cv%b0u^*1zMKW4EhbV}(kCdP0?xZr1kunUS!6tq3cL3bzsyKr=ZYv}}7sLRgeBY8*T zO&x8`m}3hUFyCTo@hl@rB;ilOPtE_&_J@&51Ft(b!_m^r#_jKaE&t*X_n8Me?ZkPf zmgP&jGD6ocp{k?8m@2H<7cnu+;Qik(Nw~YjEP>Gi!;%awEs{mrrGxGE?j7SC5%ZS( zo9v4{@Md;TiaZ{c!cc>MY9JTL zxL`^BjQC_}1?8qQVYrnuDhnJ`_D{!XZ!t#{t6tkigevkha>(sEM2R6wCY*sZ4aNNS zUo*z;7rz&+E*kjFYYuN9WQ6qkuzYMSsu~0aKb|0Ek3E&0(jTCC;$EJw z!o+?b>#@K^mx*>2(>AtsFu=_Vnq!oKd$GAEom3l-Xc##==-%=doiIzN{kEbQH<8bO+;2+GuHlkSt!V94~8lj8!++KE8c)3cP**?Oy|rGb!yrt;T#gC zSG|y6DKp;KKdwoQoG2r_KbisU9^L3mt+LQBpJAv(X|r`AT`f*RQ2Al#hQ2+Io_}Q= zpHYo}I&hj46_j?uTJvP|kb)#+5wpizf(Df|jBYyU4$Nx14-e%dp&ReSRC^n!z#c7f z&TKsNn_psjBRA-(-myK*m}dBa_GkF(_&L6$3u2XxyOB=)R4$_vixU_C2&=jGUBx#( zweMQE8hiCU+XrYX5AYgj7DQQw;p+NDsNrOqR=O8Uph%DbS!G{OHD2=^cEQwr#K#hh z!5EQUx|_rsL|Z6#*+_ErV&EB zS0NNh%8!4*90gqHI4penM-%ZmkHS!aXqACBAK7-#b|sw5}l28 zLTxHS1wTQ&ev&_Sl}U+mf+Y7uPw_6csCA63MMmSs(D_|~yn!lcRo?~l~V|b zi*SPEC9xf;0q0c0)W}Y&q$cBxCl8vBEsy0fG*|N%14t@>Zay5oMQ8XqmXg{j>~H-b z2PxPh-4fke_EP0%c%;$)U#H{>h*c)gxc#KCw(ifdD&<;yNOuWYkj4QLV`+`|jok_V zE!?%HetkMNR8)rbIJ6)&;g|WoR>@Lx9O4xIy1a;Mf84@SAV5-|NhhzHr+Z@MIo7nQ zpl+9J*vfI*_JB#N!a8pdb%b2!-$1mUDy(# zMy6rvp7%Lw2vs*{siaj3TLirk`)6t@;I~dfuh!)rNQ}RDjP^!JBTQ%HtK5npHz3*j z<*fa4fvv9DVRYRR{uY(Z5_?lN;!VZpfg^i|_q_g62h=|=TNAtrbxLvYO@nL^;bBb0 zj-k2hT@iy7`pz(;W8A+XQmf9Lav3RXA>0ym@24Gf^YGs*uED%^F^te_uluuwC*lMg zJVU>k)TpQbjYlt!RV^X1Z5Qzz+5x?Jdw)Z)n*QY`{Pp-!mt1Iyv^~IVLm(Y5BXrpS zWym?BUd%(T{~P)Lf`8G1H1||K6Y2TH|7HO|q!#-ZL#S?Mppqia?ku z{sjMZDB+-R<>Wp{z#kBr8R74KSSB^>2}qgw`9j}$_ggbw5o{u}2jTLj{UJ!80ofRVHWdqcPNJ*IsI%zN>@%V%-^NtqSP^ghwY(Bt{#+!ln}$fsBMtoY5Q6J;yy%i->=(HYkuhKz{b_OMFF8?@$P5E_OQ$f}3i*O`mW4^-`;=ouI8Hhyw~Dd6SvEN;`B*nT;SE zS}a=~VT*CKZKt2;?LPeE`XgmoY+EM(@t*VOvJxoPPAop@cV*`+Ja`ESemde+CN;tr zqQaiwM=bKLW)D7`FZKBpZ(qLg9)M1dBA6b$V&$m7l|maLM36NhE%Pak8@v~KG-y}u z``!~yEny;y9z~<-mb#N@Zo2U|chpQ3xm07$Q51 zGPpQ$V|Q`_1^r!W3HJUUWangrq+_>*@6#In9%{ZKG;4OFz{M0qsV7Fb5 z7ZG87!{UBsfD;jcD2Qx&l&|~=+neG-wIK6auqS4C+krn>1(+**@t43s!$=TJPVRqw z0BR?76up**&AaT81azm!J1|i-Ov4=EZN#kwF+VS%owJ^JH>wfDS;P<^Q4{=8vUDH3 z8drf|-Lo{>>vkCHkNxq+VSP`c1lzf`+%>nteU7%e8FV_r{!%VO*Q!b*dD!@l-AiVL zrqEaQl^UIeoLQXD4bTP|_Q`Z_U+PJ>ajxi!hg>Nx?%ppAW1l}2N~U=Q z0OWDALOwUqC61`?xC}h5o>5!=CbKg&M(A>&Q_2E|u*OZD z53&t`C_}L13X{E#+MS$py8;#EAsd8hh?Pz=9ivCwsW1QM65eoTZkoBd#a(5z(v6I# z{9C%mLdWL*E*PbPA+>&0?uovBN64-Eb`s1}qGrMaznZj)PDXLA`ulzCaUCDW{FJX@ zTWfmp+N$fK-sZC*ISs;r>BtGbyD(B{Wl;#NC0-~ai&j8atf5^N&8bf)el&74FQ{VOhsuA0}qop-&FaVJPUd0v?LT_1V ztl(CaMiO%GnDk@$Oq}+r_}4vu4iN@>H2<2iONc{34b1DT-EYV$AKfxZSp6MoV-2hw zzGweXO+4ZaDT}dYzm} zQ3US2WxG$KIAP#19p)&t&ao&={6tS&GcMch&uIR7?slRF%+;~R4*p04) z*!fot{@!O@>bFnAMcT`#G<v#q?eabyVIZffX=lO_C3MhJ1eFzzHtqj zKnG+*-aG*ddG~F0!^@uhj?1J~lfd9Wso4pB+A}zTRuxQ%kT(}C>_$U0zn6g?D^-=Qhk+V(aUA#AOaJg^~>bWaAwxGifa%QbswN(p!AUMiI)2K zf+P!MK|312l%8aeo8_U=3ln9(7D+aAuMv~6?xKnlZy8W4-p^n203Vl&A4LVXV_j&s% zI|QE2!E9yuKj^e|M?Q-ENrbBS6RDa*0nouI>jM7onGr4yi&9t!n%HAs_AX=3yl9EU z)G28EKUI!G2XwLthmwv=NUUhY!ic?3iLI%2QoBZ`%`G{M4#Z?WPw*F<$FP16_>a?4 z)JQ99@%fIv7YpzQ>p)L%(|0+YwOvH1>zKSmvu#$?5O-8Fg%L=M?{jLG%UjUhS zmf=XrmM+BAWAYQS$w%?X#2`-$y;C0laf%mQm?(65$sd?(awO4y7_pGHy_GPy@dLOc zW{p1w_x3tMI|P>tX_is!dkWo2kvGgp9n2pD_3pcdq^`~spDMrHy7jY2ly zF7vnp16=PQ%sHpp#ur5@yvB^z$zX3hr5xx5pAE!d*WifTHv9;KsYQii7~`jK=jyZ zud8UUfr;~oOF8sc1Y-6KDi#u=Sha72ix`*hq%=&FWURj4qOx1VEY9k6r`Ve(0$pqc z8UL%e5wo^YZ9o<1YJNDCAa?pkE9jriv9ws;*w--fd~g^g$oLCpv26d>mxaJL_I7i*INVZmlB+t;8$nwFzfXO7ze~dpU!@QmbdQ zPnoe%APW*z-vMk3k80YQ+X<`jHteQv7!xHIt6%Z&iP=}<5TM!w{g;z2%V?k<(7QnS zfY{g!lRBmj#m8WZ!d6-0^pg4$p^8yr&Es*-LYDVOk%$%bTEWVDj%$x}xFA%F*I{FN z7?$lln=pl}IibA5_~iQD3;P#qY3CaC^=MT)>BA!)7&EBb#?Aur#Jk?)p)qJ1?{&AM zS~nhdIzZTFkOkvDS&e^0G2ke)KL^UA)Jt~~vr|p+CU)Wb;w1&0VYWm4@{Rqi!NrYG zkS_=u+#Mm;_STfHj28k>MN2Uu-pOO&HNJ!mDv;@9|naC zB@GRuuGRz4qeI59O4?YRGWd^oL3_Iy`V@>UP?xZ=hItecD=Bs4U|sG1q~OgDwDvXW za42Bl>iSeC49?munOtw!+qkbW_n^3AttBZa;?6Tgn>)~Hg=FqgHoV%Pg>N_?mvX=j z${gQ#ueF(>x*6&_*+i5`Ua`{PQNZHSZiM4hSWOQ!y(1+y-aVgwkuXsc0ALAMil4SM zy$DcACJ4U~8POH3dqW)V50I?yzjpx~@o%)7M=)2J)On666{H?n3%V#ZjG2GOCal!y z5t!YXJCSf^ z4)QdgMmf}WI{$Ic8vMbIX8at8FYCwuv3|OW8&k?*q1^-q#VlOQa=AF^32a*@`;4uC zj9`($SBgN#0W_bv-{-}tYyD6b7LA3eFB<`7!jaY;J7$x@1G)X|tWZx4drRWkrL2M#0{qJh7 zE??vo%eb}&MP4$J@3&pSnfSp##A|KR44{h5J;`Ttm1yRA^~^+G`^?btig?BFHbYDf z|M4gIM~9m5tEgclUaCiGp===y-+le{6CC+ZBsiJ84`L2v$QOKe?>;nV4}D63;b}yr z8=nET{g433Qr#w4lf7DsoG!(#T8`f_rpUv)T{|^%F|<6kk;`75G~U1*)O{{FLo!wI zR4WXq%!5xZhuNAF0d!#TR)d;|{mR$71P^;w(ZS4u@bu-TcxIMyh8CEdE^50%w}#kL*Ubi#Q#@?5iQn{y#NpVhJ#4}i@Xd|w0JGBxO@j5A5j<8K(}+ znUXqZalJ$E3S(OA2IxSlP0(``eBE>0ksF4QCJr#f@Z^XY7iS&g)66{7gDGgTXK*sk zW4ypw%wixxwR0|-(7O=|SpFsc!W^8rhBxXxoaE1Dz9Ikc3QQ5}V^7iH5WN!kOrB z2v2Uk#1u%Z@ykQ8Q_T1xbh{xu^nL{P=$ik8{1}ufQpM`t?U|^* z8K>ramnJ<08cRa}BNmRfM!@NJ|A>AL{=M!tR^M#N*DVNv+R=k+VHJ=*4M=-)(IF9$ zSQ$1Fn&nu~5M(u8K*Zl9Q>?5zhH2z3|8XBBm=U8fz(+4|nqgX-It-`7z|@zWM%m${ zBgKu0X~mGpK<>D+{O&xa0j#x{H(r*Z1PtiVYfM2&Gu>*5X)5gt7nK`14X;c`#!APx ze@Ydz{lrJbOw^hB$S@O3s+k(q5yX8zFgp>LZER4mwkWhPHH%9Xt9bF8P6fbKhdG&4 zC+1ENGvnS%C(&DwDfUajz@Z1lXY4*gAgzmP3p{QPV2Q0^gt6-jY3`G-m~rHg4({Ab zD+O5kaFJAqEWK`KT?49=^}(7YyTa`{O<;DJ{Zin!%H0r2l}*xpMCh|`<~TJThznt< z$uBQz8$eSuvB?4@P$nrDk0@?tu!lNXs!hT)NdjpUFcbDh;$1l!icM4dO_*bQ zII5Ja7GY@j=p#0bTn8)8yjtfZ?ThtPx*VKtYl+2;$bePgTkE(WBy ziF_)m7{QE`NR3j}iJ1olm%uTF0_L|SkGTbd%v-f@^4_PrcMCoYWgS%_jUa@q-;fS8 z1`K}yDgLc+>>7s9JGEcABeqBLPgUwI5{#9<`A_ODE?vbx2Q;9)B~sV@pWGb|mtN=t zfwH#OEgF~>HmHf#lr!#9;BLeZ#)y|;fo{HCjFpHz@`<;FL3qTygN5{I)uCHO1d{cW zMeI1>lmpzYYgZy&Lx4IK#k6)FfP&h(Rg?@}B{}=7F|iPiXL>T;%>nG|dRW}t0i#~L zGe#3|_c;WE=q@T8;Wvy@X`f}OhCn%qS{TTu&~4ssJnWnbA9CP(_UJT=*CCHTzf6J< z0Ic(}xEu1$G`!MTla{F2%6!n7(Drqxd^O*J2pl&ab6MYMf%z z4o$I3cnFq@tN{1!91}nLyJEJlbm*X)CY%m54jl`K{e(Po5(7QzFj;on<>PF3n;9s-uywx6U90QLKIUC|}*#9kmu-KId+eUQcj zU)7o$*UT2Niijo47C7G+z0iy?Kuv!54cpDOIoDgq)otZXSMG-`3;wG zFLe{wxZ^7UL`o>Dyb6Fw`S%a00cc8tJb+lak7P@J2Ex28gVomCWJ$L<2IL%^vwf6arjV~;1{U>tj zZt4qN@D}nR5amC!*MD9*KD~LTLU#c97R)-f8M%?ydH1FoL?RCX!LA_D9fw=@VwA)V z|8eJ|F}_h!6+r=O>~s4j$t!;4OX>mOw^GNB)b;OmeR;>O*Z@SV>yqTcDIl{?tSiP2 zDA(@@@MKrMG*d{W&2dnDf!uX4V(3%y8X3ei>Ji@5QC=xU#4{{Tc%9lJ0|aOl&PGJ{R$gVs zdLyr7!ncX9=3}Rk(}yd??+=>zr~(OZxlm2q5SvGP^;h!LK_1i3LDMYVMoWt{g$Ktk z7J3T~chHeqk;6(lC<(AGFjs~v(|nGeL`=>E-Q9U)4L%et)0D=S6D|p--t*iQD6n|c z*yX7&D1&G_kz5x+1 z5aPv`Uly-x52hZCm^`@$zGLmlif!O9^-10yAIn!6cKG=FKwHm@x}2HBKHk#8`ckbS z&e1S$%hAYL9}Bwpvp5{iV=vp=1O+@j6Ylur?C4d^Q;8|0F%92}@yLOuO5)zvDXsG+ zOs~DXD(073X*WM`kRs)E@fPc5D^u|A2A8YXKYeF%yRu)1Bsr(py0;@OKK4XJLzA%F zJiYb{6k2;uKXe{8{LwDyn0$>K=T%!$b0fm2|#JZ9aZ7<*!Fc{|*(TgGivqBCYc;nmcz0)?d8l4rl_<5ZLo_Q>1?geV~v|nScOn zlYng{qH0~tmzJDXULg-4o7C+_@AtLHb5E7elrsZ{U7mPUN7&=Y5O`H`yvzl8Kp9Tn z99MMiM-P0YqiplTk~XqrYF2u=^)cN*Uwlcqor~-)nS3g^1!e%F!l!PKiK3g9LZqK>nQRQJJ>L7>TqeIR5p84U^ z6?E|&e+BH!j{qVfV8g&jgJ%tqQ6cnxWpTtaK+s`enZdKcketc4 zJZgq&)5nC)_+k}$F*GuS2@eR};Vv&VFeKetKif&ImPetOD~2Vr^ZD!XxjJ5UXPtkiy#l#qnyX|i#)z5>ER4F>w< zYwbwd`ANa@agf}`J#aca{IsN@A?c*1^{A#ghPs5js_`)-CpG88ZGr3ko)^^tU zS_VRRm>Zu2*cbv`qdDm4v+gi1Y0@>qul=5ZmD!tUOy_I!KGT}+WVTqPOD#=7A@n2{ z5b?YgyFZa3^pEf6)7JTXQ0K`g^yFk2?HN#3BF5E|w9(>}GBvyeOH6DQb!X=4Ofb4FNGynB)0k?YC$f@aqSh9@S4BFNQ4wN0( zBjwkhX&~&?@bkPn`vDXtAgENgO&oA^PhNofvnYQ6MFaqrxLg+rjFcI4wUbLoLfP-7 zqaRdUwFyX0!eha#Ho$#%z_jE}x|=UO;Tfy&zt9wetyVx@ZO!*R);Vrh9u9n!$w6cM zh=%2bg`!k^OvcnOiuXN0LGcfb0#lZiW|uPtzwCAwj-}-j5w>1ww0CyR=jX>%%K&K8 zE|2bmvPLamr)9&79q{5XwX)>S@#=1Y@)&h>jN2zT%IkDNy{q}CI(;SeI<09_W49j~ zpydis*6L>+_+UnP033XL4FE}tBkCk3;Vpi9u9U-d<)CH5U%&LV$g!CepW7>roB$YYszY{*T54N6^(7uv0p! zCGv6zeeF^j?KAQ&pt=?vM`VW!dF5<%KwGQ3kqg61yl;@W)y6}DR{=eID7cyE8oP2y zK;u{2nO0Sx`6!PND(aHO3b>Mi0Xj+#u&Wb1V6_T&`58c@N8R$uvmp=(c}4(ctaWrb z-G6P+e}z&~+l4}0WwlN+qPNw`TNOq=vWBajo-=l@d-9o$^O<}B5cgeh-|NdDWPTZf-@YCpy#yrg zgnIQAiz&bQLP-Xi_<>P#tLav16(na5{NDJdN!BX^%>{I~Z}~`!Gc*jOw7Il`DR=9G zqaBO7TT`Lk{uOLs4hQuC(csztMC{kx3N068Ksg;qr#WxCnvmq?Dr@`EMlgvDJ!pe$ z{nLi{%BWw-W;$Ld8IYCg=x{}68~0YN9b4+w2WWMK*H5!{nJ-mV{m+!{ESE2~(`r6& zIDJq-lpa-&@JD^sHXt#Hdh`cz>k<&99>n(alvUr7cuS|(mA`Jg+6?fgM3y#%htN}& zA7{*zrxog<>XD}-lkMb^lm59{7NY{l4FhuL__|;HFj&`HX+U1Mi^j;mnWp{wop3m` ze){W=n;(Qx!*5aO{Zka$yAK>^zH6B2{6evSJ4;xZq0Pa{*ZVYX!gumLFS03?{FC!+J2dKR4j3o0g^(KRFk+-Mv;RTBc%qiKM3=F z|3+hklUV@R%om$bj}Y=LHCOmmZWVQUJOaPVjuERl);7L;ZZ|0hkRRxArZg9dDw6`r zuY$cNxgJ5*Zqf#Pyh7e4w4NFLcX{jpYJdQT?~nPd@788qqG(b%+ztcTXJ#5GK;NUw zOGsdWa=H(j+QQ29%rf%^bM1)pU^}SqftD-3VnV0B6SDtjPf6*>;rVPDd!gug>bBw^ zdvx_1*mt?HP+d*kJyGlQACC}vlxrsnofUV9a#2k>N=*<9kDmfb1~6M%bX-~ZPEZQ5 zMnY@UY$A|Jj@>38A<16!`QsP}IPtAV;m>k3EE_U|KBSA9D@~W8*1FACtwz(SS$m(9ql`PK%VGooC8b{|N;%i@H4Za$5&aDK2 zcjMg3_wR&#>jo?9-)_%S33fUMkpj?z&mnn8UqT)FxT<);YTuI2Nu73f~|>pQB0 z8pOeM=hd9~5AfFrc@cey5Er8C`C!*lOYd@Z+p~?ZzU;FoWrSPVG0v@8>Jx`Xod2`~ za9lko^x#SE-22%<-XU+%Ew-az?(pA00+c`Qh}gzcYiHM19T1eA#bHq-)ZJL<+cBv! zK)dQsVYx21L(hl26=<>f0|67N1FVr>n>FR`2M$+i^h$B^788j9(5QdKOxYIXUsU^R zRPo=Cwf1~O&SbyD(x!kg_N)MOl+z>si%p7kvSSr(Bg-!PQ1#$gs-4Fk$7rZeh&EH~ zh~WltsA`0UzkXi~^$XEosin06D<5aTzAGSUiLI(D!7Cr>baYVHK{AG?|CFc{CkM7Q zm8h$HU!p_e&Fa?sWn1#prLBJ=V@Ok2H&$fdToUc;Zk=&G%3yB0; zmUI$caC&!za)xm&27beudjvze1)OY5HKkNgUSElR@Uc8VMv@V428L$g@|gE}eoE_L zng0ca05?WAJp{bF?ZnL0g`PjJ47X)aPGGi3E_^?h1SQr^hA!Q9L}fv+jBizS=5KmA zuF<#rbm>ov9X3{r)h!Az-=H^0PRMvxShx~E@9+3BzP3}^5O_E~ltxgpDV|>C~zw)@- Gwf_g~;>c+L literal 0 HcmV?d00001 diff --git a/docs/img/eth-diamond-white.svg b/docs/img/eth-diamond-white.svg new file mode 100644 index 00000000000..8d82be22886 --- /dev/null +++ b/docs/img/eth-diamond-white.svg @@ -0,0 +1 @@ + diff --git a/docs/img/favicon.ico b/docs/img/favicon.ico deleted file mode 100644 index feffde6a690..00000000000 --- a/docs/img/favicon.ico +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - diff --git a/docs/img/original-coverage-loss.png b/docs/img/original-coverage-loss.png deleted file mode 100644 index 5fead1bc1e2d11970b970b0e3fea9c32bde4cb1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146953 zcmZU(18`;0vpyQzww+9DPMi}v6Whs&jfss3Cbmv6v2EM7ZDZct|9kh{-+gb_uG+P` zy1wewy?gEMZ*`=yqBJrB0Rk8p7&1UcLKO@QnimWVyaNvApX4okjOO11%0&#I4)^c! zg)@uz_m1x>`NLJs!NS$U*x4M+66j!W{>{bI+1woHV&&j^4cRUHPl@fnl*FCQja{uB zfMn{{_U2#;4nQ+wFEUm>G6{22b9)nWXEJtHc1|)@E`APneoi(rWrfdo3Ro~OGBALI zsJds?#irIT+EKrqXNT7}ABQ!M>4z5L`ug@Cu+3m_1ZcyQUYz8E2^ds^ohO0lb4gbK z)R>tH3Ppz)H1Vjs*-aIXwqUqGFaTOK^wLDzZIjQM$KUts&u+W3-R*r#TvK>Jvq7@VoL>hcIiDRV1Y9mrW;tI1b+~kA5F9#TmfJCbQz8}!%a$O;)0B>|~5@0!y z%)j*1`Ml*1(?1bZ?g1c$|52nm-KT`*r9O4}UW*+AiSXA> zmZ-phn#nr>%a?Hxzu2F4y=^Y*hO}}LI5~Sizm|tzV{x6G1JwQ(T#-_8m(VNL-$xOa z1ec73<;;%vd&8UkhjG__e1BUNSSYa*I-4xhzZX>7{67u``(ENTID*n;T_b21< zYp~_M62JL>u0NNr?X>ZSpMAJSd&m}IdX9{V!7W}>xE-_+0$48ViOVVJ*52BxTn9Sl zk5Q~cKXa7qw4;L}fG~~72r~dx0`4aKL6?hReSHRh#v|D9%i}+>=Y$>{XAaIz$FpQB zurR=3)wsjX_mT8;AOt086BSv#T4HdQ@gmSWs0Ik%2 zn0{KXz(OS06a7~_!1Ps5X#BiIbTM2+E z#nQq(y7eUDxgDjl>2F9K*?-0yFo*kl&2Ez*jR;Aosfj;^DOiS~uL!1z{mWtRs#{%M zStA4mtsvqCQ?`!Ej|46REkc=W!0(FXKQT@NPg1AtYF$0!I@FB!-?&A*EknGh`aimu z0OYJ03JmtSjF3sEVj*_&U}7J+mnY~^h?pIn+2WvQ&THEBjvM8e zPeT9`s;oCwz>Au;3L_%nky}V>l-~zhdDN$YA4sjd1NHAnXyh+`XN(mcuenvVI&P(?P?U>QB5Hdp zh_GIV9*TE_()LFjO8kt85BTIzFDSrnInZoSV1Ey4j%)dU22409Irne)b!2v2ILIok z7OzY!Dm_twrX-&-Z@XCM(#gJXcn01HLbTK>4L#b7MzJf|grW?c3ma>ZBIQ%a)n_|t zDwWF5JCr2G{fF+>!J8CnNjwKny1B5e;Qu$5=_VgVK1aG7DE@!jBvqLbKluMF`~TP% zFN@+R`@dul>5l`#e!}JIcz^x~mgT1Y&oWM3CS-~uNO=Patd;ob6RG?ra#p}BpXaET zzRs$17N+I?2j_t=#rKTu}OlH&i-HH-MqH2bHTtF2@Q4Wa^&Ce6TtCRJI?mU*-% zh5-ZwOO&}YrmO@t+79y%e%|>(xEaay)-~$xukrknV(B-kLa!iDu*ldGzsF zY15Iv$R1WIm#q*nc`_^wCCIAH$d~QQ#}#%H*ShV3t57^5SUBi|*ms?zt&& z_@OW*=*A^!#YQ$%KqcFg;APWF4x{?(od__cSd8cazO3k^8TA<0S8enFygD7y8E1{e zS0*oU>RaoKp?mLzcfYE}a9-m85Z;SUR{tw+aYW>2(L5}fnB&@?XTK^`x2NO%1H1h$ z>-#K{P0`ffWQuD|>G6cQ@!D$D(mt#^zKC_FyoYAVMHH4HBKi>go!pIzsbRlCXpQO7 zBQyOXEmZk*e6oqmLe zhWoC9g{2|6jJ42Cx+R7dMlMPQBtgxiW5}q=D?^BX>c9=jCqsjf)KI}b6gQxFnj;&s zUXknF`iq4niU0TW#c(shJ&+6zn!LF<`}Q_I$Nlu)T8~!TsiJG6l(GEH`0-wi0#Edv zU!?u&{*7$(*Y9QnvcHg^@7cx3y0F&cV#C-x?SsV zVU?#f$0udOEXZ0H#ZfHa`nkpN5(&2t>9UOJZ(R{ayx{lV5J;F{V*i&f8lXi`A+4J4 zD$KdsJ&-iu#L?a*@@HG!5cIbBawNKv{LQ+d&}ga}I!3cnWhnDQv!|t3Qnzl!?1MCC zEPy5&@naMbkxBRl420@ zm$L(1fm(FfU`NRy?U*n(1$=5Ie2U<@>ghFFHu>+1<)AlftEto_qn#ZTrp!u@lC5Y#z`cTay(LHBao4yQwe>qEnX!_hlTq8%a; z#-Prwi_WJv&{>P(&!=jUnq?44w?OIhQ~NcjdGIin=I?pp{|ST^1r6%lfnV~_bn2}e z#>TsF-qmKVhj3C~=hse4)z5~{RKn};7n^dVixOj%{9f<%S{lM}f`Xpj!gEg#ar5!H zfG#ivV#D!xs_5Q`p4G!gMr;D_sKI^uoO*1#R>2cBsh+Jz+zs#QzrKRD)Bx`vZ-##z zM0OTba|21Jg;mUUUxd3Ji#emsqfcTBAyOR|4mVg*y#DHiK5MnP3Syhkt70bkzPI0J zt)!a08K*`>f@LurbDw|Mnf5#ciW7}d^Z9Pyhj?!NIy^t-)v&)+^r&vt)KK3fBL;97 z(mA#KIB=AwbgF+u!AH?u$iPa;x01_Z1s(-PQ}Dxy6iP5D4yoo-D?%9 z0sHZYYFZ!^9ayJU25x0IWQhk_Eg~`mm*OLkN%fTWtC1=DCjQe(@8;8?w@L>~kmm~W-cgb29linW+ zN?#89zQ*9JiX`nA7USY^rFemMZyYjndlg&Y$gJv?&hDP7#umg9SLLx{b-mCj$XwU- zDm3^y)l6G?3iieG2&gDjEbfzt7=H5+s9pbP-LM7Lsjlx{cfc#+%=xzC`C#z*l5LgB zReS#?1-f~HPSJcvYHj{Ze3_(g>oX-TE+}~r-sMAu*rzm|e|*RW@AX1njDtk-wx0%f z+97oWv|fg@ajJQ;d{C7sijw%cTu;D;F>&g1AE!zjzc+YZ`u--KF7mtqleQ1tVBh0Th}RtuzU`g-Wo#L4+emPI#l4E>jUSObt$yI{fLdB!#mZ~H=C$6O)HXXGFyE@bP zM}g(*7nxc6Cj(Tp1x7y;>oE$(H9LDnve&8kc&0BT5(;sA%{FtkaI|cQzbw=aE5d2K z7;^JoRI+rV^R%hs%-#7muW#oYX*f9Go#BI(CbR0Gw!qplKdczd)COMO@&Pol?FFI# z8kfGA?JnWINQs(|VJnZ+=b!9U7=BUTS#IPFAR*ow`2~)vZ|gmD^fsOF%3#78dFJ`< zZXg5y%80P^kSaUy@Yb*PX6xmpeeIa`&wy6TYZmYv*8om})(Pwy>XK+EgnHYdZ6Nf_ zNp@VWh^T-b>$Da|++|tz8gguGRDnIX(Z1_K{1FYiYv#;`<*#Z#@1ce9I<0SlB-^`)-R~ zJuWsYnpvlJNPHZD#`JY+Z~;N(I?2xFCU`F?VizuItO#^Ct09uy1fdDjHiL!iF9E%x zl8_v|A?bNUY`0~O<<+(CaySEi7a?*EE4z16q0at661z(bY0@Rq0O|rFB{<(ksd?){ ze;8QaP&mgnF79{ADkwl#P6R9FqC<-JaS0iajffI>~G9)T^$q$8w>vPW{@ctDJ|c$A~zMj z>(-r2HBm7C6zn!bqAcTzPy4lmcv)B9vcK%d#(-lc1GzYQ_N25nJYT?4I! z(mPI$G2o8a-s$_#732D*L34YN+ZE|m*3g~^9nj$6B}rjA^jKv4QAf5x@ZzSzmP06S zl+?l;D>k(FZX8{QQjFtiJip%726ZkyI%B{K9j#=C@T6jrnl1w(hZl};`8@-F6p1M} zrupP$eP`pi=9C$Q#jkg)ZW!O)5aAe|Kim+^;pDVpqF(?IAhC#6s(PB}u=}r;Qte9j z)S?#4-SN*S9FfsOJW18832EgJaW}7|<-eDiAAXL%CT>A5)&90ApH8f>%$sLuon{Fy zP=-^nKLR7?*uL7u@#BUxAVB?hXWITX+J}qf)AG!+6eei!`eCseTl&@apTwb{c)>v) znmWPMxt`P7+1nL2Ecr)x&Zjw$vJ6Py)cTO1+D%Sg{$l?bRf+W&=<@W&F4E#2sdb5D zg^pu?&t|CVU_aR-jl)g_*XOw5wODX~fxw4_q|vFQ15JT+8>mcYwSlmVA?S}cAIm!b z9jsiG|2M4*<;R(DepNmiRA38wds}lQ6i@$lgO8ZDLuh)a7;79t2Rck?o{*~NoI!*f zoEW%<#x+q)%Qq<5O~gP|2PHW=xYt8#_41x--~nGdM}limJQ-xZ9_( zW6IjpYC?1PfPxtDC!pNl%jJh7C%T$uu80ykx?H1|!`PbM?{Fc?-=XL{>VR(Casm~1F9E4zj?IjzYrrq0I zo%Ku(p%dE-azH(hAqKZs#nk2IU(KwA11EnF(cQX<;OzPa|9IIXf^EB3my>JC^@KS+ z#F0TpOM8yfHCHD`jQ-BG(DE}$Z1aZywVzDe&vb$7V%_5|70U;KIU=;M-j^-3<||}c zykpUJ`}N%Q{=n-lsi=a2pFJG=!SgPr>p`fKlfyGj!gz~QDsl2R!_$+FWH!z&e`Hlu zlxH-6DRO9G5$kuH%zL+fXmHTATByM8=IgTdXD`L=t1ah_>Cf6{z1t@-ABXH?&GtW~ zXIu4l)ppNk0i*~J=onDKz`U(LkZ;7~ea%fAXyuZeHZD~B!be}#$f)x<2p?n{6`CH8 zgjdYC-Qnwo`yfUEI~)8G6rv-6L8$sLu;yuf?#r2_! zUR<-7vB<}2#pdS)Mi46!T(G0>Ps*F%ohhHws*kA7H}tE5%Q zmb&8m&=ztb^SGO%Itn6PK0|MuT6Nvb z^cU!2cvR>}Ru?@C>Y|a>N2pErbF2M)qVhxdg=1%{4y)Or*-eXdY1`He=wLax_2in* zUUlfvtU$Vuv$gVd`SkSgHC@=*;8L;SKygwQrQv}O7qC4P$XX6!=aV> zO@f&R3rvQL#e9jZwOr5_yz?1(Xbb~L`c+#WeTbqDrO0o3c2GqKk~l8fI7qP(IhM?u zdxLth*B-idZl(`%d=xiU73iU;z-&Zax2=k}yqfs^R$khq_}a4go1RJ+i^8$?bp?Vh zX=#N78JyRve0U4{{WxW0j|EVzOS)D&fn3fgo4v#`p^BS$TmGc4R|aTIGEPe4k91lw z2}--2gW>MwQAC9w>hk@F0@3cx0M_a#c!O)R_;%yyE4VqT9?9r$mej9^MA+XJw z6OF`5n?8Ph(u+$jAPdviiFMohEBm!yrOrb5D1&UOQX^sb?3 zui3hCQ7eof+B{0*GJy;76ecyETVg}sd0w$u;B9a1SN$n5iR>5>WKEqmg2Shtvm?<* zW?Q=Nj0AJRX`{EYvFBycy`m+0LQ8PCux8Rp7`uvrRI3(=$ zWi1EiEGB(iGKc&c4LmXDH(Bz+BrJl!a?C}nEdNkhzi3j;FgxyZ&NpI)FE0P3^@28Q zaDw7Jr07HIoLF(adptfNO>Q3E?Gxulk%D8y5F4~us&sn!J6GY+-Q?KOSloQDAmNJk zcD=Pq=UR@UOYyvP2@2~tMMcLyzf7kNgg*nFvTYZ5S~P8MYy|pt%h+jU@k?BvV9tgh zxx<`occj#?Ts0&u1$Uh9Cuc}!PB?ixYexsKBJ63Yl#%MnDBka&4KgNvEn-o`kXhZ; zM`KqthFNJ7IvnhK3IoX^sK%KNTzreOD9SfjHoIfM#MUOiRV|fwXjrQ~i%VIZWJofL zj7N&4IN;c!K{na8XLWYcq09h+l>-DbN|NzKIF3wk0FRp9eKVlttzFs1DW68}e~CfKDbFEW%R0#siexyp z_Uzyz38t77z24rTc8Y$0%bTHeYq!>6`W_M=3lUYG$H*|W<<@;m3Pd>w6W7_K0aaDj z5q?9TR=B;)0_b7JNZB{>RNXAGDy}o%WQP(#i}&Mzhd?ed2>f%dQ(xJ>78(>uP6aEFdR1>dwva6CaQ&JvTr`)B5%PGoBg(c$vE>8M45TEg5tD|3b^df=W)-T&d=Irm5hYiEn#2A`L6wqBl zsrxegvP3<$H3k*8XLrnQ+l8?TN-Q^<;+R<@gQHu1Djg&OlLVIB&8;oCI>hBLt*+_f zp@J;(MF4suwt;)yj|06>V%naOAxBt0??QBao&kA9r_!|J@g%@rz)@REHpx0g7|!&K zJe%m&T&+5|P1b2aXtkA5O#gglC9!66D&OMm4Je%eK_RZuuaLnmInNJHf(36%?l*AS32DPs zOc;{KY{rgxXHP$@-L$I!k%GMzSMf}-s)>X$>o`dbRemzD8=pVR?tJa~yC&25hm3S> z3e5UPKj?=?#S$C53yI;#@#^%q51otqUYCC9EA5oyw3-DL9zxJY;YSgi05hdPL)$FP zWcnuV-cgw7zgzZL@f!I2+#o8yHclnPb69R)*J{YB8DbNPXroiNlO{2# zq^~yr&c(C~aXAS7IMf>t+&0h+Uk@#J6Zke7H$tvOZQhx!eldOxnplVW0;MznY2kV;jv$6 zX_rgmov2uV_D{;+W?t2?q4jwpb%ZT`elPA);Ncc$;y{USbAkPt`c*S{IH?h~1vP4y z;a36>bS;Z-W3vB~5KS;Zk#H;QV32B4G4x)MspphO?TXP9hv6Obrl45;-Ps>PUrE_J zjm=at0AtSPx~?n^Z4>{_DYW4q@%kXZrAc7FWh1G5Bd#tocpK~TN1%Kfnd;Kt2RGFICH(|WoesQA(R?t zgFesYx}85ypmGlpGps#CuSWzLZ=6J)YJ$-t4zp?lh^Z)RAnV}{KjTNBzjwju1*rtfwf}SPdP!8I`N@i`O!sC9+Z|jC z-R@*J-1C)vd0<5|Td!XVOTe}s zFjKr;;bL)uIctHw3Wb;wFk`&KuO3F8V`7xa&yDt??@l=5$hr59UIB%*jN_R**oB2`Y8R$dC`5}lwq46+B>hcT@gUaGQ_Mjy zM*zPU1<+fL{P9*P)D@^aJL8rVf}hChDwPpM<7(GWWgZX9yWbX9yyfW{@{+G)yEFF; zZG{7`5CC_R&7H~vp=#pe~#2m6#P`U`BJUA`rf~|zc@}VPe+0it*>xAlcNu=+okLiK3}wFM!}kq ze zAZIu6Px%Zq$gI9?H9_uIR$_gJBI)ADI}PPMk&q{jMccksaftC0Z@iTZlb`C75M6$7 z5-5C=a3vOpuSJS(F;8H3V|BArSk+CypF3UBuD-nSE|%s1LyD#%+d%o9F-#aXnR*9^ zqekMyDkuTWEjalolz-B#8-yfQ-PgoN_*@`2Rcm?hHLIC&)v&t8Hk9Y(7et})zyYh6 z)isdU8zRCBkyhA@D;Ggn-#U0&JqmjO{Av|2m$A)k~g zV5>x|moL}k?8v1@HH1z`nl-z9JTDJ{Dyio$uLp2Na;U<8RGLjH4?jG{A+Py31v6Bk zVsvGgqPU!DMjYn6M)FL)%KDy3aqs#!T%_Pq_zXwu1)kRL0oA%4X`CYjJMSp5Z#2j5 znH{>M=vMqGWk%$9ZVY;hSW@MKS}xq$=DywKz|6)lS;<)CEXBlI-Gy`Ata8*FReXy_ z!s$7%X+q@+pkv9}k={7;4&jrmcCq4(uW86K?=2X`5p zq9DfJjP8_`z%pFXLSMmd{2xN7>GkbBK6OhSjc{NzU)V1pAL5?M}z zEktplPR5GCX})JkL%uagEwM}4benUMUZZg5RfOzD zknw*)t%tEc%wId;cBD4{ig!eG)~3XP{Q? zfGIZlY|qD!0a7%rAzfz3D`u4Y^j`7bXa!PdfQ1#SE&WcDw(XVUY?g%>`h=vN>$K@f z+rpry`8K5kITe)u4#$HaoOs7@ERQA|^xDt6Q!ilCbZh?1?v;4OI!s zt?HV^n1iZ5-=N`wPDeZTF5w{^o4(&kXWfNNP-`pZ1l!*08BH~c4b#sP_G>VS+?1M8 znv&P6K%~gLsk z-JT#om?{fDvQ$6F`MKI+F{U|4^-DNToVw0#vy91*pvlD;F1fLX`$uu;)@i7@$Zo=! z9R4`B;XALcO+WwRrizor`pWK~K}z?UlZPVV+DEuaSn`+}i*!m%syR2Fqn9^l>q5*> z443az!-P%Nn$`D7_N0^ogUxXyJA-NCHFXp1S}gaPRz@O!aew& zlrWFy9rYXs4M_)Dxk6Lp^r06ueWBym^+ew#+wJpYW12~7OuUXR>AN&!R5-C4RD#c* zyuO^v#?t*q4%Fj7mvBjCaE8LdqpAH2xXaCW_K0KkuzXz(Vbz0I*$a-?*~-!Nyc!3d zOoRC?kyp(>whVT|K}s$qi6*6kq{abi-)D^L4R)n*oAIWy4_5j(y9Mw=ulTR^4EII! zI!4xOIiv7Rdx^rW2sDFS+4}2Wsgl@|V$Reyg{MXSaK27!Ny{JX517)h2{H&&WNo^6 zYRTVi6KU^+Hb{+?-Ss~+>bXM@?fXOe3yZQAajV}H(yT`G3f*UxM*@fFq=lAX-L`b~ zY4?wv*x^e|(G$ah%C-JNKp{Y z+G>`a;($NHr=sY;eZnkjGT+s^CtEa3kdkN{vAxmx)Px4~zfI9xJMi$CGTr$^C;1jy zsljD*cwZ4!FE70)Q7AbXW~^SsE`pdz80_t%ezN5rGV=Y7*xr@C&e`o;3+RqjOw3WH zBS7`K4y6pyI^562Z$JX`~_kd;W4bwx>bP?ICvV!pCU043UayzI5bYAaL_{bxX2okhgw9>(*&XZx9}h z+vdeuz7-1ly2K3T>2uUjU!=hvziS+%CrEYoa`6dmt^d!Q;MU{f(8qIH|3b%koySiKM*GQ2@w}=;-UN%9ve@0y8 znv=(!m&bh;{e%$FcewkS`+PD*K{FY6tkh6k7M!|n1hJHG%^3v$qoO|GdR&@?0oN| zsft_K>KGDWTz-8%N9WYvm#LD_jO0*@;!q>lmiy~y5&V|B_y- zw!W8rs9|85b9`*^a;2ApZ$C1$X1=AfeH2~+Z>M3&mOw>8X0kSb96b9*qh*3FyUJ;( zWJC1~qtLHR_S6?gYJ&*78)$eeTin~qZ>E^FqZP%L69<=U)UyUglwVj8fI*%eadTG- zZ-8Q}x4O2+;=VMZM7p!`#n*+ip98L?Gz-_r`%Zf=h%M*D3N(iKrpajgaq~H!RZVqb z1D~TrP-+oYrW&@*av45^ZD3gK)Kz`=8xr>A%r36A{T};a1$c4uH(S4e>y|Tm-sR)V zH={+%)ZFEFw}4Oj^92>9(2yGX`Bc;Q+FImjJFKuA@nI+M%wcSA@LoDHovh;ni7?6x zakoSJuWi{>(mz@+&Rb>_HhHg*RaN@OuFFPTP4U;n=?4-_Jtx<9|Fs`0avfxh)U>2g znFgG@wbnWR<`JOLqHy_`-Njcd;luzY)u(P9(@yGt0kIChcYJ5hq53`dx}+C;UH$C2 z|3(0-c5mh_px(^GSN-iqwQGQ9oZI^QV7`Ej%hMXRA|L%(nb+6J3|9Ca3_V-Hdb#Sd zo!-!;7ORbNS>+vRbz?*_uIF11M7KdhB#Ot6)zzKqDJG|0PUR%)uG(cwRLDS%hsbFq z=ZhUC7Adkn`n#X8-@YdA2()!g8PrVpRgYFb&2zGW;-Bn#h%H1VFUQkFX0vmnqfQEd zH?cX`N*G*4{o`2Qs8#rEtuX=}GUX05)Ehz4>h+;je826sh{*pkiS`~}q1n*<-+VxKGn49?XYg~?zA+W8=WY*Ccp-P|O#U@2ub4O; zLzBBpLMYXyAsL)FG%2yd?J2U4UfIQs0aYO3eHxGYgK}QT9;6r#>92xd{i9Y$`jQgC z2n#wX;Vsd8R5RL00zMQ;t~-7_G0NPCq(8w&Ee+zLqTdfpyFEC`#?%=G#b`v;Rc0RP zR2ci@CoDN!Pg_YKf_2&_EvEC+v-f$T@pF{$@eodG1&beku@t9j6FzC5^G39MqE&cs zVo?u?@lQ$Z+^to&>(Wb?%QMt~H zI(DQPx9{BnJI9`4CSzDf1ts|0!^OEX?Xy;}=F^dAO$nSPDN^L`7t|A0rT*4xn!fat zY+3}HC(z{5-;9|>)m0iZT8jPQh!Nnzy zjWu4P%)r*!I%&jfW=Y3ubTczvXD={zFu(-8C^qlr3XLTs#hr5WDi(9@|J~zY=Q{f> za9k4XllwAoT;r}ISh)|3%J;$9xq-jTd{P-z@Ld4=Ze#Hxy=M$RIIT~HENSwUx2 zRIg1#NJ+z!@j#TDa*k=`x1>WUC9x{PHmSEjV_JIhZ)WwE#iWOJ+cs1r9J+A;Vcau( z!_{&V1C9#guokL_WZTk_eErnj8n&0WzMllo(o=K`XPOe1a*%HlFQo3P+kPOj!r zrE`rYTKls;GT6K{Dhe94L!{6MK7-f-P@0_N>O)wEw*CB+4HW$6Yym(>tfB z(_5ILUc72t>~n;#daYGf*&UPQu?AHNhw3J) zIM+O`CWnIIAUUQL0(gDN$N@fXwVe&O+(q|H1ra3)ms=_ODZ6Lo!e}A}1s8VXL=G(V z!4R1^d^t+>hTEK)T%7#qo6J9MV%`IM{6eGh3p8cHC1$)jGWD2oo`u{%rDNy;uo{3g z#sv2Kfjp#|#!W2MV5!*TvlR;QM-P}l;P0$`9u(UNt~I?Y;H|rD=&~4c{&3pJZ(f6` zdp$NuS+5r%1`S3~D|Uqtz6Wl9Kqpfd+k+m(q9zC%;Mo zOpc|?JY_c4eO6(V@pae<6hjp!;gA_|faQPvjS50-r{5-NEpSycB=Qc)Yf)k`)=9T= zKt@_kP%FY|6Y(@o>V-=A^+qV^8poAzp$$@zqgPATD~EYlrZg`da5sv?qA2nDte7hc z8n>G33lX59$C8xP;_CRm(Ny=zrmgazo)B6(S_EFMJTg#db_O}I8)1Mphe}icj6RI( znNK20XW}p?9B_lYK$=cwx6_2yB5-Tkq>~({CgN_HQAbNaVwqB?#p40kBDCS}??~j> zR`u)Diw=$}qtQ@rQfaRY&lhs}dW7d1o^lYuGdT-(R}YN(W-Y|tIr<>^e4A=gc<{|( znf#p=dq%|xjh*zPJRm=2T}?dHyLsHZLRyHeR|}D^D}%VYYJmd3&N>w|PssG@m!eDA zg+Yu;z}Oa;!^Dmm@7%LS2&XhKTC_i5P%%#&^Mj;M;vx9CI`!YVtX#7iU`%P!nJK*l z&uwO)@)zUbko$1g_ZTwODGnc#oa&qy)2BJCVDv>bEzfK3qzCn!ZT^%u3E`!}e`B8| zm~2QU8Duj((s^{?fgAQ!~gK2YZrGYJ%0mHB0 z*bjK2t}$Y7Y}1cv>iq+Clvu8zrTi$B^$L)PsJ^+oTj3nS{s?q5fN=^_!hNB0EMkRu z03LZhoMR9gnkx)s#wW=q*{EX07&O10Nk^-H`+Pn&3@1_ipZgkmEtMJiqQnEAZv#Wj zjVeK56^R~ae^AulY+?#uZxJ{pU*H_R&qEtFrvnCM2z*$iG8E`>$W3278-+K?jKEN9 zEiEGUTN}c}L-48bBbC{))H$)%X;Pz-IHX?URdDr}^Lb9@m0c#J_Lzng_IR4~l{rlk z1j1$2#l-$myo-5}sz;VH zlmin1)FayBiCg;3Wd&$$LK&ansl=#S-^ujQ^toXuVe&bK=$a~P^l#}9C%>0V;wRcCow_n36oN;>veQ@uahVQE$NE(wcV-|b;;kdn34b@upp`k{1J(%*Q47w zgAS-PFwsab@*uNpL#PNi*89%)tM=y{pYHqYYnN-LV~Ley{pc)`xeKI|;ZOn5hv#m> zZy^khrK&~i@T*ppE|UvL2O?Krz_?9&y6yHp#n`jRe-Y5VcNIUli2kSN84b+eCaOE{^gQ!qN(-+2Wj9Q z`u=TzZa);;NrJ7z?V9J$EPxa%Q9Z{9UIqFjr)gHG#BIc*Vi3dI1Qx=AU86`OYgzS2 z0@GyjAR4k&7=FIv54ugE97SkhY(|Q+$I~HrKP+&FnU)lBAxFo>qT6_7?k=1YDq}RI zj9+BmlJ$+uy-}9$N4fa_JcnPziM8!UWOwRzD2n~j7dC7t6|!>FGo#X$Z(g@>z?zLr z1U$XB04fAZ1TbRuLyTcgApShrT(B&*nHCPcu0+`j|&fdbALw zJhPK4!hqenoRg&K1PPM>5E5ZhaIv|X z+bzpWG=q<{62tN2ja=mrj`UhCk^f!;FLvp5apkTFw4@Q(EE}T2~{OTTVSH zhgQ}zOCXJ)PQ*6F-p4rDEN7lu;P(Em{Nt(jma|ZVVD`lAl-8@M-A8YO$T@w~LkQ1xC6bb0 zKf)6$!6J!LMJDtKVk}Nl;ZiAMojGS;c?u@PSb`&Dz{kum)EF<9tgWuDZ@H_ZZ#ls1 zlK(SzsA!F*o{Aenm$BhVd2W9oodBeGKubIy&1HdWBj_W4U#OTHd-(-BZsP-%qE%ub z)VnRBbMPZCVxL?f_Wa|pZiq1gj1yLI&GB{J_Pk1W3!e>lQZ;Wq8rA zN^ zA*f&Q*Aa;!{)uSTh;mBob6f9eiug~2f9$L8`YK_x+9=)oKldp~&`o9;1_s{2Z`a*M zNjg7`JcuZN57aU}TwbPNFd<6Qqio$hACaP?5}BUftXc-gnHb9SA^X z?jK4bpc3p%Uu!C3|*r+@dnm)@=F z5(a;{T2n!9ESNCZ&tE>bti`@0+nScaj+10`Sim^RCnKol-&6uDFV~qW9e?-5V$N|2 zIQowRz6n5|^-SB+&tmLRWx3`agO8WU;2I0~x?9I|H})c)^SrFuN zgVLQo!$-!Z@K6QpuJw+?n+ZBr32L}<Yl>HRsvZi5xAWQ9+w@>pz z8f&R~o}pT5;FLw-x<$RN5#uNuNVo~YsZY!Ux!Q)$xa!3fulN=Mc?uIs#I-ap5r zYk(YBQ-(<8A88s`;LYlcNlT?NLPl8I>=)el#9uuExh9+9Um-CFq~Xr?8!C9=#e zB-Mz<*b~E7SR~Mm*-Q9<^&X!JRVR?K1obggYDo0IM$)!grjLf0H;qEmS1EnHr7%tr zvtpND>dy&R*eU7yf$hCO9dVq2;LUw_MAz7P7xXS@mW{QY5ARgmA^iL)7gwjyV;r1P zB}U)JyhjI)f*K{4XBd{vwf#n^_*fPBG|>#HqS;>-!bNGFE)H*GnEZvj7I?@J`{2h_ zZmn(Zd75@93B{}r>~S)9kR-6f7o(lhX+ALU<8_XMc#Miq4svQ{SnTq{e|UgSwk_jcUOQjRa`+(OoZQTd;dSE41gzkI zSLeu&MQ-A48pHCMol-#kvt@F=dMqAjaN~T~a zB3+gB>td&O7y9Cw5Z_~e)lvYNrc{Wv*vqb&Azs)mTTx~u9u94O>@Jy!U*Y%+Jvx@q z5%z(su>WjfNf>Hs?aetEwW{t*lla!GS<{f3OV&x)1!uFiJ*qYW1WGHoi~o=T|AA(^ z^p7X6ktWt5+H5oca_ z{R{V!np7`Ap8**|DfC6~n{X!2*^_XE5ylzpO`Itm&qt41eu|+fIB~_JbIDXfH*kr? zW=<0?kQU2pvI)xs0toQ?Y3|&kDPGIi?9t>vM`P2ZR81dOTj`e%)t*|TyPb{o_Nm29 z;x6p1GqxjshyaUlYGYF))ki_aVDUP<$>ny`yt47=UXo zzK^E_YAIxBrXxBZH?ay!1>qMAgv~2fb~l^%gbfvlM0^HEsP{OkJuS_0w)@|@xcuWE znuD*ONsbfd2y_uP=uEN{*}pyMvLzM47qW^1Vhg$06|C$GjxRLBuVZ8do1K%ZkMzgb zga3?%HWC|jY*4IB*P*Sv@QX($t7IjbB@yR>8w-x6#a%U9_lYs&w&m7RQapu`JC%Eh zs0pj`K^a7XN*MKs!}YEoPcJNgZJgFV%60#ZbZr^mn&SVv9V^T((tod{sqKyxCx7yo z+2MEURz<`VU&1w3H_Ap9iOEl1gwic<g`B;_2*^pfvd=e{FCyd5~%7<=s zr51IairHL^kIx=`8oH{l-EWM=A#W0v5}ydm4i*`i6rl*G(wE(9i8UOv2h~aX;nl(h z*ugm?azRipNx{dJfaUw|S%3lZOJLGvr-H%8=26x!re%~`GS2|>SNZ{ks%yKOPsDcD zv*;{7m4o=Zq>QfqCzwp#G!$Ns^Y0^{zqNhkvCnR-9AcY*{$MdIim z9Bw;xsRvvGm2m&8lcJgX9GFF}7DLA|E8K?+Zh|v&#vLj@b3*5@ret(r&&!&$?VHWX zpLD`~mp@CRA%g2E#$Sc~HhfPuV751vLQj#MRd^ei??)t!G#`?1SU_qe_<7iHn8YIg ze=+rzQE@Fx!*GHI4{ielXK;5XxVr{-cL^TcWpE81++D-K;1Jv$hTy@Se4Kmk{hoKN zUcL5@y}PQqs(N=UiI2(*y@w`y3 zn^&>l));9UC{j98^1D4{yN2;|17?x+xFOl|H~F70&T53c5@df3QUvN?UYwXYeTuun> zxWcob%5v9SHjc{f$n{}*1tKz_SS-UKLT2}Rb`ST+03{<&@W^K-J*;1#W6iLdFO4I& zG6J8R{b8sHSZ!bkBgnz-4UZ#;pRtk$$h!w1YRE$!2TUSJy0qaYf>@8xW}42SJ^k1RM;fCu+uBl6XHSV`|Y75mIZhE|z8rIHHS z*2t`@psQG3d6jhSBGj*Pz{(Zff+^8PJP;?@Ca$4R9^vE$aqXmZF1-?vMStOLNHNQ{ z7{Ps99QouJ^Uh+Mt`5m2o&q7s&C7ODOzjgB3PTL$c7{|6o0WuE&(+tomLL09ZPl`^ z^SQ;5B^)QbroYZ+2qN6s4<;piaHN~~(YV3Ku&xFd~QSXI?&|s>_=7P%&sRLW$9}ve`ane4a=+X1xud_(}G#H&W0&s;zM5pS~xYECY-kIM8lLB z+3z)HuY}u=a7q!&RbWG>VaTT)XC;u7P*#Yrw(pjv!Dvm$F#F>Rx&Sy)kqxZi6HROP zUXu{}HvB~Q+r1|@=oj6g`W=(j5T@Na^NXBlY$&IBBag8YL65XCSezlDy=$V`WZbrO z$hkta|7R&Zn+sOMeAGxWBd%E1mqBvFBM1mHWKo(pWb3)?(CX89-neJ$>Z*3v%r*H- zF3HW&iW<3Cg)<}Fb=pm%>>PbGpONzXc{Oz6OYM^j( zyVHBq8Ce}!pQ-l0O5FNcpJNdPy1G}PaW%#K-F<#*{lpmF4rU>(OmqUcc=o{yq){TfMZ_ROz#dDFS`gfa}?duno7PIEKHkrc`4dY4qu5+oZU4mq_Q)RYuN zm}zHUizp_JemZl2bny?^izd{Dj1A{L%TD>)tRl6%9S#oR8W}>)aD&6*4+Uo&y*$ea zdgj)c(E=_uOy~g`7EfpB z4=!?H)b}&2?6Uo8r}vsI$r3201cW1U5e<%VOA@87lVerBDx{+>Y4Aq-ZxAkI#NY$Wn5HIO-n|97?|bcY zFBoitVtO(R-_OJZ2pd*@|MG;PcXegz+&HSo2d){!H)!3Dl6zb-B6QlXMt^=7Pl1J! zgvm=~g zx5F%fM_bqIwvJH5>4y`>buwiptT%o7mUFJovNys7-?OhyKSy)3k;#cl8Ydk(BWCSS zyDKbjx)T733y2~vf*ArtA_(1f__vt%MLVdwp(`k$yq7Du9kaVhmX+$%?QtXs6gaFr zaJpES^}&-mHfV1cG3rgldNvHBWY{0E_b-uhaLk?>_w;_5;dauz^efQ%Y3tI%b#+|53fHr!UKD!qf}PRnEXP#8lpZx63LXzJ?1sUnF_VadB662Y zh+F5E1#r-^UMk^g;V1S6Mrt|sWJXgQ$=KOgI>pGha9S!t9Z)QazT9QakU_gbK&^b) z;`XU(*e*Zy;jPZ9Lj$2)G}))V@@~L`Yna(1g|vE~h54M0F%whDEONEVv!iPrz~OlY$^%mAyoZ-gOov@q^=}bUG}3>PkAr*c0~aSE z?<4GehV@tX)F~k-hxfLT-7#i>4dwDx2hnlloim>-Z%vLR7!p2MM}f* zN!-{bTT~y8f=0f82k>iUWq-kVz!S>hb>4$RBriLvB*OuypCy~U{&n744=x?%dPK24kn zwoZk9NDa8P550d-14b zGm-ljZ6Z+E7cG4tr9E`)Jzpl)`QoUCUO{Sqd#hhqU0rIib;4n+)XBBPpL?_zdB5w$NlC*#6Lks7K@iq=dyi^;zOIj@Ivt`>DZJMB64X) zgP$^6zPP)4pc3VL7=yTc5%%{^(rO!RK3?=LH;`II=UAYs)H?~Z3>Pq1w!doRW@IEi zaFf)j%GW1E+Xh%xn#~U0(0$w?k_i;0&zu%iw4j@jk#ypW4_; zwxV={r?*gi%fa*jpI0IEJmH++b}YnSa;)cJV{nYN-qx$Z6`DoA#*@^(U3@Vk?sY@KY3l6*=)b zy3={fQrxJ*x)+$y04*5Z233kP-0U$PhP=LbAQ{;tJ(I=0A^G@fFpJk4SjM^|8_NZ+Q-GgyiaZHT#qq|FMoK7t@Vr3(i{zyY;8H*ShKQpO6 z-Yr?vo(x7mxW<2j!Bn=5r?0M?FRpnrF?b-$D?w)0od-Mv6{fU#)w((I*a?+qUoPer zztP3Zf|v!mxeq)MIjb|C@+wB9$rYWV0EiG(yGrZ0(}%K3ISz~|;} z*UTsojXvS=_9z=u(lTi=w1mv;H4pw`aI0_)vuqu)tJDXySk*cIhzvEK+h6!(#!}Dc z2$a*35Wf4sa zEq-yR;bO?C#3{!wShsemo;DjR|D&;0|C^K!g_=r-nc3f6(A@4LI|~Q0-lyXJ$4^s2 z;U<13zaQfkAM*bmUlmhGeC1o)^v>H12ne@IIMwb>d>=D}|L_uc&AGEr!t8Gq_xEVC z6x6}(8T5MM_AFqOvAt|YM)gI63YGZzWFp_~HhQpEkYFnXucL0jiE-gUU^WZqgYT-n z{oO;^YF19(_=*jA{fS`A7{fDEA)Xc{N(C>#BW$WvxTbqB3_|_-m1A4L20?A-k;{^y zk+F=XasA!Ly%^1SK)|7Q@rURvyWB0hy)d2u z@s!OrJ?$D@e0sg#B8vYzqh>%julFYmj~Uq>=PcPT13+VGNo5 zc!w0x+2!mL6O$|4DLb&>7=s7fe-?A?D9WZ?pptWt9V3a?jkRBH(X-JxqQ9>HJjl}W zkd($tK@o3o!dQ4OcDAe`Dx9%>tQ^|avAS~t^?5zPD;B3njXPNI{yM#%*#LiwGjvRe zP~>6Q?wWQ(j3-jZ)THs-B{ci04*TKk_{T5Nq+<%nK~KPhII6^7oHqD;jS4gZ}Q~lLl*f6ERxMPT_D(`11!Nri8HP3m8CaS9u;D z9`w5$o~Tz!za~S=q5*KK>_^ac#?c$RVc4+WKDqAlK_^3?UH4W`CH3fAF9T zC1+C6)^$>G%1v+``nV$5^LK%sMGudUX`0@Wr9NYRI+s6B4OnWG?xSWu+wK7(>uw)W zPU*)bq`+}c4N*EL+f9*6s#RiJv|(-S9Gnn~YdCkkR#J=k{K*-Fw|Kj7KQbZfFi0Ru z*Myo;F>!Hnf*N6PTw@nRlJY~_%E!|wM88$B4~2H6T-tYsW55 zv*z3YI;B^sQ8g0cffalz?!3qpCApP)e{wNfx4d=JP3(8qd<;UxuraaAr^Pc+@;#rY zbHVzZk(afrk>&ExPt@uO=yCFW{#n(#DRldi7&NiHENN;n`(=Iargib*AZYkRTHkpdj5J9}TBgRcEPa^JO%FqK3_(pywlMSb!KTwpiCJm?!%FjL4+9>;b*l=b6_!Q&pOq>H3B!;kYYZ!t!0+3-2%UB zJ1+hzWcWwy4(gl`2O<6IdyX8;pZF7Kf7#AnmXNni7${oM`_stabarg&YVQP#)*vRD z9$QN-z^fgMA>fdC2w?8KYU>&G0+?zoomX-m8fA-AFQR#Y0 z`y9+zr^0;o=19+CpLejTpG?Njypp}`cEuH7RwF~2ow)*&uZg$)HDtb7=ymEC1Qigs zVWgF==N&rm&wuEeTARW4+gKS~UEV=F@Vbvm=C$p8b%L^L&r{`kEa(Z>YF`N+_CMtt zDU+kwaP#-JfVNtNZZR`_wQZ2nLZPU#3x*J#EMd4DOk*7#2{=6&@)pphYw9q&8 zQDi7Kjhj3&H&2!$H)Xz|1@^vE!H?(i5SX#lxdn-N&{b~fXi|^d&^^E zr5Z;jc}qo_`?}8A{}xyd(Al55UH-y^5DN^vUAj(IYCpu-t7+qD?*1AFC^PSspOJO8 zq#oQ~A{ADDsmjfMzF+e&ToTy`Yd~`4f>v@cmTtLwEpHg^vk;?qs2vFqjF;n%YmnTJz~QYI5X(?^>;tGVoMj z&OZANEqFI}k1e+@JRH8Z&{=FRy_Y_KQF=J1Vh2_uMN?P(#H)02`XdrYiBK-u4lnHW z%&M%3G7dm3v_t$xnD^u6uZNaK5-c?U~i;9j?{ zhZ?7`kTx!j8T*}Ix|b&fOH9vLTX1NK43udiuJ^7_>nTK^>yxJXg$=r0;bFo& zqZu{W1*`wuc2wOAaTejENRn$C*KC0}ma`Gw!HkWl){I|dswCTaw#{G=%EtJqm=v%N zW)_a6yu1f*i+`KsFv{J%vLUn;jv;gQ>G+7XdQ0a`crzaS>61|?9X9U*l>o&#|6Xbz z*7qifo`$~JfIjlEq3-o|alNg1A5$7goB_0{i}qc)ORnIUTTGJ&c9~FdDze{Hf$@ky zSYLAs@KIPbXQ$&mM>|&3%!l$nRCH4X*5_WsxXgnFsaEk8aPxpGFXS|NnA*O}em47F zg@9gY(J#^xzpyfVwK>O_?;OUo3d5oO4F)hQQ&m=~kMCTp%fIBTq2^~Q|3M*K)r#Yg zOn>}>j~x6l%d~!SS|RCs`wZD^GzYuQn{|d)jmfRlSUF9H7K_}$wMLo??>A%74g!^o zT8Rt1PL2GQf@OAzr}GPanbnYvBSt3~WywH2ZDtsUqe8oysjS=ghjG}CL}QcnoI=v3 z?be+W)nenU*Z*iGWxcINH{tTt+-y~-1uLusr>4Y3Fd~}%d$IgR`W=8HtB=9e ze4ACVRk@ywP5e6`B3TG&{KKKzxTg2zFDw_g;YVIco4923c7ynGJ#+@3`Uw2FV^=Y3 z#URlX38@JW;u=v&Y*?wO-ScXvoC4+_3s5qLGdtt`MusQUS@58Rm zqxI3svYXw>Dtvs=B{n^Ei7q7qrVOJh;_9A^-&WT(nDPw@ARJeiVH+7Y9}SpP(-Nqu z#SGb;%bYL2CM$;Z&5$;a0?J&R-~3uSDLa5v{Sc3<@q2XK?!SHJ2f$Rz`%71d8t^;C zZDrcyn-!X{cUgJa6Bg!p!(!MNQ4?Cm*}J>%O>yq(1zMD?9`UQ`XOG^L!A?dG)QZS~B8{y3pw$hl$E0*cOa}A}9)> zky0rIO<@}7gI&sEX)e3$@)qZl?c^zOr>VTc*k*jBN=0Kz8LZ+3OzB^LmO+nRj2j9w zYF+J3;Ca%`2J_9kkxn@@^LAv}iF}j0oOS_pl!>Ll7qNtH)z6d@m^xVJu#>uS7T9lL z9sFmB&@+%W9cS>l>I{rD(4N+~f`7=sC+p#BUI!lUjM#&P(m2a64|Q(!?6uPo-&3{n zaaZ<6XZMhpbf1k=^X&1{eX@+PtvG;!`BM4fy3BGGXBy9pDF!*cpoS#Jq(LYl3w`c$c(RLe55 zx|Eu-mgy27fO^NRv|+@^+}VdEj*&pnw9H$ zIwo?8JaxKNdCGTb%py+8RH9XMovKAXwMkXgJIfY3zuLahesVp>1aT+!Jh`C)bLDSo z;vH{_{Lf5h!8)!JDm%cWnpI?hW##rlw$^p`M~e)8T#Rp%E76)VD2RQ4@nRq0S@z7% zG1?i9MMU-^e8FGC(urIiS8 zkcf{)zw`Ewv6T}1hbxjnW!){2mvQnu#tw}MF*^cCcQWaP zbBt5&YKa3bujeC`GCxR@0`itRDsIu+$3Nt+fG{MmjeUaWfJ`yke|rw7^*SOV=9BQ9 zG|Gg4%qD@!NLx4RrztJubC?Sy92P!b;EmoDsQ# ze_1a+09N66;u6{-=}78V6n`m2(H?U!@-6tYYoLKy-yIfq>Grr+$T4yTgM|ot-e`qL zPne-N^XsX5ezA1pgE_t^q5MEzS4`!!xvJIo&)Bhdg-i)u`xlXN1VoV9Oi^HjtwR!R zHB5@zoWsM``T-jFepSpmbY?tFSjA5D4V_(y>m`_+m{jE6yE*lQkpVJq?YsTnf^|m~5^X<&#mnJB z-Q7K^pWlkrW0K0wPB^Om?|^&_a1DtQw~=BMf1-WlJUb9q68#xB;CkxN?eOQj5g&2*1s6MQS}dDVhTaCtim=kY_VEC zyKj<38+e6PYajdJprc-7`qQ6^rU-ERB1tAHh1PG$sM_5KLKzyg`c60yu zzn3C^hXe!LMt6$JXC3|l^WS!nRM?6)`G@Rpk));6s(nxQ;9cM!v)77i>aWY>uRmo` z4x-fkN*V@cw52|uAo4cigzM-0JtW$ESX>>?t8%_~K4S~Sc@xhDPHG}_*_1fVA1ZD* zJvKzv{{!&GCE65bk^1p;;Z{-q95cmmPQ#vId2KHrvyT2h8n~S*=KMy+k1A6A=22hM zXku&JtqqVP?c4xHla1_Vqdr8Cr{r)}gWZ)uP3HCA{RLJ!x<6c-9EGwLr`TtxXt25a z8(fM-vr`ZMk0uj8@e#A3V}KgDr%EZe(Lrmzt1J=If+MHRd(5DZ->K!~oABr|r+Yfa zAdUmo4`9YgU&eIOD_XYLgcx(U)5e^aN|F79zY&3N1rzR&SvCPeh4@p$4JmYTG8`Y( z$lqgca{eno|Ma^cxmDGeV-daGXr2fTIX>?6p#TokU!)CrL9{=G2uMc6XMPMm@MPOJ zk;DtO4v3Ew-7g7$Gx1w1{)l$iN@VZkC~hSxB1bwcFO7=$h1qc9I~%&Q9d5Lo$x7fq z%Jn}!$(9rafMR;vhUG0{4oychb3$;bV+hihcX zMJOgy0MGx?2EHGjp0@6T*n+Z)gw^yS3qO~BO7^mK?4hJ|^f>&|_H!^zx=U>zrHo|s zY%~keE zdsl^OOXfe{JwO951!;TliCF%Q{f%*pYkkNjGlDWSGVGBc-n8+|{G;dpZM%!2L-fXH z-g$h+?j8xbki=i;b+FkLdwnwtsNqa43)#=texXkWnI)7K^vKw}Y_UU%%fmZZC}B2o z!IIlEf5&br-}s|jhRe(r7IN3tI{m+a|B-@4(X+GoC^Z>ShNIWOP4*Y@DQY9648A2} zx-proRr{*u`w_+b@bkqDjijk&&-RXvlG@j$t09 z6VhYcm$zI=_tu8%|1S_q>0W=wTm~zx3{t0hPygKW9>M-s`%DQ2T;wiLZe|H#Tq{p| zyYSxQ343qvZ?~pLUY>PU;nL*yoJP=+^VgK#=L>|#hrsdle4&0Pk~^}IF_gaK?+tLt z1P#(Sf?WSMRp9#%GX??Kfj4CW_p%XZXNfnDs(H_II8&rIo4R>`z#Ui49pdN88Ad)I+?vg#XLEn-C-D zVEi8t$#xxh8)?jBgfz~QKw}_sMuvv3xGm_@J1k$=xDBUG|H`*J;Iko&*7w|^oIwag zZR>r1uYO^!=ki>cFN~bj7`;yM-OuyqZAhKhG%U*>4*g1rwj&SyDE{G}&JS4^F=5L2 z&r6FM%_wK4!Jmw0Dn06fvdo4)hZzIwnXX34**nj399DeNoj?6$ju9ZiL7^-oeJw{w21ga9|Vj z`?CK6|3EIRNp<*fXI5(2Si$8QC2)A)qW1E*D0HrTC-rzvelnm{=|5Qh)9u8sveG?_NUQIoYO_s|7zyiMtd`iYDmV zqAd|v;?UA&x;hX+1zJYJ4eZdCkqg+Cix2fQ_PA>Qor8R2E#J-|y2%k$f|j^rJ{(x= zAvLE|uOmjv1hdDY6xK-@_C8it2b4uOx_jT%F??f}^I7X$Y-%KvEX;jAK7>+}Z5_N| z2V;i8p(KW=1P}r{f{9!OZrbq1|Ll$lNh+7MpnYch~#3lmq{&{PR3@gn9(JN-h2c_10TzSMe06I~H9VcbH*7*?uqpWzbq7v9KUbYn1YLUe7>YH(rpEz@B-2d((5<{JgFL)*qV|i_P zZ}3>Y>sQ>8oTxtOtlN-}-`8)OIc>1rlFPhGVTkDB(A3O^pPQb%a4yq{CxFM=FvC&JG2i!_AgZ51zn&jsYie2|X^Y{c+Ccbt1oKppiuZlwRRyLeod!)aYju*8B3LSS9i` zh~)+9^18e$Y;OoH3-rnpd79PsIa?BRYC ziBf`XGM3U5jR|=napmtXL+K`d4@7^n+SY}}Ia5$7afI)}fjwLpu{VbarP);ZDMrN+ zY({xw4ih3y-o=}Je{=m~yHGH5(u?;(gQw<9HXe4Fw*in%&BVy%LNWpDqI?o z2@LPX1rZ@tFZHnt%YCew=BJFkE0vGrvL1u9Fabon8$0)ax@j}Ax5@frL7a=`dPU2` z>|{Dn#TNz80ikL#s}e^cKn3B=j5N%-+}U(6aSCRnopfWz2{+lvcv}xlh>@|oy}l%e zvQCUJruVV`L4&uR;iQq{2w&-MWr7)NLy71;7?2fDDUEIH1{&O2lCnD6BTjK5DZukn zE2$&6NO7av3?XH5|CTn>3n9;YA8xa&i$^{7j#D=cla_7Q0Mu1fE5P&E;n3wq6q`e} zetfsfNo#h_!Ijd!NIEvqYav-nGj;p;ixqyz#aZ!+n<41#ac85Ovy>~Ez!JDiRm!u{ zna*zKM4wP-woSlO+BQw-lEtp1UfBAW5^SO8-4f;0?ZdKft}7>^FoI)D=Uy|d7otW7 zhO{a^^PEp-TS!QmL}+`G=U?#Zv210x8j97cFwW57mm98?uGczq!;i!eU9Fbvw);alszhxORe6P%$V4|G0+nsxJnmF%L2 zKLy_ibH$q`j>q%`8`<76`uRCF^y63L&l44f{&Y@fSggH@@ys6sM;a!Z=?KrO#u^MB1uS@CeQO^hnci zc?~KKs9z&u8)d5L;@$H=@oNoL&4At|D7lv6sUXN8*tc*$49>8#+);3wDLS?(ELibz za15qn%#{QG-~{!vq1uDrp#qxkd|@Lho-hw==hP+{@I; z52$%Niyz+uM4V$0%V>NGO-(;{GCDb2dZqK&gbAe$v2~i=Zxag{cAkBF7Y0?GR8qW% z;DG;By6WU&VUu*QB7rB(*3CK8`V)*{!Py3iyo;?Mvrj=U@AB zq|U=P85n&5wUg#g_lA9{Wka5vdvZLxWA(*0V+|O1&GR<${=9{|M;_2gQtO~^Cb6{8#EZ|y$ zK3YoIKlwF7o%=XckpY`!=J7vJTiX`OIdHvmm~@uNxL8yX!nbFBaPpcG5P*fJ42h=+ z!`;~(HPSYyVr2V;7xn$cdqdT2*tHqhh;M(#N*Qb{?G-w(8rjTnavpx4xV%LcStp#; zhDTTQ(NK^Sc5GZf<`{h@mPok6v$pkWX=`boRMumwSKZk%C(+-hQdL;f-36{vW>)=? z8HA{zYfcrKQ0ExwZx^yjtTVHv+Fv|+X5+8&1+j#|=v#cXiA|4UE)n z$64(N?vYV*)m+d7uA-LzZ6dm4l>}J7VTNasrw@Ft1gwT>h6~ve@Poc2s^?7(X=5eNNm$7=IuWp z&B}lV{P|sC4zyd_1!2n6$`1K7oLcn^GBZl08&|e|SnR|;eeTX#Vqs%ro4`awR(db; zr(A~ykI#mvp}l9IauwDPjl{N@9T7DyiMr{r(qLs=Rw2E14sawTl@-7A+rH5p$7PM( zs?q|PD%52_&No#)4dO0D3e3Q9vJE7Vyq2Q$tj40X&n~?Yj)?$b3|(g4axBb7PMCaN z_|vW_6j0U;kt+i;?7~Ep9RVuSe~cCC|99i=!N_6jcJrpT^?o^7*_Uya?*-(d9x+$j z3w3Kan(M~!&ld%|d%$7ZfDP7|y5`Zr67t1sDvZfgKK9+7ztf>@b~ZAU{ZvKS0&@UK zQZHTm>Z=Zpshk2nXuHng#;^UBaELTgU5bxc26Us<<@gL}w2Fv4d-*3uT~Mb+g#|a` zhADZQzm|#RVj{i9rC_Cxd7kfdU8%}AnBLXAW;kgX=-wmQf-+{46o!rQ#|}OtP`@KB z@xTm^XTjT_$D-W%n+PBGV3B5s+zfQ6wr8AUJ@ouHlG2;+*jt^Xvd~col@Mhsq}} z6O@>pJB(H5&35X>=9j?!Lkc*)(CN?Zr~&e8HP z`ZD+QGh@(&?7a6!`!g!QZGI)MyFH_4G3tcmx6(X>o2b{MZu}+qSKK3&bGS}gd|vRi zeOh!aOeVL9uMo7}vf$>x4ZHl98_V&l`xzr5I5n%>J?!XE` z`=k+iAL*)?$DqcjkjhSQ*Va@&86%cimEyX_#(D)vwNtx2S`o$pBLs#|k<_}mlf#yY zE_bgUEeXqVOZE=&|XTE0&UW*1shOA0?qq+#oXf=mL`#nFol7uG$<)f!4xY6YWSrJtQ5|I7~N zHN7adeUDZ;Dm0l^>r5SY7zQ*BB5e>jxfp$n?4Nrpi81BeV!cg_42wZq$9s}Z*UZy< z5Em0ViOt^`W8Z=!ViPeA5Ezu;010Yo;KV8$(|M9&4GGn_bLkfJA1(u-f)RxlMcqUR z3YxlWpSs=>y2qZXZoaVCN;vT9cELE{=Li6HIw!_E{YGpE;80oSDe+H$;-HM4A8j~1tP zaIAjlQda2{q4lW{SZlNnLgtwQo}VLCUA}=aIu*1O3E~N33p$(o2M4j{8|3{BD|iQm z6oS==LUIgrQ=-u<54dX7&9pq&B>c^a68Me2!+=W+oPnE$4=ZI_d63u$hqOmCZg8k- z&Gg>&lS3K=c*@A*zE8P;e=4v0is0}Qb z-DP^Ooo0knZzy&q#j%R+>wDbApPI;ZbnVRQ@EB8V_4f&rIAUIlSub3hoGL#E()+r4A(!`Iw))4tfNZK%$~ zOytG)3DdxF&lL92yV7^R-SrtG_)e*4CmpXnNH~{A66ep!h+rZY_42o z-$^UgP;z%lQ1mI9tpEp3&`w`JM-N`5Fh>2RLC8SIhR5H8QwKI3{`%k-EhR%5j>@k1 zfq+g0z2{WriqRex2YIaShYvTD)#{^^Z)#_d+pdZnFh%XVo9ited&fm_4?Nll(^;`2 z>Qx|1>JevI>J*vcBja2Qr|{*K(Z9#}3zxcR4n*&_^2T}ZW=bT#D$|;$z15!ft5(&w zGw}DwbP5O@&J4U@HTnx7f1L(mwD5Qzk{KR|Ja?x1RH)G+Mf*AS+;3N|gf3|#D`3xR zw9!*fFjmadB#>rotA4VHsKQ`Zo0ZJ;)fB&^zMK4|`#Eq4dXswGHACp?kHay}MWmSg z8C8nUv0}tApzVaoB!IHQ+fCYcHapWyDlwPnRQI{7xdLbxK~Tv6Q43fN=!7EUdwW=SN8VWqe$T3;va5_ z^h;C>laeh|Ib69(^84yD>o}niQHZG_=bF6iW~`a}p{@6IsSSO|85bn>j})XHw-#Eo<34J*I~eUBd*$OpU3 zV&hzUeC6CK;r(2JJ~k;ZW1RJ>8JRQ^pesuwE>^TKo30nNv#>-y-MnP$mzKd=#@YUQ zrg1^)5e`V7Z?EloHa7+R(aqied;#7vkd%C|$Cg-s{H9T<{?^v+$eBa_HFoZR%se^> z*M7JV#$hikK7~4lsLfj~yer}=o}IPVvbqOj<0_H3-)X7VDzdiz+KSpms6BPpF+61} zjKc6*FT@n@Vu9BY4t7xEF%4Jk|1?_AhQAmK3eCO97^uPGMOTz~e8^44;L%-P+tQCA zk3eVs)4YqO^oS5HXLDNPa`qh4wY_!?>r~>HXyb2|CnIX--owMP8-dK1`o1O3Z10C) z5t+o-*~m*?S){AjU$^xs{ljkIvZ&z@cAPYJ)-ksnYuf-X=P0sjmc|U}94&IK*%H0` zjEJ&8W8^v))R4Z>Lkm9H*RiZt&M72N?ES>2w__8)pt8?=%lYzkc1`<+?-`2by!-Va z14l4@Cl22E6J>O`fqvIGaZyh7_sI+InA~*=5#-V5=_cuYPul!>O8#!Nysr;1ED2az zjb57y%aY?WFn^aXZ1Qq?*2#~2Q>(D!bffoahA>J7WQUckvfp+;_YafYQ`?u;4&UD0 zj3KMuydsVu9y2=HU!2ztu6dn&=v}UI>E{W~n5edx{Nf$PvvF%&U#|#CPGyzB3cu)N zqPbSWE7jfU2^ng0>fcfAhVZaB*7p?LJC^h>(&KTEdG*^6(T(+UvF|WieFSIE8rW7x zC1=!6Mmb==c_3~0eZj;oAp{dN5SNscYc z?cx&(7NBV|%obI3>)0UPOJ8)}zc|WcZm=zA31k-!Khdb@^ zBJ&Wo&Lz z?he6y@WF#i1}C^{aCZyt?he6&ySsaU1a}Rt!6A2EIp=(JtGfEf)O7cLe9PKEH33JMF+2ohyb$^By3Iet;Y!mF1=MM zbOA|VH+q!QW0k;i0KP(kQ>ijeN_W|+ZZ|o-4o881$EssQJ6*X_t!$MCyCg=B+3*bQ z2+d13Vq#L0EJiNo86E8OHqM&%%rMhRLk7@22sX$Zvz;#|**DTWw4)~CtO3JJCxzD&D7^KZKVnPNyX z)9~amCG%<4I4*II?vf5mN%4l>R$WWLjhCLnkywKSg+4d5>TFq=K}fQ4^}*Kr|Vu;xxL(f#@H+TL;G~1AR`&lQ>+jF1<}TJhn9wTKm7sW`@><1=f zcds5dZv){d)*^gvb6mz`p0XawHg6ug^hDMR_P zl!5}nCbnnX2$iX^Co3#33NOAX49Qrt~fy$rkOsa!9hQ$jsiNM+{M-Yreb*AK?%UB(AHO-^LT5UV4 zM(R}v^^r6#5~k#AM~4S@^#cRSvy=g^%Or@XE<=pRs$u2A*%z=q<*VnZ7KD61^~2M# za6)}zZ>W9`=@g-Hev?qWYTgluOr zA#_HYZf|aZUjvz;E$ypxM`tZDM=c{sW*Ns(I&3GQgZZtL(6B(3E>kh}Lb|ejma{M1 zPiVShN$7bWoz~B-aDieW*weICAk*@^t9;uvC-!1yB6bpVt)HLJJmF%K0jKvKx3TaY zx|=II&u3p$Q5pnsJYY-y8$Y$Jgj95T6nXoJA`u#)V-I{RX1o5)rf~DPJH3IweITmf ztAAziTddoCn`G1X4epJ9y0_L*&P?&aP^nl zMtih8b2JGbL~}BhpC6BHQdIZR^*SCudP?Cyih@uM67K4#ef7m7D5hdEee%Ag=0;^p8Hr+C5baz1Rt|zPkJ9d* zT8v$LpLJU90b6y3rX5@W>*wG596FudbZX z??fp?Yi5v(F_~83a&_Bv+V8!n?AUGv*B+g~51VHu;Qv*sF@*R#*0MZux%voC+n z(OA%Vu|dH@V{`Ct7^htAZ$9uaq@`Xw@p)ePbZiw6VHhcnNA9366JnI^!5cWCv(9}y zTyqdc=#^~|kJj4UJkTHj?8AYf^s)6Xb=?FE~z%ysD zn(1wts|=jGwVh%4_PP0sa_*jC`V~TzwXQbF^>Cu(&t@PCx$$Rp!xPdt{2on{x9^00 ztGWk2&mhXo718Dt1uuzB%V?cvp7grTpXUldl8Q<0bAPtqJ#vqx-pJtA=qznYOUcT2 zQ_DdLwB-n6cuxhV2~sZ*Bx%5zoBzZ%xBZgqPpO%qC+hJ}t+$6k>XAsa0KL8L5EF?z z__1;Bw_Ox`!b9(h#OFR7i;@Emmu`tEc6**t zb`9fHS1H$lF!Oyisg{#qhXd0Pm`~;FIQPQyX!NP2An)EH6|!2OTsR~pqztHM=}`Ym z#s3ihbhQ}lU`3K6)PK=R$t6d^=HqrjZU(2ulqBdzkhz=f248Jvs4dJx_~w!kAR=4! z`3w$kyg;qY*=n1>lg)^3R! zVZ=1wkih_mkP=f{l(woh(VFPkUrB(rB)s|hjE=o6bt(O|Q6!(IuQc<^6*NF4$?`(K$9f25|NUmz0bw9VEj!cN0+bt zK7CI=;X(m%R+fQbab%@Hna@Lf^dSbUbr`3`spG8Q%M`8#F@wrw=4bl2Q2|W71p#Rb zzu>UJDSjDFnW;heKls>-kzP2kUoi&&DrP3j!p==!U~>EPts^ISAg}}&niul~LidZv z47Y%zVSvFX>bPf$*YZGzWqOm5CKnz0O>5eB8M!qBhw`;+WWw~+5%3K~p7S@H3QTrn zTYLssxZ{NlXt7WuWqNrBpOyalD99*DwTWe*?Hk94H*rY&qA2!lNVI!9=cOX!(w5Se zt4r-=&~gfX+lL>qk~GhDuTbN0)XjU$V4z)8apTv~MS&ri@L2`=xF9db@7s<34j9@l z=fA=IBNUotO;La!yNrtM)FZR(SVpYU#qhUtXmDMoDecd*fO>R3AWiHwuC9~nqT}o? z&Tnw8=e5QC`1@a8%T|0d+vXMPmrcd0-dpJV9KNA6m@>cb)XH@6t{!*ew1?VANpy;i z{>z7>Qz$(9?9>8+uEj&dq*L4TbbOzjGCIse{gAzSXQsQxXVe9Btpo=}^wYPjliqYF zt&awgVqYfwBR+ZE_r3hbMLJDNV9oTGe07S+aON?bD3Y<$mdrCl{uauee*rKG2DlZ> zx1P{8yy40`kuAe=Mve1{eEh1XeU?)^heQ6>13qo3Dz49{k8>R@XPW}2*f zeIL^XkDxf|U_M-cDWlH#_rU*idob17e0*N?u;rxXAnEi98Y`r1b4DDfs>h(0p=z&y zzY4X^3?w?)$kBk_3Gz+IkL4s~hfnGK$#4$^`U4!VUI=ZcMh7Y~4!walBS>pO1 zzrAeC%943GL}IJL%Q6)8aPKsgvex@_4g3sp?Ot-({1Yzbv#^f|sBwDRpUCc53c>Cf zKBAh>&Pc)f{NJ7qUo|7)S1Tbzl~D`GS3Vr$6mFlluq_^_UWi_SfiH|!cMOC# ze%S~YO+0fi{9l)x%c}pdzZq^w^DH@MpZ_BLjYmBbdx+2k$Gl6T{JYWDo~b#Nyo#`i z$w>lgVx39@`>S!<(+3FHBmw#&DGZqsfX-;)c}a}+$Hxu-Tx5LN)4oTC=D)9ZRIGR6 z7?xE?J}_CE?2{3ELzwS2=E5rKOA-W-~NypzzXc z;q3UPlc|w!1=NW2!We8`4F7L(tgTj#?T$Q7g`r=5niyEq8W7G)%0jj!T#_?VI|N#U`D_0yQpj5$CToYw<;_+K zp`+Vtn}n#{qFQOvN}#Hp94u)0e(${&aq69KMjT0P@gSR?Sl{YvnprIrs^2Kd{JkUm zN34fE&8!nDsS!C4|JPMQr|p$5Tp)=CEz|LL_%TP%IA|n$C}HxsN`~>65CiE2o#oAM z(fGg_iZh8LEFXhBe465He)+6!HAXqb@>}s2ZNpRdiT}xX&Nob4Q|)M$f7HyQ)z&=i zo`+tS#f?U4sRYl=wM}8_T{q;$R3s1{-a%UZcI%q!X%|I)iw5L1IOq<#^UI6ExDT}f zoaNn|w*2A#bJO!g{$TL-1U;imeBoa4f4(A{>c21Of7QdbyGPY;q;U8EKqhct z3?0vDcTxY;4@rEtY!2n)pCCY|GA`}g_4kOER#elZAK!AJ6voIAZJanC|HPWx5$O4C zf@;9!|CF1Bjay>7?ZqRywWV#ys1*9K;B7>6Bf(dgh4S2(Kg?z@ zpSOq?oc}!^r!`qHBj_KD#9u?Z_Z3K*)mw)oTp)#XRbB$9jl?;TjQss- z7yaLfG}t9CH~hce492);MgskFeEjpDd*+i@-bW8WjehZKKgzSK$KOqGjAQrB8{UoE zP#B0 zq;t<|)20)Jk)v5glhS-O*>*u?Ig|@8p221AanL209 z;>^vV#X}@0ygln8?@9bO^pQy{gsPuV6d4KdZh4N+oL3rO@}-y8c0%G zUpFYXV%Tqa>2M^J%d#BqW*=rzqjzZh)pDPU`<(THMy2=(ggkbX`8K_8t{K_Xqz!cq!=FYzta4^E$n_!-$ymC!w9bWbp8&&r z)15_P#fSE^vNURH>dn;oxVa~SAID&`wGSl3fuVaQ z6CO=|MByR_Tx}R#e@>fH2)j6k_c;nEeA%!GDopLKBVCIl3jaL%q*Lh@_ClR~;QkSc zZo-|`jPN&4Tenj{PdFZEA$zY!P`8Wfc^yR*YoWRNYHr81nu~mYdkns3_F=MAJP&b% zMJZ2kvQUe3#Q7q?0sFg2zeCnVcdMMp=URtN%WjO`!ERSV>=Cr|JU$7-PqUIR2K_8| zU!9`HhMC(D8_bfPN-u{(EQ!Ei1rF||ueI%?#cjxfKqz5EawYSr4uWT1OWC-ATfSRR7`FF`e< z9t(9396HLRQ=ewSLBiHBLthR^k;J(&lbaS;i3?#NN&iKM9FAduse+0TyX-k2qxb`N z^HTd+YRgF=(Y(CVu)Ej&PAcD=@;~h}``PF}`I=;|#90)kdLfR#9>dHG~uVs!a zALhaxfFjmK0(o+7Rcg>)a)y&i?$1ByYZ0c~<(Plp4{sT3n*I_=?lA0n*J1Y0*1&2Z z^f+i_RTaLtfOA#z(iB=Y^3;UtciHu6fy^@-p~od!+qq(dT&{p1Z6>1nZ0$H`%O%8j#nE&|T} zBF^KwjRgQZ{R5m_wfMgH;dcgp^12^n_1Jt|r6*jvVf`Jx68vT)(znBuL0ohT@r6M7 ztiThMD0-ErSIgZJ)e;+UUY@NtOHU4g*bX(vD#Ay1i zC6+948cQX$yx|HPV#Ws>`;p4QA;tKD>gV89x)Dwtaq*yb0T_Fx?z?PkM1TRK3J31S z*_yi6BuIV<$=POgxB)_&6H&ggt3RXa!eLGYKB6ORo1Sf!9P?IjV9eh#Q26|&ThKi%{A8A#39Y}^P+;es7?5lhs}%9 z=^v9xun&hF5q87xDEe6O7(ldeDRZQ;1cQ3oyTVn}<^*WV$BnI6Vyn$S+ceqD0z<;J zx2hu1(&(?@b_DD)&RD2V!(GbPg5$X#4Zk4mJ#O6Mtb>Zv&V^u@7mEz7ZfkUXEP(6+67j#g;H0h)KV{QUuG5zgmj-Las?#>_D_ufzrX{yilV1Hm zTB%s2>;oW59$n@M^L}=AyBnYpB!&=nN}I_%^T+@0oLMGOK;-oKKF`9;Z2jk_pNF^H z_W^w|L;Ag}8hci0d#tiLiKKHuW?GceOO3eO_#zLoihfC?Xj)#ifr*lGw35~I5gpX` zTdb{`YrXFX45xFCIx0FU+Rr&T|M-jic=xLh5Nr8PfMDxS#IN+DjLJ?%&Wh`_o5kf?`JNT6Wc|MvauX;K2TKqT48P0z zVppWZ+jWJk1h4}ekcR?r>5Yst&@5-Djx-mO!p9-jf7utsig*n-O-X4vcW# z0&2Wj*{jo6z2!*fJ#30A><|uI65-iBlq3yM&#a+kF+x;(L7-cWO8&~J+p6wblngl| zgcHqVnw>odx*>z#U^MNq%Ppu%JrT{(2W_eNV<>QGd+H}k?#i$JJq9xJnah;5uEeX~ zS0^q+mCQZkag30PL1DLH; zMv0drAU^H^4YV1@NvN6*X|qGdKXy%1#oAH&Jp-Yg3a<7+XRZjf>GV@hPH(V^MFpm4 z1h;n{kH;J}r$1VM9M7gw*yOoz%q%ZUk};WkP;m3x-C61AYPR*pSwk^Rp-t(>xjnn` zG?VDp+XCyebMv;Nq)Yki0@DwB2;B`HoF!z%pWot@3 z@9aZ>QG&dJgN;w7Jvp((IJ@jdnPh8A%QW#x#mkUX&e`a2I9)oiBKFx`II-{unczSW zQr5BnUllxV^S4iLF0LPVGz=Y?N0xO1TPf{?;qMcI@RVI6$e9;C3RX(U0f-|CSC_Yd z9&eDd^JfJf&1Ke`uEPa~(zz|frz+Z%jrd*#?3t;XoFVpUQ=vKf@MGQewJmQpTf>wc ziIV(H(m8Y*bHR^prx=^LQ;y7pRMpgt3!b)JW8{^qK8FRK=WHeE7+7jC6~sC(zkcft zPYd@RIp%Si$2h04-CUoO;lqo&5yOZzj1}93;G@=dk&I2^_@69+=v3IxAJkN^0%@7{ zU3Ymh-u(v)kgKPEsN1DTqb3n5-cP>!wk+=BXqRb%_5cqnn%DG`_u)|?#=^SL`h(pL zEZw2vjeum|lKh1U1pYkI7FBceq8}FZ+JY}vMtvsQyEjQlmMzkEfdfZ~VhYMv)j4eY z&63M{QMZN~!JKFFt+)J9GMAp3FX_djrY}e|$qAAkeT|kijnn25aRK&hy+}*-BNkYN zZ zWN-0~Y%X5Y3$o}GRL8SkR_fT{V_aE(2-uttwfWP|j8!T^CyBB4JxG@?CG4SRyu4- zahJOC!YQuLrcuU)&5WN&(gfYi zXtqIrQE!Z^l^uH}u{Nlbh!GcTu}fHZ%7S~Bki(+C{_Wan;JuJ%av^(EBLVQ&`K1b7 zk)&InrdkSv9y3(;qrka$0{iy|557c?c6cC&A-JMB4WLWb`34pa1d;YRr^ zxoJA%o~QAgD1_av3T@ebgG|Hf2nvn3nUR+4 z0o~yhht`2Ns-I)I*o?fYAlCppf{FrwF4c6U2{c-cBMIf*Vcn^0dy_fo=)@|z!d@5h zK`LIhwY4)T!6FmQBt%>gXC`5cr_JS+hz0k1><@b9M_StI978`ZOkQ$_>tW*ci_`i~ zHP;P##545_9?+^^NEXU}xIK*hWZ_Bq*zS^UKLoCXRBi>Dn*HWK%;)3m8QvRw8M&U=n zdUY)p{T=zRXpN||eN3JW*D|7yIeN^^7na(7;a9t${V5hiDko=8r}t8n8Cy1Eha479VQZEL(-yD->(ib{@&ADZ5=n#=2#BY}ro%pIZ=M*Jud}Ebn3Aw&RWHEoHMh ztHMK3t1s*>L!HA3KRT_s*7e7W63nS730}sez8j#~egu~Uv`QX#%?$|C>GCSnffN&j z=W}DU^belAV2%Ef(b8O6_cH4Eq^ez!LkiyE$&lGNIB z@~ALKR@9A{S4<>k?r6}VU4@7Rc9#EgU2$P2OgDrnNuoHS_7FsIHK?Vo=oF@}SIXSd zk+y4CNC>cOk2d>=V;dKtmR*S|YMu1+nmd(MP19AVdMbI8KmLl7`h}|jK!ERiY6rv4 zGvJF2*Zpa!hZ7e=*-~9=S^F@>E%$MZp}Q5>=ct&Ud7`_ny**`ZR_)E|T+ED=bw6q7 z!zKoL(2q)`RjR@K0uc=MuxkRER`-l}3+yGl~XIhaiW??Gyo ziWT~J{fj=V<3KO`*L+25`xq40vHJ0=sWubAWR6jE#!6;;=jC`czAcM{vm~(0G>%yH z`Apiik^?}=q9KEM^8 z_T7TwW@sD-81XgKm-O2P)va@NwXgH(HZsVN>{74RxD+R89SV6C7t@fMHClCZdfik7 zPX*kSI0pK;uqWlI(^Uyq)@|Ju;JIGd@hsvlKaoe0*L9oVNOGNYR5qdVL^E`A3Jv&b z#WjXY9fodWWn7SGq?#qoC??IIXV_~vFrDan%>+#kx?)Yr)272HVd4JPVhZadLeoqn zj6Ikmxq^#@3Q~`$>Vjx^q$-)&TXm2VnEh}Ejj<9^D31=}meBraXmLHMNjn`z7RM$U z+V})R)Wv${m*&(lWZp2OT_La6wp2&mkRceg410rwa)Z{u3pIE2{>UZP$PH?iUFV=Z8Q*Zm5=KMa z*iY-#PE$lL`x)-9^W_cAjxicKp4s3CI(!R0O#Id^(&h<`$1dv*W|XKCRg*!RG#|z= z5zakGdP37Mk762W>^+aBwPfY;?u!)rOgT7vHRctwBx0Zcp*{)#ZG{;Ok5GkD_>T_l zi{{hI68#>4Q=qnmd|E4M(ls45Q*DfUpd}NQ?I_l zp?K~}*$RQjwd+<6W;KfSps6~sfO$vk5sWgmP^9IzceONO&QS_v?w4^a}3jN zv=(dX$@g2`YxcOJT`XR4j^?7MBJ2%N8mtWNEV)ZLdgu>m^hH;h5nC0+U`mV+0*IQ` zr^=io5f;dT+4b~%@Xg!Krr!p2i={f;d$oQ0hwtl|!A0o|vfVfU0zfA7r*FE|c2{dp z#6P0B$|qs(XGjk|YC)7#Ru!wj%Z#z2jHw5YFF@ay^pR+CCl<)D85-Tc^Q9I;Dtq}< zXC5W^C@GE(l+)r_yjZw)jHLiVC`)=A!;GFL>lx{%7hpdgI7 zDEUfhWSyhIQz6)8UF%>Iiy&u-wuv}t-=tmnQ%5bySx}u|cY-gil>ykv+y?Glp8TYb z#IIX%kCaH}vvg7ip#1D$>6>!MdK(l zF98W1B=W$)^SsZYG~xLi3gd-cW*J+}Qpfk%u>h4*c60?P`v<@v%kp}@N~rr@ zD#h7IrT{p!yc@=s;YQ!J*rFs(0fzY~6RLt0oG%FeF+E1{9l)o=w;z4p4CNjMaUPWBW$7x?l0KTpa?m zQSnP%)=k9@;nIRx6A&`|K@V*FR9-)KT)RO0Jq@EADky&-tBTCgfZcCIuLie_G6!f_ z%9*dCbr90WI(60}#wPw0#H!&X)G3pQj=u6qha$LF!jQ=RHJzY;5QA4(1Bc%79h&N+ z<2g$HY-L^B?3QA)eDG1c{6WUpK`R?Moe|@E!nq@KrT$)LlZQ|OI4uCSz`?fG)av5V ziH6o@#bx1dA)99ZzrZ!xQmVKT;PkOKn9BoVg-u0%|5Qx!FX{Y0ndgVrix5_2UhgVNLhYs`f z#eJgwoNT^+3?JQ5Wx-NyRo9?nbfqN3vaRTa8Rd~#+F7<9-lyozN;yrvbew6CM+-?% z1)GM9_#^NlgZH4~7dnh~4&LiD-l6(xFzWqqM+pI1`za3$qpU1@_=dZ3ixSpX;VFfv zGxac`BX--4y%*T|BkJ95`RPX*IPQCPRFuU=*^HfG;Z{c>Y(qv#YEeogvkw-)UI%8u z5lXu?5CSvGVpIZ9z8$hX=98l?pG&IUEgZqI`1L%g%Lq|Ndg^^g5{5D+(wgDbFbKNBXB{7%o5Zt zCsDsJ90&y%;=m3Pz`@z`qu;--vQ&_u{`#%MtWlvRHuer*Lc*`JH`=!m2?AkN#UApYZw3}E;WJ4aUzU4L%YS*c| z9||_cI5du>{+t+)4b;k*mx8KwVLNm!8<$Q2<#1nq8nda5YGxzsz~2R^WaHAymg-nk z)lWJ9e3y{5wRcNRhke&wPmWwpt&BtYRXB#V^4qz5L*E4F0bP0op}SjU)a<~w))Q5^ z5P({=?%Mn6C$3f31@W*{>!eyztY*ncF0|As->_g{ZE&yo=HZWD%WJ>fhkm6iManP& z26{Q7-2-F9zE~O~)m?ntiLnmFfgKQ@sy6gA5Y&V!$)iq^1KM@{{$SzqBcxw~0FoPE zs6(4-v{i;!0NyweD=U(Kr-U&w%D_Xq`I2$@&zxB~9DYUs!D(8?N%R~0d@ou>E_a8L zhVtcqB|AyMu%D$$yK{jrb-TcVJ|)PtP2dc3frmN^2;TdZS|b1`bMuCEOKsf+(r%D_ z_~whJg*TW~RK=h3xz`RqRJbL=3I(_uZD!&_`Dure0VxnI$1WtV%QIqv`(dKW(Y(ZD zkL4yct=r&7`Fv%4r&9(w?{#zx%jNo`V~Ne>=hd*qG%b;_ol{>y z?eS}gr-Os8Q!4h>T^L*5&?2PNs4on5oqgNs`KB*5C(*0rnchBzhmr>Ra(dGOldbD!x`e|Xpv%A+C- z>akPPgdp@w8;ZbG@=B1s z@|;7XYMm#k7c9}?nHM44MbD`U;&Ke_Ie2!5kR=DDu|sZDAY_qboQHtj?(mBS|)40yE_7ze%1)+V-E3en$MtLtXvE5;LK zyAr}v8I|{#<2>{fMGK^JNH}$^(*4a5S(sP7l(Zitug~~%*jLSI(z3JzLD1k+CN@WP3JEx#n z#QLcq*A-zz+yc|MpH?ZlbEOGjOq8tCX5#GCsBkkuWIrFSzN!{I$}!bZbi64G*WW&JuMCg;Pda5 z+Za%PUBvpVndTRuqb*Nv3fZW;9k0Ia+ z9nW2_#EH*1h3w2N>O?v9YXR`t_glxO@mER~6sgstge$CU`oRa;7TLB0LtftDV3VyV zM8cSA!U8_8cSb1TUZ_^TQFE(h?kd^4-CPn2UtOCsq1b9zuOfNlxKv5Hi~YjBE|b@8 zoPH3L9=>OYfN^VC{6}RI=B>0a*eLRD8dA`ktN*6!amUYb(4Yhc3guDcj;aVIA4Z`M zK8#JXrs)Gcw2KXGLwGgdPtD9d9fYUqkaA{9)+b=Y36>=yO^N|E>O^W4v~2vo^-gh3 zUTL@)rmR`!!u#8P$&%%Wf$$XqCoeW_5qxO_j>dVL?@CGLNYR!o?~f{=bbixjiI3^G zgp^%ehf>y(#uX8pFxvSKK9!Ou)?%7Rid&{RvFwNy%Tgto6S!}rNEZEaJGQwEt=v|2 z00?4Y!IR#FV@5raMCy24Ab(zJ79UqkthoCH@gO$Z#&g2TE>dmNjA|Kbqp{D>kuydc zg-vOvWGYFl!wWQ_c^kQ8y#lSyu-x^o{QwOuBX?w-<}|gzlH)g{PwYP1i66~0>3?`y zRw%eCUPf{oj$pP*z#2&uQ;qF$fIZ0^uM|S5ta|S@@YoEPoLTKCvI*$yVL|BTI9oQ2 z#Ff15024CD35sEi<%?MiR=@Yt!Avp)Tj^*+FQA4dp>I=+H7UMN-LkY+D&_9Wq%!?M zek5aGC;(+>eTtD*ybj2ZH@H<}7ackhkLOJhUt1**tuCbDR z-A~f*W(MkqtIXhm!gOFcpu^@gwT(dghcQ|+uF3oD9i3r>#RgA&1}gqDp#}IvTg<{= z=^((bJFg$8u(IsMRy!oX;P+<_){ZRZ>XROwvB4iqaflISZET@Kj^Y zkvD5<8|;e>nEh06=sBLVLg(9r#~3sgmSt1u!-F_du$Nh-o0)F4arGI+Ct5C}mA^ph zP#94oo2qR5TI<+FiS7m3>du(2d}ObBA0B$jV_ms$*Q!>ff+|il@M{{noe`SPv}L_i z_>@ygT%F(7?I}{qIqjr5g3|>fb;NXyb}C1Y*rZyz95@Cp9I$hbOLNmDbzku zLb*f8C!M>(k)}h*UOoN(EzPr-q;40{hcbbqXfDCSFOWebmKgOjcZKfSk}1Pv!i>V@ z-YqCB)WOp>sYxy)DupZ6R+Vw^D!L^Uhd~L(s!Mn=i*gK{cx9U1h-UY%f=b@|ME=%7 zK2HMM_>^B=>Gb>ejb;X1_x057%l)4T!q`m5lDNssvmWBvm-&w`r*!xa27h`mUT{?D z4m`ImvbU{EIY|^Z&*WztL5lFBD(hYgt+IP(@>=&g9=-A3rSwhFbxPmdQAN=?`z{Z+FtvHlPRs`KClb z*;HBosh&!@y7TXWCLOJ)NhxA0xOhjM7= z*r^)loV1CFmxm$VB}jN}VAv5GM+IB(oQ9ys>@5*UFn9jDES<9IGuQ3o7L6PZ1)+<( z*1G2Ykyn~kJ|d8PieNWHJUchzAR$?P7Cs;>MQ1BPHUzios*pE#-_j=ABfHI*$m}

|~@f4o_8$Y6253%@awg0zUpH z@6#6K{kFaLl6b_AIHDv77=zG{{Wk#-X zMs)q2!?!Z3Z1r1f2k)OLq2Qa(66E$g40)yo%7YdfeeZ?2`yvx&l4VMfv(pn~z<`0y zhSRAs^dJsJ1MU5cDhQ=G#E#5CgrBll)`P5WX16<_{~w1~>0R=#wNJt&S=11n68mhT zQ*+~B#$b)YT+1Ui;LuBk&-4%dt>$|O`DS8IpR4}*+TJ0XfiZ9LZE%Q@C(b;!AP~E- z2*=1it2l?WyN83?-6xPUNfJ#5KJ}Av0l{Te{_uspor8XV!K7fAtqf5#5icCKTZa%U zx6r{s(xjQN{8_`l9tuUK6aS}?p8m^{ELJGH%<@OUFu)~-W(4(E2w(1lTi|0DzfH?~ z2cfwTfT}Yg+P)3Rx})SX00_os%RT&2Da#`=wCp#kr0G!y`zVna(#qM6^h_U&R0myp zpliHLS;RT%OCmb&oswe8EHJhhOJ~U-X&~26FNTagK;ZhuZEPtQ0g7$qYqg}NM*3JwC4T}(I|de!D(0_ff;ZlE9qe}T0^eL zo&W}#Md|RDp>T$t;Cp!V8C&^$;8r6@r^d1z#){|Y!*G20K^@2PFo`avJ=Y5%{$4yXnj$GbTO3_*%wdUEcKV27GKhn_ z2%F)(k+C*f_X%f)LOk~K1UmtR&jBs^4e#!*py8p`=%C{g{#v7Pe8!=pPA!IKv;f|F z-WcqOM2;kq$Si8qBx%Lm_u-{if-o8&oSP&;QyTi;;$AA4lo+A%D~hUMS_Vz~Giex! zXk)*~ux#q(oiEiK7$xsd?mVh#%K`Gn3s9L<>jcBOFW+mNW$8vh&U@4$A7&$|Rpdem z5Gkd&`C~wBrh$oH(q%Y4rEhn{naSYH?`}Kj?aYl=XfQ9x+STEi$4~ z(Xw69AX8HzyD`t4{V36g=`*cO;u!SE0ZXNrj834Ljz=}Bs00^wA~P-hMzS0u5FA$5 z&m1>2OdpGm^v-NJVknU$av5P$3y?8F=KhKW|@b(xoqkER=2f)5Q(2v75PxgD59rv-ai3-XfKDn%>)HO+Mu!HuyH)k2Sk(!1r8m-;KO}BF5!GCTqyYd+A9;` zV$;B{l$UGF&e&)@WLeaFsl~~)cBeYnA_*35PoPbCLQVa^u@-B$SUF;@Zym`9i4fYu zktDJPFPrv%!$g$fD=Q+8ODZG5+dGGT2u#hF0rTf?rxulOedIp6Q43u1&#<1D9)zAR z7?DY12#tso5P;cg3XIxcgS?LQbGo$>u zB;R54xpbHR*NnT_b(IAfFL&G z#=O7)xJeNOjr=(K$_U-ooY-Q`5;G)^h1Xs1XJv`ZZhZo!sksmddd|45061Ah_{e>lct;s|q-!2fdqM1f9?87pE4GjL`x%blm{O{@hfV31 z8UM;wrMIoVP6RAQZL^`CH<9;m`{Z)D-^8h2O!12U9frR|f19FV8q_Q51&|hB^5ffSL-klN)YrWOLfEP(CZC2E$Umt>|2~cl#{JRZ^v(%iA4;o-r1RmTx9z=Z7;eQ zJQ-}bo!*zGfKoE&HCpDzWb{RZK@;cFj0Vy}ZP39gVl^;9WB}?>MH|^X{a4bVW9~84 z8hZ8P?dmcQZ4)ONRyLLDTBI$%T4nuSnI2&f;6EWYF-0C4XuPcUZjC+TMimo_LKV{+ zBnjTYjD>Pw@bwMI4n0*QmgcJZ*jsSHa^WJ(2QFnATch)|!$+_ot>I5m9i8KHfC$J`XJxrAy zs6AU2)t(zM;fv4+vnNI6L`BJ|@&HJ|kw2pn4|CIA_K+LXT`qA%+YN*Ex?ff}*%wB}~VU9AtKyx|R z34!FMu(9|%q$uu0B=4Kxj)*QdLC@x%dk>T5shs{p-Co?A?sZos1#o+mkd%AYjus#j zje^Fc`3{^T^e~2q%SG+~n!Lwm0C%zoetV+|d8a5${d90trx{Ji)JaBLSbOt?+4myF?niWIC7O`O*q%AYz7VGP@p0YK& zfq7JjEs;kLpckSyea?LKMr3q<31ga=(?#%V&msUSXe}YyD&q4BH;RbEeNUm61Z!PR zqKExV@G@aX6O2Zq*Y7$G@Km9%=>J*NJNs?0_1j=%xqMAtTGyIY#lLRCXRc!9n$uvg zud(0}-hTBO``A5-6`*R!Y8^m*VF;NC0?!DJO+lpv818lIkw=yYBOS~u=lm=wFvO1H zv$X&0(5Lq@B23Yr2(4{z##k*42L%-|k#n#>tJ6b~K7g>*skMSNq;}WWy|UYqx3;7G zEvX+FiwroUsp_PE?nMg7@0srFSK^|*(=7^_u@dmWdr&2}s>)Nu^4{gd|90UemrQy@ ztLrQ2*afp_1j!;PfM>}z_`oJW%Q`X*Cp$=jA!sIcea4c2MNeDR&>JOCS7|S^46Ltz zs17Y?hN|u&_BaUK+5a|pC29$5FW#>TnjucbM8_9dR{GOK&QOWnAV`%2PRT7|B60o3 zl2E#YaKX^ylUs+ID}eNS34K3bKMiZ057AXm0fxjuoiSZidrMw>S)N-Hy@sKuEChK0 zBXumI4ITXeV%I_Z_=OzkcmMl+Y-s10dNV?YjMy+4RMnXkhk>OY(Lip%p#6a?)B9G@ zvtW_2>ZQOB#bvXM(`P73yqZAU9oKPyCoP#q8~D!Mpedgc$3pBHmsSKSc*JVpW`+(p z0VleBFz?2PREL9%o$T}JE@-*Q1;|zR5_N4^6&0XBLxuplpAmkB!ZEHVyhZxathg&( z_p>lMV0VNR-TdA|@~e`+h1~kElj+h`bk^d-WN-jUPzkcs5mF^jPnS=)L!&Xm#ub#4<GWn98*y9ZM)mM3b5CssSuQk>p^}pTUzYgjhZugSXaq2@A9*3Ne88@c$t6n`d zOV^bK2nCXHdEIWB1lk1VgFCn>&p*Dy+!zI}Tl5O+#>rAc2I#XRv7ztl3A#=eQTgpMld`)&A*BOwZ<=kc>DvuvI9~7@kfE zc>sMSsP7!cbq!f$#)5iGD}u^OJ`EXPHky9fP}=^eMV}@g`cY>ogKcogWl)#=2r;jo z-owSmx#d1%Mr`&3woQu>8U)NxqBndPzRFfI$4~O6e>~31TG{RPtVo~P*Z(|{{~=FR zp`xODI-Rsf!~Ym$FFQ*&TfZ(s zF(?WU+mWL~&0NNW7z`U08XfSm@7Zh0UFfsZSDZv{l6EKiy9Z8eM(5&I79+2vxNgZ4v8<&OMo0goN+IlUGe z&@?2iY~L0;na(E`(%24(ZqHB{gc z;l$r=nq=BTp^156n}FW2Jm1_6Vk&y-Aez@&P5(%U6y_@$J^}VD;!!8+(n1&CH#lu1 z<)XM(B{m^>Fl=GuvvyN1#3JUvJEotZm=N7Axh)<;j_3fX6!6`$S-$Zv&edWazB1R| zTK0~LOci~4Z^}%sYyp|U%LKMsf0UdVBz&LhcB-qWHhCo9va^ZRz5f6{#K85kK|Y0i zalf-iVS)SNjIk}N#<>!I4IpXY3S5*|zz6%>5YYV6_r_=f{%^d{;1yn+Bskg}a$BYV z8;{&Mnm6xn2~CZrtTnr=sQjvb0cTI47-B3{~g)QAH-8-&}y2N{*3=K4lqisUP+yz7uUgQrk`1uf9)n516rD$QqTq^WUDkM z077*`a1`21B>SO@k2GWoVPr>Bbt$-wsRDB)2H4CMg#!J7_e0)hwWLK%u@M z7dQO6D0(@*_V{>llgZacErc!(irfP^a!XwkX1U(=xW4rGuDj*r*X@K}Nx+5l!IRB^ zL@Vpd0BDy3e_M!UbJj6h3!sf$3o|EwIQDiBJPdevCFgVr8zMpJt^+T`3Em@&9yPHI*}Ul4>x6Ve>`mg<{$D3j*o*vH>W24?WZtKh>|%1MWs^(aH@*+{ zt)qV4?V4aMl+QK{j`Yk zga-mPQ6y?0XcXDZYoHQ#S2UF)*K3xenDzbO_A?u1M&3Oj#8-T`-pz8IE&tv7o&y6Q zP+p*}t9-=v>v5@FFfua?w7c4UH}s2LwhDf^z_W8t8FPi@RW;s~x^91r757`%&;?3M zLS2fgDw$v8RO$g}OfqQKGXt0}@?s5-NI9e_NLeH#Jxg)?TG_2tu3`sUwfj4R5279G z1oPefwY?$3nUvL&&){`4XpR?`zKh`D;yYJv`rJsc!Pb}TJgh4sT_jG_07^$LH$=f5 z$5Oh}yzjUUa9QY=@9BA!sgz8Uv}eY)7UnqFa^9e}<%ruvQ-E+AEP)Hfh{sv4aVW>2?AP{z{8R#HjwKo_$P zxgD)L%J24s4e3L_5biZwp4s%Rasvd5t7g814Y7%qvbtW(wtAHh*&7-yT>B4QymN(% z_rxO7%FniK3tENGif7l zSx~cI@F0hQ)}qWn!gf;rjiLav;wk8lPDJ-p)Dr_37cK|a%ps! zO|%esQ@jVKMAV=iIOAH>7aH}!vp(l3ZK%_Y>TEaS&@3O1ssVhU*>e3*$RKp+7Z?cv zs}`B&%+mnRm+e9Tfy#s``Z-8coG1UnP@3PhkN#6OUaYRgAgp~_Ju}X- zl@Lz`M=xqkLHG!az07_w%!rp_Q25d3udMJ=rO$yo(h>?nWb6eFr#4*8m-E=L0ryqS z$!kA{>I_|RFfrCG?Ed&;{*Ra7pfsN%`#H_$b^81Gs4c|e_|$0(G#J*Knh#m2*Aqs*Q2|nUe#wqEI$A^g*L}>9F33lF z2}EaoXI1sIYFo>XTE)}X$M^0vKD^gI95L4ywnIBc(l*+(U!E?tFYvOfW!`ahXz_-x z*l7f@UtYQfCx;(5T`FsMB_6ZKh39)1m;8n@K&N&5?2FRzjMfHU74q(KyQTuAv?Fm( zjWVi!+E&@UCPt9<4n5%QQezF~cX-7l((0JL;_}etzA~StRD!LA+mUu$QJX} z(_=unA{<}-%Qjf|X8+b(7D_Zg<84#_&qS>qBT=Kyk0Y-SucIj>+W#^QfKn~Z9H@Xa zG!<&BahzZMi{Ajsl9}tgfbxGXtTz;e)+6tfDDpjU4sUvAcYp5?ZC@Z4x9MHKAAdXW z>0jr<**d%Wt8eIQ5*9tr5BSO$saVF*UUIF6A_)sXM}6>Gp#rdUXgzP;-r~;NGbaQE z7DY~M6oCRq7Dw179iArW3Hga$w_B=t-r)WmOT#cGc&gLe(M}Z=$Wi#O76*pofWwF$ z?VK(IquGX5K96*L4`VL@abIGFJiTsZlLw6spFf)AZg$FG?HF7%EG&d!f1b72;63_z z5_NkMk1b~Xqt_)p!!5HGx68uy+f4hjt#?8>eBB+Zj6ZAtvLkq_Cgj#RCf~gdp2yXM zu)74moa}t_^x-y{m56m1HY<4!{v|T-$DEFyxxS_E_On(*`NsgI?PNV)yM!5#VDdEM z%!&ZtGsEU=QxEpvIcLB-7%*kNY&FW-vy8-=Hov296$w-4?O%Mi5G_@N-zTUu5P5Fc zIUb(AK8T&N-+5ydQqqvHhjsX#1l6gMa-f>7chLht41q$8D&p<>>X5u7;vz*i!BEqo zSh9SyeTwMHDrBgi6~0a0TJ+OJ<;Uf0S@N%mX+||mMVtF$T7r3C4HEiDjGYmk1u~M& z#Fu-m1{$l1smWSx3x(5{yP7Zxs8KA~sAwcqj^2cU-+wjXAjD|5l|1xlZP@f#4mB^_+3pY!&$pM# z+ZwCKgS~b(!XAC1a>T$p?c{f@#{Do5$?avBT%|(Xcu)V}d&BWu-Q^7Tcu5-vUd36B z{fBD0V?=7}4cG7CjaoOeOy0$&piH4@>z?ZI3&Xq0Dhxyn!di^E*ymF{i_ z-VDDEXV-I(YCtSf5zuI%5<$m6Cs-*{|HF=HdUN zSIEUTp2_fmmoxq8*5K~Xa2al>ZBQ#?_h2I1{ekQEBA8}_^hw{{?UQv~19^@s3>#M~ zzREQt_KYCwdzs1oK4=;S*k<}i))erlUZqdQS2Pv9)d@tzL<$&PY+M| z@547`WN+v7<-&x|bj`d^8oX|goDyz8u%55K>l0HBuM;jub0Wi84r!FD2tu&3P0rjL zezhL-^7oEZEy9*euh2euouU<$3hGQ@aj{rg_E6DB3jy}g{_LO%f;0pWepE>+##qDYAwdk_a_M?dicb^wQ zwzWi`&O__1acZhafmJcXStU9iJfpFBuJtm7b^P55yXkhy8s5*-5>=_MgLW0O*?K$R z-%3QeHTmJIsCq4=*QYPq2|h;q66q#*dmlgdk)CqO!w}Am4KHo*+dg?84&ZO9B7duz zKP+;3olvWO=2kmWK*GSue_@?w@#-zKM3}t-^W@dmSt9!@q@cD`YHF%7@7Q^*w`EK- zBE$8WMR2WG5KnWA#yiD6(LWr;H-VkD%gHbt?9cJTYeBrpV&>Bj42KRHD&u+IW{B^l?x=+?5ESPe|!=B^uqn;0tNR91Q zwUGYrlicxS1mo**B7s)V{k`{+=gin}5C3z`c>9SiG?#NqsTh6e0<_!7FX#9R+&ID& zD?vZNNJmIMjCRK@&o?O5*E#J_S8I^-PS5_ZOX6bl=6a$CXSaPsro!Iq@%t13;bCYn ze(n!OVMR6b4Vuawe5nn5QO?PxTB;WjBN^sIVoSURxop!~=E2__BR%beYwkeCe>bnN?z(jMWan7dU>N9EN?B)SyA z!5D?n8l-qB>70np|6YMXEnm{MJa*{L;V=#&c)#iG4i3lE;mX$e(2Y)YQlmC9N7_x_ zJfR)B)3QqthMt?5xo^{@nVYwXI2wk9$7BD1b8KfAfP#IQ$=L7H;yV}}o-)vUOe7-w zSf=2-pJ0bwlkz^8Ld&Yi*%?tH)E+@zKo40Ov{5@Yu{CmM9$TCpk>in(h_W*?Zs=?3 zx3j-__V1>XNvNN*=BfEP8;|b+r)(6kP=Dz0kTe`_ob(F}k|5;({e2nSEhd^JE=nI; z;ckTeVY4;!w@VJ(aPD@EZ@}CvIq)d@?xf+36TvBBL_Q;kRTb^8$F_wA&Xz1J{q=5a za!5C<=ZiMC<^h27dOn#VZ&yuG=WZTBnqn<`7W@8kqLA})@MG=tNHwfd&oha^&om=D z_~;-j7?}gDxaV}v=FcyT@tLz3*Z0X7%iEwKoDG}n%ug`y)9J2$H^NuikDWg>8$AP2 z`{GD)PHR|0Pk)y0rj=Ku&)On&8X@&OAM|ch^*(94RHL?6n{SXlE~{^f^)%(|=d_IO z&xx+@mU4IgNG2-Mg7ll}zmQybKFNOcs@a;E<=n5NiH7LpzQDS^P(Rh%U7h#pM!l$^ZJ-R!inX24M=ziREdn792j9@yFi9C2-^eIe zH`3H3y75^fW$fDt0g_sPsTd694LOu(8qI)&$hRn|?ElZ`;#Jl(xyaS4FB8uoOaTA? z180FTtB{jNbj06~_8;5dfh32K{p)c438!SF{(oQyeBp#;ru-W;|3{G=-~Nwx2VSw& zJTQeK4noGd{h`uUUdqX)W>B`XjcRIsXe%lT3opjMb_VkAA36vz=`4v+LjYG!h{1`u zc9yXGFMbs82>t*?JiSH!c~)l~p(R$d@mAkWPwbH5SO1u~7Bwb#tgDx;FChz$gy6BkRC?q(+uh^T7P zuyAM9j+W;doLMAsB}m)Lu|Ww@Dv^f55PZv`Nm7%$eRIn#%z6fe@;xQ=-Pezaw^_p; z38WvD`Byz1ks9=D$CXuALs?>@684#avysj6yg8?{mak7^Jq>L5U=6<6$t+*?F_4DW zB^k4gnVU39fsw1Y{5P&iRF+b;Yog_`MIoe{888&<^rrvvME_CpqdxBy+z%XcT;(nk zz~=;?l|E;Ym>B2N6$sK^;Q%V80d1b^1@^SJU5MS=ApU_cCJzJfsnKWNT)%^Csp+R- zx5bcr>*l||=80A15adLqjE|C>{6BIt+&<`7Ow_Y0Xeo5>VUp}vM1G6u1M*c%Vq#)* zoW;dR3UFD=>7zZb42J0kCP(dr&cEsU957CI)j>AXVttg;q~v1fZQtep~! zmYE!*i)AV9*LNIfzMh%o8gkBnJe|@tbNORV>=Fsipaz+LD5C#~bp~GBCc5~)1Z-`e z)mPs>&9iu)O6RIph7ygUuCyiUZQ>fe##K~f0H-Tm@pxuqMtdT7`gnc}dq6e_LhyE- z&grBVHnj8wyM`RwhdG0?{vX5L@zFL7oag5twe|wA_pOzFmp`fTbd3)#8I&yQnF>JG zIDLVn84wFW2@ZJm0B|(1+{?p>y0UO#Z=C&NR|sCH5A`^n?(Ss~n|7$c&-Z*xU2Zgs z5b`+AqW>GDg+02Z!^k4YG>=HbqY;g^QChPBJ0QKUK0m=GN~sJ5#S^d>*T z3=+fMVCy@onnXMh%`;L*j5khkHcWSyDqVKDegmLJPyhW<;Idf7sHEkv2BSQPo1jQ* zG06(g64)8A;(mR>Wyo@?R*Mo0i)}z}9hJL^?0)pSmixTAylv0TA%8nT;&d_%Kx2b0 zT8aC+4t*hS^|Zyl&f7XQNGYAPXlg%l}vpD|149rqe=a8%~XU)`acffnpYZw z3iLCZJP?!*L}p9ehbB<;r{%a=nO%ZZNZ1c95}rH_8YVuyeP@M2J`4SfIb-p#anzO> z9peL_?>xvjGJ;COo?`qOY&}Z~lcgRNHD7Yv*6<^fApT#OY@JODXA9Tvj=gwww+fX` z=jvp*NYH*1ZC6(?b1WS|4Kltq7pG0E7D=bJl9_#f8-nH2jjH*IVMKLl{m=^S;B@sv z-X|LvF*SSd+L_kyeojBl^}l}YeMUr>!RP{&`@;Nx$cLBxZyTS-p{$lJvh+0T=_Vgr ze$FYzhCyo=={ss4d&xauD)mKYluHQ6(hK*5_0zYnbrp*KdLu zA<5!#cmx1|ZFaF`tmpXfeNW8rXv`kY7Sn`{mJ$4L<0Ll{i7jCp!mLCIB5zOWdbYiO zSmk%G`ocB=b?g!m?wz_tt2yh2t1$fn60-mQ2B05&VH*T18RK`V{paBpuNI@#gge}NwT_0uRryiD)kCEk&F9jfPZ z6kD}0#X32Fcqz&;zhs#TG%^e{vMY)21P6y$?yvW$?g#1p6)PT5)&cp9=FG|eA1#R$ z-uGj0_ z~ka|WS4fwAWn?4_%ZQ3hV7KM7KYBa8Uz3RDCMOl+yf`I%(H9aNj42aX>| zAJY+%6s%UF;fLV$DgIf4#>~2T3#-bjn|Jhtyy{L+J#AlR&x1sSP@K7pi%m4PCMkeC zqXx?`QzJtl@pskL;xQUsiCf}0{I&R0%NJX7uq)aQ9=)9v z7MCGc8#6EZ(T2_yhj2IA%B+3&;!(6-PCa}Hdo8Yp6_W5sYNR*j(CK7%s|6G9C0AGS zK56w#g5~J^r7A@op2_)lfeG;xJ={p6o?^7rXpfj`U?EQ6U}1a6N@iqY=fTh7&_g#) z&l7MK-ylz0j_$NsY#5zS1&wDy0izhT2>NP{e(n~VxN!5ZrvpFYe&CvD9MoH84HVKENm5rl$d>I>l^r}#$rEBD(bK}vT>~knEHi9YHL6ne6r3Bj{ zBL!J7$p2%Ue}O_Y!h+m1x{3bNfWLIf5I7q$BD*)DXc=XpmiJHQsK0IZq@zQ)(-8Xm z5!>mC8v<1l?A1?@V%wq?_DE1~$puuaO2p(V+C(K zj?^SYaLH}R2mr2#qmt4W=W=cHyYCz9%j{{SL``9~y8Ioty0C%%{FQ$DrZcwa8WwKf zw<(tsVOdaGhcs65WGYqmqgzSG!|9%vUj{!mSvWBSuH2Sh?s0x&(AZNiNltjs7yl|a z_v0jj&49$_(yf+gRNi){4>wspgO&>UXYoDNr0IP&Pum+*^?Caxb>^;)^L6;d2|)_e zx3>1#Et+Tl7;Wx$4WdjjtT^lZ>39D~iQSd~PRV;0k(HqX;LEP4zkQ%`i|$YhWa+u( z%F6YK?9QgWahIXAK1vITF<3P&uxP><`p#(TWJe*qxj4h&J8J=)r>mEw22{IAd)`nQSrKF)?`NuBNYWsEgZ+CrON-Ve>Rdf)hyRn3{AfDqwQ(3h`2WfTG|m zyv9#d4U~If3L)@t76k}71(0FkdOJ}Ms9iX6?x_oN(25n|z%tsto#~# zB&Ua^Y^QJue(;XidnV`+MY7;5%Il^!?r@7`mUDY3#&7aX@zM&?+aIeiT%DZJ@M)hU zU@s5-OjMxg=W^%y?UUGr*c396h0M=iuWM|2!77(*6E(rAw~|P4sFp^X^1aPHsx%AC z8I}U6Xirob+M#fc-${IsPSDlgWKG>M)JMpX6b6<=L@-@g<{uBYNQ7yO#(o{vS2u~| zk@6H>uJNsY-Q0nlcY+|EQR@sTE!kpt1RKRRlK&4oA0TJfwCD>vSS{5&PAHL@)P#tQ zpEjuPtZU#=h+Tc)e-AYa9{<;xllVD!ahyOVjig7IBJWhf- zUhBm;d66anXri{nP}M}(q)S#mLS#93C4XnXEsxA9^PtPLu${!>Op9c?zy`RKx%!;s zhzgq8!J_{n+&9fuqQy9QU|p;0UuVjq*cBUb*TLOa*`!m$2@`Ii#Teee7v!t!Th z6Db!Xe=pN0_Ni1vWHM=aCE@-Ru@X~e$6~3bmO<6VzIJ2Zamu)NjVKl4v%xU2aZp%D zVH8r)2=2?!1cOMkQt2OS`>xsiZHShmv=SlS^b+J~M%201whwwdDfL%`hy@YdBbPES zz%jcj)sQmRls>tz<1U19fE1u9y?jB#(uMkgJINNMj*Q$$q68HYXAO`&9NM*1yj14U zv})LRI;RYYLMf(GIy>z(G!I<{B?`CG1XLBCAdU_pu1n?PnD4q9P^97k4k^eC?#h)1R{v-&p1 z6Wde`JyT;7YRow#P9w6o7=HZapSE+F@p~GP>Y;1R=)o9KyKU|ygsEV2?ukehSji5!_+xN>C+7+ zW+ilOu*&kp3g=CWRgGFt6(2#hiw)Kcm}|j}%E)oR1b>GvS=l!&8Wzu&Uc6AT!m|i- zq8pGW8}`&nd>V`2Ty@gJCDV+b-&<`632_Jp2^kDATR`GxCK38C8MbcjX&1|uD(s0D z3sqV*iy<}R6G4s%L$d)g9Ud3SS!5kq z^C2)k4AxVsUS7X=Aw(lK2BYI?61i2dZtd8%oQDDK%y@jt^ngf#6B9z8kzOu8X4Kj; zp*dY>JOu5Cx7PQ3`#IrBO$C5H9!_MXie91$!5{?8{aO2GoA`9ol}BK;5&Agq`v{nbg`@Q95CZ@dp>?=f?;bBbCj z4L(8G?I22G(1NMKHu^OBT8F~vocX;4I~J2A28|R~NRBa;8lYDhbZs`=@^myv(IlM= z?v}e&-JtkzzIVWN=L~yo%BEk)_=co!b;0!>!T!hBh-@yuHG1YHm4+y2S!;heS-b6+ zK#{)LS$X$&_R1I1>Pfn*6U$_lNy08d3c_iY45Gt%t(!B6;L#J@U;ehGQzv8Jb22pc zD=kwK>PCy}$yHLtt&%?m-tlq6YuMmt3bnPiua4(CW{;hkij|yqM4)u>AR*|g)6)w^~Mep4FYmbuT#_)F=7(t z`VS}Qk+*MGZ_K55I+8p@MA_oxgXXSbKbnMF*f2_S$7)MvD%)VrQ zZr+*hhb&jlVStVSq6Ry)jzD+c`Uz=luCD2%R&4(IlE<_5&)t*&qtyY}c6W1QfDX*m zeOrt#G5~@wXU(8h^+3C9VwQ9-By>493bnUzp32d5n|n*|mqXP?DWShbkht0K3a>TG zS(-4y&->K@9aYK54oBCJ{&U{?Z)j(9vFq7@uD5p7tS-1olbDIBtL$K0!aVt>0J-v| z5(5Oq5xMKvGO8F0eOjbywf(m-{OTzNhnCg+Ba0`~Aa6(ic8cLvqXAPd@k2?efwpr} zCn+cIQ^B8>?GpVi77#kR7t2|--+GMKQhe}nVVDdX(=>De!evrq$!2Qw{VBppU!;ba zouy^^|1jKdBKadqO(GUo8R}C>Ofz)*XSS(QtnVbwzJpV8FAZw zHT{lNE{#Mo48F}O0%4VoL z&^nUMlI9kuSP_cVlx|L_`tBMnC&?^NR4isfX18TqZMm&X;;9fzgk?9BtYAn;T-jG!@=T>k$ zwD6`8g$Tf_rAtoDA}vHCu*7=J9Q^o%FzB|HPG*Lj>|OQY9wM%uR40QQ&rsd^k=R2s z4?L{>fmXgUrXEi))b6bkywQASt>^V1*#f;1WsUvXVvMN}_)Wqv=3*gM^ZDb7>m6V} zqi6N_UOQl?2rd-%o)W))d6vN(kK}f{ zBR|YSfgCD%vgQ?BwyRSuyIOo>(uKJ!EQaOIVCyYsRMXyhrCj=DOxbEfH)$h*R^2pG zTg)ZL2FlF$46J*EQyP)E0#s_)o~F9nG)*X#YF%ob(jR%bXY+2CeLI^LeumdsOp(3y zET4*{r>kdS=3jNSueva4mF4Do=MpoWa;i!t=Jt%+B7{$5#|R*jzr@)yVn;lc2=um% z`mu}C)aoOf!#5b-NW-%7zMdWF=+y^KhdRqB0Y-$wb0XYjgWfkQzQ*B~j4>Zyz0OHD14Ow%2MNMtZDGPPjb-qJ~$} z<-5-|esvX_`zC|^l5@!PFo9x7!IA}P8Vb88f;<;4JJ_?t1rf9Ybf|p;Z?tFp%D%{E zR_x3phS8eiK!9xh*x4J7uI(^1hU@JbnMDDxz^vZ|EbCXJuZ<-aC)gRbT*9a{VA0gw zv}|%$BvbAZ&&Z5MQg?~*oXX;GCwMY~_{yA>WN`fHoa5PNO5Xu zCVLS@tJ@*tkJ66&1Tle7%fbOEyWDL-DgnCGeEkz))>zl}vE%w-_a;+Dv)J32UVNb@ z!OMkot+d^B&9Gsg%ys32bqsbk_^%-=C}US%LcHaXc1{h-yISukggA0edi0>?!hK9T zBxp*pEIAT8FFr9#3|G6!I5~d^6i4CbSLoK}VSsy>n1`xNi2VRdg<~qsDiL1PK9A}f zSk;Vc!Jz7ap<}h_+cC||YKG1&vxtIoNV;dPN1L^=k0g;lcGm|h_1fmuH=V(tt?`UF zrIAY-`>p9;Wt|1do7V?RS=d+d1Ul<_c1>a})tFwUY=08kc8^7tPCGQfH0}}dHuLn= zoEJWxb}+RM?9>f6S7PUmYru=JpocVF>%XH9b6I&mS_eG|LwB|fh2PR9p#i%+VZE92 z<2@gLLiG355X`BD7Hk<6Blv_qavvLBgW65!9=6}JY7L3H>stjdMdMjdVEmK%L`=Q* zN|f?xoH&a-OuJ?Y8irf{j#Khb5>R3z8#sT-_UoSEYT}u+REVot-hCR{uRZfr(+}mrmPgr(%yyXS$|ULa1+O^N-g&xiNtN zOQLEkE_E2uTe5XA$Qu+2+X1$`9Wd&Br83O)O1AGZfnqEkw%>|YP}pYQdGEWXHPzx7 z5uB?fs#SK37mD#CSlGA+x}y5yHuL8h)pfo(6e#W5w@&torv*eCfvX2)V+*aoYwb{c z*DJJcdY-jTS8bm(BoY-wR^bKiL6=VyV<~W;OR*<8qgG*g>@`lUf+pQG`PGH{F=uPQ z1bW^S6In$0dD9J;Q}rL&TIwD9m~OCzgc(5U{2D zNeQQsOXaXr4M*}&!_njpR?@pUC2FUfyc%f6CmO(LOhe?*Ay>0sNt(^2M9uINe6EzuVByUm_@9$lZxpS0>clpauy<3oy4uSIMG4UknST% zw5O8pz15&?4!5X$l#!?15NL9Vsj{uv&n&d(2r)!T0;_h{K-F`r^ShEl1*5-y2flbtI)sgGU+L5xyXie~4mJjD z(4lYdXqHx#YC$W>2xn*x#?{RCVF9KB`nqK*CrpUzEUq3wFk`&N68Y{2ccZqE4V8${ z*DwpraPtIVa&Up3QTu2^H6!9=BdIad*RQY$ma1uK7^Ym1@t#2ownXm<-LlVlFLcRL z6UwWsWQkEGaO+%Y`m9BT>zFc2W-DyrdXs09d9f#IoJ!V=YwY6iNGv>QhI*vJee%w0 zD60Xo^Ppl-lMS_`I87n=tm6h$_@qUxtia611x>Z^B94)Z`|qfv7l1<22cRxHv)j-==mL{iMS zk<1uy2Ii;b5YV0tJV#KF4r@K0)h~peVdk6z%GfhY>b9*!j6W0%(lBEZjakzTxbR3z zcJ9>7s8qZx=5OOW4CO_g0Y$Y;`eKI374zC2mFGSuilGpOp^!Ck* zr++8we!fkLVK;j#b401>ZV$>PHZPv6XNohSyM>9eoZ*bksaw=FF!z^d$TZKJm0_8A zQw?8eXY~~`Z)OCPXbB_a7TlQMVFY+yvbetL0AX1yDv9P*a%#P=*8iNxhCNZ+Voie@`KC<+S%kyJfO16)jsiXlF}A{sKIbp_l+3x;MwdGg@j5sPIoB z9nlgLA1@QBD~WrbLBJNXdc!+^%R6+{DC0=G^8=3PnS<*pYzjHIU zP=slRt6iy7qvGBpf3AqfymI;hSnkRq%7toT<=DxdVXLlQOGRyy9CE1W&|CjSMraA4 zuPFxh;e@)vC1m2SUdGcB>Os7aG0PcSBoG82Fz z;E_7m5{zAUCP>vT81wqe7fQCyZl{gaP~w=dR_)%mvobNAF>0|O%BilQXMW=v$X6+y zyH9Jr^=8K~(pvBPgI=qgBG@+OY#wkk{itooeOLA!pqtOIh=f@nRf8~Aen-b%~^)hSOeQ9SGRf8uzyH_WUeXT zoO3xOW^%#j;xwO1;l~6!Uk@B;Ta_FZFp(#{O!DV^)`=$r52>wcZ54Sx;5Un&jlx-m zv~{L2mkmo(4u)`j0Xdzx_W4IA;cp$|lKk0*1pEv-#%=ySkQsYY34G$)sfV_o7OPPn zytaAv8}vRP{iL~3C^~mAFFuyAj{f%UM%YBJGU6jn&$%zakQcCxHm-PQE?MJgguM6OszrTGem4379vV|mW@v3U9T zj-gG{6ub+Wl+;$er>0rz9NP>W#1Tq#@p#F_rqqdCcL(TOjXBI82XVR+l(cQ3cn)FH9vZKFRyX6((A0it{B(!t+ zdf^#Ae~*e0ANMs5X3)D+x|qkHeann*p7j}g>ya$}Ng#P4Z|np#F8EH&r>g0}<6Qsu z+VkSb&cGOTS65e`p~vNa>DB$hAuSFt$THARt4cx*r` za;&1Avn9epMFUZyCmW#d_W} z4OFGqmEWGY;hJU}<5p?2GYIw~#U+|QX?S`T2(46@a3~n{CqJ8&g4bdA%9N3$XXmP6 z18ON|e=q~ow$sH3$t+wv8l94f za{WRt@!toM>>KC}nv#Ln@36h%=igIrTmxTUE*m?bP&FyJ~hU;Mg0XCw}3A8{J{D zL$b;$%Sea(iZ1E0$WC~;c9TZ?uH*YQgb<>+?WuB54%bn`JAIrmyw0N$hVcKG`s$#z zqh{>_#oe9a1PBzjBE{W{ySsal;_mLjDNx+qHMqOGyVHKT?|bjecP5j+GLz(-J^R~z z_St=gOb2elg-O__xoEn3e98uV@_ACQJ^#VuBmIH1z{3s>0HHs6-sQ;qr4RmMO4j=V9Eu7$%Z(9ionisAS7MP)g)RC&CfoOSX*?VK|w%jHr(`!oj5R z<$8ki;a=TSpKqBdN)m)GiM~aR2>5)BK^_H6mf_#H_w-^MVt&omvYvLdy%e;yLLp4( z;^hvv%Gn6f_RX*eB(f=5|Sl%9)jJW+E1^cc@`oMsml}Z)W>9 z4{(a6=CXT0V+c*O2Kg~MZ+5UN9rmkH7vCJ3iV>zzRG;i3Jw27zNV?=Fl z=b4On&`P;qc>FJ5zkFN0$q44^^u6N?r&7(v|j#s|McD&Lfa>ZjBt^tZ3 z_UWjH^UY6UYRqd5^lU$_Bn<7T zQ=`YA@dkZ16P70prskFvW(RKa^}ocIrH5{K*de~|Zxq8$?niGS1GT=X9Sq`YB~FSC z@tR{MRbAuQb^Z`V26>UTnP7bmV;hgGKpI47(D1sq(-`M>nfAHei$$nv6rin|VJm|Y zba)<FHs2eU4Y_7Exk5$k!ws3 zaV)WoslRFF4;Md@a0Yg4!LtpjqUDEG>u^ct$wxp@^^7=ZM^bA)6+Ps)4F)KbHc^+u0Qr4 z*jA;cN{%9FR;MDi*pX_KIjO*E`lZlJWlqKoedjaBkT?%bOuQl&AFA0ZovTTAxtdjX zjZ`p!i+~A`pTPc-DZJt2Lo$3scJSN9`9JHj$92N(ZTINVUPA64ajfdl23gz2uH;td zSe!Y2aZ)%7ryRj`r@h!0@x6))jtM#z$H~o)zm3cAi?AY;$srbNI3)1V;=R^2>iovS z=e69?mXd<%Wj!*=b+{qt9&PtW)&sEujZQ?OTx-h=yldar9a>$;{DL9Uj@!!|7r~Fz z1;n&PX7Ho;`@bA;3P|G;k7l36;3#1vuuBP*&A+ek$ZY$C?)3A5;IL`{e9Wm*Cvlk*_NpnWxV8bi2Xb?oMhrlgBgUpSEw)|hOnp# zxQ9ITNQudN{qmce9YY`k2PgV#PuEI?fVCtuIWPl@X|u?QAQWxLeK;6CtfS#uzUL*- zz@YrbXHbMt)cc6Pdwuipq4(m#w=KWXTq4_wutdvw4@fnBX}X-T`PHIb$Bx5;?JFY% zeGA$mj|q;XD|=8y4?7_rF*}5jX`<>1wDszSH_UW`WJZ*fd%K1#S`us#1jvxY7$5`S z;S#Tw>V5Kj9H8%N)in{Hh=v<7jHb=9yJkYkzu1-yNs~*brZ=%;L6S?wphe8lO!7gy zODZ-3?LBh-z0?L(?Cmq>#&W@SkFihkcb(O`!&i=>i%Ui8ncH>sz4kSH3=|4fU2JXt z@-|B&9%K`CNxDxT9FvkAABayVF2T+QK+vpr3 zUTfFoS@aMf#WQ{#cWvr=HU;z)9!rsA)NyCC{P|2hl=)~-I0L8hd2yV;&mpcE1ENgH znU^$360I^M9@11g#ip%@dM{ES#dG=PZY;${w_LEl?7;1BeGC$;mC_#GM?d%+?cpso z32(%|@n!d(IA6L@6rzQi@x`EHOh=M2`JJs>?dKMR4j&f2hDP3E*P$|IWd9duD?92% zn`7JA26R`6cZAMoJ4hy+KlZb*x3!hlqC%WY2CZpEiZ1U5vS&U;0wq;M*twnl_PUko8Z?;|@!CA~L{nDV1OH2n+(wj%+G~&HzQLX*) zcW6ZjwW#=zM7C;M03-##fIST;ASl))3JES7F!VJ)vnC6=?Gr0OPHJQ=XX3&u$=x3(G{Z@?7jMdOX_XnMRN8&a24b{8HzZt}?y9M4w+$Y~# z0dKaShvJUdP=L#AEfaF~c&nHZ%GV&O$5*N*s;r)-8$0wRwrm~inpXD1+e_TP`OcB? zNEXO=)Ksg5$$Of0Y#If&I$lG4Upb(~5?b>{_S^=G^`mS8!0wHsy6z+DSLp_1rOAhk zz?4Xw=g(x>v_ZcoUM}#yl13{d$K4#5XH@_2%L!=X1qnjaq)#`wdCf z(HIv4@`-}V<8Ww-_4k<@hH$mbo*WgaHD#jrP&2S$(Eb7=YJ31FC$*(JZGQ+TdCn9@Y)dd*z+icS1r<)yUnRVnFM@hL^UTxqq5mbv;L06SGChyO8iI||!pnIR)g)*5 zvm|pa7yCSVXtsIJ{o9*!(i1Bu`dEUH8!HZ5JnJ=VFl`GF93+yIbf6deQ}X@(mdl3j zsBGScNQRy8;n+rcs;XvJ?u=$(yPcWF!@5DEh$Ie9cipBQKV{Q|B)ShV$OzP>Q?lI( zT!k(M0IqS35?9n4=ad{0MsAyub|2v~tej;QESF+LpxUaGz+(P1?Gk9(YY{iRe_~F^+p2IyH_U=?yN@D9T4T zD{JFwq1`q|q}YSvX?F(aKytt0!3bpHAM4g&sQGbC{|$|1INvhr8^=!Bj&Cc@G>T*c zAL%PH9_wOQu-&gVz!J^x1+7lM@tLCGko*#TjOUYd<RVBt&1;-KQ|cT4py{EC z>RYi1iwzCURLT0*A#A58Kd$X#$0!gAT8kwj3q7V_tWL2yqq9ckb@o?;x$)Trm6$n3 zaP|r@JAYemx9r-pxtK@tEOP40tWQe4*;A4g91-eCaQ`Nz!^Km=CR|0zlLhyL7XgNd z3Si2`8m)`dn*H+f_U<^HI93cvp4O*^F*%Y9cB}vK$n$4y(6PAgT5I3dBQTPUB6iqz zjNw5$i0%{(S7)<5V6Ld>CjP=bu23w9Mwy__a>TK~lH+jsH;z^0TB9^|IJC>4KX!`A z|4l>clSd?NnSk8qZmO{2jc01X9xB zpN?xK7F_ITXz*%m(Fl?`ncdmZGKnXo&v<@cDyvb+Jt`|G@Ds}TZSl-Tli}+5u`14- zm2Syq?4X+`sIfO=?!|z-t*-ee)W^cE=b)%R_%&)8w~}DoySKC~(44?(_L;aA?p1c0TPoJcEMVGc0Z8GWD`+DNX*Ve(5Qy9vco zopQ**)G-?iVQ@*YdVGBwL>?PYfdtGR%d1n*XVO`bO7k{%z!Vq-9emwj*Njb_W?xt$& z*x29FS;eiiVDYd)@0uxO@Gw2|wJZC6&P+Jt(pMvB@r-y+{*ol?;JdCf2*IkEXSY&# zeDSZ_-&%*e@=R-V;+#O8UdEq5d=AR<+NI6IlrCz9#plyg{J44jG!mg|MrbKF6NT9WODfh?N{w$yqb;d?{B54UPb#RD`Z`Q1FqHA{b;HmfHHumnL05z`&;eMQWg|r*LTA` zjYUrxp80I1zxEY_gCDHzMsQ7FUAvIsRBM7H3*a~u2969T7s)919%DyC^OVq~JOM+T zgk6RUBi+l8NJh+)!^q{Go{AJOzl5tqaVLTo{S!q(h!>ew13-sRXw~*+^)MX29|s7M z@J(O`tBFuy^a=C2)`Q?Dlhwo!zF4TA$ZxJlgGJOi!o{*A4)(nQWDV|Whez)fcu2H}|Ud#&oee5$P@Y3l0@e{9*a>}=cm`d>l+ zu9O0S^<2#ZR|^%MGAciqaniipX$G-%-rFl>-&KDTBEcUldAge<9Hrv%9F3tbNVgNq zXn)r4k^Y)jO66Yd;7r9K_anmEEoMv4_SUwZ<-s-)7S9^_eUmr9%`VJ<|%m z?kzcxEv}MNEB!<84;#2KdP_jS$k{DTqp8V@x87a+4AH8!+Jv7l$V=_xn+r$+<(7tZH}Kk7T;Kk|zhi2VCENbi z(RN{2#_*NDs%A{Qe9WYHh8k>KrN43LY;aprcT*%@pQjW;L>y3L)Y;vsNj_%FL4;C> ziO*Gi4d!|uU^c>Ee2yc{GFRTsL~OsX^XqDy`YI})J|LFSYZj)#P2;czwS4yuUnN?5 ztO`BWNHeL;+|@d^b#--Hv4I$d2xuNRHp#GvjJ)qM#|*)UOajw6uEPvGoOSrrOo5Y< z6O?g~U9$BaUml?ePNo41UWWrjYZ_>tHr;~;O{6|n%6B*qB0(?T>-NV{9-*USBlgIa z+~0Ib#7IhsibRXoO@063OiiZozWu#+rRc4wRrzwepr7@nvHET@R(OSZfd(>iw04Wr zu?wAoI#$DYg|T)$xO(IERRKyK=aH9Z{b1KognNNnWaou*61eoTy2@7CQP$NYjeTzj zYHrebU)YSFw;Ym|0iYCKFxpB>uY9eqQ{R6|o+zj$j2nuc4GxGvc&c{xB=H z(2YO@mTNxHgw*gf$#O4ty~t$6;iocBvXJoCYF}<6k_~^w%^ae2ucGrRaA<4de6ZQv zp&iM@BThJS7?v)WZ|NV&`6g_Eo&cXx7q%N{JWE^xn)}JR`6GD_=owN)jK0V562y9y zrm=QwTU4sNBaFiI^N=`Af7`E&6`r6G^N2tFzgmcA_!qw?gG_WDBrU;|pFOwQ0pES5 zReK5g_pj3nYx9d?6qs6mK!+qVhrE6<@rv`=k6QcMHFEgxuLF71vAl?OVSKpN@{6}D z0JBN4-$m=1dd~@DpFG`4&(DQDucES}#T;;^;!%p6ccQ->UxKKNHH(TZVI}bgiWfBw z83NR84W&?WJ0E@`s#Fb4Li_+2#hVvFk|bu>rP537=TmHm5YhKA*C9+vBP9KZOpCb@ zY(s&DV<3gJNNj(wQ6{DpJ8Dv+p3iXMiMFS82{=Onr7&E9fPFD^93i;jS`QRyqv}?Y zu`G_4L`(4vJD`sARNNy~T7U{{y!sI?$J-+OT|7WuB9+EOUx!u)n_U4O(udZ2oEct-?~e*zh0;>>qvnhk=mFfghZT>kh};IO*3*pi*B`W z_=NE;i8!;b4043=8C3os7eG!>!mubav@Y{A6tzM`XyNbmt}{+T+87=*sy1aAQ;5>( z3R~XC`MLy59Cs3m88}>BujWD|t|&JYgxvb_kH;iQc-9oioydh{q-(LAKF_ zX-p+a0!G`Y&*@L8$;L%>8dudtoznI7!Vd%dB-U6FIAt-RQK|a|eh~)U;o{?#dA$&( zfe&I{d7111*CFiC4BA=p_-DU_#3Pkv!JVCQX&%ANz1bA*XUQ{;gIBD7gAr_aS7hNK zJN|w+iiJq#ndK+)de*G+APr_52u5XAe1Z-i-9X+T3*-s>EXY^;l zLwlPs5&7q$ zl)5VcE_-`k7N5GOqW--a)X!b9D z443_l`qzVth~YF1YoO=j{q(*K%An0L`~Gi4k&!w!S@Ra#(|409 zR->THHFoPGdh@AOLi_hFn29*C|30HK|60UL8cYAx_bp%drgkU8cB)42IpP14L zSoK@d8~j|)d81z}+cCYvQQ>6^X$sym8>u{P^ZSfviaqPgicH4$(?O)NSl_nSRZ{Bw3pp?JFY4_Jbn={pc(D$u<*hu9S)qy&{L%z&q9Uj#7aqtV zHMZrr@LMUZjT}eZpMqF3d885QqXFy$6bULjns{9_wSyLE`5bgdOHoi9M%h>;a9}6L z-eYe_H zW@y84(8ofb*{FEGP8@9EQM9X#gaJkU6(V$7-t-N-Dz)%*?tMjNb0lh*p|0nY_=B1O z75p73qSBUMc9(${xi(WDL`!d!ngA)zkDvbxG1GcZ?Mv8oAxSjzk5*1kq^u=@*YJO! zZ)C4jo#imMv;~#{)<9dC&l8j(f53wmzRdU37UeFUi~UC1?kqf3(76GP-s7C zgPfu~9wpwln7(vlDLs+~PBmf3p=Q5zw7T^?c!7@aaFDBlC>1qRlalTnjXvW3^&8Z6 z3KfAVExPwX-V{e@_!9pJ+($2qjOYYyxD4F2_Ekb8Kh_(RhZ zfwnO_8(n-Dg5*VIaeEfKjh}VKC)}5*9rD)Kj5&Nw(|oYI9jNE+CN$0a*5UNwZ(ygW z$?p;C@&Iiih|aA0MOx;U=LoSwcW+}KgulY~Yq{ZefF7MUXcA3ByWQuj{*DbY>R-pQ z=NWE+0UQ~ZY#edFuZ(rOzL~=VMByzyjsuT9H8p<$vaq06(K=PPAU5PXVjrrCI^CZD zxS}}eA=BBtu|r&a-qV{!mI7=WCFa4rzSDJvufPSbIx-A|cxpLXU;A_0yH}^Q<~Ng7 zWtkG6NJw5Zp_XeIFS1#TDi>(s5EPq`dB158=qOup@(4hb3FOB}?(7Re)-!GRs$m|w)Pk%~kPq)P* zB%k3%t)~n4cpfEaX2ujs2_s_pmwfn6Yv`Z;*K^?U1_Re3`XPvUZg?=hgf(Xqv;B_}L%`o@ zj(%Qr7%LJs0{2!dPS2uDf#cox)f;3^^&Aw*w{dUKZbzaxMq}$dm}kUik{QqH`8I#$ zcbk2Jg#2yvBRvm#-8_-2oJAt59PC0tShb+hKw>T4^L_sVgI%CL^6!9}FOMGC4wOS|(48@+r35@nJ@lBN83h$(zzIcVY_{ z8m#4$H5n>ITPo!1Qxtj)%~piZ{|*P_23nW(cu|hxXjVvOBBx3Vd5YUnhQtHF6g4;jSUqx~6o?V^@%q^qr^%4Gl3l%l4QjTp88@K# z(k6UKOD2&fT2;OPRaG_R`@}vOw5*YIK=wnYQ!bguS4Yk%7U{nf~;IoJn$y)AWd&kzb zJEX*4Ja{=lm&^)d$qQJoM{JN69IU zPE5AMn`BUv5t5cJb@=yg%(lxxBe%u$4I%hP%VLAQEtE)Uk(G$h0!b+51~rvDW#~-$ z;s``S!)#BRtLroUCzEMDqr{H2#o}=Su{nH7xE(E3ZaM-dUf)Ed= zm~Kdrr&Q!*KhHUU*dp2bIACB`?)OY|kdn+yhvM@QvaPPk*Q81B!3k)mJgE3D%MHV*>PQ_*(WZvsn!@M*I>wrdBF}$;x zwNSwWwYL1=K8@xlRMAXYF{?42tkiylfJD4pyS)u&CnJs_)9Afmmbn4Aq92;jwnpJK zP78JvgM3tAEVwe-Ne;NMz)FNm0&q6w5d9vHs5VwmuO<7LEK+gFgYmD~X}dxS(z>mf z7S=@m!&Q!y{l6cPuuT{2OPa;=4bPDmO0_i90`BM@&%MO>E%T2je5kq1+McPsc~X^Z z6)9|r>SMMzBm+eg4<^;3lf`(Kwwvh+ zMudD(ghio+(o%Gz;Ys069Qm9?z2{`Z?$-zHJJ%8x)GMxkW9nBrTxE&A@95k@AfBtL zBMB!sXKi!4&rOMj9NIQ2I8}Do%XqP$oZxwjPNpf8AZY5GTfVmq<@6koA z2os75fw3)8YJsC-B3WJ|t+a_T)wIZtHj)m)Wfw_~jDgsVD@u4Y1vb)fqvIev`w~%3 zLJ6iQlT=I(cIXeq;TV(%8^vJ)4TUpmuu30*5-$-Yf`ceXnCiRc=cbSf`^nN!4p|E} zPG%XcWT4Yorxwxd5|;=ABzGKNT_m62LBbA|j#LnBOTw(2X(;Axin1wti~T%P&uW`( z-h9X(@SOo!X9b7J$%ZLBql$3INrJCpIMQNg-H6FJnnIR}_T&vMKc?64yEfoJsqw&W zYKeMf!Y!h!@v;`e!!Uw|Tk3;4YNuCh!z+d->;ol1g0MJE1K*BN zpW*y%%b#DIY7?<^q|cwelpO8pPm0Dtu@?!DIp6RU*6~lB{LI0Q9caw5op0keaJX@R z*L#E$mx!8kta-a_W+fD3VzzDcwE6{&9Cy3!6H=|_g1Z)m4FSv`ncxA)JD;mw{#{G*oz=%R zT^4rP6xRX`6+b1uy2J{tgbHVKNrc_n-4mU%>Sq5%H_c0=^G?|dZ zu(oyp`++hFXet}a zlhqloZmwLhNKY*a{5bh3;#;1MGAo$%_SVtS2@dfaaIzjLlBf86H!y}YRmtQu2FGbz zKexHx-cHrjuJvuG8xxYYoMimV#?#m>m+Yjzx)~* zcPw@w7Q*SdJcdm|S+ga(yxYhLU+v>NQcv|-JgOpI?eCXozHIh%(mc$-2J<(oSV)h* z2E~%w-OWWY>2F*Ki@We+66`n^XqnG`D`A(h)PZyq-}7}h&Kvf_!M*9)UESg9_`*3! z8K+5|#obsC7d70*|-3Je}6+t2=65#@9G9BOGBfLY;uAPbKHX;)&?TfSQ zEurnw3$n`3Y!y7|b390QZFiv`N<%aVn?v&k#bz=X`S!CS zXVyDig{n(_t}6kF!wuy3R-p_Hz|Fpz_;{P;3Td@&6!D}idfM24es#D8w<}2`u@OQ* zHSB95j#I|>-UvS80QsFlowJRM#=V?EsA@889DJM4RUh^RCEgOojA0ThedOPffE3?( zl1ai61F7YY!!TE$$@#|uCNvaMgc*RcJ2HssK?l^k;0MO{&Ild?`RUaoQJ^Xajnx&^dNiDY_W}Av_JsMGvNENOqKw zJIapqVf}I~A5CiXFJQfoZEkgR>=9~sZ72+`#e<+>F~76;%+l>#}3i4tl1g* zVK)Km7PzHTeg}{IRIqM|&`+_%{nd&7j^L-;Bq#BoH!jpS`wIXJ`z~a&^w(C7MADr| z+LOWZT{rVux%8`lHr2gmiWI%y_=z@eHy@$>%c3BtzJ2 z7k6VJORcsG$I@x!WbD$aA}5Kh@?BoW5v4~mKn9E=5|1YcQJ=d--#f5%2fHhZhwf2TiUezy<41i^GQvm3MV9g>d`oMCR|w7eIZP!;u;LFWJd?CM>T z@pyUp5=l$qVM%I#vuhvb0f!x{5~MW5;i6FPLqe-*KkZ7YkU~ch!_P3nk^8Ww|WLST! zXK3B1Q{QX!R6=Jc+N--odHBpVVHgp9Gc9WJvJO+ZiND-0+Z zD3C4LY$CHh@3!nBFnH!sNsH@lF9bAvyk0f=ZB^(fNNxAHoWi=%>lwr&^vN6 zP?|xs;xN3k?CD|J{c))E8&4A@%yn3_szJNMPMWLyZd}^YO$-OZ16bG{T=&kCsLS`sT3b!Ct$NY`%c)t)gKt?gl|J6~H~-y&2`G#?;r@eAQZ zS3nA4A>0`C?{x1I@)Vrnj^tNnF*I)Lr)b~6!L*@mZVNK!Cv;xEsyi`Lt^T%D^8T;> z$-LHG?<8l-p|bI4XM8T_>OjuAJW-7y1zo&{n(qUo`ExafBz%P)w&-r;Q$>K8)zhzkUT1qj+AO^H~5EH}- zQ!y4uS96=rLsVPeEQ)pX;}5M%+rY0sWk55I%i3n|pf6v;tkCW(9RiD;x&nbSh+yBqFlpjfv|8c=G9k_h>9*>U2#DBPv>jnRDZXWjPcG9p{~{Gf%hNfhG}k`M`NM|?CgvCy3HOw_rT}p{43riwX^PP@ z{yaS|esdnnyUEMoRK3ELU`gCQ_#`Or4S`MmaR7HkHkjhg@O+9K{TSu#98DA{hPL=Q z-f(uWQExQTMEMq{@DcA@5Ykc!iVWT5^*4Z5%kT^IChU{EDsp*Sh*l|bRwzw zviUExWR|GkDNYBzU972JW#+(ip#b-Og&=x)Wo27sMSSU=ZXRcnLKdMQ+%KN>g`D`K zWqoux?Q#f&p*$*3omytK@uZw9PLp0sc(B8nbl+T1QZ zHLl3aB9G{BdhI34U^-LkKhUFX(J?cH(LgE!lX3RU^A%dlkFX{p44RQH9Phh%fGxe*zo;& zpc8Fs6Gcj)twM1OWWFMk8f%)=E$b=TC}F?$bXYFfLH^@9Qq$az?*4ji2G^*KXn=(B zeF=r1CN_6;{@tv)eJbTbev?4DhB5oA%`%(C^p$fNsq>)Cjq$?`9Sl8eQ~n4%)gwCH zdtUSKT9fF)P5K=_QLOmj{MDE5O|ro&-GI&=3E%ba--JpFQP|h&P^p|9Q|)6h?C$P8@J$js zes|vx!RB?sa$f#sxQ37yzwywHxzo}=^gFn6aNnOzmm!2Zd@Es74>HDoa zao;pJh_veR@^0cH82@YbE^?GxmlE4_BBJ+R`h!ty^=HZ~40!l=Q=!Sup{eoj-aunzUh-uh^ zuzqJ^nCybvoeyq*efAid+hid;fGO>GNmBbSmp5OQ;O8enyTu2*e$C~_mmT2dei%Rg z(e!T$4K#|Qb^AfimtlG$OoS5GwD4dQS;qPDDeU9AIYTEkBl1g9t+X4hz z2ECiTJKPwl;=W7+N{Sm~%B>=D6X&pAB-e)lw@wR9{{^*|^iDCP{R`qHiSUh1SLUF^GtIuE?iR4%kEIoe7BZkY#-|us8q{~JzNO`^Vyc;-7X!m`&wYR&g zW$KmLaspNc7Gn=>jab9;Az<|{jV{z?;gqQ#00$>Vf z&XA(7sM3od#Pj7=Il8(1VS6^5H?n!++gc^5<3u7X39JR)dR33C)UjVUpi|RDNTLK% zG>gKNZbM?B-=!EkIH5m`I@ogQrM^N%sa;on@=HHXONry=5ZYvbIoG&wj~u}cp!|v!PcSmX(3bgA$M9-c9Y3~C&)ps zV_>j9+kp^uQ7$YJ(iey&X<}CI7I{|}Qw>R0+-Y25XbrUQRyv-2?Ww6YznFHMOVv5{ zK)m)@82!Wx#K_+fbDL@G*=WN>+}V=?xl)oSzSPfb9+hUhtRoT(>Zpp6rf3k9JU6wLw_ zmONY0zQXL&C+(1By)~bpaVDxn+;PGyYQ#$h@A!ky&N_ITS`I32K{@){yaqesdYhfE zv|Fc*FZRc`wljH_zr9J;QZSN%*aA}o^0fDL(Vxf&w&f)3+?%Ry9X7L+bUJ%9vKd_X z((8k#{>RZr`b2*!6?b!sNc*Rnltv_&S;#VnsFP-YyO^T$e(=xl)4v5qpNBgp{VIVF zys7k?C`#}sn{Z?(79ynSrlNiAeVjS|6|od0VvKD-`TO>AO1=ubO)S2m22X8v;EBrn z4|yDOlDKSs*%fP#WhB+zS0qp+zSrd3OnT~qnl8)|w5;j~3;D$t=WliSnuiBoacyNa z!C^q)b;cO&o^((91yrH45s?%oRs*!!)RFCA&kVH)AptBX@)&af^8#V_Ta+|Zcs4oW ziQEv0grK<2@Ci)!@%m!3t$Ehc{uw2F4N_KaRIM!&&qo|RqF^u+*;5bgDkg}lN(%f|CJU|Q6lRDNJd*3YFnO?MOfV$4E7fG#HL zn=2h6u|!ZBgP;WxT${gh@uZAHPl!$!Kil8CX?Ju4cnISW+^%~ne=KOqqM9jO?3Vj= za^YFxGCJ4HW>9sk+R!O5qXMfxsX{oM?)(rrzgK^Qy*5y>T2 z>!yNKBGaZA`!*c6s5aVk&B!yaA!>!uxMEA2?JT~#2_#gV;duIEamWX8hSxL2g3Eft zIAQ6na@nN6BSzfZjissuWa{jsz=BdM9gBjrw6=Af;w;(rA#<|uD{&-znJ@2WWJ@*e znmlK+$N&gSrJUU(85cU|A)=e4`{O5iKMN7LCCH*m8M3Q9Jyj@k_*{z7zN&GZkR2Ut z1;tkJEBufJ;@JWzFft{3*{oI&n|I@#vTq4shvVT;bI3kLH*LW{O)R?(8sYn8f{=-&u{agf$%$@8 zM?2wmGd}7iv_W_12vxx|lU1H`wH+R6Ao1BKsUnn6Zs^a9N3?s?~a*J(RDrhIQ4Y`Yl_nEuYfTt@9JZw zT;l>%HT1*6!t#O}^*{6W_W3si6?99Vn`Lv`7$~8PC^al5oF%I#e5v;QJ_cQ?8L`Ia|wj3=vx-9h+XkaoF zO$g!=vRI(|u9=+4nfsO)r(eT@5|AqXN8R~{b5M+IbF2FvbQGhSew8m@mjlG7Q6gX% zm$RoLqHa~Nbf=pfn;nXyQrz=3eM1_gCpL|v$ zp6f>v4r1Tr2)+>VMSH{BqEWt5(vGpI#L_=pvr5k<|1}k%1`{;N%cd=>kk7CHL3I?4 z;v+-Uv{H@3Hu6|l!6r@p=^_^B^5Tw;_y1-QKT~lH6Sa}efywb$^!^gJg#HcSMG?s_ z>Qm>n66Cxb2>>7w(h*YCOU=yFpJ55d+VkMZWkK3m984J9iZ0m=BBk%cdqttMRjhD) zqE1==WE9T=)DC$FpH>7&oNdndE?`Ji*>7?vWobYM1+tiAI&U1YCPT^tN{mJsc&H|s z5oK1iu?MppxJh9h68Ty@nS-No^lBEF%q1r(zVkv@Nc0>ioSb+w$)WQ&nc1f_+Sad| zv;5x+hNubJJsc4lX1&a*(JJ`XK+_Eekqwpt#X4bC6w z=VI6=Mv?Htcb)Yn}irzaWd3)cFyeM2PPn2R2pazrOg!%ShLkaCJUbs%jPQQ>MZ zOym^km%$9d@gRxYi+gko3@Y8BCuT@4D%~*QyLB@Uk`rd`joT};Oo0weA)LB`E{f{z_Rkxyl!!oo;+ zccXaw13G9&FxmE^mVol++Tt^PB5x9%%LKpd=tSUG8W;_N=7l+yYEwE-40ghMt>~ar zInb#o3H|MtVka76if&pLm{FFJl2YdgY-rKhscYn!gbz_8b+BZ$C|Hv$wdeS-bSUGs zHFY5j$cKCA0;Zq6YddN8GNQJ`IyX1)?!T|8q_m0+)3a#MIn7L;k8A@`X{Fc< zem!$tkVG{zm1S6|yH{;1w>hnG01yU=0x+Jnf}IcGHjY?ankTV7dFUJ!e+(5D8vS&R z^g|wHrS3@8#hB-|=DxB5v*C%ZtJttYBv1@1s#Yh36|%J`Bt$z@Kwv{r+PBxjMp5^U z>3R&Z$1mC;AS)D&t`u%}cncE*?A|?}6cG!%u@R(-l;}7gR=0uKFx&Fock0r4vH@|V z$Fk!O{Ic@$(iw%jB3p-it!~X&KeG-Bw8Xzq4YfVTd?lNLR0M}aXCz-#@Fpf4iWpuR zWMfGn$@AKPuq}+V2$?ItrTqH!Vh*{n`epP~O3Ceod$36l<~&aFpJ1+gm)A9U_UBss z$^E$g7L!S4nj#C6VZmXTAO$*)bvm4ev@f>YNqIWg5p8o&NaXFRo}5iMNyuidani=p75k+EckMdcS=eWZ!U#0Gs zLQet@-_3)&FGxb?_p$QpG}}~0snc_Z127Q4=_wj#N?;J@ut9RyIjR72O4>@M0Jh_# zjgi<8&!VPu2eJ5WZTi^q=+Ct@kxMa^YQhQT)J1UkqX#Pcp^az4N=q{o#{9+Vq##E( zOe22FS@aqVe7>r(Fw}yZ%)I1HHZivN)MNA3H!moJNvH?(N&~~DKjve)$ix$APm4+x z#4RCOuXW?{et*_oKb33*aAj9(E=hak45Uy(WkQ@+;iL zQM1J2<&|d(Qmb=ub_NE~e4H)*k$C{kq{npPcDIw{X11#((pEp(_Ul)Bt59BYf$U61 zLI%g-tdba}5XCq+x^t0V=q^UV`iZ!o(n7M0^!o1UgUe!etZ9GiV0(G4%+{yg>xK(;PBBs~U2*=O?-9O09O|MP3WALDx9@HUpJ3W*&zLW?_Kr zID(a}2#q6LTFQjb;HjCk4*(W$KUwoQt#q|kEuRz6-n9MgD^szWs&qmB>I%Hz^>Xz7 zG)44PvCjuJ{mu+35jWA-SERNJPJRou>kb)nRd{oGb%q|JJ? z*Eg@k$we>u)}Q0kTH;xh-?T)`+=le&_4U^Ggpy3YwM1UXE#lm3+wbxQ467n(9Kj`F zqX`7eonoT2^jg_UH<@%&mBr$_{ z3nWY|c_EenAoBg}D|3>oe;1u4(F)T7}pw=5t zCohly3~C-PtR(hsX8oeWGmckIa-fTXfP7c&Xki!q?&NquEG^i2m3q8oQlJHL=*y7) zWGyEutGrDK(D%3?BrwJhj>9lTlv$i2X$sI=oI(!vV{kA$V>rM&0X_>aPyXr9s$y~R z_k(jqO(zA2=V4aTRG!aiwl3PK6|cI)$y2Zr`-$u?76uT z*j?u+t>GZ17$2I6U@^0-iZLtDf{-MI*1h;L9slNzSxTGmvx=ue@Mj_G*^%_U&o@SJ zz+@jHOI_}R!7zx6-6u@4_)_>S9u9Wa*yIXm6$!UNv+=6|I62LMwGv=h;Ghc=9YQmV zAXtJu88QX__5=Y>8jh=&J8sNje% zh!-Uculny?culSkrYn29+h6pw%v5z8gG{ny|_24LHhcu^2os@lE;WW&>M}KyQiT};K;37r~3C@ zu#_x1{OMU0INqPUT37er+ZAP0e!W|T0fo`j%FZ%~vy=U*bng4h4i?TnCUFzBeAZBpW)$$xxnHRAWIy@FvS zPqxY8(hnhM(H=oCtvdMT#r2D8+sPh!{yF-3`^gAB6H3YCx-M#JW=|oiwNvF`kE!eX52BmPtm}9_p2z7N`Mp*$mvr{%-tE`aCV@h}$WTewB z6`p_kqnghEvyR8QBK3`XLg@MjC+|G%XnxE;Z*WhGol2!PZq~_^Y;b>1KqOhQC89Bh zDaUawtJD$iCRk}kD*3KvP@#?1Hn&%#v_J03o^c9-LX+v8P47EySlKT>hb>mbA0Jn&=65j1yLZ?cWiwjnt1>slZ_*TI;SSl2>E6 zn>8-GIKnQqg4Qp=DU>x9hR*grS9elwrfQsiac1p-Ufy*-4q!Y%C<~?m{St6N@5$- zlM!0or{*VSissx;2WM0#^6sV0+EKhK3LcPL$0)HF)U$tK^CVg^8BkJC9myJiil;2h z{H$u79yS(}DravW|M@khk1R_XunN|gbq6KTx|7VJDvO*5LahURoyQwt^Veyo{gHp5U-Zy}>2^L93}Zz`DLOcy^=%3aQ2Nvmmd@(+LY zIf*Cw^TkOmKE6nF?LPHhU|%P=l{`D_V{fMGExayUai51Zdok5+Pl)!j09>8lUh|)i zOCqsSk#VIM0~oJll)c|3MZ~95PC9&i$J}Bt6G|!hc%|@JWK}>C;Ia5WsT_vb#YEzM zd1q73AL)>;#I@Uh^W+L4q#CO{`VV$`BwR%y4j7eHQXE$<-EH zcoE<-9ubZ)!uCun3Zh`EqbwlZLuL=9Jx>k^4W03+6qaT}#tkE>@(7UkU^69(XyFQp zNm7`;wKyJ}UC8=ZoR4@0@<<+b9n#NWBZ*jQaqVt3h{cnWR)fi3H2G;X^s@<@o-w(V z+CIhpc^if42T5JkcTbnnq2<+6Pcu+88+3r&z%8%#&qt|)m^0B#8E<)kwVhYn?0W!Q zrFy8zhI`%YD=_dd=Dx}H>S7VT1Sh###t3)wB~g?tFi#!gOhYWrPMs>xjLL{AOY-Yt zY*T7U4}tks_(hS|Wf>3*5bV2_KQ7(U`TlydQtR+#ain z$}Dm)2=rki2y<+aDPSD=+`h$V_od7Y3DM94nrN58@(7$NH;h&$mWHvehso3PeL6zm zKYHS{&Xq0!=(46RNb7hdAxyPFMO$fbMc9X}QVlc4-e%dE!ok_+Kc@{dA3eLbdYGCh zGW+SAI!lzi8JbMKf@#`Fx)!iKf6Z(iSM}7zsw{R-KyZN=+H+FS4{d#0 z`FH&q#q5?2JO*>l5%PWnSH8uZ;g<~}*wexHvAgZ5W=eSoK za7g!N*&NyOX=Sbj=r;1{HugsBl21|*kk)m0#S68O%zWn^#XFs$;5N>jz_r_G9nb!0 z>3KweQhm5h%HPd9E|1t7A{B>jT=V(cO>m~@Il>hf zS3f9?JR%u9G}Mt@@>i+sQGT0=O|spXoVLE(ZnCQ|&mwDOmYmI}jBNU=_%o(9n_)3M z$KC{NW9g)C*0)~@&ZcS@k;jX-TQV5U+7~YD`&gQ*e(`Jxo^(KQgIHS3zKn-#r;vrE z?(#z1NgoZBEKE>ONTn}yZjB4^qFWjcHfBMTm6ob*AjJSyf*_Pux7+I8jB5ZJqjZ*- zRI;&f@L8X(_o@^EA{UZabX-CTB{D!@U9YPbZJChYBXL9bmS#9$I%o9LRDy41x+;T> z<-Y5p-EA=Z%gqzuwU@23wI`1;d&our2~xy^wT_64YZG5buK4Z75PhcL9DhlA{oacv zfQ2?q9|WZxEYMicE9D$8N0UN$H|=J0Oz6tQ5<&on0IwuTc;CGKxt<+21fHQ25@t8q zthz#c@qzS4AsuX1k?=kSOh|O;0m%Rc|Cz2WEUs=n$mtevgI;0TRM1RF+4R!(`j1@3M~dL86;=s4s!Ar(|s&5FgRJh zTDKvbB9?b+N>^lttGQ=kkrLxZY<~iguhD#w!pXb}S@R`R zLtJ60;k!f5Po*IaTB~;2~o97%(@*;a|rzofv76$fGxVcn7cZcX_KW z39}83DmGS};!dQ8tf@uc(p=gbzgre2&%FCdF(-_xc$8^EqVu3F1P-~C-}7SOQ%7BY zse5)E7n1!%3hU0S*mL!JTUVY?TFqZyh-IX6ulLbbU5+fuUroO4B2(v)!!O!izW#3N z=^_S17=;w}UJ<2PA$jg~@$_AEXm083&2}aduxDY1>Qy*6o-yc+ayPr#2mWqw2$iI> zZW~*DVfQr2?QiMDvau`Lr8U5w$^IBZV{*MD{)ye279DzT(#iJ6fe>EPqr)>`W2K{) zJ03X~`9&l%@QF=EOJ40ezG5y-hxP{wavQzD@3&V2qAXzFY z>9~lc^^WnviI_?n@?mhPOxaOwO>;leI3oSFE%+lsUbjf;nA5muXA79?cMI)9l0hyn z*wejmz>X=A<{IC`LK!}PxCIozvb@=*@f(CvxJ3Y$#&J3OakOE2mOtDScE+eu-3$|U zb=5PyYkl$2*J$T6mpf$%zu$xe*BE;T zAX8C;M2)0w$XdZ`{2t0K;$;ofVb>~Q2Dhk(PkzUIujS_C6YBz*O>}*A{uSJWT6O)~ zu3a=m7{Hlet5nT&B{I6-yYqt($|JGR5=5GjddUsX?dEdNCp5!}OdCo~-~#_=XATK5 z6rHcJ%HSxP=?!liBRyRr=74r<*QcD{#@imBO_p7mJZ7Z3@xZN7aBvhQbK6U+K1jPr z9m(x+6IX)^^+AsdJBdRxO=viGDg|@s4c!HRCxpggAcoP`x34y8s2(>j%qzi-2-5^EJ#{T!b!1i&F z4b~q*W`;>{Lpto$GS+naq!Fw`rUH-6R5o1?szH9m&qlp zwEGXEvml}KtWCC|SL);+J12*Cfw#ri@{}3-xR{@EG}>675}rU3fxx?m!+GNA)0SqR~W@EjYQPe9mvjHABTil z3Q4FoD&wOe+CsYn0Rrt4dTZyGmcJz9#H{b3pAc5voQ4!Q#KsxfyX>>7xrr8{9^KNa z#F@{)3j-J6Ga8eKC^kH|()ry1b*LRl(4Y%YzA9t)bY5V6$rj9vW+PoB=8N96nG*_c zLW+257{BK*Vt2Z>UwmXF-l;w>psg`BO<7(t|9CGY z@Avf>x6m-W;R$F(kZ{o&$$-ytOzg->&wBCTS;RB{$s6ASXu!g=yX}f5p=xg>5q0vf zlo)NE*Ur!EbiNWVpAT&#%Pn7U$fv?__9skVCIbD58~ss5T)L>I}yaNzp0=r#$F@I2VperArit`DsON?_qC_xHjR~3N{VLM{!c3mJ?PbPX>}w1Q zo@8Nug1k~v>=!d~#%rBv@$4r76`DETK+s|&h8Javss0I<>wp*{{v%iUJ*-)R=~gn{ zqwKK~jqG6&bb;6~>!_B z7BXzaLT3&rkMgL?G;G9eigflpRr3bNw_Ir&b^406mVHs0!~-`#(*re1a=cpf^4i~Y z5qPyNNU}gcnZZ0RPeqKA;Vsn0sZ)O|m9R3iiO$7pjgg$rM$053U@jHJ$u8_%Vp6u>LQotH3iQJZ0mM3 zBH6YkL|0G|nTxgdh2E>xsksXHhLBzO1g+Phn5)>B`mT>srbOT1b{-%+d#mNKJ@N@^ zreL#s2Lyz$uQ{Bu;o&-t>>vay^-_)tAEyM#4KvoLGu4<|NxaTrCvZzEK+Eg+XaWCX3|g%Iih2Z-dJFVWiSz_ z-afNuP<@ihXM>PS2|qxQ`^nZT1xfU&9*U3`^obZ{ja}C~VJORWSx~vql@0yXIneo` zKhJtToQE^gdz04Q%ut#%c>0Z3nI_CTHVI+Y!ieu(UB+cX63gVlI(T-|F{+n?VdO__ zQt{S$vU*ho^uQB>cXG;VX^mwMybM?FR~#)HOHVl&EqhtII-ei9TNeaeavMDh&V=Lf zo&YCJP8Y=1ucoL`8=H^3;o_`@De@+8$bGrHxV&mEDfM&HP6w zOp8lU^*55*BQNu}B1rAV!>Z+k1w&FoKL$F9$u*xm!esT87H2`W2qlVj@zCGzu_oHj zIlpPwdTALhxAWv0u%{+)8f~}BGxEx&$LLgb?th5VLJ}unwFeNbeu?bt)dNzhPB(%Y{fybsR?f0f%B_mj&&5eXBjM5_-Wtb z`HDQd6tF#9HOPyB>$eC(zM zP^z+TJ)FWcjVXv)3Rez4n0#fX*w}oo;bSih*RxSo6bGSPaGd~sVY-73rGDMg_rmYG zWYfeM5|(xfFnMQW`(&yaX?6~+rz&{$-MtWD1iegmrv4?=KhkZ81hCoTG-vyv87F;| z6@S(NuI`gTXmexWoc$7V+I#CwqE#kjv-a=;&$xNXkzPcPf!cpA_jX1iAv%#q4&MBF zZeRbaALmQ!BnfjzjR@fj)vVR@i0M3!7zBii=IM8v#;`r$`^5!W?6iszJ`wW<=&4aA zSs0{}QX^@82(v64U@z;oEbR}oV&Sh!gGj^-ll|RCg%@>UwRR6|Hum2se2I&TKo;@p z)pzc0U@=Bla5<(Mhok;J>ghdU_IKJWeOnKGVU-AFGf<(8oIMMF9#4{BhM1^EFqD7_ zvp~klAM%9lU8L6h}B3GnjwIFzr=gDi~-LnC9Du*sRl%$c#nIus?jX97i9W76>h#q-yu zE7aRW$C1r~b3VtBeSkLq5P2^CTy|V{Fn4uOFgYj2Jp`D7)74#@hwbbdEvo=-438LH z58walN=@zXaD%WiLn!HEj4fm_gBjphf5bUb&?!#45RbCZ5)$r9;DRtjJav-3F@VU6 z{Zd%Qz2CmGIm4`Q&=3-~)@|s?(1IQM5hf|-h>_O{3h05Gt(y0YGFWw#`-*WGCihjF zs%j{r+_kC}P!9C-EG%JdbsXvFBCE*)NIbVXr~=6=<-vFm^1T3bG%bT_c(VTDZx+?? zm!E)47kG|=bOGqkvz_O-U;YvCUviQMJj?^2ivRB;y5Yvm`@{PSLS@xt2pg6J$o=Z1 zUY0(lt07vFFgA!p=76i&v9fP(93%f56um-~`rcnWfM$kcsf-R}^#6_O7I5?X7Vo0Y z+bcc%)gsF4mNKz=LV1qt9W2L|w-xiYOegewrMB)?-O~~Y8A;56KEZU~0WG04qHXT} z{@Uw*13_rEyu{yUG~^Xeb@%S|YFoSn31*t>dRN{j6&}E6Qge?gFRxuf!xb>%Dcfku z$11q6XBg2s|JClFrJz@MKb^&DUi|#hWed7A>YC7BGBj!#N85mU2G0`xzWR{;t4wzO zBct@EAdK(B{c%S}BA#p(ANuGse&4g1F*$Dy;qf|{`>Ckx|A?0T-@t|&)6wGxp}+VV zV?BYJV{CPIT-xcP-i>Pedo7so#V!z*L^%$Q*=|>xk=C%nRoiwTKdQ3g~*= zbBLPc!!8I@2~i*mTryhvYii|1{6qm~P`Buh`M-HvN}$BVTM)A<`|m z9_V6~IY#+w8=?6;%>R<}fc%4N01vNHg4LA#j(a|6Mg@55;{Tgx-cKdi&0}KyMCl)j z@qZ6_Ds%sdhrN!H>Q-QT!l&w$(rA)si?m$_bY5{a@pJNe^6iqNx{Kdmoe3N`0Q{Rz z(1iY+Y%2OFmG!h754>&YAc^>&b@acvMoaA>rWNH`FqNqv%+2lq-OD7ERBA?c#>S$r zW?20V%({<3KA$KzvHzzKx(JZ%{xq!=&pM-BPHUca&qYT=RORbDitK34CJm*OG=3qb zE#m*={X|Yen~7Y9U57S1%-}Bz1*`bAa+g+B*R%raimYHGT1tnQ3gPNCW`ad@mXkrI z?dNy803QZlx39%(`D-YOVJZnos3saeg#YjP_cC(v2|S$y_C*BWXekK_eDc0l%DeCl zvd;tP4;tOxUrF*QsZMQbJ-ouRGoouo-2v3#!_^_NK=hxnZd2Zwi*I}HW54h9-ZWnB ze|uzURD1jqp!=V^Azo4{J2#|V*C0Njj-~wRqghQW$Ne*sbpMELLkyMKn!1EMg6ZQ& z>mO^ot8Jq%H<2gp_1LvG3YV$OMB7f(qeL{RDHBqv9d(P7G9iN++rsw(>yWnc_G|y} zKc;&7o4u3@lS9(S|F1spCryp`1$63KkR#{gJUs*67eng7(rRI`27>hT-9kIlo40wK zAHVG4xtSjNTV)(v!v^&DN0PIu91NG2P7c2G3+DPI6)UD1n{ow&$*spNoBf|UnTqo7 zhe8uG(Qm4p_KtwPu)tiOq@n_cetrC{M^@ns-@H{#^C2$UU1tVSVHHNl`L0M?($#Rt zpl>mSF~~FMT&K>I)T*&mg9%hxdJjXPg= z=Rx!DKfjEu)cZL7sp|#lz3u()cQ{cbh1aL`nE#RO3O|PS|CwCK!>lIhcmmP4H8eyr z9(1&{Oxc~TAbrsqilqd<1gg9k!pY9S6Vk~j3MMbz4B#Yjxs?;&wI2OUnM$sWzxcVw zgpVSLp-)5#dpIEEy;zjK&y9a=tDRau*KN^LhK<)g@}ef{?B5MPru38l_#F>E6HI=> z5Co{)I^dpgLe6Eg24;iPitHXHUXIJR!|NG)zN=)w;fZ zovaLK?kX#`nI0eY6{8k{xHVg}Fh3X54uivAH+>=A32`)pLAKjz zxH#H_>NvDsxM(y~a-xlmi!BLBM@LRXPVAO#nAU}EzJpU}ml4qJD#dvlrd<%A84$8( zwl_Yzta2Q(s@&iVN?4}VRn3L2>^@ZO6@V$ZB^Iqkoo?slU*vE1ryI_KoZ4s35H1+crcJ$ z1QSsG1Egh~Q^J>I5La(49TZkbNAoo)Afh+M7JZwF7IIF{%d_H(vQVmFxK8V>EEXkt zM21_@Sv$XyXV2UEiyY>1-SUcQU-a!NWW17UeVORmRFBH6HNZ7i8a57j$gtOb$g+Gm zuye4{GCxWdS~`-qX+PD5&xG(CI=&s7{Lr(zu8$i0 z>Qbs!#KX!tSv{GoWsj24K~lVQpsG4==wV1g;q)ntE>M@2a?~fJVZ1!!$MqfWg6ZRohqT+sM7r#kTo!z6lQNP;{(+a1e2Z$Sbi0&(+ z;FU>6$9~SzvtSO|v)bj=-R!Q$k%!@UqU`K_v7gEQENfy8qn@{O(9Cigshp}A+3)3S zl5iEAi;r7@Ryz1mnqVW3P`|yT)JnOl-BV~iBBvB5Nb4^Z0cT5VOAlI=oudUy9!7y% zs#J^S&e9wM^VlTV8MUm5GNWZ1AASw`eg70UnA!Gnp=d)WuPpNRX9Ql%Ri@tR_j$RGa0&k1qWZpJr( z1AI;cF?L;evlhW_1eBz2>Pl0^raV{f>A#DeH*c)fER!w&0`zL{k9j}U z%CH6b@|pvY8oz=;j#eAo3u*) z@XgG;qNOD7BP-Yo{%CPmn{FIk9YBM6ges6h(=*xp$`AyfTarV#%a|T!qx524Q(~^E zo)vnG-BQ*oMK-|}XDm5*;qbOC=D1AW>k&!;2oUzkF6)=iG!jds##XEkSkIAYYXCKQ zu|&(-*X=5{JZhGe8Kt2XSt_x)$lhr=okPHEDLlO4#KNUJzpl;GtbIqREHO`$?qRhD zGgW5!;sjAj$;JpbRzvIld*kdsJ7oU-MwWOMQ*VX1CGoqQ27k650+zM4D?`i5&2(AE zLACzibJ4~}Pl^w8Xzt&x_?TfR)TZ>faMsk~=9P$a1%xj;cm!>+7Hz{FBtx!q3QscD z(4;HfUz0Fk zVfd6luBNOfguBi-b;ui}Q%It%4&rI1=0Se>W(A}I>2WbUh?-z!Ojv7_UP>xy_Bh#| zI^B^X;lIro5`npsH25=7&`Hk}X$G=(OD6f{j>7X$nHfe(&I~$KMl7d}9kmnBZ`cZQ zW7m-svqV!At)KDS&5r20y4G`!`G5jy{hir9>@wsiM{ZD=2GJ$_d0P_5qJa(aNc=2E z=7ecm%Jt6DAo=Y-5o9+6aDr!K01+rEkh$fW%2by zh)Kdy8cLF%@?*~J`&rKGR!OHPzf>4RH{5aI2`Jh%mg75(e^&b~C5s(p9?a^`LoUnC zrph5V$iYz7C?&tx{C*CDNCOzq3Cw4Qa8~rPav)QgEVYfCXe>S~B+5<5$ty9eLPEHC zvV$b88XZ(zT>t|tHCXez;OI|{HqT$QJG;)Qp?;!!Do)V=Dmj%rRWTJ8B2kH!(b@$L zl+h`NI&8-AX3;n1f4^BvW;X{430oOb6S9IN_TG|eU#GpjebcE3I?A;xIH8&387{S* zn1ZdM&HF`w*aXHfX?;)!+6aY@2&nUA3~7XEtRP><;K_NehYfh$g(ujc=G~<&I$aCo z9$d3zu7|B-^dg0;8RJxDRg<{gx45_hk^`pfeQW*tAHRdT_$?fl)FfvECP40;8`2M8 z^QiYt&B)>rt^!u8a?;CX5U!AUu$!=CY3ER`X!e#}WKX-74BJi}0zvyj5|n5>KGi>|@r)?w`;DCtyc+yl3x zLx#bI2$oR%0b23SF=M7lVHIHwdQ_CD)RCtgR@)LQG z;oFy8S)&lX3_Y!VvvTeB4dNL&HpBT|*AXD=?-;xyz=P+&H?w|MGk?e zdc@{d=cxL0jR#*uY44z&c$Js6op@E8z_E+j)%GF1$_Cyw!a9tAobS79bXW}p-d+xI z)aCBS{0P`;@fkKOc7A0v-2QFIYaFx$`mDyg63BhnVoDCu@kDf{WBG<9h-uK$miEqh z6C-3>k(E##WJOrDvvI3~8X#)s+Kz0Sz<+zbXTS3l!rG#o^~zl+TkQA`#uyf>2mWB2 z1%5=VNfQ04V_+x!JmQsXm3p2%Uwj&<$!N&Col-Cw09?q4RoMvIg;RNDS`2vTIt+fMUqDHxV!wJxj zo`D0Y6rK&Zj_yW@quMA7VPGOAJol;`e?xY4CbmkyT$+Ropi?4Z!AS^9S@f}r4dECH8hppULT%bv$$3P z^4%Gv3i;epwJ6$tOnuk{YQ3gMTS;VP$Y~qzHyvS&FJL{YrAXH z45i6QwsP%VCr)`L5rJdYS!?jIe)`N31G|x0lvYj}tmPv#EVgs^B$=dYSs_9e?O`*a zxz@MI&$X+aV=Gm{CHOCqPx821DvF87Vv(A zU91DE?Ivicd2t{N1H`QJm|0H8?7Ybn4nzd6=rc(QHI8dI^PkUr`9~!|QR%J(AIa0b zL4NuA>sxk>>7zPp5YjvY-+XqX3_@ns&YdKbf5*-t!F!$6O!Y$)=hjzmCefyvTcHPo zsdTB$XhzPE106v>xk1K^0*a-$IHqgMg62*H?__(H<5=C)P6}DnkqJxZ4#6H`3Ba9y zP?Z)&qL^%U_BT~YnRFqaTp=H5x<;a^zUS|^++WFEQgPS=_Oz;I?zx66u^bj$SWFq` zQ-`fO;eb+n#fijW2vQF^OX0_qe3IiOpn^i=Rk{&rq!IRwj_+UTNJw+Ca8u9832nWH z?C-X|24U&i?*>IFMyK9*`by3$qYSbMS|#fG`~?_6&Jylfdcd*ab{8XzHsUaf?Dadu z13p?At-uW}Ajk=p=25On$KujAZf17@S^!5iQ#p4cHe*lPMD{3u3MNPP zF@+$(&iDl75|wv{?OAi7SP~U-kgmEm%7ilo-1;ZI;e71k6z1izrKSz1qyft5kogG+ zq`hI{i7XFXqOR7|@x%-d*(czFKfX}Q?D%I`x%r_z#02EbUN5R3S_jPO&!`r+P0g)q zCYeO>N#hByKfU=@CP-M4D%Gg_JO<8nz(kGWxr7le0pG1DLW{Gz!l48X0kO4gz2vf<2m}D6XnoJ)#;;`^ z!B1PgFU~XKmsOZxFEytL^Q-d9+b!80X=h0~=ui^b=yI^;baiClRGr`NK1C=qf_Eps zv9PwQ*`}{3<3w!*?C}@aXmJ>GXzsz63nV2XP7-Nt9>TzlWq;!_uW5A+-OxL(JstSD zBt75|26T9F|3Sih?RoA^LT-4-`S`cx{$Wcz_#OtP*gN9D(j?2VyK_Z&Av^(*RWCz# zZ&IBZoLnyRQo=G?oz2s&feR9B%xf)5Un-JWW2HSN1n{4AF#IP9PB{lFGv%%vIvkCk z{J93J9t^sLhJo4sTMN)ypy)X?PbLDyEc44VHZLehm1+PE`0cRdYm^o<{!tPyTR)u7 zxhBJFL8RepEHz5MU;q9>r!vJstUXI>J~Cd~gcw$4NJH=)PRb*{ulH4I>D<=I;f(LX zgUhwD*N&)$wv5%6JMSR6xvo{-*Fky~=lIx5-9eCpR*I1Q21ZepXa!JAhacvbXOU7R zx;{1h+|({ukFA_-T0Sn_G&r9doh*_d7K6gOalCV)CQVzw-)t2Ng6gRmfIkzY7tK~r ziG%jt=sStfoEAY%RQ^IjNuyrN0KZm4Q^3S2(`URfE%sfyfZSZB=UutA+1WP{5K{PmHd zX+WoVG97|jEgaa;?Dwn5;y5)L@1|uAQ7MBpi;(mn)G-t*k;p{wN2*ro#N{8Q0`w(W z4WtO#XpPPPgiXy`f_cNpc^Ko7Om>}X6uK2G?j;~7l_JYf1sGTkVo{Bn#1NM0p}i9z zD<=r+>(Y7sLZlSOXSqfDy)PP`{Su3eQtXoTr@jm9N+0Burg32X^)j4BD#@R{E`Ts! z($;JQHCJ})91;#dW{;JDbn)N&Ya04n=1tx%kLeEN;*UH6^9E4Wp?>4Dv9ZN5h$_v0 zo=;f?q9W$3^QiN6ed3v=q{O$q>QRrsZ-nRA4xsU8kn!;mN6)v2G3Mt@!0=Z}E}S=! zzZX$&PoZh6W&26w@$E-{x4cwcLIAw>qPUuxs@lNUK~|inSDV!yM6;%1$+2x_=m`cu zq*vM*;{^9|`2-r0jHFLILD85S~RDDGK_v(Kk~&1`Th9 z$e`-PV5@uZv=3P8iLrtrn%Y9GzauAMz4pkkpoHpH&ab=+=PKqamN*=G z2h;q==nDkhyHic3HVj`q!b!8ZQ(p`dDT2ehoXKe+i60vMC7vL8IV1u&41cn{K9GGr zOCIlaNCaY)g>u(MXTY`!<2YGoVH_KbALW38o$9&34;jhA821~PY#UO#9iy?tFxeBt zG($zYgp_KHl$LhsLwB9q&6J)AydtHg0W<^@wdqlrIPEf+dgQnin(KK&eOI%hhsSzq2%*wCZqx6crjD0&oM zYps1ywDaE|(SEUe4R%6Oq!Ojb+k13=`PAG(=mq>jSOM-p8r6}#PC-(*+AD>YxQ;$2 zrYGXi(r)V})je}`!FG5il!sZQ1&MV4>m=H%cuLdc?3VB{Nl4TEUbCsoX!=W|MpLM};6W_kM6oIo8tNGZji%U=L51$p zGG*@6d6uuf&!arya60?v&sFtD9N2ij()?ctEB=Cg1+oc+==Uw_kh0(zed=&CA#@a# z`I`9zrOhoda)b#+8yswiopB(FkLXVoa*j;Pg(u7><%k#6% zF(a|Wo{D5^Pk^U;ZgTc7l}^>6C|W$J!A{nk!Z~FrSh23%di=u{j&=eU&tZc9@G*h4 zf~ej-*g>TS5k|a&q=Tg(@q2<$l8BXgnTR|Zz8FR(8LY`rQArP35q;} z;QU9Ttao;fs8xzo@`37i+)b@fL|c>!%jnSFiwbP$bthDfTN&8DT*d&0|S& z08+|dYPOBmigv2^K}Q0%G{%to)VQ2nTDl^~owtR|hd!>AKJsLNOplf!)#*Y?oR|N4 z<(tLz??%oR-Rjf^Id)EO4OYgkQT~v82`;!95noFr$*m&8u4X0#0gcqa8$!GrjDsfv z^u|`SrhCL31dL|bx?0#;wOc%?&ftz_Vl2);Bh6!m!`}C>l{5I3^j$9?Zgee(YL^(M zG=9u@jta{=oV$jlTaPJd8lFG<#6H8a14WpuhQ$3v)qg z6#fmN4x6gy;x}$0QzDq35=P1&P!|7`99VNykDJPD=?Vnr;$su1J5GEl)>L(b-KTe7 zCv8}=E^Rk)Q~mR?t7+VFh1zj+?wY9{fX^@IgpE@HG_m@cN~)#2VFU#R*`{XQ+5&-6i$#`YJd}St(sj(AE37!9aIeP>kn0!*NV%H-w2U-W z+xDo2?i7^d1CqtL-|)&Tl^L;1mqEmMfMt|cwE|_Q2W47{c3zWrBWzf;c@`I#6XDt3 z^bSI0TUC{f4nw{+2X+l5MIm9Kz3G~PYYmI82%Dq#f-;qg@Vuzwd>-{PGD^*|I5@wlke{)qlZ8bpa&JyqN*=JAlSD{OP^xG1jykqO>iK&c$A3oRD>-C5MUrVi9{xS=~~wsy5v-r$0oo! z5PQjol#cf>@yu17f{HV0%AmqR1jg%N-yw%2yDu`d_MNSUOw*=FZ?5psn|@Us$I#0v zmNH)3k(N4I51P2rH5dlwV_~&>IRvufRb9p-0fN-G{))msY}dL+oxou=SRl*gdzl3O zTv$K2XBLa7L+-OL*)1p10}h!{(*q3zzrM?j`>gT=mkBifl6l!2J84g&U9ycGnUnH1 zYaGElxqB7h@9U`|*{#o~*DSa4yjX)1Qdc7q?Q1{@qMfrVt#PtR_6NiBdLQu#tpNu~ zIUqIO)OG~Ty#5A7O6;~O1I3Vtkj~RJw|D=T&8|XkUrkMHa{Oxd2Kjw+j*_!ukeXdh3>xE=(j~{Y0EKZ)@T9?er8QIOwa1^r(;0%FQ`lwa%pUcp;iJXwzqgY z*;Mv5l_+G4_*S$T?Ccy&c>?Io9`vR5R!Ap0G-PG#hYqsbeVG*&-5(9sb5uE1#Rlek zS{7B>wI6rAr0f`IT&kO9(9*ZPdxMER1ge_2+`T#iI0Zq|$mervs{g*mto?cO`(5aX za7%*u(GJn&ibLIx;^4Lc6$M=`nNSI@L9iY;Rk0+4%|BKF09?gvnJnWnnqkgU_&2YMfOIL$rm4F0zza z)`;Q}Q$B?G+eCt|Y1601Vt;PtTMZt%##(yCR$IAbAz%ijhLtVJs)mhO>eC{o#pbJ~ zZ4ZbgKO$tS<6}XmnQm(`VGSV8R)s!(Ep9^$8=qTZVAc{V5@$7lE3-8?2xr)LwO^;F z3o~U`O5f)#mo#zS!M98cvoP;hp=~u~OPVdQ%AoV8@at8-ert&oOG9H zAx=A~z-Be(t(<_0%ZO|w(c^mg_m{iUfP#DrEN#K9Y6iC8834*1U(P5)bUF_tzEU}+ z4Jpx)f7i7TpG8@Y9bSoNWQ`BH6r=DZb|TA{r~~!(8ZEMW$Iqz0+gfFexC#yZW}-UW zs8ece8a+}D^Wc%@QTk-v(&JYT$RSc>#mAXI#Y^h0H9SJPpX z{UqwHoCcOQj6?Iwecq^O(d;NV=6KX3v!>xPlJA9Ny0Qulb2^8b`77)}HqE2uDnBlO zDe=3-J2L(bCWO?bc<1^OwTI{qJ=;gUkJ%ozglWw^JtO2FL}onQccgz#spl(~s~!y3 zoN17y)+UVUd~Q9s=RbtE7(yQ3II#V~V~4y?kkhrBul>uFPRBr4qw5XN<8_?#TJsue zi{U<#5HRT^+1Ss-1H{#A{N>s7>yh~WZA?OKB(>D509C~|XhHv>Vz zDAms&?9op@`W{UQtIFzTdhkt$l#h6g(aG5z9FvToz;JQ-fdQQcFZQx+0Jd{0DD&33 zY3XTEV5xP_@=-ax&;3ABI^I1Ooz_M~2j|qwAe;=P-ye$Cwgy9!JuZ6#{4hCMmmuxZRn+|t`XgV$*9*(|Lp6+h%IlmuYEUDU zm@RJG=hFH}-FM8`a5ZLA65M0a8=C?HfJ-Ir`mc`h}aER{y8S=qBag~uQ(SzK)U0wrO4jIa^vG=co9}*xnTc~_Da<@nOa|&J z4J>~*2>TOYj6d_M*x^J|(cW&>e z*A)tMLQPVwp&?J* zgVH=c>eOCm$B;PQyP+o$AAM%k^QD3c@-9CcAAfn2bKb!-;gGc&8?=KUUU2CK5$T@ zBl~T*vPaazWcP?|U|*>AURq_r*?xIkjBKycpWAAN&Xvo{V;oJcVG;EAXMZe1bW_3B$#8-$~}H*xbJEjM?g+LlItBn8oHr&$n@c4J~=Nk}*O8#8}P|8Cb>{SZXZO#fyQ%JSDX3aFarIhI;qwr1YiFsia?f8BE&J|TvX zBIVUE_Fr}_#UhJh z$;&8o*2j$vZ9Pq5<8|)QwaI9ME_{j|{ROtd8wZN~y*JHXF6*V1xap)*+lL)E4lugz zf!=&OBmKs`8#E&t+(w1#+od1%k}M9=%5`|{>Z1aKB2D+x33CT&`J+XI_dy=nyAS z4vlGRT}$he=AuEQ(w<+SuId+mI%4(ZfkV+jh$0iRB&k{x0JL%Px&06gu!5A1$Jt%n z)ImAw2mB>%T?QL{Mm`|-vdqHh!w_gpu@q^_43Fx~y%rgsm39SB#)kUi7kj{fS*2!S z)upFD%XQQ}Fb&pRB68b$F`k!-hQ$m2qZ}NMqubW%HA11GsKEl?xX|QX- zbBP(8fUN06T`&sMaM3?r+^dQUp0gJi$(D9ZuGwb#PTyGf6QmaupnY2mCCgwND|ZI- zrOVU%$%$tm*txdbg)!el2^ASleDRy4#)jCpM|YW>OG|VRm#hl@Jx+J~=fd5TbZsW# zTu8dJyJ-W2BF^i_%UUPMI9;wKNWI2scy;2#^l+OLo&_F($Mqh`0~92b>m{jNBkF8x z82rpqk{S@Cyhu8&f-Sxdfy&X{KK5Pt%(0@SrbqC}e<2xAtGgE_dks;4?!qJLBGLH) z%5ic5x@yf2y=r25sFN}VP~@$n6_+iXZglw@R%^SkKgBwwu!}jZ|L@TZ;6df zNwBV2Xl1qhKrf&y{+hX#iiUQ=yv7hIUc);mCeSwtw1H#`E4U%oj0HxpFSapPgL|lc zjv{GngZ=+u28OFJy(xSZ603H+7WtEYbrrS37(9cZGpP^x`&?Lw`tuq-=LJIcr+TWb z&MQ9G?||L^R>kljIf5Nj^J`nf=L!(A%tY|!kT|Bpa@pmcy!r@*?YHGDcF`u8SZ=ay zFK&bwRI0v=FFeS}Qjo+jQjLi}V-?}g8+>$8IY`?eb(}72Ti?sz8n|hLp<%4^06mr% z7>$o=NQoulmO9QlRSC|SGN%^^-*??Ma8jQ#UTt_MI@;59I$c})6*{;`9$nA5TwGaD z?5gwuIfiTj*N~d;{0}82hupgha)S;zdM^~86azyR+`~?UVt+sK?$$_Xt#lEgm|&Fg z>rz=vL=ylw-9EmQ+rVEp58))oU3f`sI7UBuv&9yks}+#mT6vMx#yb0!K-f<Q z&3ynjp$FF{>*mijJRJaF%Xl=b#>3-pRi+P>f`dWsISe_2Cud3J8S>_&-w^&?c0CSR zvMP*Os?~pRAdtSeA^82Wife%E^ZiiW-ipUwNI)NiC<$hx6+%+ql%=in@Ud z_kVYn-{X+V%gx0lH&HQr@Mn>F>#rV9kNP(3Dg7}+qjwkg_nq5mJbFN&8dVCIB$@Slzvub7 zyJRt{$Tx_-8e%3YY0GKSc4EALoditHa?UJYE}t4caq%-vtn9)%@e>aZGKQ2v#bbz}7)koDEj zk`L%qK6l{!+tOv9{3KXuk|=Lk%Yq(PSj2$3mi9pi&6)Rfdbxe@$ZtG@6lVabsoWG; zz2I5@*lHM8+HXBP>K=9XZgv(x!vGJ)v!^c~ox{OhTr^?k%B*^n8q`l53Cn5=$(J#; zjd1BAOATc+25MAIa`14ESt=l7?4EHVLO~-TZGM9-CX*|Evv6(=;#$}@N}GohT+tD&bIiDCEBKjp z#1@%n-MJ?{6VFcpE@%SrUyZJl6adNYE&V<@U=Z>`%N*)1YZ4L!U9X0eE;EUoiY z)0o)L4|V^VKqtniy^f;k?qdt#Yxb9GF@a_Cr9*EBnU%3df=hIt5vv z!Rx>`0D8F@Vi0Qef%Wm)!$g>|zOR%Ni(Jm~V6}|%IvGRcbd|N6&qPIg49rq%d+xSw z&_ihTBB6+ZZNv5uT$x#9&^ZlU`lM$XySwdi?x1A63iO}Yv~DIa+G@zmk?kUk?Xd7*addQcZ|qs?iZjkicvr!mM{It( z8(qOQ_!u^Hg);^X?#kyW!u9;|7WYX(RU-FXwlqIDVSjiZ8`~l4{R4xNY0z}x*%M=v zw_Vd0z@0T`%d_r>EII7D4We0vn>~51l4yVscsY`*q8R(mf~b1Nf+75f@;9~I%Y#^-LyOfv?91^PI?uR}>JvZkF-y#a!2aNNC> zsLQhDH&#j~ChA-ABV`|v5-d34=FTMd9j7XzI1UkSN%diJLMZm&Xn*BxD$61l!7e(p ze6N9^7QMX+Y}T}?$LK>-u8nTpsubk`$Du42cGzEYUIS^MtYf-T6nxpp7}3)FlqTyw%MZBI5Wu# ze?guitVh8ENhxA@+hM|IezEpH``Yqk6Et{*^$Kl{UUyha;CkYUo5ng*l9qoAdd^0Y z-5i_|TKlAKeLy2F7OJ-$rA875+Jn0zal{ns<>#Yl*;5#= zA@jvWcl-C1l!P+`_k2rkhmuHi9v5oBFp{(FfJULz^Rwou0LoqrA;Lbg^$omCn}`yf z{ijH`g8&?2EfD?`!Lnbkcj?flhHy5Am(SGy9vo^r{O=h=-J;6}(7*C~r9U)#>$mZn zaefYvPK;@KZ`l$BOrvdJH5bXiLb+l!BakF91kA}RS}?*>oi=nXZWXXe2?bj(iN%Ub z8_RNhFL-{ZbUFvea%&wcjY;Jx&@GSWBO{?jj84Kk5XhIy5=LzJw9=tJIocn^a@nD! z`vVuCHK2+6!!CrB`|&6lcT$Qkp}h2I$r1&q`hqI3^kjKa>m;mv>EhbH^SBMw?D74R0FCYgK5sTuYE_+cPEyfmfy1dGd9jgzrZu%S%6u2+`?j-LvDM(D1fF!QXvRElp0T9#wblJI>r% z=f}$%;IMB^wc#$!g{$rY>5|b+2_v=Kw^cvIgrj-lD7)5yftpeCO~^odgmsx_0u=u; z$Al%d!20}acx^|fbQ3b<7q5Ls`*#Hg2goA0+^bh|#47Taa?a&FiyP7F-dQfli^qqe z6iE`cxtS>1BMCROBrBOniZ^woFRas~q zX|2Jo_oz(VBtcDlwTdBzIf^B)rH2hCuX{%@~?=GBcAP2^2XEKVooVX zuFFA0XI8(Mh8+C}Rplsi$EkBmY4e(BI}Yy=XAmdmCoee>xM977uy%otk58ATQ9)_IZ<99{=57j2d#_np^H%mZRYlGh2?<*Op^i#*TUEo+f zRbRaLXSH3DTnzF5p?I@Gj@XOS@(=uI0eLzbAYU*FYhn4iy{0pDCDajJkinRwzSBeK zSZ#l`#PEJD415zcN0l=s_WSep!Wf$2&*kmA&ain@Wh*k!3wWu^AI7LD2E_%^$a@#tSu@;dx8vB%MuckzmfqHn*v@CMkd zk#No};(dU&;qdV>P;HxFsHdIkRiBnV<7{h$yF{dbL;*rI@4$oFM_oyzgVK$%@_$@_ zrxua6ai?dw9NjOFpE)gcq+02iWU44Gz^RG4&a^u3D>p;?;@5qHw~9QobluT#hZYqE zI*xb97#))Y|BYBcu2Upjs$t9l0@-wILh%^nryry^tc71GBgE+ix5Dmui9z7XAp3yTs zw`Vs(R14behAlUyMfR=;C^0>8N~HYEN`A!MwnNmf99U`@Io{51F4aS}t!bReQ%H7k zcK;+l34asHM&`;nvA<>ZJvdpAOJWERP?A8&AL*UD;iN8}fk{Q@SD~tUkrntwHbT~9 zhqgZ!J4iE+2%))h>kD0ch0(?#7YzWAZ$xKgO&a-RyR6U{@ z_~)G~_4nmWAIjzS(EK|8DNX_j_PuN6V3!Vi<_8$@{Cq3E5{pq_JtLHtztUXJk51)6 ziWF#utfu&hOnop6mbBh6R9Mb3af~9lB>f;t0T&&Qag_S7WOU}5y4oN&*MY}6nO<@= z$KbQua5^7Yo0z^ilERKrt*B^`AXND7T?!LEg0O82ar-Lelgal36uh|%FgXe>hgSFI z{n1&i3@JN(yGf&Fwo#j|*&t{AEq&Ag_0Sqx_sT`xiU$G2Eu#Z%Q34-O^3*FChy$M) z^u9dJqI|k^qq=dGpy6;C2r}W$U^0fAHlXJpHKcKP@hDow_^Nvm&0vvhIfU8H>se(r;yt}yy0E`K$Ax{rHx>nCUhdp+dpeho za>=&c_s}Jld@N-Cd$q2#;pz&2Ya1n(88bJm!6&^hqz5o+iG4gW=oq!Fh>R4K#uD?M zn0xXg%8LJYT=8Bb35XySV)=>Wv1!T%2b75voTDIW+;&E#&XFm}6$+e{v9pt~P)740 zRDg~70jOv?F_@?J=zDM9OZ>uB#aLKH)QtRg#O8T-L860XS9LNJT&zs7eej7{Fzu{8 z%ngUuS!exK4+zoNC=u>`8;TNh`grmr964U=8tQ7Q_t{3`&BFW`ruujB)TN zhKDLm+ELA;5iiwUDn@0zyt_|ehbNe|x^VLA=<(?u>lvZ{nnuszNS_AN4(eC#P-38G zW2YJ^8}P2GLlTvzL60yS*50(l{Or49dVUj-Bug+yie`Q5ZP)KXTUr(eNoVeV@Dz2q ziKGb$nnnd`sAJQIl4JQq6~4+^<0`qNl`Gwt?M*+}A!jr=N?b{Zm0&)sEU)jyRIYXM zsnVs|05htb?3@z{;iCu?zOlNcMqdzpdf;?)%oec*V!7(seW2@*{ZS;-HD~!lr|u&a z>Ri%&or(xOCOfwi@<1<_9YhFCFF;hP-X17r($DsWZ$fuf7?b8TJcdODnRViqpT&2^PTJp5=9ZBH7cyPn4}#Q=kqs&hLCiI2BV`S zE?g?EG60Gq@B4w~-v_*yttm>AE_4;hC77~OrFKVU#*w69l-HqdPtUc1_-lOdyBzdh zr5~{e$PZHZ_%gBaZpL}(AF?MEOX5OrLnV&8gqe_xx8`n5XO~O);Fypwe+{FjySmDX zw->&@+XzSr8OE@JXR~IsLZ_0iA`8ho4H@sp=+$~$703WSjKMw*M*la4qGC6n!7^zAq{vDccrj)TX$Ci|>0mUXg)Vjkbi194ky5ylYpHEJ*IGyYzYsOx z(zmwBrIbRRlKUEgAT*nomAf&-UWAJp$Ez>vL;9YfiHYzzZplIyok`Hd%@1UL9#NIX ziT;h18%f4IF)-6NhiyqOA7y>VF%dGf_m3o)Wj^Bc#xhi9w6=#1byXR|galQDU-<-1 zr)3F^+@y>y&Eiw6<}r{-4PcsLOc0$|q?_jmY46d|#hEa!ToUYm`{QYbEH^w&dO{{Y zSGd(S?upJ(BWLI%I;e!-adu3IfaRUB1KYA%yvteq5$@4Ax9ObO|7q7PiKz3^42Xq@ zF`yhC9}<9Ks$wNI02$;md;N46PTTo_kkB`sE|hFFh)`ebz+QII69)$ybII$q(h8Pk+VIq-41@Q*Udb8fgzaO1C3u=3S- zPY5FZS=K&H$G1Nh+TUwQYpzTdq&~Q=_bzg(qP)J&Sm#9Hkkb)BU(&Qr=0DAR6APaA z?A|GO-|n#cTa0ku5L&asA!UT-Z#1BroBcap6)%wxlo36=e|*8Jw21i_o5Tm=m7yyQ z;vNWu?dYtFyR^LHPF?bjroH0WVM)C5l0ckhv{NcBg4+6}88c3E5fkH6B2C1r6!|QN zihb5kO&c3-B?@6j|H?TFmk>g>3nyV(%Oi(RBU^54!=KU0wWt3M8Tkc~t&<6vmOCe3 zt%01oFU~m0spFS<{+CvV7 zVjpS^_k%5BD?L!vbkwq~bF!+gQCz-vV5og0j5JaEp{Xg7&xRb%I<(6tC-+PdswS_{ zbj1k&09iH&!Q8!Ef8)L}E<7~S=Ibs>WVu_phvg4c@i@TtZ}K7-yQlT>!b66~b4JH$ z4s`pueP4k9mQf}(dU@YLA(!Vg7c7MfqqD?1j@`%=3uV@dsbMX}fYlR_gLPf_wCg|) zII4cO>otG%#Bd2qN`jIokI-m{)WxxJN)tT4;u!>1WB_$}Czlu$vQP&RlqYVTgksZU z!@(O2rlw~23OhuDzDbnP3HbRo_!Xga_lu~tqngkfE9WY$Q%yx;^hzvN!=k4VvmZYL zp`J3FoSbe52~-rqORcQY`(cZW_P&$N@%c1`y~R+1n(oMISd=!TWFmyxVR-saJVPEW zJtUY{2@{zXW=NAYrvBin%rTC~HN+;N#m=UN` zI^D9}zQk{zii?OtP&MlGF;o`rt+S?v{~eydnWCiKGEt=6s(jO!YTFLm^dd?+$;eRS zvb4}3Oc+<(302T-k`aKNQ0gFq>@z^(8s9Or%_}n$zvg21u7GP$YyX2S%2ww_1aeimb<-I16&=B_qWa z7THLpSd{aFAZ&VW>GYw|2=>fe9&OV$bEN22gHXC%9uMI(x-F14nfKV{;ef8h$_TGa zcMSlOTWvW0OSSE4OjD`v-Z^PJB=9n=YSL+(J8c@kNeRNnDoKc+zvP6!F*WcIQGbtW zP2`A_U_4pk$cZ^~+I6$|N6)m`- z8)IFUOm*SJa9o|($CLu#sx>hCLvJI>fjQTZp*DIfla$W?XHgM*0bBH?MoffwPF9I| z*z|uTmq@S`d%WaKP9O(-jn~B~(rX%5tiGY@v7PggdhE@Zmhv9zAw^7MiBm%(PfRJqHR-R!$_n7~D%iRy=TSJ?)z$!$EBJ zdKe}2Z&{Ve^v}?-7=0C|@*)1KZ~CR|i5=w`{UDUduXASi(ihyhSh~5k<;qcHuf?lB zvU`}DBA)+_ksjP0 z0K;K7dn|f6+6OPqefF#8A6T*waz2)cF-kFJ72y+WTYwzj^KaJTJ@H9xhZhzUBX#*@ zYNyRM(xkV*FT8xCMS@of%sQXLkjU^0>il{!9~Lt`^8;Ij)H|V1fvxZM9-C&;y*yA`%%v?ERS3-5ZG)ZV8g1oMI0c@+jv-o;&j?D5 zqb!pj)9Y`)nXCD?B5F?bPb~4qS6=t~Dq_FbaTDn;m)|Vj6K)dpXJIJfr3&7@%)|o_ ztZ*T}$LwAtHtb$*1@B76&3fym>E{^r+kQE$9bD*CrZq}AdnE$tx;KlrX{sdoz_?21 zTC*!$N_Z7oSy2-0>*$udbYLs&3DSn{roMKTOHyl|)-+avx^@FgcE>C6a!ERyhK-|3 zWvI<=Tp?t&HKV^wtIVBnI0kp4Y;W2%yY!kc0~+Afaf&W|dn#ws-1DP?{VSciy+?$5 zi)V`tg(W>>2?ewh+4lQtC1pQW7Fp0&U0SU_SvysfNtGUuuAMC4<5WVy-$gCbu3369 zp;|fr=seIm<@SsvEnQ?C8)K-L#t$st8zI6_RVJtSckI@Sy)6Ab@i@FVzfMF+FzV|0 zdnaPAdROB4jN^R9`ki9!RhxB)6iF{IDsBiOat+CVLopsPfpVJYbwo`B{il!?J zVwx0xb(9y!qN!^r*q^GsR&|zh@Ym;!Ju*DJ7@Q_JI;HZFPiy*~Z<4Brt){t z2+aEkx$nVu@7FfgZwF{^&D+H!;xOZS+qns3Rkm35CtTz@);F7*MAoZKHoGXQ5bqoX z^(0v5AEbKvx#M)qSh$@T{IRoVw5AOa)k3{Cj1O*17}83hU$A@bnLh z8Kck8f_lJhkKITKlATY;er(dU=YHCj4^D|*Id{`N8+2Wote@R5Ij9KQQ3m}`hkPs% z)I7gW=Lc8SF~Lj7Uwe%6!;I!Yj=R9D`Bu8c@XBCR?-_I=DCvQw5?i7unmkq9EAne5 z9f#>ri>GpNzud1yhinemOs1*rwj;sB2hX?6a39xaCO;>)u$WIqP+`m}{w$}q>NCYF zSKxtG8twe!{t*!VO?xD)!>$qE_GblDCsU@F0$_xSw%k(kGy3Y8s$M+8U|lT~ypF|2 zJv`i(%gcU5@(ARipTp!q*}P28n6_>`GjEhW8=TW}bH`oC zOY@{#{(_8T@~BM zFnU}B6|7iaV|Nhyu-5JrI_F57yD$36Mvjz6zs&EcY&vLg+0nb_NVuQ?ulnD@lxbiQ z{8Byi2+u=?dMcvw{l@i`VG;Vc54abtv;|X6*;!IavpT_sX}cjp5TTHBW+T`H>*-t{Uzm{{a-hUqJXbU!ot z4;{}g{~QNoufuVoI2Me~NHlg{E5;PMKrC0|qNCp^SgQqbaFD0MU`l5oiY!KX_y8zi zSHU5u;hx@ne^SaQ+C+CC4=hiQ-y|dDFnw0cL^d^_0X?45ULJ)ch}MH#s7qDr zlS14vMS*OQ8aqO0>V4yCOqyQm$FgJu@WO>48cbU1Hc4zb%t&zED5FY|ZieWh$7f>c zAEro=k+y39E?AY_KR7n;jJEjT!4p$+Wgc=+-mRz@E><${itWA-xyBA}!NrR!m1Lw; z8@Gbkf~u70+Q%~Qan`n6RsX<}3Jj$Kbwu2WnmWy7E9+ic0b=df5EA}@UbrD@YR~3l zRdvUiyCgP{V8O=O93od}PJ61hEvc+rf+RG|u7;FN5!bm`&MrTQkQJE>o&40(*R#$a zj+PLd-B<6TnA+-hbK!GDLW=Yeg{nk`t*P2RqYuasD6@gRD-57VOnq7fwAWzSpE}iF z%ps~{1MJ3n)VYvLBJ(5b#pdZjb@YcP%wEfLwOUxS7A5LpN_O)6%gD4D-_MntZP-P1 z^g1_?FL7|K50{_lloh4+ZoEo3>qv@ak}y9p%0JN$S!zXB1d~4f=y;#4*>^QMu2bq+ zvKO7Z1OsRs_QhqyO?qZdeG!gfg_r7UMg^|-FC^6)78evO&-K2m$#u1`+b`s$a z&>9+D(A9PUprYKQ1cy&wOaoop((w2WA-smHBHAQkgTj4kxs};i)?`##Ngs~C=dDs% z*rm0dT$@Ae(mL$Tsnkm()rLP^T7O9BAJ$l)B0!~$aTI>-ttQ~Cvgi$7a75j8%-k! z23hM=NZ=l#?>sknw`f~t6@+oOySEX_n}Y3S+KU0ICLQ|X@^aUla`Z?@+AN_z2kFdx zVLeafRf_+;AxiJ?_(vvwEhgC3t^4db?T5Ad;*JWXilV>nFp^L{I{Go8g~6yHjVu2W-AYqo04C&@Q}UvtCbIMG`d0`#n*IySks8 zl(2WGyP$0evWLNQnHM#+LEF%46^M$mkV?sg9SEI zi`)WpYih24{^Z!&E7$0Bwu(&|wzIcakK`s0K|$0suiCtw)?^bw z{pPFtarp7JjW549I|@k?gz;>YJF1Iim7!$+j9)8BsDhlD0dmo;Z7ub_Ah5f5<~4Gh zT$doKB@iO50T+tW9>eN?7<@CKjlJmq*#dfJy@hl8!H!5vet?}t+tv9+c!Ge4|8}Ym zhTiqMjZj78ic!IWppS6sK@T|w%_+CD^^_{1{cVc#?*8j1=pp-@0<>Y-o0ET%vlQLI zSCk~GI2C&oMpt8NTKQ=Rz;0Z&mkcrhNJ(uoZxTR{C{1hQ`LSOeod-UH z^|buHLOx$cg9fi-+Z26xi-@Up6QS*I2%n8}X8j#4sP@7ThP5oE1Zr~Hhg7S$G25X3 z?thg^pP=DIZ~x{>OqPPhQv*2c?$FN;Yg**o!z7%Y7V%dc%Bzl<7NJ@-+mNFz{~OPbxf7) zpRYpOkbm(^C>+}S( zc~0#LMS}>_9FkcWl`a*cG{!SvUK(qThg5TThh4Zl5!ld|{#G$0{r7qCS8*e#S^rK# zt^%ikiW1k833FF<^Fei5NtC6<;KYYWOvHYQs+ZJw5Cbw|RC)xwVZA&sg3_2DeP72d zDkIf&7W-5|`d&j+KauANI)8}M0zN4W{+Aze-MC2jrHjSS7`}>49f+J%{MRJ&r8YyD z{I`ueMO9&($YJN4>m~*L!6X!Lh}kAJ;%qwG!k5r+hyXvh$41M6iEwdz5W(AP}F0gniVrdnTL-#URUmS$+6x!}l5g2I(r*;25@e9_$c_EZZe{XX{8R5D#etVL*SVSxKC`vqr5 z=UmK@3_{c#M^;+qb{dj0Bq-tEOADH^67fDG?=zMRP%>tp3f!fNgc&D79-zq0TQ_bJ zHfi}d8%tT?u#+MIZPOz165E!zVyNYjH*t?pjzO6eSsXDkg$JD>>6 z{R-hg)eCYXRct}Iu~1S}aUA-J9k-{8dB2l)N<#-JtYrx4a}~EVZF6wyO<5VnbZgr4 zZJ5$Vcf%w&QKEL0k+P-AgFTN28qKutChv~aq`rR{{Ke@(0XY2-rtfefNKDnA>-LQV z&sq|Is(W!%)GPz{`wtt1+*}AP$qdQulMzFHtrr05=42IcbF|3+U+L)*c<=w}_%}X^ zftZl-a<4XL>+2f}%ViaEB2Q-=`~Em5)jr zu)+fRN11xhPLBM=*J&TPX;6972MN#FQLh{a*_^-o3Cinlur*`JAt3OOz!p8h-s}ck zKM(Id81jze6`~Q&aQB^xnE7yY`F!hpG1p`J)KKX~q=+w9O zyX+HA4eGtl*xKp?zbQBRk70FxJ;-#do_4bV`W^#V1X!=~I+vw8ezfR3dK>^O4lEv< zaBdh8NsdnEa#2FiZE`3$kQ>!YtAZbRQH|0?J-+kQ+&>jEC2qd#kmXcE()@tOIrrA? zEsr-#I@3^O$omwNr30gVlMB-;N0)bSgd(cb4CQo)iXr2(S%uvdmz41emlJ6s4#EuX z|8W6qHaXg(vU7I^_`U}nsJ8Y6f=l$~ExfKKN2;Ol z_}B#3pFJ7`c}BUm?IJb#Lp!HG)nl(${$+E*PH8M}AL0LG(tS7Um`q+kFa7%#n?9dI z?O8H7vSYcN5FP!E;>eAt%3gnOO-W2wu-}n%R87&_&f{5sgSW3`A`z8Zp)<{2({vfS zZc$Nwk}IZ^+b8bSy^j_BXIrB!BW+pvNWaCd#a>pRWdqwfY62Eh41}DTm89ImF`|GhS_U(t^*1OTfDO z6YgCqF@4s+9)9?UbkM?$XcwGNk-y?)VIPd7@gDoRkL+w48W%gLqJd3^2`#kRlI$|& zWQH(zgxPnCKbdB9kxXodYcnEg;P%y}&nnTcQWU5>h{pA+{Te2%<3l}^WD`Rck6t@j zCW!)vmded?nn7JSk35!1xK=J@P!IDKmb}J-3XJoP(4)MfI%^6PBBH}M!zj4Jgo7!m zl;7v)o#06gA;q?a_ivyAmJS;4=61{!5U*MH#!E zQ<|$%RY%QF%4qTDH*{iDs9S#nqrR5Yfy{ts)rETpXP9ucnc$-RnDJVn=6*F;Q$ zd)_4lg5o$HV*u472zq`7@~A8{r_~Ssu~g$Vn|1_oEh1?QM}&MzmZX)<*O=I+&E$ty zdPfIMG|_I6n5v3vVYH|Q4eUDoa$4S3Ki&C^_d$r5iev@|*1fn#YA0sC554URP!Q0w zGEQ}q5^KCxk9AXqe%PvWH({VfTVvyd z!5&NGhLW<&Qi@xpK{GAx(m1u8S2yw!+58UY&hN@TAiV)pUFAdHKR$ z7YVP=#5LU`el3A3lZ>1YQ<9pSClVxrVicSLN~^}=GL3ABhza4Jv=YP>riFHX-;xroO><-71LnW}TQUxrNjjpW&3W=p&_Fa9+$yh*;NEA1; zR(wY}{61zo;2{&~y95qn>KG#deQ#O4uHBW1d2sGMzump_EocOk8=+%{+QV%L4J+}e zgiZ60WSL5OvZ20-yRs&iknS_s=ypoEusgk;bAW@Y;NW8jWbzZ!c|S#{n2g)Ka9DpNgQ@{PammZu)$ekH;`^;z^fS)G`5gsL+&AVb z-(MItRX2&oj8q(e;75a?_&N|W<_2Kae+QwXti|x2wv-RD*CA?_rup7eC6V@j_cLJTj@Na43 zea;XX|EWLDR%s)f9v4lR1?AebK)_k2vYJ|F&gH29(Uc{{JRf?m_&LxuJXW?NTWSG?O?YfbbG0Ug034;wgjH6=u zb_b5nIXmSND%T4ceIvH@L***a#GFjasq2S3^b53ijlU9c(e&oLzAf#0o==BrhFSDiNeGx~j#Zb>>2q0`z7e|`9ItcbSEs~oEp6@B%zrKF z`twH!{&e)ghy0v?wj}@TogxT;M1>Ts2ZMg{bxl-O1eK@nStwsOJwes;5X0O~pV0G3 zybA-NDIRS-{cHI6?FPX_nWKK%G9F2me_TE~+j<|Et1m5lekrGIp%Aapx%mG1#KO#Y znH-sy2R#g~b>45hycVtRR*}vSOVA zqMCsFUG-^_63-Kro!(yA7xqo9yy0rmf{6@D4VDK(*9RL|2USZ=0vC^y3U(g0%jYj`S?42ISPRS%!6N+zHfB=lw&t5?jC7Z8?0e; z5)Iq&L(P)Q74yh;>~8EmvPi9l%XkLX+`JULN8qi_I>OGzek&`(zc6ao7FuTh!jCD3_frhaW)3;EfRObda z+xBBa=B(b3TCd_%iLyWBVPE5 zHuA9nYz42>jB1yO`;h4Xpv=eIJoRiyaoxaX&JlZ%Ku9-uAF04;Shf8YWvr7OX`po| zPw!wsJ8{e{n*%3moMHD`UH(-q+{tE~Sa4K*(a0dIP;ZPE=^Fs&~>6s3rt1t z(Ak}YeZPlUWF{z6O&E5d|L3y;}NOm%KVL(XY)T8y8h$*{N^aTI); zEYxRlUB#aZg)LjO`C6)X7^r`8neVR0e%GKD&8?oM(#hJ>$q|Z7MLoK0&#K8ih%O}8 ziu%fYV%3Aru%`EVx5EF;BWPD9w5d7`E&%Jk??;B(NXsQ=g)g`lLO?jSm{>3JY+eFHqm*4D#Q?&M+;7~8g%^^&E zUyVnRwEB4X?plX9`M zmg*OdGA`iGXCiC6Y>|RdNwwjfoi+E3FA9!<4{6aYjR4ziHL4D`CvNcP&vgJR^6bf1GU zqbzx9O9+UEz1vMPD?1Cxpe?KDcUdsh;sxMU=(J9k?%`-4I2=gj4mnQ^Sk|5h5?A(6HXDoUbL> zh9wB3gj1&zlrWbkQ+pm9SKU{6bPL7Pex3f;4zi;_!pnHbNU51Qo+4{mTmTq$ zJstJ!&Z4t;E+n-5EzyLbD4Xde?$jJ*W4CQJ%#;a{Z?wVY?of# zISD~GTvcp1_PP22$I3Z`1lcpoGWM_MR0dxq^qM-) z#(5kswjPbu&*zRRPQusP%A1LA$>umE9^D4L7MZuFr&U#YM#X#qy3`Ky{+`yUmFHw@ zha$d~o}sDMI2@s!EXzg>guX5$d8=6bnN(ef+&-_ZA~Y zS5~%P&LM=BiLU5OQ7%S%Y4D$*c)M^i$&eHMnNOU2nGLuUSvb|7B2cj9#8ljZR!7D_oOpvceAih(;x zBCUIHw7Cp*ND?qcSdQY0oYeBLhB|v~smH?=76<^_dWe!8e{C5T2&m%&`|%U!Q%blM z=~*hvg>yngn zqlhZ+QW)y7HaaNLn5db24gc z?{rAQL{z!-u#E$2OGpxp5)kKEQc?}n8gVTTbqH!I^E%Ny1}TI+!#f7m6FQ|~n*_75 zK#9lJHF-$^*mK>@SR?@bg1cpYZ!jb!YK8XUu~e)x-{&JOhG!&HmJ@tf;`94+$ z8$uv2)Xyk4iaZ^n36sf916KUCT3x)5SIIATD>BkX3Ssz=JkQ7tV~w{F$p%_G2H z#M?`;vezLQ!vk+R(vwOKH(6yF`!Mh>jiNaTt0s6b?2zya*0AycCn;qIi2SCpC<__3 z@inUHPX-~;hPiA|Y2zE}i6n@Q3H2*hb195wrWu$Xi9A3_8Gckbh1ZX>4fQJ`P2c6m z%i}D&?vJdvIU{C|+Y5)(qB7kYaZMfNBvq&6G5YpbgQq?PM%80+Rp0AM`n7sp#<`NR zf^UmX=em&%>j27&Z^%x6kKCQl*1?>q2L2Fcad5p8Pb&Gaw~|{Ia~nrnEiX$ww|r;z zzn^@^7SgH|`>0v0d+C?-E|F=CjVEmG$`_y6LuoePTMG>s@!CfR{vz+GbHe!tS>t-t zpE%Yh*YN@{%tAJngxsuL?*6t1jqpEvXz@--zLkdlpKgc{1ypM+O) z=qU?h^XQmo^*lZmdK-53_DNoJ%YH&Eu~T;7AF|2LDp~gtaFsr2ga+S0In~Gd`*?#s)>_p;QlIg&@<#DLeRn5w;y45nr`k6vviVjmk<&0<|tq2L7 z{eX$9w`)9sG&X6Pvp*66u1vsNwZdEt*KXrxkvrw^Uf3scqLN55YlYk1y4ThN0RVpPzFR5Lo%NcBYlX=h+0G6K{oG^rF^YV|^B zBPJ5xOKtuK2}1n5uC3By#=^Zf5%=JD_X|Gc&BDx*DBpi%3~r&4BS7i^iM6C@Qm z>iv7APizsG-pZaz-+Hzv&-C}=f@W)YM2EAc;c8d7UG5lE9JT|R?p1y zSB-kaXd_Zg3eVX*9G-W0DP8r_km}%+JnS8syX)Pixm3M43DN$utaGti00lAG=0;oW z`fq%nJL@LPlgZY^0<=cr8!)o+e=DziIl`y@XGuF!2+y&oz^D&E*Y(y$o{gt2!$C(= zR^EqeG|h0JDDdZam?YeZM79bBX^=`lBwJJZkzTJ@T{w99BtAll#6_DCD+DC{Oma~% zw{Kb8B%-(~X0cq}znS8+x93P?MGsg1BcLMDc5jHoY`CkCfxl-x&@0 zS+#lSR0>)&_};U%t(;W<`9vj}HpOgra|Tv9f!(08x$jsjjBE9p`frnVSSCH;g7P}b z-*tx^ySD0$#7gS2Na3~W=+uiv^Z5;yhf|mvp45MK_9t zPb*2z)u^fMP_ChZ8}iZe=!!s{i3mXQZ@cM`%=5eC+J{Lrk(9c%8n)Su5uXfQeVjo0 z5c+)Fzl}b*DVKBj&+Kn$-6t%1v!kZ4 zY~g-0hHaH}`lxjJmf!oB0&5;9oup?x>SLUS5=}#eb_&Y6h+M!y)ZfhTl-86ZkMNsI z|D!V%tkO4IW>QvK?h+Bz_3JWrDbH{4y}gRqHVnn-CErG0Vyhf8c83vWlFy3hLtBT^ zqvd=%m-~5du=KNOZi^ElU>iB*ucubO$W)_wtalD3+T*;CPmaHOR)gpSQfq|3Fd)f9 z51OCIs1&-UtO-%{{K!eT?U(+@1b z;g?PsUK-lw`u-g=_x@n+)u6544aDH=uugHAe%4cX4>sk;y5Tb2gkIKZ3JwWvsP9@# z^^QVXWFPSzt-TJe%IUr85URYQhgR&SG}BjwwswpWvaII%_`iG<1tn?lPxAMA>SS#tToC_Z{|i9s@P2c+H~c0U|I z;`d3c*54QgGm-U57$+uX5_UGVjfMn>6dh@%W$m}6`(#n$a-UgxFAtnN>cUE4?G3XC zkit=GisHN=VmPPYBlJYd*6b>g8{Q`t#r_P12>@y4XjNC$;%<52RF{-$B@UDxz;qKl;~m&f%P zY|yn2{TW~HrMyNGM@X5zx!1Modrj!ntiZW5qULuj3TSmJNrdo*Bs;7GaGJo026bzO z{1jb0h~z-~h3@t6@8soyIF4wFQF&feFc_P$^fHX7keuwh-Qp4nN@PI+HElbr2@Nkn zbA^!wZ@cAQMqDD-5AgC!xLcl^C8y|S&7vMBl_mwY@^VIC_25odqmW)2;X(2d)qCCm zn0neLWBD5R`BIPmbat}E5t~B>OD^1VYpFenSZ9vMj9PWe^4QkTT3vYxkf}4WCf_== zg&|MTht`gcP7>HJg_bS&c$Z}DMPyANBnzSz8roqG8#0zUG;f%&+0Qb0Eo+XL)r_Zm zrW$%5h;Rk5Q%aNJ@KP*&F+Z`;3`}^?xOCxGB|%?5t5c)S!?##Lr?{~UrU?o@)vq?i zC#Q*@{*DqAS-oe0NDdLvGbr5x3L*YB7`rpg&)gw4Uy61U$Tj-&<1^W(9p%v@9`|9f zdA9H{_Ml)Ck|F-gtbBt!ql%xQiL`|i)u&Wu#4!Ej0DwSX+*qJXEW`4cb{@oG}I&@#Qacp0x5KPlo@g3lA)27pQ=MbV%RWd;&)k+;D=}KbvW=>@1v1aaGPSm?{VLKo?y|fcU&PD((MRN} zxwUM4h+D40lwOpsTCH;?7ap@b#RoSX}!IPanYA;As~L%K7% zIF2qTp_WaK#Cl6BYw9=Jj&I#(8;m zw~Tn!QP~H+ApNasJgEilJ3p~56e)Bp?SolD1{%_6-MK{#u#sf%eX^2Gr*N^r`etEH zjJzlwtjn`*s3&nhb2>AB$t|Z$KXFY}jS~-e{%u)@{O9f|O9|9PH)n(5AwEZ|B}Ti( zV#k|zry2WgCNz}&D~uV>z5Ki)`iv46w4|9nciy}`F4x@vvgn-tMtt#z-)-Tw$Wt`4CY;+jx!DaUG+fSwhNBF*YJl)EBT;$(-q};tv#4$FAz2 z35thp^wOQOLu<7;#>)sy8ARq2WEeEDtC|Qd-_d&{BU1g5HcH4I>Z8V$0$!W-7MggW z(GlwaycKx*7ev_Dt4y$Rd4C z*Jpqi9ilY{$6M8$YFBQOhqlhT$VINvN=N}P@MD}JlR*bBW=y2Vxf({UNY7LU9T=^e z!1<6Hgrm~w<-QKuCEL(TOgu-{RlR112}v`fDyZ}XjCuXk+gZXieW(?O@0`N~lkwG|sdw>hfI;s7wtDdx=gFMH$gBvzX|rgTRvj-9>VI zShQo5W3+c3a45rDx`!HdD$_Zyek}_Ja#;qW--QHNa!+8(u4?9>QAJ^Yvqs-Qd1k}sPRm)&2gmIP<$GNR7?Q#D!v(llJCR^X?sVklZ13~*y9(3^WMsAt< z0D2#cwb1uj)Y|P*-wd6F(EGbV_4hJHU{HyJ!e(C6<4x}U?10j~O56pQcoHDM|FO{j z+PB3wbX2NJdD;9okz9Zk3(W8PBA2`c54yQs0J{mFAczKyI$4J!z+TrOm-x4fYyq7O zl?-$VFf-&QrNEEBQ#oG*N)QKGP%Q$P?x${Mhj>5MC<2O4RL;N{+I=K)17yKqAUe2V zSaRRQ4~Ju-O*xo$!+dMv2G8Jg9=v>~JrlS{)C+DnT84~slK<-=DXnlkbC*Q!QF3{DvWtg%^hikI>>G=j)MTudd;a2IrF4Z_`)Sr7R9WA|m z6SrQlCSih@0zB-!(-ZV_N0ZczuCrE1V4i8h7%q`Hqp!X`SxI$A3z;V<)Yip`>;07&_e zHs#nOnM&`E-`cNVCKO$wZq5?DjeQgBLF+4SwTeF`X8EapBlq`=xJ~8mr?RAl%1^Pu zV@8i!k4@pV_pRSSN(PEAGUe{@aS-L7?8`#cY$uoy>}9mp4JFn(R%0lDl2_0)%{>Lc3gZj8MC~6_0AbJa&U86nZRj>>I^-G=N(As^!*m-XX3IPK5lx z5f)2w@^{)TAD_%~MT&+>`U$|{c%rd)b5$V{`UCgv9*$obd1q_uP>nptQ-iN;g+*G5 zB#+Qk>V#ut$IR8qGW~GKSgltIE)(N*K@E7&SHS61htpw8Ene2QkUbiDhfFPBzZ-`- ziZTU~WNq#rWrXCrd+!VYy*)~P zZp3G{5gWdjW`<0+!7ycmXYu=BIVZ^b+99UKU9r1)&#(63B8&ird+m)gwVBI948#Vc z5vbLw{#Wr8MO?^wn#cDai-&y~@P+YzWm`xGUyrB~~w(vFxD z8|uU*0LXukJ*!ZS3v7}O$gxng$;-YJrmV_(aXMc#VNOL`DLlXmWV{g*`if=+O#f7Z zEj4Dgqm3JMc@ZE8B3o19%((kTG&xaKDky4#9F6GQEU4wH-qX=P8>0UAkt3O{Za6Un zau~;qhhNXEhm*iGo8q(P^o|pg0pItLk?^@BcBuRqNcvE_9c~IU+vHt4So6x}iNR-B zCJwEvE$NwcmK>i8{O&(AXCCBq^(JwlE}>AId{DfOfw?6`@K_7I4Z35$hFi&M1({2D z#+3sN!?OG0?hU{FBn8SM8z=oxn^wI8+sfeP;lw!MAo3N3sVzhejsux7f+NOMI21a;AQVBlWO%?B3x%*}g z3Ks_r?gWM;KOw(C$ZX7ybx3}d#mh4)BWO-A3QyxDHXT0{p8DI%B8C6#qt(So_(8>H3-mAE3yfGj3|%_gfX_OT;xC5oZ|LJ+p|C zYOvxAb^z6v)pUf6$(@4eCcY=MPcx{gEox75sZ2mO{<|CKh6BxR!T3FQLpL2Moax&z z`XyMCQ0Wq3^uN&Mq(C{HHRDwdn)KBLf4hut!F~SKeR1t1vofr#&=nPi7L>_Zl7p-? zWu*0ZLU^-h_sch5+si+Rmon?@s5p=OGXeTSEnzj2Smmr^+f`_=RWSG_U~}tdvqGt0 zmHYzuXzBd#gPdh$2={8)t_9OvdwOs(`s(DO;L&dxV&r1cl?lY+S?LLhr^C*VkbVSpTRY$2)V~Pm`c^ zqt7si9+XHPltL+#QnO;@Dp;z;T8(9bWf^{=5R=9gXDmNHFyP6Lr{J;WTGFZ4WY;|n zk>`r7+Erw@^mnJjyiry7OZ|_q(q5()Vkz54JScGNDzCqS!R47iSNM<<`QU^#LSoO5 zimzFSFGS0JaHp{7qGC!;^gju)oUkA8ATQ&6(8z>YMms1y9>wHm!+eyfHRR)YO84(xV9O6WWFyhzz4gSW1_Pd}@n`@R_*LuER!=AiEhEplTc4@_c;QB5 zwe*x(eE}qjwFn#)M%2p1tj8%=kzqwYU7tqbL#w|R;O%FB0mDm?ba{$Pa=080J56lu z=h~MUKE1=$RRfxnjZbjA99|?aC8N`cja%yIE97|Wf!+O%uaO0Y9oP?TSNS#1szhAs zhJF{QHBylgM_3+4zLEFb#$_yHzdK#=4R=>4hY#&OU?r4((3kcG0$cCzxuC?^SOmhp zQosNw(KUZR%+lgEV6FYQX2-U6a|F@tc^s^D{<2n)!Bi3YYfM(#iFoTU=X*z8OOG~w z)4Eq%@QF;;26%AwbJT_cba&y=C6W?{+R^w`M1koxy$A}C$Q0_chD^CKt!}n zr@#cSzGe$njtf7NcVek@`?RIbJB6G)8})p`D2?gHX2B@-cBI=e@t@v>iNbPI{A1lt zxKJaQJw3m=7_@!ol*j)R_>+C^8u9k^?FsV5nH6->9Ucbln+jyebxn&~H*%bGxz6I3 zbb|dw86@&ZkMhUG)%|prQ)r^se10i$qDX`O77f>FqNBb>2wt>Fas0)jFK{nnDzJLb z_sf^Zf0}do;BWj?$|ETM^mIhBc=$hk(48l<fn`~Up$pQ5|v1PJ;6{r*2i#M)W_ePG{re{@K3_yIT>Y*T#8 zl=$MM2|XIZw|U}<~;5VFT(z>d;fmO71d&bmYe$?DA+W9YEyl$ zbpLf=3{N52GETga%bLE&DMPbNWcJQz*NsI04$0SS=lt)RHw!Py2uWPIuOv9mK;hARCCiMy#0#XaEnQcb(# zWq(!p(K_()eng0Mgk)jN+DjwV!XP6xmqb1(tfYhuBfjVn_g~#^H(sstzy+y%f1IfQ z_#VbY#6PJ3=hN&O8pkueT++RHP+g7T)y*;pq#DCQj=t-Kgo}B2dab;yZCc#fosHYd zVI_HZ|2|vDgfIL;r1!F-{kq#k!2f6~=w}qbblyVZI{sgcB@pvTQ zWM;<}SCzm-YSL;X5MzWDuSmqf<} zp(@V8Iy=>`9Tr3~49JjGae?*8Ra>Ky0Pnx!Mb__M0!3owJ79eMbBoYAl>Vz)saOgW zaFn~z!NG0ktyHC3M6CwgAhNbIDwv(uwxK2*RkN4+JCQHffV+hjgqF$AsKu2w&e!ys|7KB zkFwtG1W0mt2uO+Y^a`o&BFC$8_#Z?0+iptrHjVyqY(?K^ZIxUc%+dvT$IoWMHt_zd z#-icOMIFtfjmw@1ef^wX0d^3{2ky(VxtIuqazI5T*uxY|6VEZU2~xOKi-fjdkMF&O+ zR=9G6QSp?BS7P-6XKKng|Bv}#v+U}7RH_zPX)1m*DqAcQe_(1OFbWcH#P5JAMqbgFGub_ zM*Wumy}kTjJM@+{uiMy*Q=MUj{=YtnifnnMG5Hz>2t5x$m+UfoIi%RXC7Q$Q{c=8( zw0?aQA~>)-2|-kNE5!6ZXA{q%=3gg@FB+CajE~*2n_2#q@8a`pcvDOG9~u0gM(#9b zeNU0*mfnQn1GHFZT2Cxm+orFE#?HLnnf2vUX>=?c+lT`)jcp7QzET}>a~dnN5KF&M z9A6jWZC@B(ChG6B1c_bkL%&owxwrpszrh1FyMaEL?3cdLl1%eIH>*eM4u$kPfGpk0ZzCR{^!sFS4<_BG4Kul8})KUAT9BL8f!g0#ZNX?GDTHvxn8K1`L9e+ ztiQP_MuivH*{^9B8M7(ASxUqO=2uumy7R|~rzDus7$(GGQ`BbHX{c3!CoR1y=9|`m~FbbdU5+>jtu z*={Xg4`Yb;9X8E&Aao8d!NSG+y0y!Zn>$)MdL+7gz*K$DaaT(%ui>QKJW53k|F$>OR(z;Te(OoUkU^^EA>x{t71-WfO zf*l1o+b_DCI+Z}xaoG&csZ!20{r^k|)VcnLf{-yKROz+Ek%9hWwEZ|3H8UWK36;loFk%e<8kbajvmJGNOT#UHLWq9T!!d?Wjty3 zSYyv`h^m9^TA7``H>y*z-swKTDLJUD?k!X6Qw$+pd#Cyp<9;-R;F!~-GzNv+1t@2J z&C!M>ba>W`YPn6`d%E||l3D<~tZ7Tv@4n^=@4W_8eU>dW2Qy7stb5HBt=;5%Ip3xY zBPwYrl`zrnG29qlZ>0`2h$)*9&xXnJYQ~ForIN_Du*75js)nYvsoX48_lpt8o@}?; zOBsJ4gzTX-k5)HGKYPod$)L8>gso=GI_+OMm8-K#@~-X|b{#0Mvb8(ALZtV+!}MhR z66LZd;Qi7H<8PFvG3XfMW0-Su#ImO!As43`BItKBh95b(OcgF)(lVINVm@I| zM~ax9kcLI6`j%S7s8O)1ESMCe6?#uzUF2z-Tc3W}(nUD7H1>Y~`}vR_I|{5mGCNTo zcx@c9hrV-KcZCC$;!6=Jfm{fOz8KVY0p7nrN+}k1bXg~AX*B$0tJD9=ZYi|fhhnA+ zIF5NNcsxFrlBpHUGhrhLi+w20VV*wuW)TqwlAzDWmLR;}}-)E_$U^Rscmk!s> z5>p(*gAOcnav7DR0AqCuEp?M?(KyC2{YOzeE*GqGUu4LR8#XWMR-^hVna{N*#-24| zbLqd{YumWIWL-QDNQqYPmC1*gM^YLeHYx0VcI4k)_e|Bx$miyj!o&E+;+v75E>3yN z=yiibnU@e>!g6kx7;Tr^B=Vh1B%I)NR<*ubkIm z79(Sz%(-Z$0gT7c_iJpeF#@;tP3X+1CdzmNMX=byF#@4=Y6e=59D5g(5ROq^sunWl z3pkIg579djRhJC6%8M(B)^u@bo8qLy?el}U$gR~Ie5%h**rp2Y$lMb;BXq_-|b==IpfuH zqD43azVyj%tDK7Bz4gX(7Nz|LCHwm9KhWR+d6>-3U+Z&Vg~XZJ#MWI9(bNdZcjB7NGKqx1wzqHi)D;1?ygzXxW!HF3ecU7);DzwOQKWT( z@L+Z;YRcrs$th;C5j*>3Z>*=gAhM=+|C|%UOinod5D8~+6(yz$^;-*RV2$&kgU<#P zN?yVvhk9j#hZk}B_^fv0)X5_ag90IACxK4Rd0MGVPy2)Afz0AsjV+(ZTm>M)w0wR_ zv+smWDUb?vQHJ~M8*65rNg=eaY@6vE6nsBKsYGzQD-0tWsTZ?S2Wd*ijGXCY8TeHK zb*>S=1-Ysbl!Eh>m+;jun^Q(FKus;rn?e&v&21O)G)4{r=^T?ml0lCx?9AeukVWf7 zu@Q1u8D)&#V1YnCSng$%4VmxE9d++_mpvnwIcz)ULz{fQEgJ<^r*If<=(7MF;UiL z*NzKS`j-0MaY%4OfI=a*j_wGpr-pbeLLSbdlpKt1JlB7=cIucD94h5 zLM>AEFp6J$_OEJ3zZ#Q5EWqP}vlm}Xac}*EmWlD+@SUccvvT~?kueR$xvjIKZIEBj zywSGX@fs#GnBdp9$i>H>?G~Zm*4Oa_BZ}-#qWD0bj6HK6K6&^naZYA#-!1(Rwqipt z^+`jkV|waRvwNFh9+M3sOr|5K=y&dO(*MQ+5Dm!cuO-n_M0gWK|Jc-7+b<HiAs9CVPRC7nswr13eJ-rKWMH2m;?xlOkh2;b+!Z(@aeOxa0!9z!SIq} zUs*?ym=PUNHP-YF7m7JH2|}wLkex!L-hZj@%E0VB8=hQ$T8(UT_!l33($`QK0|K%Idb!MQ&VFFi z$H!AbOirPit1(_DR&(M$lU08kbfg1hWE?dh;p8$|;0@ig$qqXX3_W}J)??pz@(*1K zb>x=H5*?Yfz-WF$XZLvgO{0h6)EMc7CseR^JS2deJo!Dr-wuqhox1ci=$S3kA1usL zdk*IUUR_wu$FqxQv(-D@jX;+X4HA~7tX-y!d1&Sds*_oXR3ER2CMv9v zSG&`7=S$6^m(Gm{%MD}fTl^FyxSE#JXA=t|*hTElke>Hpm_)L@M z5$KPnqC8Jq2gVbz+b>Kx4?IE>?oO))rF=!3XqHb1$?0FcU0p+AxWW+c;D}Pxbgt(sT~c>QgCTu=v5V6o!sRwp!jqRzUc2q)Q_VreSH=YrVFx8 z#jupl8bB_94;KE6SW#d^tsa#x_2sQWfx!gV=ni%8+OIQ)w}aOkrn%QO0$8_ythD}m;q zIF&zXW;xQ13AhiF*KJZkJa15J#YjlnZYw|)cQ&wqzetqLG>L3I9uEN@6?4HNS^1W{ z?G+Z6PMW$bL^G#$=&yZ=H>cX> z!F|A#HOYOt&3CRQsR8aS-rC+y;%&5(*E{cQwTa=P;iwGuQ@U4!Y6Z#MLpqSG zoO6ALKQA6kzicC6lerVHdrq+k?~Z zS^P>_hpe9q&Y3Q!h8sB0cfQ?YVaVf8a<7NTwT#~3GbP#5( z;a?p-v2|McgnpxQl8rq+*V&D3g5BDh;bDG({$Rdjt}b;Ur0ZNNzwT$lAKYuOXcrUL z*~%d&o<$P1Qu@v`8E(HxAc46@e)lFQr(b9n%bJ3Dk&k1*o42-gNM)YNoqOPLl)Dp4 z%c(b;zhZgy&wf=^#^~Rv^nhWKQBomlXzjgK&E9fBcA`b*)2?D)dp+4Ty%~f2#nq?B zQ4G{Sns_DmCmq7}{#WCk5k!vyVf1qKg>BDgQmE4qoRIyIV6Ucv&f9FMq_&dH{ij6R7(LYH zF0|;7++)p5*3d2dnL4vowPOTCcuKF2QpJv{GY+<@dA(L~F}o!@r^opnM$f#BP0d8Sbh6kWKaxl0 zI!gKxjU!Hjz#RfxSi!jg^%%-hG&?H7noMVt(h-$h)KgH{Ur%}SEQrj^s8?3R)}#zT z*MnF(IM8Vj!7FFWk)EG}457Wsj{a89I0)A`d9;6Tf&ivMHR|JR1wSoY5P*Xt-WeN|_KZxB|`aRs^mDkTVxvVJ!zAU964#M6@AZfVod-?No5@A-V&_$!|RK`M)R zg0yQb(>LEg#k`q!5|^egt-o_((_0oHct@F4=SDtwtzNVJAn6ctu9o>0`ymN{xaLRwdEYXbdMQ_~ z794x7dvAYAf`!r(furh{3O&Ii9#C6j<5Wml|AF1_QpiNTo^dndsA6)EM%xh791!pW z(}-*6a^Y!3?WXyI5YKhCE*j}kZt<}#nq2q?LjeYo+eQo_Uf%b-go|Ock$%e8M zGV$Q&7T(%HYBo*{qb?=u4Y<$Zm1PwnZa? zJ+VZ5p)L(fOl%f+_kxuy#-MK0%{x_oMI^#wy7S^;1~yO5=^P%oX6G{Ln*C@M!LqJj z<&Rom9lpKj7(*~Pz@t;RSt;cFiK_u`kA49}tOD#M(+GOahtxqvE!o=VIh0}10q`@o zFY3ipmdbWmQx~~3>=>BiA9>PAoJ_qE59B4rbB)2I<}Z~HKsD*L^I3vLaF#)zlUr6D zbKZ&059ql9<@6mpwn2qRdUwvHT#TmLa{$s@*!Mkuc}B?l_ZTDaUA{SA>sU+$Mo13)+oYc1$#@&Y%Evhhl}LuY(SK@Jw{c=HWaSs(iFh0rtrm5!7FMm7YnC(}gV{b- zn)I0VAXA9X(UX_DVf4GHl0;OCbZt_Jx0BTPjswN8haO74%i z00AEzzaif@&2&%_5jYYrED0rLI9V;sGiyf1Yu;_iYF2tYDnDg`9AgcdNA*lW&SDupswrqEE)}jaiscMr71lU}HOhDoz`7~mXr+nz z^czo-o}?ck{YnC2s=YMajq&zREoe|J*J5n==zNbQS>z8lbvEnIFYV9IiJvuD^EPZ9 zyJx7fVl-s8^l4zh49ue8+9AosETehjgQbkOvnztQrJyUXQab+Ht9<9V;8p=sf@~UP zS>$Ava4(z24EkZ8u@EdkNP2W+O|f?{p`U30*Hn6l;}re+z=ZMcV05PP8*f|2kX9?yZ6$tSO&dSZZZ$vA-wSqkE4nY3mY09-tJfP z`udGrD6+jW-+Gpy^&z9lUdHQa9$e~q1*8HK%j+yJ+N|RfJ%S>vqbJK9+}nTe99zGx zbx=E00@BN!Ob)v;+S6h{*I=MFaa@ICrR*)EY@lJPJ~(puhfhM@aIr+DgpPrYRRYh} zml{l7$I!9lvcC*w33APz2-;%YKUDqa>H%hlQ_O5|TkfD=e1G+#;S?6!uilXF-|+76 zTzTn>Jz|a`v+$9q@wS!nvSQmxO`J@*x0M^j*w6j%DitMLnl%J!?zTuEq^4V6i z)w3J5bdNnrM49gr^l+%{U0B%(rPaU(B095`Qm;WYo5ritczLP2o0(?kR#jaa^TjrM z$9PcEF8pEtGS+VM!`6)Q=;?6Ak@C2<-ZLOKx2LyX-3c#rQXrWiU)^Mp4lFM+itL*R zt2j8_?Tmwt7J0KS39zh?_#2t~)t!kkUm)bGfdyEKh{Mc^OKI2CqL($7>3dJ$-e<5OON>eNpY03&gWoxS3dLU+ssn~y~o5ZsayrMAB z=4_IV7EOsaq3P!~4Hq$UpE&Y4bCtGcCSS}r%eJpn#tV(eCmUxiK%PCl6VYTej5~5z zFkt5!UnU&2e(>QEuQeE`aS^s?h6WlIeWPuZ-xA|+xmr+@#wh@CBK>3acIh2 z(*fGs6MxCk2q1P0Fq&;1$POqU*7wF zukYpLFvw8u+bV$+gQg3d;^SaKEN&#L6%JX zX!4KHb{p(W14PwyzL9?Mj(3hK1%?5o1ml`M!7kKQN@h%}+op{JHWS2>m17P#Xbfc6 z$8w>8wZuL%-KwXO17&8K9=KFma#@m=BvT3;jqXh?Tpk(EHhu4(2O_4}$L({A=ZF=! zKsxCDO0X^3g^BKSHu=OjUJ+Ro@pO+E#J(s|ENq*hTJlHzM5ql>d+oJ4`h=X+Mc7-$ z$Fx2IVo}&pN;%FkIrydC7Hi*18?E5R=!%seCqKxechQmRLy;H9RZ$R%p>Q*KvMU@P zWYEsUiGDY6oqF86NA>uf9#HBZycque+1WkhgtUJta6X(`(t@C8}a8pq?) zgsP-jemgc&E3OG;COvM_w8O)f!vRDq+bMvm`GrI#;$0#v8?(0H(G4e0t<*Qy!^wEA=2uhVg}7?|Q-IS^2Gv zhq$D~OX|6`>7^`9xf;`>u;Fte*kaO%gd!ryL{Cf!($cPYNQwA#TX6NdRSh1$hph%* ze+f;z(6W}AJ?D|wF<}wSgQqiN z*SbmvtoVi-r1P%CUBB)nkTKewYF^R4sF<>>ee^0Gcskz@E$OlL4a&8>CSZv4nJCHs zxF>R?pV}cARkRX*PlS&G3lK%WZe%$;$$2uDlS?<;N-I@33m9Q1VMODkJhFvOfB#iW zri9^RE!v%SqEh`k^IDy7XoY=1%_iaT%qQul08(MI>~YYO=~%(3ogy-C=4lbR19Ds7 zLQxyt@UgBP%CdQ*?^>E!9AVY@m^$6SWZemjdS&&Y7>~A)uHGuPR;WUmAh3O7jqwHQ zYGbJvk9x)%T4djfVHYv?`I4!Fnwf*CUCeoseixO@?`#vx{0O5}j^+4D9?ZZ#fi zP!FM{Kp%O;m8ZK{ffp3E)BrvquN|#+(DyYDCSOwPgQGotEmcwUMnZdsDDbJcC==(x zgpagx-I{t(Q#JVU2o4G0HbSQEGd~G?Sw%7z4b^Y!)o8yT=Ew*lFIDb#6&5S1ywA3u z7eQPqiMwYb`5OfJJmxkO?N9p#xSrQ^B7OFr2%V47_tW$?wmZ?uIU z4CJEzjAblIAS)mrQ4sFOgQ6Ktr#o7Vzd7X12^Qr3wfaG~SGhp%+f;^}h3OAvq*8bn zNi0lDTW09uN&v_;y-k+6F<;oPru`R53jzG-_X{{x4;KN`YWI+x)TY}N$<$z*M;H8n z(P4>HMb9r7Eo)#WPNagh+B~lG&O6<%>^XV?qT2SF37a;OxzRAqLk9@Dn}>&4*4ZsZ zL+$1<<-YhQ_#OU< z<%iZ#tPZj$b%%Dp)~?ZZQbeQcRR>$VRo5Q^-vTEji(b|T=5bjSOPvI9Tp=tGe4Z_? z0j(Wg@l+kpwt&ay$KkgJ2Kj|W`m#;F#DwCmFS!k|SEEJNOb(KWwSfv!w_vsPjwMyr?1~Sro}CxD>#r#O3!(c*$fCP1jKX+ zfi})2xb2g#DN7u54?ttba)O6$jh+|1JbPmRT)fy*Zxd2PY@{PQb=KpWHjC-z?fah* z(@EniabvZ^_i+40mHsFBoYPFOB{^CjaRpc0z4u>sHdwMe*)hfcyaF5C^@gKTCBalJ z3CuRDqxzho%pjd2ns8JSVrr@-lTc_nf?r`0|025Cj$Vo1S~Mo{OCr=;M;A@EGHKvP zkzn~Dw?}Jy92qNnHt_BFTMj-~ls-Fs?PW-5H0gFf@-YeH>BqC6?U4w@+OIq8IxG-< ztD2=@XL5Q@2lK)X78@PGatzh4WlK9^<~C+1c#T?h%%rS{;4jtmncow`m)#O$))QM1 z&2>*9G)Eoio&GI-DHOjwl(#g!_GRX9;Vz>IX_R8Zi9+W2vVdp1xHdlv|`3- zK^Trdr)sBFD*H8$H?;Df0_m}3>7CSb6>yYKO5S9gd{gNU;yHqO$Mu1loHQ^$ZX_|; z&Fn$j!|!QEAtG?#dd!*OO^m3dD~p32v@cRe6MK+ffM+1J41_9d8BVAR21DXU1=Fx; z`PkLBP?K%yfuU4@usR)inxMEu6AUYx%-Qv-XeU@fqtC|6bX;tsq3j zhBIF*oLbyWjgI=US*J8%l!+81hiwyb@G?m^tQIkJWVb=v_GGpNrwFHR$~$I+o%Bxb zhB?Q6c7ZAVLIy67)T!wA_T@6h=M;a7Dt5b6T|gG6UqoLbLMO*z-Lh5PioLTLl$-R3 zYjg#EAm=I1VgA%F}SXuqS(jhZ4a8R;TCK^uX2p4GAu-j&a5~#>cQd@sP$a;+K zL5-eXL9$~LCSL3;f(Rl%;oG!3$iPNQvEop#RI<4QT)AnE7$4$n1=`MneS`e6>PB08J z<}4RHrp?|^9}cjcw43yC3%7zuts}DzRFHLviB%cWOL1YLML}7?>nu7IG_ektbYDu+nN#@oM=Ltsz|1FmvN_bM^7UlyC7`(B3mKzW zd4NmJh`2j$bwG3H=t>B6PP@?NLz#_jC)lK;LFNPLIqNv{*9a>Gl8W<5D-AbYoTgIc z>{gY|v6^%%T#&cRf$Rg@N)L$SsukJ0hs!-WnNQi}!)fhu(-Z-fuiMprd+k*3DF(Z0 z61P!PZW0qwZKIw=g`gp&%>07wxiy}Eb;uwqNDCN}rap9bMuENZ>Yhvj#Hv&_;pko` z+R^mO1kbpbi4CcZtF>U90!5?2y&b+`gbDM|zBc9XyjP|FC+7%?nl^R`L5o;)gmq4Y z?a=lLMpdPqQy{$RFT&iMAJuCwaUkSqUJowb+0H4(V4|J4GRIYmon#{;L~3(zRL$dU zwapXDkEsN&rI%0yQ{+7^v1`Ki>BBnkQGyw>K6q(EMlqf#+hT1g>st6c1b{1^8FBqQ zeXGROQvPjm?S^>P|+Tp>t99mJMR(C%}I6ofP_G7ifDpblcs(sH^zZ&)Hk zN~5uI2$MZPcq+zFt{V1Q?XDz&n6htHI~ZlK@r(Ro?-;#P&rWU#S6`;F;Lr}uO1Ins zP^1pJuaZiSyU3Ju^c7`?mzV@?NYOMutw_;-UW8HO2WcQ7W_*URfSSrV9sz@#oNjIz zEY3CN_sgMBXWtatpa|pWQm1GMOdrPgV_!TSi+f}rF*MXCph3c@f<%)f81s&>Fo9Hl zRi{(=5Q1%dR@}5ztC=5F=bDS}xo{S$hs}A3%yv4ItJJjAWVvzk({3y5)Oqh8s!!e~ zsH`5;0%Qp-Hh*sTGzH#i&giW;3OD{o_VNp0^O9jgPMuNp0?hz_3)7rE?VL zBIG1FV$GWGfRFER7@Ykp&dtNF0Px0uWLG9qj6&t9JDcHpKc=K(7`;> zqE#2tuNLpbQ}}y%3%pN?F#58uTP=fbU+KgQ?Ys^wsK2c?_3Klh6WtDDR$BV{gIns{ zgxM3%B83`zwnErA6|mPM89SL+qR;eAQkpVBak@pPk}1m$=lat82|K6~4Yf+iWW>Ot zvSu*ZzCZYcbFbqvCZkwBPiTDV7~`^nrmB)fxoRoN~8sm%|-iV%pV@`%%*qWX92 zf+Z95({@7B$3bE3$0!ABNT;{`%fo>8OpY9@g}=3T&OrC&3*Xq7ltp422$4)Xj z*3KC+u53Y)Bhzvs%CPP_Xxg;n4RtvgIf)wgE(F?fcS@1S2T=>W@5-ohFo#4y>`>PVhoGAmV^;Q#Z0( z$pN#TA=g+F(kZ@C&U|uynCz=x$n6HY-~5UH6r&8*vZfxAx4iNOK?A0yLtd}o?YRJdUSrM^hfF&xI9-wg>zO< zRWQlyTHNDggYB=5J6=O5+*5_k?Ud4RemZBd6F(ese9+N>oJ|BAy{s1c*1{0>Q+3Qh zP(b*n@(-L5B}>;0>fhG>^tE|7bP}Phe%`c-ngKus(Ct~W9jU)-`d|&8%Ptq@Ja;k4 zDRXX?!G@|7lIdvK!{&&DpCh&LccHJzI18Vk?}+Lf=Zb*TY4^e=7puq6Y!pC!lh^u_slGLNoagD;Lee6#h-7jXR=hIs~~? zm7XHC9{``wCWW}KGA#qf#DJYEGZt8qCb!X&!>zPN5*fruWIG5EipxvopgIk84apP9tUO-jkKE>S)ov>t#Y}I2NwB{DKY zL`0wDw-O|TZDsAV1l6R`DX!l7f$94=C79#TqCI$MPo{T#BCDFFqnt>#?po<3H>nm0 zTX#1qgPfYh?LHXa;u~BZqSUs6(@T+?lM*8_B@>#}H4OhS&=r!LH@QW-vSbZ>lGO%| z1s_S#ymIDAmEN}QPe;2*-Q75T8q{L(6|U-}=#y=JZeCem&!Ed_RG~#jHu=nUJC68K zY$POS&6oQmX2e-Sw_?2|#XPrX+cZG?it}<6oB>>Z?jrz~#fG-0jOX|c=F$1-9ShK4 z5t6WBs3jsXx~9}A&3p#1g_4|<((Lmr9Jy%K4)Uj<^5>}XX35FqlSa>xvf8^EQ9z{c z0I4#6p-1qIfGN zy~Zt1qx+^XW;-m9yzZgu`Er~n;tj8aWD2zl>?~$qxOzgovEdR+;D+iYlMmFZVS9x( zTa>48ib#p9aBZv9gXfD5?$>2~j(P3fl=y)wv) zgG=y6)d79C2!%Ga#4u*!J~K?l1oC5W;(cCr6vt!I9#$)9VqQ=(#vUdmPup9CILe*Y zq>84T%ujkeq2I=;OE=+tTz{X>xJY}m85VH9sQS3#oZhaC!%qTBUAu6I)&o>^Tvk54 zk|%_aw)F*H2GZ1XX_s6;qU6%~8f7P-rF;d8*#-8d{hvSi!!mlMO)7FypdT8r<{YV< zk-#4u5g2QwOr7vrp>bv`8s)!pl>(`qilfaU^EG$T!PhN)1VOw*rq|ol;zH$nuR60S651<(LCLf#Yhu<8Ue#G zpr}e3wybWCE$gO0B&k~_8E*L>v~A9#P$|EZ6>tphHbi*n@ZK$8$R=jaXW5HYB??e1DF*3W2SdIdt+7^=~=p0ATFFroR$u!Rx*P;Ic~d;z=ME)~HD+ZC-8PL9m3<*PoYH1zC8v~iqp zk4qSph33h**gBO#F3YLmLdW{0wt-)0Zl&$%hlK zbh0vgu$lb^GFRlL@$^eR^ZS=jSl)s2{aYX5ZFc|11<&K$Y>4zqo=chO z5$azqiFQS-HJtx{G6Bwm*nn@?Ha|i*?3`IO@zdW0J_=U9DES~b+ON^&r4;s;YZ>;~ z3vAvSUI#Biv{G!Azc&z<0ulL~BO^C)@i6yK|98*dH-;;|NRRp3LHIY!!F(W%g-9iD zAOWsc_AJh4r6tYaG0XHXUn8)=zSiGvhv8R5-4*|S@~@vJE*qONi43@r?rJ$=5Y4Ha zt!(tPU|kZG!rnEE=$dkv%L-|PtA-dASa(JeVkRx>MBX1ZRn*{_veOAo74m8s{pEsT z@kI2H=zm9zVuDB`7w3TYSN;EfgKq3yq65=@v^t7k&OR7t@I-6VCb!hlc#-mxcvH`G znT^odyqUhPb&XoA%fUjg@^3SPCa_%RH>C zm;yf_cKJZep3eOZ)_b0>fVYsQ&i>S&hBCpbf5ZYAeK8*>ouIE>4^XfOOC>#C6L9C4 z#r82@{Mr*>Z__O!ZuCxO4DTIOoBhyjkGbM>_bP7fS}_i+Y@Fvf+4oiq>}LzE9@wlQ zOjOlt)j3F7RGhYQExi^cbGiOUxYq#LI=|-=;r=P)Fv}wjpwJz|^BrsM1}wjCtI{Ut z48JsYC>{hzwmmV!jR6dn3#q<+s1tfP<#^t2E5nJAUsJ?^8KwRAd7MK?7p(|hk1ro6 z0xhulYIpEN!?Q<~-LTb)2?oA%*GlUBE0l>~DXbpTTM>GJnX|c`Yu9V> z%x>W07{4m?me>Vo&%E$N_NV8#`R_9Gs%<538GV2Q(4(o1Mp;8~M_0GviBr4i zBAmY2;x&Ti%0f-#v(DX@cbT@j9F-3Vt7>=HtV zab*(zH!=TeLV*0ejWH)=jx^dUHPV~Bp@ssQ2pXoDAz0qCL3_7@1Pq8 z4R4yb5l04Ug@slJo!_PS_*}g^3!;FA8Q)#X>UwOwV_|Zr{=GjVi_z-vXJ$0N(~8Th z3s0ui-?`l(6#CMd`1~-zkSk(ta8IxhP~SGH3Oi#6P37KBJ=uCPL7YeuS&2afEY*tP z-@_X`)Cuxm3L^Y~rN`aEfJuV%#oTrq-{AgAy!|da%=6ISFBq18E8Ay->`}b)ZtKm}pBfLzr!z(Bon(BGc!jn2fk$Zo%0rsx%)_o!*%ArEoXC%_~*cOU4sM(8+ zg)ZghZf!;>?g^YJk@pMIVS^cdFTlP*$79TrztCWW40AjL&55%yvkj7Co@-cqwu+umxr-LSGtga^T5TKq)#A

5C1kK?m5L)N_78tcUNakmkv&yGe_yWrV21CSJk)mCr zi<0ppspgt|9Dycu=^x+zQ)<7f){X$VyN_Ssy#k1j=NOV;WckaI5=U}$I+d62IT9-5 zMsC9UVM6>G=nOK>DQyptAt-W?(GwzH$+dmmK|Rso6R4r@U`*^AjvY40&%gKA2!?yB zmBF^_eN!2m>%4U!@n_cXn(BqaclsK{i!GM4fJ+cH{XUAEs4!~%@Jno{lYLlQ?dZlX z5=`rA>JLKADF1C-WcEEN!T^PClXzrZ6jLgE>7zjKwru;&ko&F1^B&gR$@r;M*O#Oh zv@hs)(XzDz0uzRc{~z&Qldl9_&aR3K-&*7ha(AnJPYU#XKr?unrg*+2lY`h*)_JX? zeBc9__j$yF^u3~Yx=f7VQ4spv(w@h|ZYqFe5VEIG_sNa75S}>EX^Tm4K}|!D_4VGT zJyG}llz6Lfjv=e+xI_6r6BV3xsrY22Z0Y-mS;LoLCApUc8 z4&O{$O%Ye~hcvYU`3hcNP%piLKl#Q<*{3 zJG)0lSSlWvMCl8&5^w%(6#FrOU5wY{e#=L-u4i};o2*X>xhxGWS>tbfHm;jD`pFf7 z4W<8s-@NbP6v+GGps&Ai68o*8_D6nGJ*L_U@ourmlNnAzQ}~bgi+ZKs-*} z-jSx7cFL0lo}v+E%@4b)E1EHNJ}SpQ4@W!@(Q zayZ)Itu`Xdv0=3O|GDi=7X?iFL$E)Vh);LO3N^Nm$MSensppt*hPAl6W!yU>1%CP$ z63>v$9&`QAR5KoNh+}n&`Zx2CVGNscDR#O6&3)T4K^nQMrXBpIO}W#G@7!1lIkb%I z0bd1+^?v3>cup3)g%nI9!(y!}^etL`n-!69s`2C*80Kqke;O`pUbK^H2~pFm8T=c~_O&+)>Y;0)4*{;H9(X}yl1uBO0XK^yMB!1#B58fQFr}3p3DL^=M z-lxK8bj$HrRWtPSZ|BpyZ&dQ1>uJRI|F-@9?oCMIu-ECam9=N2%Ruk`rKTU`i$2)W z$*KeM#?TYT8h7x70TPN)X=7L#rLR=tXP;_0>6=2I<3w0A+5=Q|n;8DgTD_B0w7uf1JBANkPIO-t01eX5&qKDTs4 z;~keb^5WbNHE{-V9Dv|Voa@5Tb<6xTPVvatCW4IBr$VuBqJeEPJh8`(3;S+Xs{JoT z)V?5Pi`9=7UB2^co(&Y|?=)`ZW$uoE@8e>d++{LL6V2~wZ&3gJw|)CJ%7Sqmj`DNd z_T0Rf95Qh5&gEjlG`MA_ta3H{Z(e@zbPDO}Af8!0nEs5Aen84GQ-XcVdxcRo!tBwMc#_3u zvZ9DXRS^go1rI-o9F3q2miW;09*~NMF9n2hk$>hEXR_ri_^|6}j24=UK4bjm)wHUD?k(BH+Bd@U)=dWjps6z8()t-Lo zAPuB;FxznEcaz7r(+k1Ph?bMu@kWMp@;^DfK99U7u$wJF3(32*oQ zjbr?u2Blgori)#o-|ZBetS`_g>|){KN{3d}-6hg`Qk~RQ_&#kaoNSNL~ zi2c-~85nHw_X-8lzba{)Fr=mAW~$Gt4$x^REK;DD-X_G;ew#W@&)#FR*zOq}R6zod9WRW!YCAFEPp`0*1o$#d*fRX|TsV3b;>0?~%$6Pl*3uur`)T7YFJ#-=^S5s{VDu$B#|)f%ma|`4ti1S4-`EJ0imqkwrSz(0 zG_RJ-9M^#qtz5A~`z~IDk@rg#;%LHo4jN6%H&4UjLL|^oSa{gSdjgUtUg+k2-BD3C z^xqA#8Zs8>OLNQ0KMa`U8P?&YrR5ssK-g{DBv)z9iEZ@5)2otZ zn`tBPP`F7o8bY7acdoqw8d)NQ981J3EjkX38hS1EvMSxR1&g_xDa0^{FaN+mVPkG{ zHoX#g1KVcIw_(|FW)?(Jji11l!33fG!q z;Av?DRxa~uf7Ya}8nxQdD`V=;|G+H6!9s}vjN(AZEXd)7jFI9v;BNNisz-JBw^#LZ zydIY=7*!w4jOnXuqx?!n?LkEsrEMO&oebAN-y0tua*P~!rf;_>QahM{YwK9AM+*OC zonLbZUh(Fd0%Jkg)CzcZB8xdYgwy2X_K`)Bs0H`{p$Yp5Hpwc5pXB0z19g;tm#@wI zOz!g#aAHLhDLY!Z32Cd+S{Y_awGh$h^i2m%YNPk84sxILdh)0oN%p4dHQ5&9HI5c> zDlt2tP4&ho!fI)=u5a|gscgbI)72|fwuP^!X2Da0JH=$~*>YW8$#DKvXQC80%HWAHORS5ERq}>Ln`o}d z16FGYX)!Dey@Ri$&@(#8DTlH4m*JGv`<-o>icBL~|ClEtHRY6HjJ)c>oYc~c+iB@Gay!zI9?UfR9<`^{?7>AxnINQ*tB zl13~Xp+NPb`q!O)c3m_%EXKgJWkl}_nWD(nzl!8#;$+yH+!rGkY@?_?D!hBQ*c47`8zJj~Fv8}+(86j09Z;i}O~eSe}#zxc8;(6hp#kX?YVx^ty~ zAhX|ZD33kts{@61`X4BP$snSzeO|`+ywP=AmU?qsFe>C%**DT%!m+Kwvd9PWl5~jm zxa5A?dOml4f;d#3lBxSD0Pn}tN#xAdZ%Ww8&j*Du{#%bK@`Ic(1*p~F`=iEEUIAUN z8!J+`lcG#HXmW^qFkc;aMWQp@Mh#=#gwL6ynqt7L8n&vBbtqvuW zGKzIiOM^j7f4QCh=_LDZ0d6wmbd(1zT*c$F$(o&;*bbJ=CExF-=Hl6A_4=*-zqVKu z6_}M4%*)|71d+5DV|-plWqw5Hz653Id?v_BtA@}pMLkI`BOGviCuT8 zn+vBnJ+7F(qEVFPf*!Y{NgKVb@bVq0f8L;q;93vsI2-R4wsvhr+#9kq1@gs$8n+0L zfyn5Ajl5gyu;{hSpB{lUng$|O>^YoNw@hs}=tq?9QAn9TJkrnyZIec8u$(@Ge&*5J zI=D`aP`8U}SPyj54_`{)=w?v)G0x^r6?7J$Vo2;#^`~;=_OiH^^`y1u{Ri!*VA3wS zm0^F+;(?Ob#d~=qTV^}xrh!4B^TiBti$x5lNLH#-pqLMz`D+t{wMhS~_t*Y{q2E94 z3Z6U){o9sjEb11{k> q4Y?J4j}r|mi&IDTe^_=v0Qg1%NPryHfcXp9=d*;ur%Exyum1;Kq~GiS diff --git a/docs/index.md b/docs/index.md index 4edbe01b4dc..277f0f58f94 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,78 +1,74 @@ -# Execution Spec Tests +# Ethereum Execution Layer Specifications -

- ![Execution Spec Tests Logo](img/execution_spec_tests.jpg) -
+Welcome to the documentation for the Ethereum Execution Layer Specifications (EELS), the executable Python specification of Ethereum’s Execution Layer. -@ethereum/execution-spec-tests is both a collection of test cases and a framework in Python to generate tests for Ethereum execution clients. +EELS is implemented as a readable executable reference in Python that serves as a source of truth for developers across the Ethereum ecosystem and underpins the generation of test vectors used to ensure Execution Layer client implementations are spec-compliant. -The framework collects and executes the test cases in order to generate _test fixtures_ (JSON) which can be consumed by any execution client to verify their implementation of [ethereum/execution-specs](https://github.com/ethereum/execution-specs). The fixtures, which define state transition and block tests, are generated by the framework using one of the `t8n` command-line tools that are provided by most execution clients, see below for an overview of the supported `t8n` tools. +EELS is a collaborative effort between Ethereum Improvement Proposals (EIP) authors, protocol researchers, prototype implementers and client developers, maintained in @ethereum/execution-specs by the [STEEL Team](https://steel.ethereum.foundation/). -```mermaid ---- -title: Test Fixture Generation with execution-spec-tests ---- -flowchart LR - style C stroke:#333,stroke-width:2px - style D stroke:#333,stroke-width:2px - style G stroke:#F9A825,stroke-width:2px - style H stroke:#F9A825,stroke-width:2px - - subgraph ethereum/go-ethereum - C[evm t8n
external executable] - end +## Where to Start - subgraph ethereum/solidity - D[solc
external executable] - end +
- subgraph ethereum/EIPs - E(EIPS/EIP-*.md
SHA digest via Github API) - end +- :material-download-outline: **Getting Started** - subgraph "ethereum/execution-spec-tests" - A(./tests/**/*.py
Python Test Cases) - B([$ fill ./tests/
Python Framework]) - end + --- - subgraph Test Fixture Consumers - subgraph ethereum/hive - G([$ hive ...
Go Test Framework]) - end - H([Client executables]) - end + Install the repository and run your first command. - C <-.-> B - D <-.-> B - A --> B - E <-.-> |retrieve latest spec version\ncheck tested spec version| B - B -->|output| F(./fixtures/**/*.json\nJSON Test Fixtures) - F -->|input| G - F -->|input| H -``` + *First time user.* -The generated test fixtures can be used: + [:octicons-arrow-right-24: Installation](getting_started/installation.md) -1. Directly by client teams' test frameworks, and, -2. In the integration tests executed in the @ethereum/hive framework. +- :material-file-code-outline: **Writing Specs** -More information on how to use and download the [released test fixtures](https://github.com/ethereum/execution-spec-tests/releases) can be found in the [running tests guide](running_tests/index.md). + --- -## Relationship to ethereum/tests + Implement an EIP as an executable Python specification. -This collection of tests is relatively new (test case development started Q4, 2022) and mainly targets recent and upcoming Ethereum specification changes. It does not replace, but rather complements the existing tests in [ethereum/tests](https://github.com/ethereum/tests). + *For EIP authors and researchers.* -## Motivation + [:octicons-arrow-right-24: Get started](specs/writing_specs.md) -The motivation to implement test cases in [ethereum/execution-spec-tests](https://github.com/ethereum/execution-spec-tests) is: +- :material-test-tube: **Writing Tests** -1. To implement test cases as code and ensure that changes, due to spec changes, for example, can be easily made. Moreover, changes are easily understandable and available in version control. -2. To avoid the 2-step approach often used in [ethereum/tests](https://github.com/ethereum/tests): - 1. Code (often unavailable) -> Test case (YAML). - 2. Test case (YAML) -> Fixtures (JSON). + --- -!!! success "Contributing" - Contributions via [PR](https://github.com/ethereum/execution-spec-tests/pulls) are welcome! + Write test cases that verify EIP implementations across clients. + + *For EIP authors and test devs.* + + [:octicons-arrow-right-24: Get started](writing_tests/index.md) + +- :material-play-circle-outline: **Running Tests** + + --- + + Generate JSON fixtures or run tests against an execution layer client. + + *For client developers.* + + [:octicons-arrow-right-24: Overview](running_tests/index.md) + +- :material-book-open-variant: **Read the Specs** + + --- + + Browse the rendered Python specifications for the current fork and EIP. + + [:octicons-arrow-right-24: Specifications](spec/) + +- :material-format-list-checks: **Test Case Reference** + + --- + + Browse all test cases organized by fork and EIP. + + [:octicons-arrow-right-24: Browse tests](tests/) + +
+ +## Responsible Disclosure of Vulnerabilities !!! bug "Reporting a Vulnerability" diff --git a/docs/library/cli/index.md b/docs/library/cli/index.md index 4231719a442..a3a65c5a92c 100644 --- a/docs/library/cli/index.md +++ b/docs/library/cli/index.md @@ -1,6 +1,6 @@ # EEST CLI Tools - [`check_eip_versions`](../../writing_tests/reference_specification.md) - A CLI tool to check the SHA values specified in EIP tests match the latest version from ethereum/EIPs. -- [`eest`](eest.md) - A CLI tool that helps with routine tasks in ethereum/execution-spec-tests. +- [`eest`](eest.md) - A CLI tool that helps with routine tasks in ethereum/execution-specs. - [`evm_bytes`](evm_bytes.md) - Convert the given EVM bytes from a binary file or a hex string to EEST's python opcodes. - [`extract_config`](extract_config.md) - Extract client configuration files (chainspec/genesis.json) from Ethereum clients via Hive. diff --git a/docs/navigation.md b/docs/navigation.md index 002b2b94aa5..4ef0205eff7 100644 --- a/docs/navigation.md +++ b/docs/navigation.md @@ -3,86 +3,78 @@ * [Home](index.md) * Getting Started * [Installation](getting_started/installation.md) - * [Installation Troubleshooting](getting_started/installation_troubleshooting.md) * [Contributing](getting_started/contributing.md) - * [Security Policy](getting_started/security.md) * [Code Standards](getting_started/code_standards.md) - * [Detailed Code Standards](getting_started/code_standards_details.md) - * [VS Code Setup](getting_started/setup_vs_code.md) + * [Verifying Changes](getting_started/verifying_changes.md) * [Repository Overview](getting_started/repository_overview.md) + * [Security Policy](getting_started/security.md) + * [Installation Troubleshooting](getting_started/installation_troubleshooting.md) * [Getting Help](getting_started/getting_help.md) - * [Writing Tests](writing_tests/index.md) - * [Adding a New Test](writing_tests/adding_a_new_test.md) - * [Types of Test](writing_tests/types_of_tests.md) - * [Writing a New Test](writing_tests/writing_a_new_test.md) - * [Benchmarks](writing_tests/benchmarks.md) - * [Test Markers](writing_tests/test_markers.md) - * [Verifying Changes Locally](writing_tests/verifying_changes.md) - * [Code Standards](writing_tests/code_standards.md) - * [Exception Tests](writing_tests/exception_tests.md) - * [Using and Extending Fork Methods](writing_tests/fork_methods.md) - * [Gas Optimization](writing_tests/gas_optimization.md) - * [Referencing an EIP Spec Version](writing_tests/reference_specification.md) - * [EIP Checklist Generation](writing_tests/eip_checklist.md) - * [Testing Checklist Templates](writing_tests/checklist_templates/index.md) - * [EIP Execution Layer Testing Checklist Template](writing_tests/checklist_templates/eip_testing_checklist_template.md) - * [Post-mortems](writing_tests/post_mortems.md) - * Tutorials - * [Adding a State Test](writing_tests/tutorials/state_transition.md) - * [Adding a Blockchain Test](writing_tests/tutorials/blockchain.md) - * [Opcode Metadata](writing_tests/opcode_metadata.md) - * [Porting Legacy Tests](writing_tests/porting_legacy_tests.md) - * [Filling Tests](filling_tests/index.md) - * [Getting Started](filling_tests/getting_started.md) - * [Filling Tests at a Prompt](filling_tests/filling_tests_command_line.md) - * [Fill Command-Line Options](filling_tests/filling_tests_command_line_options.md) - * [Filling Tests in VS Code](filling_tests/filling_tests_vs_code.md) - * [Filling Tests for Features Under Development](filling_tests/filling_tests_dev_fork.md) - * [An Explanation of Test IDs](filling_tests/test_ids.md) - * [Transition Tool Support](filling_tests/transition_tool_support.md) - * [Debugging Transition Tools](filling_tests/debugging_t8n_tools.md) - * [Running Tests](running_tests/index.md) - * [Methods of Running Tests](running_tests/running.md) - * [EEST Fixture Releases](running_tests/releases.md) - * [Fuzzer Bridge](writing_tests/fuzzer_bridge.md) - * [Test Fixture Specifications](running_tests/test_formats/index.md) - * [State Tests](running_tests/test_formats/state_test.md) - * [Blockchain Tests](running_tests/test_formats/blockchain_test.md) - * [Blockchain Engine Tests](running_tests/test_formats/blockchain_test_engine.md) - * [Blockchain Engine X Tests](running_tests/test_formats/blockchain_test_engine_x.md) - * [Transaction Tests](running_tests/test_formats/transaction_test.md) - * [Blockchain Sync Tests](running_tests/test_formats/blockchain_test_sync.md) - * [Common Types](running_tests/test_formats/common_types.md) - * [Exceptions](running_tests/test_formats/exceptions.md) - * [Hive](running_tests/hive/index.md) - * [Client Configuration](running_tests/hive/client_config.md) - * [Common Options](running_tests/hive/common_options.md) - * [Development Mode](running_tests/hive/dev_mode.md) - * [Viewing Results](running_tests/hive/hiveview.md) - * [CI Integration](running_tests/hive/ci_integration.md) - * [Consume Commands](running_tests/consume/index.md) - * [Consume Cache & Fixture Inputs](running_tests/consume/cache.md) - * [Consume Direct](running_tests/consume/direct.md) - * [Consume Simulators](running_tests/consume/simulators.md) - * [Exception Tests](running_tests/consume/exceptions.md) - * [Execute Commands](./running_tests/execute/index.md) - * [Execute Hive](./running_tests/execute/hive.md) - * [Execute Remote](./running_tests/execute/remote.md) - * [Execute Eth Config](./running_tests/execute/eth_config.md) - * [Transaction Metadata](./running_tests/execute/transaction_metadata.md) - * [Useful Pytest Options](running_tests/useful_pytest_options.md) + * [Consensus Tests](consensus_tests/index.md) + * [Writing Tests](writing_tests/index.md) + * [Adding a New Test](writing_tests/adding_a_new_test.md) + * [Types of Test](writing_tests/types_of_tests.md) + * [Writing a New Test](writing_tests/writing_a_new_test.md) + * [Benchmarks](writing_tests/benchmarks.md) + * [Test Markers](writing_tests/test_markers.md) + * [Exception Tests](writing_tests/exception_tests.md) + * [Using and Extending Fork Methods](writing_tests/fork_methods.md) + * [Gas Optimization](writing_tests/gas_optimization.md) + * [Referencing an EIP Spec Version](writing_tests/reference_specification.md) + * [EIP Checklist Generation](writing_tests/eip_checklist.md) + * [Testing Checklist Templates](writing_tests/checklist_templates/index.md) + * [EIP Execution Layer Testing Checklist Template](writing_tests/checklist_templates/eip_testing_checklist_template.md) + * [Post-mortems](writing_tests/post_mortems.md) + * Tutorials + * [Adding a State Test](writing_tests/tutorials/state_transition.md) + * [Adding a Blockchain Test](writing_tests/tutorials/blockchain.md) + * [Opcode Metadata](writing_tests/opcode_metadata.md) + * [Filling Tests](filling_tests/index.md) + * [Getting Started](filling_tests/getting_started.md) + * [Filling Tests at a Prompt](filling_tests/filling_tests_command_line.md) + * [Fill Command-Line Options](filling_tests/filling_tests_command_line_options.md) + * [Filling Tests for Features Under Development](filling_tests/filling_tests_dev_fork.md) + * [An Explanation of Test IDs](filling_tests/test_ids.md) + * [Transition Tool Support](filling_tests/transition_tool_support.md) + * [Debugging Transition Tools](filling_tests/debugging_t8n_tools.md) + * [Running Tests](running_tests/index.md) + * [Methods of Running Tests](running_tests/running.md) + * [EEST Fixture Releases](running_tests/releases.md) + * [Fuzzer Bridge](writing_tests/fuzzer_bridge.md) + * [Test Fixture Specifications](running_tests/test_formats/index.md) + * [State Tests](running_tests/test_formats/state_test.md) + * [Blockchain Tests](running_tests/test_formats/blockchain_test.md) + * [Blockchain Engine Tests](running_tests/test_formats/blockchain_test_engine.md) + * [Blockchain Engine X Tests](running_tests/test_formats/blockchain_test_engine_x.md) + * [Transaction Tests](running_tests/test_formats/transaction_test.md) + * [Blockchain Sync Tests](running_tests/test_formats/blockchain_test_sync.md) + * [Common Types](running_tests/test_formats/common_types.md) + * [Exceptions](running_tests/test_formats/exceptions.md) + * [Hive](running_tests/hive/index.md) + * [Client Configuration](running_tests/hive/client_config.md) + * [Common Options](running_tests/hive/common_options.md) + * [Development Mode](running_tests/hive/dev_mode.md) + * [Viewing Results](running_tests/hive/hiveview.md) + * [CI Integration](running_tests/hive/ci_integration.md) + * [Consume Commands](running_tests/consume/index.md) + * [Consume Cache & Fixture Inputs](running_tests/consume/cache.md) + * [Consume Direct](running_tests/consume/direct.md) + * [Consume Simulators](running_tests/consume/simulators.md) + * [Exception Tests](running_tests/consume/exceptions.md) + * [Execute Commands](./running_tests/execute/index.md) + * [Execute Hive](./running_tests/execute/hive.md) + * [Execute Remote](./running_tests/execute/remote.md) + * [Execute Eth Config](./running_tests/execute/eth_config.md) + * [Transaction Metadata](./running_tests/execute/transaction_metadata.md) + * [Useful Pytest Options](running_tests/useful_pytest_options.md) * [Developer Doc](dev/index.md) * [Managing Configurations](dev/configurations.md) * [Interactive Library Usage](dev/interactive_usage.md) * [Generating Documentation](dev/docs.md) * [Documenting CLI Commands](dev/documenting_clis.md) - * [Coding Style](dev/coding_style.md) * [Logging](dev/logging.md) - * [Enabling Precommit Checks](dev/precommit.md) * [Running Github Actions Locally](dev/test_actions_locally.md) * [Dependencies and Packaging](dev/deps_and_packaging.md) - * [Changelog](CHANGELOG.md) - * [Changelog Section Template](changelog_section_template.md) * [Library Reference](library/index.md) * [EEST CLI Tools](library/cli/index.md) * [eest](library/cli/eest.md) diff --git a/docs/running_tests/consume/cache.md b/docs/running_tests/consume/cache.md index 8d47d22a573..c0a054bed7b 100644 --- a/docs/running_tests/consume/cache.md +++ b/docs/running_tests/consume/cache.md @@ -10,7 +10,7 @@ All `consume` subcommands have an `--input` argument, which implements the same ## Example: Two-liner to Download the Latest Fixture Release -Releases can be downloaded using EEST tooling without (manually) cloning and installing the @ethereum/execution-spec-tests tools as following: +Releases can be downloaded using EEST tooling without (manually) cloning and installing the @ethereum/execution-specs tools as following: 1. Install `uv` (a fast, rust-based Python package manager): @@ -21,22 +21,20 @@ Releases can be downloaded using EEST tooling without (manually) cloning and ins 2. Run EEST's `consume cache` command via `uv` and request the latest ["stable" fixture release](../releases.md): ```console - uvx --from git+https://github.com/ethereum/execution-spec-tests \ + uvx --from "git+https://github.com/ethereum/execution-specs.git#subdirectory=packages/testing" \ consume cache --input=stable@latest ``` + Expected output, as of `v4.5.0`: ```console - Updated https://github.com/ethereum/execution-spec-tests (8c3cbd7a4eef3967abd78db32ee45ef8f7cf8271) - Updated https://github.com/petertdavies/ethereum-spec-evm-resolver (623ac4565025e72b65f45b926da2a3552041b469) - Built ethereum-execution-spec-tests @ git+https://github.com/ethereum/execution-spec-tests@8c3cbd7a4eef3967abd78db32ee45ef8f7cf8271 - - Installed 69 packages in 10ms - Exit: Fixtures downloaded and cached. - Path: /home/dtopz/.cache/ethereum-execution-spec-tests/cached_downloads/ethereum/execution-spec-tests/v4.5.0/fixtures_stable/fixtures - Input: https://github.com/ethereum/execution-spec-tests/releases/download/v4.5.0/fixtures_stable.tar.gz - Release page: https://github.com/ethereum/execution-spec-tests/releases/tag/v4.5.0 + Built ethereum-execution-testing @ git+https://github.com/ethereum/execution-specs.git@a48e0b381d5225a6c3de2d06cd9ee7ae0b6ca9bb#subdirectory=packages/testing + Installed 70 packages in 15ms + + Path: /home/dtopz/.cache/ethereum-execution-spec-tests/cached_downloads/ethereum/execution-spec-tests/v5.4.0/fixtures_stable/fixtures + Input: https://github.com/ethereum/execution-spec-tests/releases/download/v5.4.0/fixtures_stable.tar.gz + Release page: https://github.com/ethereum/execution-spec-tests/releases/tag/v5.4.0 ``` **Note:** Use direct URLs to avoid GitHub API calls (better for CI environments). Version specifiers like `stable@latest` will always use the GitHub API to resolve versions. More details on the arguments to `--input` are provided below. diff --git a/docs/running_tests/execute/eth_config.md b/docs/running_tests/execute/eth_config.md index 737171b1f7e..db7d194b8c5 100644 --- a/docs/running_tests/execute/eth_config.md +++ b/docs/running_tests/execute/eth_config.md @@ -18,13 +18,13 @@ This command verifies that a client is correctly configured for a specific netwo ### Standalone, Direct Usage -The `eth-config` sub-command can be ran directly, without cloning @ethereum/execution-spec-tests, by [installing uv](https://docs.astral.sh/uv/getting-started/installation/) and running: +The `eth-config` sub-command can be ran directly, without cloning @ethereum/execution-specs, by [installing uv](https://docs.astral.sh/uv/getting-started/installation/) and running: ```bash -uv run --with git+https://github.com/ethereum/execution-spec-tests.git execute eth-config --network Mainnet --rpc-endpoint http:// +uv run --with "git+https://github.com/ethereum/execution-specs.git#subdirectory=packages/testing" execute eth-config --network Mainnet --rpc-endpoint http:// ``` -### From within the EEST Repository +### From within the `execution-specs` Repository ```bash uv run execute eth-config --network --rpc-endpoint [OPTIONS] diff --git a/docs/running_tests/execute/index.md b/docs/running_tests/execute/index.md index 3aba6d9f7fd..6c13b2ad389 100644 --- a/docs/running_tests/execute/index.md +++ b/docs/running_tests/execute/index.md @@ -1,6 +1,6 @@ # Executing Tests on Local Networks or Hive -@ethereum/execution-spec-tests is capable of running tests on local networks or on Hive with a few considerations. The `execute` command runs test cases directly from the Python source (without the use of JSON fixtures). +@ethereum/execution-specs is capable of running tests on local networks or on Hive with a few considerations. The `execute` command runs test cases directly from the Python source (without the use of JSON fixtures). See: diff --git a/docs/running_tests/releases.md b/docs/running_tests/releases.md index 0aa18d41e04..057f2302bc3 100644 --- a/docs/running_tests/releases.md +++ b/docs/running_tests/releases.md @@ -2,7 +2,7 @@ ## Formats and Release Layout -@ethereum/execution-spec-tests releases contain JSON test fixtures in various formats. Note that transaction type tests are executed directly from Python source using the [`execute`](./execute/index.md) command. +@ethereum/execution-specs releases contain JSON test fixtures in various formats. Note that transaction type tests are executed directly from Python source using the [`execute`](./execute/index.md) command. | Format | Consumed by the client | Location in `.tar.gz` release | | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | @@ -91,7 +91,7 @@ Please see below for an explanation of the optional `` that is ### Standard Releases -Releases are published on the @ethereum/execution-spec-tests [releases](https://github.com/ethereum/execution-spec-tests/releases) page. Standard releases are tagged using the format `vX.Y.Z` (they don't have a ``). +Releases are published on the @ethereum/execution-specs [releases](https://github.com/ethereum/execution-specs/releases) page. Standard releases are tagged using the format `vX.Y.Z` (they don't have a ``). For standard releases, two tarballs are available: @@ -112,10 +112,11 @@ I.e., `fixtures_develop` are a superset of `fixtures_stable`. ### Pre-Release and Devnet Releases -Intermediate releases that target specific subsets of features or tests under active development are published at @ethereum/execution-spec-tests [releases](https://github.com/ethereum/execution-spec-tests/releases). +Intermediate releases that target specific subsets of features or tests under active development are published at @ethereum/execution-specs [releases](https://github.com/ethereum/execution-specs/releases). These releases are tagged using the format `@vX.Y.Z`. + Examples: - [`fusaka-devnet-1@v1.0.0`](https://github.com/ethereum/execution-spec-tests/releases/tag/fusaka-devnet-1%40v1.0.0) - this fixture release contains tests adhering to the [Fusaka Devnet 1 spec](https://notes.ethereum.org/@ethpandaops/fusaka-devnet-1). diff --git a/docs/running_tests/test_formats/state_test.md b/docs/running_tests/test_formats/state_test.md index b4aed6a7c83..51d341d5c55 100644 --- a/docs/running_tests/test_formats/state_test.md +++ b/docs/running_tests/test_formats/state_test.md @@ -16,7 +16,7 @@ The JSON file path plus the test name are used as the unique test identifier. As opposed to other fixture formats, the state test fixture format could contain multiple test vectors per test object, each represented by an element in the mapping of lists of the `post` field. -However tests generated by the `execution-spec-tests` repository do **not** use this feature, as every single test object contains only a single test vector. +However tests generated by the `execution-specs` repository do **not** use this feature, as every single test object contains only a single test vector. ## Consumption diff --git a/docs/running_tests/test_formats/transaction_test.md b/docs/running_tests/test_formats/transaction_test.md index 47b7a7073c1..f395e0b9d03 100644 --- a/docs/running_tests/test_formats/transaction_test.md +++ b/docs/running_tests/test_formats/transaction_test.md @@ -16,7 +16,7 @@ The JSON file path plus the test name are used as the unique test identifier. The transaction test fixture format could contain multiple test vectors per test object, each represented by an element in the mapping of lists of the `result` field. -However tests generated by the `execution-spec-tests` repository do **not** use this feature, as every single test object contains only a single test vector. +However tests generated by the `execution-specs` repository do **not** use this feature, as every single test object contains only a single test vector. ## Consumption diff --git a/docs/specs/writing_specs.md b/docs/specs/writing_specs.md new file mode 100644 index 00000000000..bf1a7b46a03 --- /dev/null +++ b/docs/specs/writing_specs.md @@ -0,0 +1,4 @@ +# Writing Specs + +!!! note "Coming soon" + This section is under construction. In the meantime, see the [EIP Authors Manual](https://github.com/ethereum/execution-specs/blob/a48e0b381d5225a6c3de2d06cd9ee7ae0b6ca9bb/EIP_AUTHORS_MANUAL.md) for guidance on adding a new EIP to the reference specifications. diff --git a/docs/templates/function.md.j2 b/docs/templates/function.md.j2 index 3b152fa3b00..d773fc765b7 100644 --- a/docs/templates/function.md.j2 +++ b/docs/templates/function.md.j2 @@ -19,6 +19,9 @@ search: ## Parametrized Test Cases +This test generates {{ test_case_count }} parametrized test case{{ "s" if test_case_count > 1 else "" }} across {{ cases | map(attribute='fork') | unique | list | length }} fork{{ "s" if cases | map(attribute='fork') | unique | list | length > 1 else "" }}. + +{# Parameter tables temporarily disabled - re-enable when standalone pages support dark mode {% if test_case_count > 1 %} The interactive table below is also available as a [standalone page]({{ html_static_page_target }}). {% elif fixture_formats | length > 1 %} @@ -28,4 +31,5 @@ This test case is only parametrized by fork. {% endif %} {% include 'function_parameter_datatable.html.j2' %} +#} {% endblock %} diff --git a/docs/writing_tests/adding_a_new_test.md b/docs/writing_tests/adding_a_new_test.md index a9c8befa9cd..c1ed762b595 100644 --- a/docs/writing_tests/adding_a_new_test.md +++ b/docs/writing_tests/adding_a_new_test.md @@ -3,7 +3,7 @@ All test cases are located underneath the `tests` directory, which are then organized by fork. Each fork contains sub-directories containing test sub-categories. ```text -📁 execution-test-specs/ +📁 execution-specs/ ├─╴📁 tests/ | ├── 📄 __init__.py │ ├── 📁 cancun/ diff --git a/docs/writing_tests/code_standards.md b/docs/writing_tests/code_standards.md deleted file mode 100644 index 54ca891f694..00000000000 --- a/docs/writing_tests/code_standards.md +++ /dev/null @@ -1,4 +0,0 @@ -# Code Standards - -!!! warning "Documentation Moved" - This documentation has been relocated to [Code Standards](../getting_started/code_standards.md). Please use the new location for the most up-to-date information. diff --git a/docs/writing_tests/fuzzer_bridge.md b/docs/writing_tests/fuzzer_bridge.md index 8659a044978..47dd525a81e 100644 --- a/docs/writing_tests/fuzzer_bridge.md +++ b/docs/writing_tests/fuzzer_bridge.md @@ -1,6 +1,6 @@ # Fuzzer Bridge -The fuzzer bridge provides a seamless integration between blocktest fuzzers and the Ethereum execution-spec-tests framework, enabling automatic generation of valid blockchain test fixtures from fuzzer output. +The fuzzer bridge provides a seamless integration between blocktest fuzzers and the Ethereum execution-specs framework, enabling automatic generation of valid blockchain test fixtures from fuzzer output. ## Overview @@ -12,7 +12,7 @@ Fuzzers are excellent at generating test inputs to discover edge cases and bugs - System contract interactions - Genesis block derivation -The fuzzer bridge handles all these complexities automatically by leveraging the execution-spec-tests framework. +The fuzzer bridge handles all these complexities automatically by leveraging the execution-specs framework. ## Architecture @@ -24,7 +24,7 @@ graph LR ## Installation -The fuzzer bridge is included with the execution-spec-tests framework. Follow the [installation guide](../getting_started/installation.md) to set up EEST. +The fuzzer bridge is included with the execution-specs framework. Follow the [installation guide](../getting_started/installation.md) to set up EELS. Once installed, the `fuzzer_bridge` command will be available through `uv run`. @@ -255,8 +255,3 @@ builder.env_overrides = { 3. **Use Parallel Processing**: For large batches, use `--parallel` flag for better performance 4. **Version Control**: Track generated fixtures in version control for regression testing 5. **Continuous Integration**: Integrate fuzzer bridge into CI pipelines for automated testing - -## Further Resources - -- [EEST Framework Documentation](../index.md) -- [Ethereum Test Format Specifications](./reference_specification.md) diff --git a/docs/writing_tests/index.md b/docs/writing_tests/index.md index 0d3ebee67b3..839903fed40 100644 --- a/docs/writing_tests/index.md +++ b/docs/writing_tests/index.md @@ -21,12 +21,11 @@ For help deciding which test format to select, see [Types of Tests](./types_of_t ## Key Resources -- [Coding Standards](./code_standards.md) - Code style and standards for this repository +- [Coding Standards](../getting_started/code_standards.md) - Code style and standards for this repository - [Adding a New Test](./adding_a_new_test.md) - Step-by-step guide to adding new tests - [Writing a New Test](./writing_a_new_test.md) - Detailed guide on writing different test types - [Using and Extending Fork Methods](./fork_methods.md) - How to use fork methods to write fork-adaptive tests - [Gas Optimization](./gas_optimization.md) - Optimize gas limits in your tests for efficiency and compatibility with future forks. -- [Porting tests](./porting_legacy_tests.md): A guide to porting @ethereum/tests to EEST. ## Advanced Topics diff --git a/docs/writing_tests/porting_legacy_tests.md b/docs/writing_tests/porting_legacy_tests.md deleted file mode 100644 index 813cd0ce3ea..00000000000 --- a/docs/writing_tests/porting_legacy_tests.md +++ /dev/null @@ -1,128 +0,0 @@ -# A Guide to Porting Original Ethereum Tests to EEST - -## Background - -EEST is the successor to [ethereum/tests](https://github.com/ethereum/tests) (aka "original tests"), a repository that defined EVM test cases from the [Frontier](https://ethereum.org/en/history/#frontier) phase up to and including [The Merge](https://ethereum.org/en/history/#paris). These test cases are specified as YAML (and occasionally JSON) files in the [`./src/`](https://github.com/ethereum/tests/tree/develop/src) sub-directory. JSON test fixtures, which are fully-populated tests that can be executed against clients, are generated using [ethereum/retesteth](https://github.com/ethereum/retesteth). These JSON artifacts are regenerated when needed and added to the repository, typically in the [`tests/static/state_tests`](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static/state_tests) sub-directory. - -From [Shanghai](https://ethereum.org/en/history/#shapella) onward, new test cases — especially for new features introduced in hard forks—are defined in Python within EEST. While the existing test cases remain important for client testing, porting ethereum/tests to EEST will help maintain and generate tests for newer forks. This also ensures feature parity, as client teams will only need to obtain test fixture releases from one source. - -While automating the conversion of the remaining YAML (or JSON) test cases to Python is possible, manually porting individual test cases offers several benefits: - -- Reducing the number of test cases by combining multiple YAML (or JSON) cases into a single Python test function using parametrization. -- Potentially improving coverage by parametrizing the Python version. -- Producing higher quality code and documentation, which are typically clearer than an automated conversion. -- Ensuring better organization of tests within the `./tests` folder of execution-spec-tests by fork and EIP. - -## Porting an original test - -1. Select one or more test cases from `./tests/static/state_tests/` to port and create an issue in this repository AND comment on [this tracker issue.](https://github.com/ethereum/execution-spec-tests/issues/972) - -2. [Add a new test](../writing_tests/index.md) in the appropriate fork folder, following the guidelines for [choosing a test type.](../writing_tests/types_of_tests.md#deciding-on-a-test-type) - -3. Submit a PR with the ported tests: - - 1. Add the list of ported files using python marker to the head of your python test. - - Example: - - ```python - @pytest.mark.ported_from( - [ - "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_ContractSuicideDuringInit_ThenStoreThenReturnFiller.json", - "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_ContractSuicideDuringInit_WithValueFiller.json", - ], - pr=["https://github.com/ethereum/execution-spec-tests/pull/1871"], - # coverage_missed_reason="Converting solidity code result in following opcode not being used:", - ``` - - Replace test names with your chosen tests and PR number. - - Uncomment coverage_missed_reason when all the missed coverage lines are approved, usually some opcodes end up not used after translating test logic from lllc, yul. - - But sometimes missed coverage line could hint that you forgot to account important test logic. - - If no coverage is missed, you are good! - - 2. Remove the ported files from .tests/static/state_tests in your PR - -> See also: 📄 [Getting started with EEST.](../getting_started/repository_overview.md) - -## Filling tests - -EEST uses pytest to run tests against [EELS (an EVM implementation for testing)](https://github.com/ethereum/execution-specs). This process is known as "filling" and verifies the assertions in your tests. You can use the fill CLI for this. For example, see how to fill the `PUSH` opcode. - -```shell -uv run fill tests/frontier/opcodes/test_push.py -``` - -See also: 📄 [Documentation for the `fill` command.](../filling_tests/filling_tests_command_line.md) - -> If the tests can't currently be filled, please explain the issue (feel free to also [open a Discussion](https://github.com/ethereum/execution-spec-tests/discussions/new?category=general)). - -## Debugging tests - -By default, EVM logs are stored in the `logs` folder at the repository root. You can check the `output` folder to review transaction results. If needed, review a previous PR that ported tests (e.g., [the PR porting the `PUSH` opcode](https://github.com/ethereum/execution-spec-tests/pull/975), and [other port PRs](https://github.com/ethereum/execution-spec-tests/pulls?q=is%3Apr+label%3Aport)). - -## Test coverage - -It's crucial that ported tests maintain coverage parity with _original tests_. This ensures that no critical functions are left untested and prevents the introduction of bugs. A CI workflow automatically checks for coverage. - -If coverage action fails (See: 📄 [An example of a failing test coverage](https://github.com/ethereum/execution-spec-tests/actions/runs/13037332959/job/36370897481)), it's recommended to run the coverage action locally (see: 📄 [How to run GitHub actions locally](../dev/test_actions_locally.md)), which should generate a `evmtest_coverage` directory: - -```console -❯ tree evmtest_coverage -L 2 -evmtest_coverage -└── coverage - ├── BASE - ├── BASE_TESTS - ├── coverage_BASE.lcov - ├── coverage_PATCH.lcov - ├── DIFF - ├── difflog.txt - ├── PATCH - └── PATCH_TESTS -``` - -Here `BASE`is _original tests_, `PATCH` is the ported test, and `DIFF` is the coverage difference on EVMONE. Open `evmtest_coverage/coverage/DIFF/index.html` in browser: - -![Annotated coverage](../img/annotated-coverage.jpg) - -| Label | Description | -| ----- | :-----------------------------------------------------------------------------: | -| `LBC` | **Lost base coverage:** Code that was tested before, but is untested now. | -| `UBC` | **Uncovered baseline code:** Code that was untested before and untested now. | -| `GBC` | **Gained baseline coverage:** Code that was untested before, but is tested now. | -| `CBC` | **Covered baseline code:** Code that was tested before and is tested now. | - -Follow the hyperlinks for lost base coverage (`LBC`) to address coverage gaps. Here is an example coverage loss: - -![Missing original coverage](../img/original-coverage-loss.png) - -> Lost line coverage from a coverage report. In this case, caused by a missing invocation of `CALLDATALOAD`. - -!!! note "Expected coverage loss" - - EEST uses [pytest](https://docs.pytest.org/en/stable/), a popular Python testing framework, to help orchestrate testing Ethereum specifications, while _original tests_ relied on large, static contracts and the EVM to handle much of the execution. This difference can lead to coverage gaps. EEST favors dynamic contract creation for each test vector, while _original tests_ preferred a single static contract with multiple test vectors determined by transaction input data. - - It's important to note that coverage helps identify missing test paths. If you believe the coverage loss is due to differences in "setup" code between frameworks and doesn't impact the feature you're testing, explain this in your PR. A team member can help with the review. - - For example, review the [discussion in this PR] to see an example of why and how coverage loss can occur.(https://github.com/ethereum/execution-spec-tests/pull/975#issuecomment-2528792289) - -## Resolving Coverage Gaps from Yul Compilation - -When porting tests from ethereum/tests, you may encounter coverage gaps that are false positives. This commonly occurs because: - -- **Original tests** often used Yul to define smart contracts, and solc compilation introduces additional opcodes that aren't specifically under test -- **EEST ports** use the explicit EEST Opcode mini-language, which is more precise in opcode definition - -If coverage analysis shows missing opcodes that were only present due to Yul compilation artifacts (not the actual feature being tested), this can be resolved during PR review by adding the `coverage_missed_reason` parameter: - -```python -@pytest.mark.ported_from( - ["path/to/original_test.json"], - coverage_missed_reason="Missing opcodes are Yul compilation artifacts, not part of tested feature" -) -``` - -!!! note "Add coverage_missed_reason only after PR review" - Only add `coverage_missed_reason` after PR review determines the coverage gap is acceptable, never preemptively. This helps maintain test coverage integrity while accounting for legitimate differences between Yul-based and EEST opcode-based implementations. diff --git a/docs/writing_tests/post_mortems.md b/docs/writing_tests/post_mortems.md index 2b6373adf94..b9f5dd0ec30 100644 --- a/docs/writing_tests/post_mortems.md +++ b/docs/writing_tests/post_mortems.md @@ -78,7 +78,7 @@ IDs of the tests added that now cover the missed scenario and link to the docume *Example:* -- [`tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm.py::test_invalid\[fork_Prague-state_test---bls_g1_truncated_input-\]`](https://eest.ethereum.org/main/tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm/test_invalid/) +- [`tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm.py::test_invalid\[fork_Prague-state_test---bls_g1_truncated_input-\]`](../tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm/test_invalid/) ### Framework/Documentation Changes diff --git a/docs/writing_tests/reference_specification.md b/docs/writing_tests/reference_specification.md index 347a79075bb..a3b7c458769 100644 --- a/docs/writing_tests/reference_specification.md +++ b/docs/writing_tests/reference_specification.md @@ -63,7 +63,7 @@ This would only check EIP versions for the EIP-3651 tests in the `shanghai/eip36 ## Automated Checks via GitHub Actions -The repository includes a [GitHub Actions workflow](https://github.com/ethereum/execution-spec-tests/actions/workflows/check_eip_versions.yaml) that automatically runs `check_eip_versions` on a daily schedule. If any outdated EIP references are detected, the workflow creates an issue in the repository with details about which references need to be updated. +The repository includes a [GitHub Actions workflow](https://github.com/ethereum/execution-specs/actions/workflows/check_eip_versions.yaml) that automatically runs `check_eip_versions` on a daily schedule. If any outdated EIP references are detected, the workflow creates an issue in the repository with details about which references need to be updated. This workflow uses GitHub's built-in token for authentication, so there's no need to configure personal access tokens for the automated checks. The issue will include links to the relevant workflow run and details about which tests need updating. diff --git a/docs/writing_tests/test_markers.md b/docs/writing_tests/test_markers.md index e297e94f2b9..25fce189257 100644 --- a/docs/writing_tests/test_markers.md +++ b/docs/writing_tests/test_markers.md @@ -67,7 +67,7 @@ This marker only differs from `pytest.mark.with_all_tx_types` in that it does no This marker is used to automatically parameterize a test with all typed transactions, including `type=0` (legacy transaction), that are valid for the fork being tested. This marker is an indirect marker that utilizes the `tx_type` values from the `pytest.mark.with_all_tx_types` marker to build default typed transactions for each `tx_type`. -Optional: Default typed transactions used as values for `typed_transaction` exist in `src/execution_testing/cli/pytest_commands/plugins/shared/transaction_fixtures.py` and can be overridden for the scope of +Optional: Default typed transactions used as values for `typed_transaction` exist in `packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/transaction_fixtures.py` and can be overridden for the scope of the test by re-defining the appropriate `pytest.fixture` for that transaction type. ```python @@ -332,7 +332,7 @@ In this example, the test will be marked as expected to fail when it is being ex ### `@pytest.mark.slow` -This marker is used to mark tests that are slow to run. These tests are not run during [CI checks](./verifying_changes.md), and are only run when a release is being prepared. +This marker is used to mark tests that are slow to run. These tests are not run during [CI checks](../getting_started/verifying_changes.md), and are only run when a release is being prepared. ### `@pytest.mark.pre_alloc_mutable` diff --git a/docs/writing_tests/tutorials/blockchain.md b/docs/writing_tests/tutorials/blockchain.md index d6082529d5c..b9b0b068de7 100644 --- a/docs/writing_tests/tutorials/blockchain.md +++ b/docs/writing_tests/tutorials/blockchain.md @@ -66,7 +66,7 @@ Each integer in the `tx_per_block` array is the number of transactions in a bloc tx_per_block = [2, 0, 4, 8, 0, 0, 20, 1, 50] ``` -The code section that creates the blocks is a bit complex in this test. For some simpler definitions of Block creation you can browse tests within [`test_withdrawals.py`](https://github.com/ethereum/execution-spec-tests/blob/main/tests/shanghai/eip4895_withdrawals/test_withdrawals.py). +The code section that creates the blocks is a bit complex in this test. For some simpler definitions of Block creation you can browse tests within [`test_withdrawals.py`](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/tests/shanghai/eip4895_withdrawals/test_withdrawals.py). ```python blocks = map( diff --git a/docs/writing_tests/tutorials/state_transition.md b/docs/writing_tests/tutorials/state_transition.md index 8c9e37deb7b..08d279c98bd 100644 --- a/docs/writing_tests/tutorials/state_transition.md +++ b/docs/writing_tests/tutorials/state_transition.md @@ -69,7 +69,7 @@ This is the format of a [Python function](https://docs.python.org/3/tutorial/con It starts with `def ():`, and then has indented code for the function. The function definition ends when there is a line that is no longer indented. As with files, by convention functions start with a string that explains what the function does. -The function parameters (`state_test` and `pre`) are [pytest fixtures](https://docs.pytest.org/en/latest/explanation/fixtures.html) provided by the execution-spec-tests framework. Pytest fixtures are a powerful dependency injection mechanism that automatically provide objects to your test functions. +The function parameters (`state_test` and `pre`) are [pytest fixtures](https://docs.pytest.org/en/latest/explanation/fixtures.html) provided by the execution-specs framework. Pytest fixtures are a powerful dependency injection mechanism that automatically provide objects to your test functions. **The `state_test` fixture** is a callable that you *must* include in *state test* function arguments. When called at the end of your test function with the environment, pre-state, transaction, and expected post-state, it generates the actual test fixtures. This callable is a wrapper around the `StateTest` class. @@ -79,7 +79,7 @@ The function parameters (`state_test` and `pre`) are [pytest fixtures](https://d env = Environment(number=1) ``` -This line specifies that `env` is an [`Environment`][execution_testing.test_types.Environment] object. In this example, we only override the block `number` to 1, leaving all other values at their defaults. It's recommended to use default values whenever possible and only specify custom values when required for your specific test scenario. (For all available fields, see the pydantic model fields in the source code of [`Environment`][execution_testing.test_types.Environment] and [`EnvironmentGeneric`](https://github.com/ethereum/execution-spec-tests/blob/b4d7826bec631574a6fb95d0c58d2c8c4d6e02ca/packages/testing/src/execution_testing/test_types/block_types.py#L76) from which `Environment` inherits.) +This line specifies that `env` is an [`Environment`][execution_testing.test_types.Environment] object. In this example, we only override the block `number` to 1, leaving all other values at their defaults. It's recommended to use default values whenever possible and only specify custom values when required for your specific test scenario. (For all available fields, see the pydantic model fields in the source code of [`Environment`][execution_testing.test_types.Environment] and [`EnvironmentGeneric`](https://github.com/ethereum/execution-specs/blob/b4d7826bec631574a6fb95d0c58d2c8c4d6e02ca/packages/testing/src/execution_testing/test_types/block_types.py#L76) from which `Environment` inherits.) #### Pre State @@ -132,7 +132,7 @@ The returned object, which includes a private key, an address, and a nonce, is s ) ``` -With the pre-state built, we can now create the transaction that will call our contract. Let's examine the key components of this [`Transaction`][execution_testing.test_types.Transaction] (for all available fields, see the source code of [`Transaction`][execution_testing.test_types.Transaction] and [`TransactionGeneric`](https://github.com/ethereum/execution-spec-tests/blob/b4d7826bec631574a6fb95d0c58d2c8c4d6e02ca/packages/testing/src/execution_testing/test_types/transaction_types.py#L163) from which `Transaction` inherits). +With the pre-state built, we can now create the transaction that will call our contract. Let's examine the key components of this [`Transaction`][execution_testing.test_types.Transaction] (for all available fields, see the source code of [`Transaction`][execution_testing.test_types.Transaction] and [`TransactionGeneric`](https://github.com/ethereum/execution-specs/blob/b4d7826bec631574a6fb95d0c58d2c8c4d6e02ca/packages/testing/src/execution_testing/test_types/transaction_types.py#L163) from which `Transaction` inherits). - **`sender=sender`**: We use the EOA we created earlier, which already has the necessary information to sign the transaction and contains the correct `nonce`. The `nonce` is a protection mechanism to prevent replay attacks - it must equal the number of transactions sent from the sender's address, starting from zero. The framework automatically manages nonce incrementing for us. diff --git a/docs/writing_tests/types_of_tests.md b/docs/writing_tests/types_of_tests.md index b3682d6687b..ae5ff062c05 100644 --- a/docs/writing_tests/types_of_tests.md +++ b/docs/writing_tests/types_of_tests.md @@ -79,6 +79,6 @@ Test correct transaction rejection/acceptance of a serialized transaction (curre Whenever possible, use `state_test` to examine individual transactions. This method is more straightforward and less prone to external influences that can occur during block building. -This provides more targeted testing since it does not invoke the client's block-building machinery. This reduces the risk of encountering false positives, particularly in exception scenarios (e.g., see issue [#343: "Zero max_fee_per_blob_gas test is ineffective"](https://github.com/ethereum/execution-spec-tests/issues/343)). +This provides more targeted testing since it does not invoke the client's block-building machinery. This reduces the risk of encountering false positives, particularly in exception scenarios (e.g., see issue [#343: "Zero max_fee_per_blob_gas test is ineffective"](https://github.com/ethereum/execution-specs/issues/343)). Moreover, the `fill` command automatically additionally generates a `blockchain_test` for every `state_test` by wrapping the `state_test`'s transaction in a block. diff --git a/docs/writing_tests/verifying_changes.md b/docs/writing_tests/verifying_changes.md deleted file mode 100644 index d36f784270e..00000000000 --- a/docs/writing_tests/verifying_changes.md +++ /dev/null @@ -1,4 +0,0 @@ -# Verifying Changes - -!!! warning "Documentation Moved" - This documentation has been relocated to [Detailed Code Standards](../getting_started/code_standards_details.md). Please use the new location for the most up-to-date information. diff --git a/docs/writing_tests/writing_a_new_test.md b/docs/writing_tests/writing_a_new_test.md index 4a52019bd1e..d8e0de0d7fa 100644 --- a/docs/writing_tests/writing_a_new_test.md +++ b/docs/writing_tests/writing_a_new_test.md @@ -178,7 +178,7 @@ which allows checking for an exact `gas_used` value. ## Writing code for the accounts in the test -Account bytecode can be "deployed" in a test's pre-state using the `pre` pytest fixture. The @ethereum/execution-spec-tests Python [`Opcodes`][execution_testing.vm.Opcodes] minilang can be used to help write the bytecode in a readable form. +Account bytecode can be "deployed" in a test's pre-state using the `pre` pytest fixture. The @ethereum/execution-specs Python [`Opcodes`][execution_testing.vm.Opcodes] minilang can be used to help write the bytecode in a readable form. ### Using the Python Opcode Minilang @@ -237,7 +237,7 @@ uv run evm_bytes hex-string 0x604260005260206000F3 #### Restrictions: No Yul in Python Test Cases -As of [PR #1779](https://github.com/ethereum/execution-spec-tests/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. +As of [PR #1779](https://github.com/ethereum/execution-specs/pull/1779), the use of Yul source in Python test cases is forbidden. All new tests must use the Python opcode minilang as shown above. ## Verifying the Accounts' Post States @@ -267,7 +267,7 @@ Within the `post` dictionary object, an account address can be: The `Account` object is used to specify the properties of an account to be verified in the post state. -The python representation can be found in [packages/testing/src/execution_testing/test_types/account_types.py](https://github.com/ethereum/execution-spec-tests/blob/main/packages/testing/src/execution_testing/test_types/account_types.py). +The python representation can be found in [packages/testing/src/execution_testing/test_types/account_types.py](https://github.com/ethereum/execution-specs/blob/a830dab6f130151ab9023a473b7543120aa21961/packages/testing/src/execution_testing/test_types/account_types.py). It can verify the following properties of an account: diff --git a/mkdocs.yml b/mkdocs.yml index bd382776217..4fca7a29c45 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,10 +1,10 @@ -site_name: Ethereum Execution Specs -site_description: The Ethereum Execution Layer Python Specifications and Tests -site_url: https://eest.ethereum.org/ +site_name: Ethereum Execution Layer Specifications +site_description: The Ethereum Execution Layer Specifications and Tests +site_url: https://steel.ethereum.foundation/docs/ repo_url: https://github.com/ethereum/execution-specs repo_name: execution-specs -edit_uri: edit/main/docs/ -copyright: "Copyright: 2025, Ethereum Community" +edit_uri: edit/forks/amsterdam/docs/ +copyright: "Copyright: 2026, Ethereum Community" plugins: - git-authors: @@ -40,7 +40,7 @@ watch: theme: name: material - logo: img/Ethereum-logo-600px.png + logo: img/eth-diamond-white.png favicon: img/ETH-logo-icon.svg language: en features: @@ -52,25 +52,21 @@ theme: - navigation.instant - navigation.tabs - navigation.footer - # disabled due to https://github.com/ethereum/execution-specs/issues/1491 - # palette: - # # Palette toggle for automatic mode - # - media: "(prefers-color-scheme)" - # toggle: - # icon: material/brightness-auto - # name: Switch to light mode - # Palette toggle for light mode - # - media: "(prefers-color-scheme: light)" - # scheme: default - # toggle: - # icon: material/brightness-7 - # name: Switch to dark mode - # # Palette toggle for dark mode - # - media: "(prefers-color-scheme: dark)" - # scheme: slate - # toggle: - # icon: material/brightness-4 - # name: Switch to system preference + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: deep-orange + accent: deep-orange + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: deep-orange + accent: deep-orange + toggle: + icon: material/brightness-4 + name: Switch to light mode markdown_extensions: - abbr diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/page_props.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/page_props.py index 774a71f0821..67589f32658 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/page_props.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/page_props.py @@ -231,6 +231,9 @@ def write_page( data-table that documents the parametrized test cases. """ super().write_page(file_opener, jinja2_env) + # Standalone HTML pages temporarily disabled - they don't + # inherit the Material theme (see issue #1491). + return if not self.cases: return html_template = jinja2_env.get_template("function.html.j2") diff --git a/packages/testing/src/execution_testing/config/docs.py b/packages/testing/src/execution_testing/config/docs.py index d52046c9579..291f6552311 100644 --- a/packages/testing/src/execution_testing/config/docs.py +++ b/packages/testing/src/execution_testing/config/docs.py @@ -17,8 +17,8 @@ class DocsConfig(BaseModel): GENERATE_UNTIL_FORK: str = "Amsterdam" """The fork until which documentation should be generated.""" - DOCS_BASE_URL: str = "https://eest.ethereum.org" + DOCS_BASE_URL: str = "https://steel.ethereum.foundation/docs" - # Documentation URLs prefixed with `DOCS_URL__` to avoid conflicts with - # other URLs - DOCS_URL__WRITING_TESTS: str = f"{DOCS_BASE_URL}/main/writing_tests/" + # Documentation URLs prefixed with `DOCS_URL__` to avoid conflicts + # with other URLs + DOCS_URL__WRITING_TESTS: str = f"{DOCS_BASE_URL}/writing_tests/" diff --git a/whitelist.txt b/whitelist.txt index 17bc1be3728..0c73495052e 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -50,6 +50,7 @@ 5E 5F +630m 6A 6B 6C @@ -709,6 +710,7 @@ jumpdest jumpf jumpi junit +Justfile JWT keccak @@ -728,6 +730,7 @@ Lets lets levelname Levenshtein +lexicographically lhs libcst lightclient @@ -850,8 +853,8 @@ ommers oneliner oob opc -opcount opcode's +opcount OpenSSL oprypin optparser @@ -1104,6 +1107,8 @@ SignerType signextend simlimit sload +slot1 +slot2 slt smod socketserver @@ -1250,6 +1255,8 @@ UI uid Uint uint +uint128 +uint16 ukiyo ulen uname @@ -1332,10 +1339,4 @@ ZeroPaddedHexNumber zfill zkevm Zsh -zsh -slot1 -slot2 -lexicographically -uint16 -uint128 -630m +zsh \ No newline at end of file From 81402c0dfdbdbe405206e5d2fc049b4a6d587a16 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 14 Apr 2026 11:13:59 +0200 Subject: [PATCH 009/186] feat(tooling): add `shell-completions` recipe to print setup instructions (#2651) --- Justfile | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Justfile b/Justfile index 23e2829b95d..58fa4859e2f 100644 --- a/Justfile +++ b/Justfile @@ -324,3 +324,39 @@ clean *args: [group('housekeeping')] clean-all *args: uv run eest clean --all "$@" + +# Print the command to install shell completions for just recipes +[group('housekeeping')] +shell-completions: + #!/usr/bin/env bash + case "$(basename "$SHELL")" in + bash) + echo "Run the following commands to install just completions for bash:" + echo "" + echo " mkdir -p ~/.local/share/bash-completion/completions" + echo " just --completions bash > ~/.local/share/bash-completion/completions/just" + ;; + zsh) + echo "Run the following commands to install just completions for zsh:" + echo "" + echo " mkdir -p ~/.zsh/completions" + echo " just --completions zsh > ~/.zsh/completions/_just" + echo "" + echo "Then add to your .zshrc:" + echo "" + echo " fpath=(~/.zsh/completions \$fpath)" + echo " autoload -U compinit" + echo " compinit" + ;; + fish) + echo "Run the following commands to install just completions for fish:" + echo "" + echo " mkdir -p ~/.config/fish/completions" + echo " just --completions fish > ~/.config/fish/completions/just.fish" + ;; + *) + echo "See the link below for instructions for your shell." + ;; + esac + echo "" + echo "For more details, see https://just.systems/man/en/shell-completion-scripts.html" From 6048fe5797c2eaf702b5794a4f727ca425bb8117 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 14 Apr 2026 11:33:09 +0200 Subject: [PATCH 010/186] feat(test-fill): add `--include-benchmark` and scan both tests + tests/benchmark in `checklist` (#2668) --- .../cli/pytest_commands/checklist.py | 32 ++++- .../filler/tests/test_include_benchmark.py | 113 ++++++++++++++++++ .../plugins/shared/benchmarking.py | 13 ++ .../tests/test_pytest_checklist_command.py | 48 ++++++++ tests/benchmark/conftest.py | 4 +- 5 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_include_benchmark.py create mode 100644 packages/testing/src/execution_testing/cli/tests/test_pytest_checklist_command.py diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py b/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py index 90024ae3ba0..b758256279e 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/checklist.py @@ -34,6 +34,11 @@ def _last_development_fork() -> str | None: @click.command() +@click.argument( + "paths", + nargs=-1, + type=click.Path(), +) @click.option( "--output", "-o", @@ -56,7 +61,11 @@ def _last_development_fork() -> str | None: help="Include upcoming forks up to and including this fork", ) def checklist( - output: str, eip: tuple[int, ...], until: str | None, **kwargs: Any + paths: tuple[str, ...], + output: str, + eip: tuple[int, ...], + until: str | None, + **kwargs: Any, ) -> None: """ Generate EIP test checklists based on pytest.mark.eip_checklist markers. @@ -64,20 +73,23 @@ def checklist( This command scans test files for eip_checklist markers and generates filled checklists showing which checklist items have been implemented. + By default it scans `tests` plus `tests/benchmark`; pass one or more + paths to limit collection to a subset. + By default, includes all development forks so that checklists for upcoming EIPs are generated without needing --until. Examples: - # Generate checklists for all EIPs + # Generate checklists for all EIPs (default: tests + tests/benchmark) uv run checklist # Generate checklist for specific EIP uv run checklist --eip 7702 - # Generate checklists for specific test path - uv run checklist tests/prague/eip7702* + # Generate checklists for a specific test path + uv run checklist tests/prague/eip7702_set_code_tx - # Limit to a specific fork + # Generate until a specific fork uv run checklist --until Prague # Specify output directory @@ -100,6 +112,16 @@ def checklist( if until: args.extend(["--until", until]) + # When no paths are provided, scan `tests/` and force inclusion of + # `tests/benchmark/` via `--include-benchmark`. The conftest normally + # hides `tests/benchmark/` from a plain `tests/` collection, and + # passing both as positional paths triggers pytest path deduplication + # which drops the broader `tests/`. + if not paths: + paths = ("tests",) + args.append("--include-benchmark") + args.extend(paths) + command = ChecklistCommand( plugins=[ "execution_testing.cli.pytest_commands.plugins.filler.eip_checklist" diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_include_benchmark.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_include_benchmark.py new file mode 100644 index 00000000000..a856eb9633e --- /dev/null +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_include_benchmark.py @@ -0,0 +1,113 @@ +"""Test the --include-benchmark flag gates tests/benchmark/ collection.""" + +import textwrap +from pathlib import Path + +import pytest + +REAL_BENCHMARK_CONFTEST = ( + Path(__file__).resolve().parents[9] / "tests" / "benchmark" / "conftest.py" +) +assert REAL_BENCHMARK_CONFTEST.is_file(), ( + f"Expected real benchmark conftest at {REAL_BENCHMARK_CONFTEST}; the " + "repo layout likely changed and the parent traversal above is stale." +) + +BENCHMARK_TEST_MODULE = textwrap.dedent( + """\ + import pytest + + from execution_testing import Environment + + @pytest.mark.valid_at("Prague") + def test_dummy_benchmark(state_test) -> None: + state_test(env=Environment(), pre={}, post={}, tx=None) + """ +) + +CONSENSUS_TEST_MODULE = textwrap.dedent( + """\ + import pytest + + from execution_testing import Environment + + @pytest.mark.valid_at("Prague") + def test_dummy_consensus(state_test) -> None: + state_test(env=Environment(), pre={}, post={}, tx=None) + """ +) + + +def _setup_benchmark_and_consensus_tests( + pytester: pytest.Pytester, +) -> None: + """Seed `tests/benchmark/` and `tests/prague/` test modules.""" + tests_dir = pytester.mkdir("tests") + + benchmark_dir = tests_dir / "benchmark" + benchmark_dir.mkdir() + (benchmark_dir / "conftest.py").write_text( + REAL_BENCHMARK_CONFTEST.read_text() + ) + benchmark_module = benchmark_dir / "dummy_test_module" + benchmark_module.mkdir() + (benchmark_module / "test_dummy_benchmark.py").write_text( + BENCHMARK_TEST_MODULE + ) + + consensus_dir = tests_dir / "prague" + consensus_dir.mkdir() + consensus_module = consensus_dir / "dummy_test_module" + consensus_module.mkdir() + (consensus_module / "test_dummy_consensus.py").write_text( + CONSENSUS_TEST_MODULE + ) + + pytester.copy_example( + name="src/execution_testing/cli/pytest_commands/pytest_ini_files/pytest-fill.ini" + ) + + +def test_default_excludes_benchmark(pytester: pytest.Pytester) -> None: + """A plain `tests/` collection hides `tests/benchmark/`.""" + _setup_benchmark_and_consensus_tests(pytester) + + result = pytester.runpytest( + "-c", + "pytest-fill.ini", + "--fork", + "Prague", + "tests/", + "--collect-only", + "-q", + ) + + assert result.ret == 0, f"Collection failed:\n{result.outlines}" + assert any("test_dummy_consensus" in line for line in result.outlines) + assert not any( + "test_dummy_benchmark" in line for line in result.outlines + ), f"Benchmark should be hidden by default:\n{result.outlines}" + + +def test_include_benchmark_flag_collects_both( + pytester: pytest.Pytester, +) -> None: + """`--include-benchmark` forces `tests/benchmark/` into collection.""" + _setup_benchmark_and_consensus_tests(pytester) + + result = pytester.runpytest( + "-c", + "pytest-fill.ini", + "--fork", + "Prague", + "tests/", + "--include-benchmark", + "--collect-only", + "-q", + ) + + assert result.ret == 0, f"Collection failed:\n{result.outlines}" + assert any("test_dummy_consensus" in line for line in result.outlines) + assert any("test_dummy_benchmark" in line for line in result.outlines), ( + f"Benchmark should be collected with the flag:\n{result.outlines}" + ) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py index c0c86c54b9c..2a47ed80365 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py @@ -71,6 +71,19 @@ def pytest_addoption(parser: pytest.Parser) -> None: "Can be a JSON string or path to a JSON file." ), ) + benchmark_group.addoption( + "--include-benchmark", + action="store_true", + dest="include_benchmark", + default=False, + help=( + "Include tests/benchmark/ during collection even when no " + "benchmark path is passed as a positional argument. Needed " + "when collecting both tests/ and tests/benchmark/ in a single " + "pytest invocation, since pytest's path deduplication drops " + "the broader tests/ arg." + ), + ) @pytest.hookimpl(tryfirst=True) diff --git a/packages/testing/src/execution_testing/cli/tests/test_pytest_checklist_command.py b/packages/testing/src/execution_testing/cli/tests/test_pytest_checklist_command.py new file mode 100644 index 00000000000..8deb6bc19ff --- /dev/null +++ b/packages/testing/src/execution_testing/cli/tests/test_pytest_checklist_command.py @@ -0,0 +1,48 @@ +"""Tests for the checklist command click CLI.""" + +from unittest.mock import patch + +import pytest +from click.testing import CliRunner + +from ..pytest_commands.checklist import checklist + + +@pytest.fixture +def runner() -> CliRunner: + """Provide a Click CliRunner for invoking command-line interfaces.""" + return CliRunner() + + +def _captured_execute_args(runner: CliRunner, *cli_args: str) -> list[str]: + """Invoke `checklist` and return the args passed to ChecklistCommand.""" + with patch( + "execution_testing.cli.pytest_commands.checklist.ChecklistCommand" + ) as mock_cls: + result = runner.invoke(checklist, list(cli_args)) + assert result.exit_code == 0, result.output + instance = mock_cls.return_value + instance.execute.assert_called_once() + (execute_args,) = instance.execute.call_args.args + return execute_args + + +def test_checklist_default_injects_include_benchmark( + runner: CliRunner, +) -> None: + """Default invocation passes `tests` plus `--include-benchmark`.""" + args = _captured_execute_args(runner) + + assert "--include-benchmark" in args + assert args[-1] == "tests" + + +def test_checklist_explicit_paths_skip_include_benchmark( + runner: CliRunner, +) -> None: + """Explicit paths scope collection and drop `--include-benchmark`.""" + args = _captured_execute_args(runner, "tests/prague/eip7702_set_code_tx") + + assert "--include-benchmark" not in args + assert "tests/prague/eip7702_set_code_tx" in args + assert "tests" not in args diff --git a/tests/benchmark/conftest.py b/tests/benchmark/conftest.py index 1659df3d496..b8cd5cdec04 100755 --- a/tests/benchmark/conftest.py +++ b/tests/benchmark/conftest.py @@ -51,8 +51,10 @@ def pytest_generate_tests(metafunc: Any) -> None: def pytest_ignore_collect(collection_path: Path, config: Any) -> bool | None: """Skip benchmark directory unless explicitly targeted.""" - benchmark_dir = Path(__file__).parent + if config.getoption("include_benchmark", default=False): + return False + benchmark_dir = Path(__file__).parent args = config.invocation_params.args or () if any( benchmark_dir in Path(a).resolve().parents From eb84f4c959ea969ec706215b1ecb20c93aa68f36 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 14 Apr 2026 15:25:09 +0200 Subject: [PATCH 011/186] feat(docs): use orange eth diamond as favicon (#2674) Add `docs/img/eth-diamond-orange.svg` shaded like `eth-diamond-white.svg` using the Material deep-orange theme color, and wire it up as the mkdocs favicon in place of `ETH-logo-icon.svg`. --- docs/img/eth-diamond-orange.svg | 1 + mkdocs.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/img/eth-diamond-orange.svg diff --git a/docs/img/eth-diamond-orange.svg b/docs/img/eth-diamond-orange.svg new file mode 100644 index 00000000000..38dd423c9da --- /dev/null +++ b/docs/img/eth-diamond-orange.svg @@ -0,0 +1 @@ + diff --git a/mkdocs.yml b/mkdocs.yml index 4fca7a29c45..9f5018c01b7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,7 +41,7 @@ watch: theme: name: material logo: img/eth-diamond-white.png - favicon: img/ETH-logo-icon.svg + favicon: img/eth-diamond-orange.svg language: en features: - content.code.copy From 6672cfe2ed3f0d8e58cec458c6221cbae00cd1ec Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Tue, 14 Apr 2026 10:09:42 -0600 Subject: [PATCH 012/186] feat(test-forks): enable multiple EIP to be specified in `fork.is_eip_enabled` (#2676) * feat(test-forks): Make `eip_number` in `is_eip_enabled` positional arg * feat(test-forks): Make `is_eip_enabled` receive multiple EIPs --- .../testing/src/execution_testing/forks/base_fork.py | 8 +++++--- .../src/execution_testing/forks/tests/test_forks.py | 11 +++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index d03e4c740db..c074c3da840 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -1057,9 +1057,11 @@ def eip(cls) -> int: return int(cls.__name__[3:]) @classmethod - def is_eip_enabled(cls, *, eip_number: int) -> bool: - """Return whether this class has an EIP enabled.""" - return eip_number in cls._enabled_eips + def is_eip_enabled(cls, *eip_numbers: int) -> bool: + """Return whether this class has all specified EIPs enabled.""" + return all( + eip_number in cls._enabled_eips for eip_number in eip_numbers + ) @classmethod def enabling_forks(cls) -> Set[Type["BaseFork"]]: diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index 7dadc3667c9..8d9cec7882c 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -724,7 +724,10 @@ def test_method_versions() -> None: # noqa: D103 def test_eips() -> None: # noqa: D103 assert EIP3675.enabling_forks() == {Paris} - assert Paris.is_eip_enabled(eip_number=3675) - assert Shanghai.is_eip_enabled(eip_number=3675) - assert not Paris.is_eip_enabled(eip_number=3855) - assert Shanghai.is_eip_enabled(eip_number=3855) + assert Paris.is_eip_enabled(3675) + assert Paris.is_eip_enabled(3675, 1559) + assert Shanghai.is_eip_enabled(3675) + assert not Paris.is_eip_enabled(3855) + assert not Paris.is_eip_enabled(3675, 3855) + assert not Paris.is_eip_enabled(3855, 3675) + assert Shanghai.is_eip_enabled(3855) From 3687eb564090c94ea49601adb284df4e4ff418e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Wed, 15 Apr 2026 03:32:50 +0800 Subject: [PATCH 013/186] feat(test-benchmark): add uncacheable precompile benchmark (#2600) * feat: add while gas generator * feat: add inner gas cost field for cost calculator * refactor: expected opcode count validation * chore: ignore fixed-opcode-count time-comsuming cases * fix ec_pairing and alt_bn128 uncachable benchmarks * refactor point evaluation uncachable benchmark * feat: add uncachable precompile benchmarks * fix: loop check logic * fix(tests-benchmark): Fix test_point_evaluation_uncachable --------- Co-authored-by: marioevz --- Justfile | 4 +- .../testing/src/execution_testing/__init__.py | 2 + .../execution_testing/forks/forks/forks.py | 3 + .../src/execution_testing/specs/benchmark.py | 76 ++-- .../src/execution_testing/tools/__init__.py | 2 + .../tools/tools_code/__init__.py | 2 + .../tools/tools_code/generators.py | 43 +++ .../src/execution_testing/vm/opcodes.py | 4 + .../compute/precompile/test_alt_bn128.py | 37 +- .../compute/precompile/test_blake2f.py | 124 +++++++ .../compute/precompile/test_bls12_381.py | 350 ++++++++++++++++++ .../compute/precompile/test_identity.py | 101 +++++ .../compute/precompile/test_modexp.py | 138 +++++++ .../compute/precompile/test_p256verify.py | 130 +++++++ .../precompile/test_point_evaluation.py | 171 ++++++++- .../compute/precompile/test_ripemd160.py | 100 +++++ .../compute/precompile/test_sha256.py | 98 +++++ 17 files changed, 1343 insertions(+), 42 deletions(-) diff --git a/Justfile b/Justfile index 58fa4859e2f..e7aa4247c5e 100644 --- a/Justfile +++ b/Justfile @@ -241,7 +241,7 @@ bench-opcode *args: --fork Osaka \ -m repricing \ -n auto --maxprocesses 10 --dist=loadgroup \ - -k "not test_alt_bn128 and not test_bls12_381 and not test_modexp" \ + -k "not test_alt_bn128 and not test_bls12_381 and not test_modexp and not uncachable" \ --output="{{ output_dir }}/bench-opcode/fixtures" \ --basetemp="{{ output_dir }}/bench-opcode/tmp" \ --log-to "{{ output_dir }}/bench-opcode/logs" \ @@ -260,7 +260,7 @@ bench-opcode-config *args: --fork Osaka \ -m repricing \ -n auto --maxprocesses 10 --dist=loadgroup \ - -k "not test_alt_bn128 and not test_bls12_381 and not test_modexp" \ + -k "not test_alt_bn128 and not test_bls12_381 and not test_modexp and not test_point_evaluation_uncachable" \ --output="{{ output_dir }}/bench-opcode-config/fixtures" \ --basetemp="{{ output_dir }}/bench-opcode-config/tmp" \ --log-to "{{ output_dir }}/bench-opcode-config/logs" \ diff --git a/packages/testing/src/execution_testing/__init__.py b/packages/testing/src/execution_testing/__init__.py index e55be28423b..d689bf9f28e 100644 --- a/packages/testing/src/execution_testing/__init__.py +++ b/packages/testing/src/execution_testing/__init__.py @@ -100,6 +100,7 @@ Switch, TransactionWithCost, While, + WhileGas, extend_with_defaults, gas_test, generate_system_contract_deploy_test, @@ -205,6 +206,7 @@ "TransactionWithCost", "TransitionFork", "While", + "WhileGas", "CoerceBytes", "Withdrawal", "WithdrawalRequest", diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 92eeb70a89a..f7e31c237f8 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -628,6 +628,9 @@ def _calculate_call_gas( else: base_cost = gas_costs.GAS_COLD_ACCOUNT_ACCESS + if metadata["inner_call_cost"]: + return base_cost + metadata["inner_call_cost"] + return base_cost @classmethod diff --git a/packages/testing/src/execution_testing/specs/benchmark.py b/packages/testing/src/execution_testing/specs/benchmark.py index 174ae96bf73..197cb5063eb 100644 --- a/packages/testing/src/execution_testing/specs/benchmark.py +++ b/packages/testing/src/execution_testing/specs/benchmark.py @@ -305,6 +305,7 @@ class BenchmarkTest(BaseTest): default_factory=lambda: int(Environment().gas_limit) ) fixed_opcode_count: float | None = None + expected_opcode_count: int | None = None target_opcode: Op | OpcodeTarget | None = None code_generator: BenchmarkCodeGenerator | None = None # By default, benchmark tests require neither of these @@ -363,14 +364,9 @@ def model_post_init(self, __context: Any, /) -> None: blocks: List[Block] = self.setup_blocks - if ( - self.fixed_opcode_count is not None - and self.code_generator is None - and self.target_opcode is None - ): + if self.fixed_opcode_count is not None and self.code_generator is None: pytest.skip( - "Cannot run fixed opcode count tests without a " - "code generator or a target opcode set" + "Cannot run fixed opcode count tests without a code generator" ) if self.code_generator is not None: @@ -525,34 +521,28 @@ def generate_blockchain_test(self) -> BlockchainTest: include_tx_receipts_in_output=self.include_tx_receipts_in_output, ) + @staticmethod def _verify_target_opcode_count( - self, opcode_count: OpcodeCount | None + *, + target_opcode: Op | OpcodeTarget, + opcode_count: OpcodeCount, + expected_opcode_count: int, + tolerance: float = 0.05, ) -> None: """Verify target opcode was executed the expected number of times.""" - # Skip validation if opcode count is not available - if opcode_count is None: - return - - assert self.target_opcode is not None, "target_opcode is not set" - assert self.fixed_opcode_count is not None, ( - "fixed_opcode_count is not set" - ) - - # fixed_opcode_count is in thousands units - expected = self.fixed_opcode_count * 1000 - count_opcode = ( - self.target_opcode.opcode - if isinstance(self.target_opcode, OpcodeTarget) - else self.target_opcode + target_opcode.opcode + if isinstance(target_opcode, OpcodeTarget) + else target_opcode ) actual = opcode_count.root.get(count_opcode, 0) - tolerance = expected * 0.05 # 5% tolerance + max_difference = expected_opcode_count * tolerance # 5% tolerance - if abs(actual - expected) > tolerance: + if abs(actual - expected_opcode_count) > max_difference: raise ValueError( - f"Target opcode {self.target_opcode} count mismatch: " - f"expected ~{expected} (±5%), got {actual}" + f"Target opcode {target_opcode} count mismatch: " + f"expected ~{expected_opcode_count} " + f"(±{tolerance * 100}%), got {actual}" ) def generate( @@ -571,12 +561,34 @@ def generate( # Verify target opcode count if specified if ( - self.target_opcode is not None - and self.fixed_opcode_count is not None + self.fixed_opcode_count is not None + or self.expected_opcode_count is not None ): - self._verify_target_opcode_count( - fill_result.benchmark_opcode_count - ) + target_opcode = self.target_opcode + assert target_opcode is not None, "target_opcode is not set" + opcode_count = fill_result.benchmark_opcode_count + if opcode_count is not None: + if self.fixed_opcode_count is not None: + self._verify_target_opcode_count( + target_opcode=target_opcode, + opcode_count=opcode_count, + expected_opcode_count=int( + # fixed_opcode_count is in thousands units + self.fixed_opcode_count * 1000 + ), + ) + elif self.expected_opcode_count is not None: + self._verify_target_opcode_count( + target_opcode=target_opcode, + opcode_count=opcode_count, + expected_opcode_count=self.expected_opcode_count, + ) + else: + raise Exception( + "Opcode verification needs either " + "`fixed_opcode_count` or `expected_opcode_count` " + "to be set." + ) if self.target_opcode is not None: fill_result.metadata["target_opcode"] = str(self.target_opcode) diff --git a/packages/testing/src/execution_testing/tools/__init__.py b/packages/testing/src/execution_testing/tools/__init__.py index 0bc6640f0c0..0164e2fcccf 100644 --- a/packages/testing/src/execution_testing/tools/__init__.py +++ b/packages/testing/src/execution_testing/tools/__init__.py @@ -17,6 +17,7 @@ Switch, TransactionWithCost, While, + WhileGas, ) from .utility.generators import ( DeploymentTestType, @@ -43,6 +44,7 @@ "Switch", "TransactionWithCost", "While", + "WhileGas", "extend_with_defaults", "gas_test", "generate_system_contract_deploy_test", diff --git a/packages/testing/src/execution_testing/tools/tools_code/__init__.py b/packages/testing/src/execution_testing/tools/tools_code/__init__.py index 26b32976579..7782729b900 100644 --- a/packages/testing/src/execution_testing/tools/tools_code/__init__.py +++ b/packages/testing/src/execution_testing/tools/tools_code/__init__.py @@ -14,6 +14,7 @@ Switch, TransactionWithCost, While, + WhileGas, ) from .yul import Solc, Yul, YulCompiler @@ -32,6 +33,7 @@ "Switch", "TransactionWithCost", "While", + "WhileGas", "Yul", "YulCompiler", ) diff --git a/packages/testing/src/execution_testing/tools/tools_code/generators.py b/packages/testing/src/execution_testing/tools/tools_code/generators.py index c539dabb939..3e82c18bd0f 100644 --- a/packages/testing/src/execution_testing/tools/tools_code/generators.py +++ b/packages/testing/src/execution_testing/tools/tools_code/generators.py @@ -255,6 +255,49 @@ def __new__( return super().__new__(cls, bytecode) +class WhileGas(Bytecode): + """ + Helper class to generate a gas-bounded while-loop. + + Similar to While but automatically generates a condition that checks + whether there is sufficient remaining gas for another iteration. + """ + + _iteration_cost: int + + def __new__( + cls, + *, + body: Bytecode | Op, + fork: Type[ForkOpcodeInterface], + extra_gas: int = 0, + ) -> Self: + """ + Assemble the loop bytecode with an automatic gas check condition. + + The loop continues while the remaining gas exceeds the cost of one + full iteration (body + loop overhead + extra_gas). + """ + # Build a temporary While with a dummy condition of the same byte + # length to calculate the real per-iteration gas cost. + dummy_condition = Op.GT(Op.GAS, Op.PUSH4[0]) + dummy_loop = While(body=body, condition=dummy_condition) + + # After GAS reads the remaining gas, the exit path still executes + # GT + PUSH4[offset] + PC + SUB + JUMPI. We must ensure enough gas + # remains for this exit path after a full iteration, otherwise the + # loop OOGs on exit instead of terminating cleanly. + exit_overhead = ( + Op.GT + Op.PUSH4[0] + Op.PC + Op.SUB + Op.JUMPI + ).gas_cost(fork) + minimum_gas = dummy_loop.gas_cost(fork) + extra_gas + exit_overhead + + # Now build the real condition with the actual cost. + condition = Op.GT(Op.GAS, Op.PUSH4[minimum_gas]) + bytecode = While(body=body, condition=condition) + return super().__new__(cls, bytecode) + + @dataclass(kw_only=True, slots=True) class Case: """ diff --git a/packages/testing/src/execution_testing/vm/opcodes.py b/packages/testing/src/execution_testing/vm/opcodes.py index 79d35860dd4..1ad001cb1c6 100644 --- a/packages/testing/src/execution_testing/vm/opcodes.py +++ b/packages/testing/src/execution_testing/vm/opcodes.py @@ -5158,6 +5158,7 @@ class Opcodes(Opcode, Enum): "old_memory_size": 0, "delegated_address": False, "delegated_address_warm": False, + "inner_call_cost": 0, }, ) """ @@ -5236,6 +5237,7 @@ class Opcodes(Opcode, Enum): "old_memory_size": 0, "delegated_address": False, "delegated_address_warm": False, + "inner_call_cost": 0, }, ) """ @@ -5361,6 +5363,7 @@ class Opcodes(Opcode, Enum): "old_memory_size": 0, "delegated_address": False, "delegated_address_warm": False, + "inner_call_cost": 0, }, ) """ @@ -5491,6 +5494,7 @@ class Opcodes(Opcode, Enum): "old_memory_size": 0, "delegated_address": False, "delegated_address_warm": False, + "inner_call_cost": 0, }, ) """ diff --git a/tests/benchmark/compute/precompile/test_alt_bn128.py b/tests/benchmark/compute/precompile/test_alt_bn128.py index 6466f554e7e..d81e490e964 100644 --- a/tests/benchmark/compute/precompile/test_alt_bn128.py +++ b/tests/benchmark/compute/precompile/test_alt_bn128.py @@ -16,6 +16,7 @@ OpcodeTarget, Transaction, While, + WhileGas, ) from py_ecc.bn128 import G1, G2, multiply @@ -584,7 +585,9 @@ def test_ec_pairing( address=0x08, args_offset=Op.MLOAD(Op.CALLDATASIZE), args_size=pair_size, + # gas accounting address_warm=True, + inner_call_cost=precompile_cost, ), ) + Op.MSTORE( Op.CALLDATASIZE, @@ -599,7 +602,7 @@ def test_ec_pairing( code = setup + loop attack_contract_address = pre.deploy_contract(code=code) - iteration_cost = loop.gas_cost(fork) + precompile_cost + iteration_cost = loop.gas_cost(fork) setup_cost = setup.gas_cost(fork) # Conservative per-variant estimate for sizing the calldata: @@ -620,6 +623,7 @@ def test_ec_pairing( txs: list[Transaction] = [] remaining_gas = gas_benchmark_value + expected_opcode_count = 0 while remaining_gas > 0: per_tx_gas = min(tx_gas_limit, remaining_gas) per_tx_variants = max( @@ -644,8 +648,9 @@ def test_ec_pairing( - mem_exp(new_bytes=len(calldata) + 32) ) - if gas_for_loop < iteration_cost: + if gas_for_loop < (per_tx_variants + 1) * iteration_cost: break + expected_opcode_count += per_tx_variants txs.append( Transaction( @@ -661,6 +666,8 @@ def test_ec_pairing( benchmark_test( target_opcode=Precompile.BN128_PAIRING, skip_gas_used_validation=True, + expected_receipt_status=1, + expected_opcode_count=expected_opcode_count, blocks=[Block(txs=txs)], ) @@ -713,7 +720,12 @@ def test_alt_bn128_uncachable( input, avoiding precompile result caching in clients. """ intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() - + gsc = fork.gas_costs() + precompile_cost = ( + gsc.GAS_PRECOMPILE_ECMUL + if precompile_address == 0x07 + else gsc.GAS_PRECOMPILE_ECADD + ) attack_block = Op.POP( Op.STATICCALL( gas=Op.GAS, @@ -722,11 +734,14 @@ def test_alt_bn128_uncachable( # One G1 point (2 * 32 bytes), overwrites the input point # so each iteration has unique precompile input. ret_size=64, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, ), ) setup = Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) - loop = While(body=attack_block, condition=Op.GAS) + loop = WhileGas(body=attack_block, fork=fork) code = setup + loop attack_contract_address = pre.deploy_contract(code=code) @@ -734,6 +749,7 @@ def test_alt_bn128_uncachable( remaining_gas = gas_benchmark_value seed = 0 + expected_opcode_count = 0 while remaining_gas > 0: gas_available = min(tx_gas_limit, remaining_gas) @@ -743,10 +759,14 @@ def test_alt_bn128_uncachable( else _generate_g1_point(seed) + scalar.to_bytes(32, "big") ) - intrinsic = intrinsic_gas_calculator(calldata=calldata) - if gas_available <= intrinsic: + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = gas_available - intrinsic - setup.gas_cost(fork) + if gas_for_loop < loop.gas_cost(fork): break - + expected_opcode_count += gas_for_loop // loop.gas_cost(fork) txs.append( Transaction( to=attack_contract_address, @@ -760,5 +780,8 @@ def test_alt_bn128_uncachable( benchmark_test( target_opcode=target, + skip_gas_used_validation=True, + expected_receipt_status=1, blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, ) diff --git a/tests/benchmark/compute/precompile/test_blake2f.py b/tests/benchmark/compute/precompile/test_blake2f.py index d88a2cc75d0..25a9407633a 100644 --- a/tests/benchmark/compute/precompile/test_blake2f.py +++ b/tests/benchmark/compute/precompile/test_blake2f.py @@ -1,12 +1,19 @@ """Benchmark BLAKE2F precompile.""" +import random + import pytest from execution_testing import ( Address, + Alloc, BenchmarkTestFiller, + Block, + Bytes, Fork, JumpLoopGenerator, Op, + Transaction, + WhileGas, ) from tests.istanbul.eip152_blake2.common import Blake2bInput @@ -85,3 +92,120 @@ def test_blake2f_benchmark( tx_kwargs={"data": calldata}, ), ) + + +@pytest.mark.repricing +@pytest.mark.parametrize("num_rounds", [1, 6, 12, 24]) +def test_blake2f_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + num_rounds: int, +) -> None: + """ + Benchmark BLAKE2F with unique input per call. + + Each iteration writes the 64-byte output back to offset 4 in + memory, overwriting the h[] state so every call receives a + distinct input, avoiding precompile result caching in + clients. + """ + precompile_address = Blake2bSpec.BLAKE2_PRECOMPILE_ADDRESS + if precompile_address not in fork.precompiles(): + pytest.skip("Precompile not enabled") + + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + + # BLAKE2F costs num_rounds gas. + gsc = fork.gas_costs() + precompile_cost = ( + num_rounds * gsc.GAS_PRECOMPILE_BLAKE2F_PER_ROUND + ) + gsc.GAS_PRECOMPILE_BLAKE2F_BASE + + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=precompile_address, + args_size=Op.CALLDATASIZE, + # override the h state + ret_offset=4, + ret_size=64, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ) + + # rounds: data[0:4] 4 bytes + # h: data[4:68] 64 bytes + # m: data[68:196] 128 bytes + # t: data[196:212] 16 bytes + # f: data[212:213] 1 byte + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=213, + old_memory_size=0, + new_memory_size=213, + ) + setup_cost = setup.gas_cost(fork) + + loop = WhileGas( + body=attack_block, + fork=fork, + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + iteration_cost = loop.gas_cost(fork) + + base_calldata = Blake2bInput( + rounds=num_rounds, f=True + ).create_blake2b_tx_data() + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + rng = random.Random(42) + + expected_opcode_count = 0 + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + h_state = rng.randbytes(64) + + calldata = Bytes( + base_calldata[:4] # rounds + + h_state # h + + base_calldata[68:] # m, t, f + ) + + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < iteration_cost: + break + + expected_opcode_count += gas_for_loop // iteration_cost + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + + benchmark_test( + target_opcode=Op.STATICCALL, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) diff --git a/tests/benchmark/compute/precompile/test_bls12_381.py b/tests/benchmark/compute/precompile/test_bls12_381.py index b05ec9c76df..4636b6015ed 100644 --- a/tests/benchmark/compute/precompile/test_bls12_381.py +++ b/tests/benchmark/compute/precompile/test_bls12_381.py @@ -1,17 +1,30 @@ """Benchmark BLS12_381 precompile.""" +import math +import random +from collections.abc import Callable + import pytest from execution_testing import ( Address, + Alloc, BenchmarkTestFiller, + Block, Bytes, Fork, JumpLoopGenerator, Op, OpcodeTarget, + Transaction, + While, + WhileGas, ) +from py_ecc import optimized_bls12_381 as bls_curve from tests.prague.eip2537_bls_12_381_precompiles import spec as bls12381_spec +from tests.prague.eip2537_bls_12_381_precompiles.spec import ( + build_gas_calculation_function_map, +) from ..helpers import Precompile, concatenate_parameters @@ -255,3 +268,340 @@ def test_bls12_pairing( tx_kwargs={"data": calldata}, ), ) + + +def _generate_bls12_g1_point(seed: int) -> Bytes: + """Generate a valid BLS12-381 G1 point from a seed.""" + rng = random.Random(seed) + k = rng.randint(1, 2**32 - 1) + point = bls_curve.normalize(bls_curve.multiply(bls_curve.G1, k)) + x = int(point[0]) + y = int(point[1]) + return Bytes(x.to_bytes(64, "big") + y.to_bytes(64, "big")) + + +def _generate_bls12_g2_point(seed: int) -> Bytes: + """Generate a valid BLS12-381 G2 point from a seed.""" + rng = random.Random(seed) + k = rng.randint(1, 2**32 - 1) + point = bls_curve.normalize(bls_curve.multiply(bls_curve.G2, k)) + x_im = int(point[0].coeffs[0]) + x_re = int(point[0].coeffs[1]) + y_im = int(point[1].coeffs[0]) + y_re = int(point[1].coeffs[1]) + return Bytes( + x_im.to_bytes(64, "big") + + x_re.to_bytes(64, "big") + + y_im.to_bytes(64, "big") + + y_re.to_bytes(64, "big") + ) + + +def _generate_bls12_pairs(n: int, seed: int = 0) -> Bytes: + """Generate n valid BLS12-381 (G1, G2) pairs.""" + calldata = Bytes() + for i in range(n): + g1 = _generate_bls12_g1_point(seed + 2 * i) + g2 = _generate_bls12_g2_point(seed + 2 * i + 1) + calldata = Bytes(calldata + g1 + g2) + return calldata + + +def _g1add_calldata(seed: int) -> Bytes: + """Generate G1ADD calldata with unique first point.""" + return Bytes(_generate_bls12_g1_point(seed) + bytes(bls12381_spec.Spec.P1)) + + +def _g2add_calldata(seed: int) -> Bytes: + """Generate G2ADD calldata with unique first point.""" + return Bytes(_generate_bls12_g2_point(seed) + bytes(bls12381_spec.Spec.P2)) + + +def _g1msm_calldata(seed: int) -> Bytes: + """Generate G1MSM calldata with unique point.""" + return Bytes( + _generate_bls12_g1_point(seed) + + bytes(bls12381_spec.Scalar(bls12381_spec.Spec.Q)) + ) + + +def _g2msm_calldata(seed: int) -> Bytes: + """Generate G2MSM calldata with unique point.""" + return Bytes( + _generate_bls12_g2_point(seed) + + bytes(bls12381_spec.Scalar(bls12381_spec.Spec.Q)) + ) + + +def _fp_to_g1_calldata(seed: int) -> Bytes: + """Generate MAP_FP_TO_G1 calldata with unique FP.""" + rng = random.Random(seed) + return Bytes(bls12381_spec.FP(rng.randint(1, bls12381_spec.Spec.P - 1))) + + +def _fp2_to_g2_calldata(seed: int) -> Bytes: + """Generate MAP_FP2_TO_G2 calldata with unique FP2.""" + rng = random.Random(seed) + c0 = rng.randint(1, bls12381_spec.Spec.P - 1) + c1 = rng.randint(1, bls12381_spec.Spec.P - 1) + return Bytes(bls12381_spec.FP2((c0, c1))) + + +@pytest.mark.repricing +@pytest.mark.parametrize( + "precompile_address,ret_size,generate_calldata,target", + [ + pytest.param( + bls12381_spec.Spec.G1ADD, + 128, + _g1add_calldata, + Precompile.BLS12_G1ADD, + id="bls12_g1add", + ), + pytest.param( + bls12381_spec.Spec.G2ADD, + 256, + _g2add_calldata, + Precompile.BLS12_G2ADD, + id="bls12_g2add", + ), + pytest.param( + bls12381_spec.Spec.G1MSM, + 128, + _g1msm_calldata, + Precompile.BLS12_G1MSM, + id="bls12_g1msm", + ), + pytest.param( + bls12381_spec.Spec.G2MSM, + 256, + _g2msm_calldata, + Precompile.BLS12_G2MSM, + id="bls12_g2msm", + ), + pytest.param( + bls12381_spec.Spec.MAP_FP_TO_G1, + 64, + _fp_to_g1_calldata, + Precompile.BLS12_MAP_FP_TO_G1, + id="bls12_fp_to_g1", + ), + pytest.param( + bls12381_spec.Spec.MAP_FP2_TO_G2, + 128, + _fp2_to_g2_calldata, + Precompile.BLS12_MAP_FP2_TO_G2, + id="bls12_fp_to_g2", + ), + ], +) +def test_bls12_381_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + precompile_address: Address, + ret_size: int, + generate_calldata: Callable[[int], Bytes], + target: OpcodeTarget, +) -> None: + """ + Benchmark BLS12_381 with unique input per call. + + Each iteration writes the precompile output back to the + start of the input so every call receives a distinct input, + avoiding precompile result caching in clients. + """ + if precompile_address not in fork.precompiles(): + pytest.skip("Precompile not enabled") + + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + gas_calc_map = build_gas_calculation_function_map(fork.gas_costs()) + input_size = len(generate_calldata(0)) + precompile_cost = gas_calc_map[int(precompile_address)](input_size) + + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=precompile_address, + args_size=Op.CALLDATASIZE, + ret_size=ret_size, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ) + + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=input_size, + new_memory_size=input_size, + ) + setup_cost = setup.gas_cost(fork) + + loop = WhileGas(body=attack_block, fork=fork) + + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + iteration_cost = loop.gas_cost(fork) + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + seed = 0 + expected_opcode_count = 0 + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + calldata = generate_calldata(seed) + + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < iteration_cost: + break + expected_opcode_count += gas_for_loop // iteration_cost + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + seed += 1 + + benchmark_test( + target_opcode=target, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) + + +@pytest.mark.repricing +@pytest.mark.parametrize("num_pairs", [1, 3, 6, 12, 24]) +def test_bls12_pairing_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + num_pairs: int, +) -> None: + """Benchmark BLS12 pairing precompile with unique inputs per call.""" + precompile_address = bls12381_spec.Spec.PAIRING + if precompile_address not in fork.precompiles(): + pytest.skip("BLS12_PAIRING precompile not enabled") + + pair_size = num_pairs * 384 + gsc = fork.gas_costs() + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + mem_exp = fork.memory_expansion_gas_calculator() + + # Each iteration: STATICCALL pairing at advancing offset, + # then advance offset by pair_size at memory[CALLDATASIZE]. + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=precompile_address, + args_offset=Op.MLOAD(Op.CALLDATASIZE), + args_size=pair_size, + address_warm=True, + ), + ) + Op.MSTORE( + Op.CALLDATASIZE, + Op.ADD(Op.MLOAD(Op.CALLDATASIZE), pair_size), + ) + + setup = Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + loop = While( + body=attack_block, + condition=Op.GT(Op.CALLDATASIZE, Op.MLOAD(Op.CALLDATASIZE)), + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + precompile_cost = ( + gsc.GAS_PRECOMPILE_BLS_PAIRING_BASE + + gsc.GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR * num_pairs + ) + + iteration_cost = loop.gas_cost(fork) + precompile_cost + setup_cost = setup.gas_cost(fork) + + # Conservative per-variant estimate: one loop iteration + # + worst-case calldata floor intrinsic (all non-zero, EIP-7623) + # + CALLDATACOPY copy and linear memory expansion. + words_per_variant = math.ceil(pair_size / 32) + tokens_per_variant = pair_size * 4 # worst case: all non-zero + per_variant_gas = ( + iteration_cost + + tokens_per_variant * gsc.GAS_TX_DATA_TOKEN_FLOOR + + words_per_variant * (gsc.GAS_COPY + gsc.GAS_MEMORY) + ) + empty_intrinsic = intrinsic_gas_calculator( + calldata=[], + return_cost_deducted_prior_execution=False, + ) + fixed_overhead = empty_intrinsic + setup_cost + mem_exp(new_bytes=32) + + seed_offset = 0 + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + expected_opcode_count = 0 + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + per_tx_variants = max( + 1, + (per_tx_gas - fixed_overhead) // per_variant_gas, + ) + calldata = Bytes( + b"".join( + _generate_bls12_pairs(num_pairs, seed=42 + seed_offset + i) + for i in range(per_tx_variants) + ) + ) + + execution_intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=False, + ) + gas_for_loop = ( + per_tx_gas + - execution_intrinsic + - setup_cost + - math.ceil(len(calldata) / 32) * gsc.GAS_COPY + - mem_exp(new_bytes=len(calldata) + 32) + ) + + if gas_for_loop < (per_tx_variants + 1) * iteration_cost: + break + expected_opcode_count += per_tx_variants + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + seed_offset += per_tx_variants + + benchmark_test( + target_opcode=Precompile.BLS12_PAIRING, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) diff --git a/tests/benchmark/compute/precompile/test_identity.py b/tests/benchmark/compute/precompile/test_identity.py index 56198ef1e14..af33feecf34 100644 --- a/tests/benchmark/compute/precompile/test_identity.py +++ b/tests/benchmark/compute/precompile/test_identity.py @@ -1,11 +1,19 @@ """Benchmark IDENTITY precompile.""" +import math +import random + import pytest from execution_testing import ( + Alloc, BenchmarkTestFiller, + Block, + Bytes, Fork, JumpLoopGenerator, Op, + Transaction, + WhileGas, ) from ..helpers import Precompile, calculate_optimal_input_length @@ -60,3 +68,96 @@ def test_identity_fixed_size( setup=Op.CODECOPY(0, 0, size), attack_block=attack_block ), ) + + +@pytest.mark.repricing +@pytest.mark.parametrize("size", [32, 256, 1024]) +def test_identity_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + size: int, +) -> None: + """Benchmark IDENTITY with unique input per call.""" + gsc = fork.gas_costs() + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + + precompile_cost = ( + # static cost + gsc.GAS_PRECOMPILE_IDENTITY_BASE + # dynamic cost + + math.ceil(size / 32) * gsc.GAS_PRECOMPILE_IDENTITY_PER_WORD + ) + + attack_block = Op.MSTORE( + 0, + Op.ADD( + Op.MLOAD(0), + Op.STATICCALL( + gas=Op.GAS, + address=0x04, + args_size=size, + ret_size=size, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ), + old_memory_size=size, + new_memory_size=size, + ) + + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=size, + old_memory_size=0, + new_memory_size=size, + ) + setup_cost = setup.gas_cost(fork) + + loop = WhileGas( + body=attack_block, + fork=fork, + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + rng = random.Random(42) + expected_opcode_count = 0 + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + calldata = Bytes(rng.randbytes(size)) + + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < loop.gas_cost(fork): + break + expected_opcode_count += gas_for_loop // loop.gas_cost(fork) + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + + benchmark_test( + target_opcode=Precompile.IDENTITY, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) diff --git a/tests/benchmark/compute/precompile/test_modexp.py b/tests/benchmark/compute/precompile/test_modexp.py index 4e62c72160c..098ee3bef59 100644 --- a/tests/benchmark/compute/precompile/test_modexp.py +++ b/tests/benchmark/compute/precompile/test_modexp.py @@ -1,14 +1,24 @@ """Benchmark MODEXP precompile.""" +import random + import pytest from _pytest.mark import ParameterSet from execution_testing import ( + Alloc, BenchmarkTestFiller, + Block, + Bytes, + Fork, JumpLoopGenerator, Op, + Transaction, + WhileGas, ) +from execution_testing.forks import Osaka from tests.byzantium.eip198_modexp_precompile.helpers import ModExpInput +from tests.osaka.eip7883_modexp_gas_increase.spec import Spec, Spec7883 from ..helpers import Precompile @@ -417,3 +427,131 @@ def test_modexp( tx_kwargs={"data": bytes(mod_exp_input).rstrip(b"\x00")}, ), ) + + +@pytest.mark.repricing +@pytest.mark.parametrize( + "mod_exp_input", + [ + pytest.param( + ModExpInput( + base=32 * b"\xff", + exponent=32 * b"\xff", + modulus=31 * b"\xff" + b"\x01", + ), + id="mod_odd_32b_exp_256", + ), + pytest.param( + ModExpInput( + base=64 * b"\xff", + exponent=64 * b"\xff", + modulus=63 * b"\xff" + b"\x01", + ), + id="mod_odd_64b_exp_512", + ), + pytest.param( + ModExpInput( + base=128 * b"\xff", + exponent=128 * b"\xff", + modulus=127 * b"\xff" + b"\x01", + ), + id="mod_odd_128b_exp_1024", + ), + ], +) +def test_modexp_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + mod_exp_input: ModExpInput, +) -> None: + """Benchmark MODEXP with unique input per call.""" + base_length = len(mod_exp_input.base) + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + + base_calldata = bytes(mod_exp_input).rstrip(b"\x00") + calldata_len = len(base_calldata) + if fork >= Osaka: + precompile_cost = Spec7883.calculate_gas_cost(mod_exp_input) + else: + precompile_cost = Spec.calculate_gas_cost(mod_exp_input) + + # bsize: data[0:31] 32 bytes + # esize: data[32:64] 32 bytes + # msize: data[64:96] 32 bytes + # B: data[96:96+blength] blength bytes + # E: data[96+blength:96+blength+elength] elength bytes + # M: data[96+blength+elength:96+blength+elength+msize] msize bytes + + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=0x05, + args_size=Op.CALLDATASIZE, + ret_offset=96, + ret_size=base_length, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ) + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=calldata_len, + old_memory_size=0, + new_memory_size=calldata_len, + ) + setup_cost = setup.gas_cost(fork) + + loop = WhileGas( + body=attack_block, + fork=fork, + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + rng = random.Random(42) + expected_opcode_count = 0 + + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + new_base = rng.randbytes(base_length) + calldata = Bytes( + base_calldata[:96] # bsize, esize, msize + + new_base # B + + base_calldata[96 + base_length :] # E, M + ) + + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < loop.gas_cost(fork): + break + expected_opcode_count += gas_for_loop // loop.gas_cost(fork) + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + + benchmark_test( + target_opcode=Precompile.MODEXP, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) diff --git a/tests/benchmark/compute/precompile/test_p256verify.py b/tests/benchmark/compute/precompile/test_p256verify.py index 04c997cf0e8..bcbc27e6d01 100644 --- a/tests/benchmark/compute/precompile/test_p256verify.py +++ b/tests/benchmark/compute/precompile/test_p256verify.py @@ -3,10 +3,15 @@ import pytest from execution_testing import ( Address, + Alloc, BenchmarkTestFiller, + Block, + Bytes, Fork, JumpLoopGenerator, Op, + Transaction, + WhileGas, ) from tests.osaka.eip7951_p256verify_precompiles import spec as p256verify_spec @@ -88,3 +93,128 @@ def test_p256verify( tx_kwargs={"data": calldata}, ), ) + + +@pytest.mark.repricing +@pytest.mark.parametrize( + "precompile_address,calldata", + [ + pytest.param( + p256verify_spec.Spec.P256VERIFY, + concatenate_parameters( + [ + p256verify_spec.Spec.H0, + p256verify_spec.Spec.R0, + p256verify_spec.Spec.S0, + p256verify_spec.Spec.X0, + p256verify_spec.Spec.Y0, + ] + ), + id="p256verify", + ), + ], +) +def test_p256verify_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + precompile_address: Address, + calldata: bytes, +) -> None: + """Benchmark P256VERIFY with unique input per call.""" + if precompile_address not in fork.precompiles(): + pytest.skip("Precompile not enabled") + + gsc = fork.gas_costs() + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + + precompile_cost = gsc.GAS_PRECOMPILE_P256VERIFY + + # h: data[0:32] 32 bytes + # r: data[32:64] 32 bytes + # s: data[64:96] 32 bytes + # qx: data[96:128] 32 bytes + # qy: data[128:160] 32 bytes + attack_block = Op.MSTORE( + 0, + Op.ADD( + Op.MLOAD(0), + Op.STATICCALL( + gas=Op.GAS, + address=precompile_address, + args_size=Op.CALLDATASIZE, + ret_offset=Op.CALLDATASIZE, + ret_size=0x20, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ), + # gas accounting + old_memory_size=160, + new_memory_size=160, + ) + + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=160, + old_memory_size=0, + new_memory_size=160, + ) + setup_cost = setup.gas_cost(fork) + + loop = WhileGas( + body=attack_block, + fork=fork, + extra_gas=precompile_cost, + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + iteration_cost = loop.gas_cost(fork) + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + seed = 0 + expected_opcode_count = 0 + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + h = int.from_bytes(calldata[:32], "big") + seed + + tx_calldata = Bytes( + h.to_bytes(32, "big") # hash + + calldata[32:] # r, s, qx, qy + ) + + intrinsic = intrinsic_gas_calculator( + calldata=tx_calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < iteration_cost: + break + expected_opcode_count += gas_for_loop // iteration_cost + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=tx_calldata, + ) + ) + remaining_gas -= per_tx_gas + seed += 10000 + + benchmark_test( + target_opcode=Precompile.P256VERIFY, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) diff --git a/tests/benchmark/compute/precompile/test_point_evaluation.py b/tests/benchmark/compute/precompile/test_point_evaluation.py index 6d23f50402d..5f723243944 100644 --- a/tests/benchmark/compute/precompile/test_point_evaluation.py +++ b/tests/benchmark/compute/precompile/test_point_evaluation.py @@ -1,18 +1,29 @@ """Benchmark POINT EVALUATION precompile.""" +import math + +import ckzg # type: ignore import pytest from execution_testing import ( Address, + Alloc, BenchmarkTestFiller, + Block, + Bytes, Fork, JumpLoopGenerator, Op, + Transaction, + While, ) +from execution_testing.test_types.blob_types import Blob from tests.cancun.eip4844_blobs.spec import Spec as BlobsSpec from ..helpers import Precompile, concatenate_parameters +INPUT_SIZE = 192 + @pytest.mark.repricing @pytest.mark.parametrize( @@ -45,7 +56,9 @@ def test_point_evaluation( attack_block = Op.POP( Op.STATICCALL( - gas=Op.GAS, address=precompile_address, args_size=Op.CALLDATASIZE + gas=Op.GAS, + address=precompile_address, + args_size=Op.CALLDATASIZE, ), ) @@ -57,3 +70,159 @@ def test_point_evaluation( tx_kwargs={"data": calldata}, ), ) + + +def _generate_point_evaluation_input( + *, + blob_data: bytes, + commitment: bytes, + versioned_hash: bytes, + z: int, + trusted_setup: object, +) -> bytes: + """Generate a valid 192-byte point evaluation precompile input.""" + z_bytes = z.to_bytes(32, "big") + proof_bytes, y_bytes = ckzg.compute_kzg_proof( + blob_data, z_bytes, trusted_setup + ) + return versioned_hash + z_bytes + y_bytes + commitment + proof_bytes + + +@pytest.mark.repricing +@pytest.mark.parametrize( + "precompile_address", + [ + pytest.param( + BlobsSpec.POINT_EVALUATION_PRECOMPILE_ADDRESS, + id="point_evaluation", + ), + ], +) +def test_point_evaluation_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + precompile_address: Address, +) -> None: + """Benchmark POINT EVALUATION with unique valid input per call.""" + if precompile_address not in fork.precompiles(): + pytest.skip("Precompile not enabled") + + gsc = fork.gas_costs() + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + mem_exp = fork.memory_expansion_gas_calculator() + precompile_cost = gsc.GAS_PRECOMPILE_POINT_EVALUATION + + # Each iteration: STATICCALL point_evaluation at advancing calldata + # offset, then advance offset at MEM[CALLDATASIZE]. + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=precompile_address, + args_offset=Op.MLOAD(Op.CALLDATASIZE), + args_size=INPUT_SIZE, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ) + Op.MSTORE( + Op.CALLDATASIZE, + Op.ADD(Op.MLOAD(Op.CALLDATASIZE), INPUT_SIZE), + ) + + setup = Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + loop = While( + body=attack_block, + condition=Op.GT(Op.CALLDATASIZE, Op.MLOAD(Op.CALLDATASIZE)), + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + iteration_cost = loop.gas_cost(fork) + setup_cost = setup.gas_cost(fork) + + # Conservative per-variant estimate: one iteration + calldata + # intrinsic + CALLDATACOPY copy and linear memory expansion. + words_per_variant = math.ceil(INPUT_SIZE / 32) + per_variant_gas = ( + iteration_cost + + INPUT_SIZE * gsc.GAS_TX_DATA_TOKEN_FLOOR + + words_per_variant * (gsc.GAS_COPY + gsc.GAS_MEMORY) + ) + empty_intrinsic = intrinsic_gas_calculator( + calldata=[], return_cost_deducted_prior_execution=True + ) + fixed_overhead = empty_intrinsic + setup_cost + mem_exp(new_bytes=32) + + # Generate valid point evaluation inputs from a blob, each + # with a unique evaluation point z. + blob = Blob.from_fork(fork, seed=0) + trusted_setup = Blob.trusted_setup() + versioned_hash = BlobsSpec.kzg_to_versioned_hash(blob.commitment) + + seed_offset = 0 + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + expected_opcode_count = 0 + + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + per_tx_variants = max( + 1, (per_tx_gas - fixed_overhead) // per_variant_gas + ) + + points = [ + _generate_point_evaluation_input( + blob_data=blob.data, + commitment=blob.commitment, + versioned_hash=versioned_hash, + z=seed_offset + i + 1, + trusted_setup=trusted_setup, + ) + for i in range(per_tx_variants) + ] + calldata = Bytes(b"".join(points)) + while True: + execution_intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = ( + per_tx_gas + - execution_intrinsic + - setup_cost + - math.ceil(len(calldata) / 32) * gsc.GAS_COPY + - mem_exp(new_bytes=len(calldata) + 32) + ) + + if gas_for_loop >= per_tx_variants * iteration_cost: + break + per_tx_variants -= 1 + if not per_tx_variants: + raise Exception("Unable to find correct variants.") + calldata = Bytes(b"".join(points[:per_tx_variants])) + + expected_opcode_count += per_tx_variants + + assert len(calldata) != 0, "No valid calldata found for test" + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + seed_offset += per_tx_variants + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( + target_opcode=Precompile.POINT_EVALUATION, + skip_gas_used_validation=True, + expected_receipt_status=1, + expected_opcode_count=expected_opcode_count, + blocks=[Block(txs=txs)], + ) diff --git a/tests/benchmark/compute/precompile/test_ripemd160.py b/tests/benchmark/compute/precompile/test_ripemd160.py index 75aef42266a..81cee31d4f5 100644 --- a/tests/benchmark/compute/precompile/test_ripemd160.py +++ b/tests/benchmark/compute/precompile/test_ripemd160.py @@ -1,11 +1,19 @@ """Benchmark RIPEMD-160 precompile.""" +import math +import random + import pytest from execution_testing import ( + Alloc, BenchmarkTestFiller, + Block, + Bytes, Fork, JumpLoopGenerator, Op, + Transaction, + WhileGas, ) from ..helpers import Precompile, calculate_optimal_input_length @@ -60,3 +68,95 @@ def test_ripemd160_fixed_size( setup=Op.CODECOPY(0, 0, size), attack_block=attack_block ), ) + + +@pytest.mark.repricing +@pytest.mark.parametrize("size", [32, 256, 1024]) +def test_ripemd160_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + size: int, +) -> None: + """Benchmark RIPEMD-160 with unique input per call.""" + gsc = fork.gas_costs() + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + + precompile_cost = ( + # static cost + gsc.GAS_PRECOMPILE_RIPEMD160_BASE + # dynamic cost + + math.ceil(size / 32) * gsc.GAS_PRECOMPILE_RIPEMD160_PER_WORD + ) + + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=0x03, + args_size=size, + ret_size=0x20, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ) + + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=size, + old_memory_size=0, + new_memory_size=size, + ) + + setup_cost = setup.gas_cost(fork) + + loop = WhileGas( + body=attack_block, + fork=fork, + extra_gas=precompile_cost, + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + iteration_cost = loop.gas_cost(fork) + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + rng = random.Random(42) + expected_opcode_count = 0 + + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + calldata = Bytes(rng.randbytes(size)) + + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < iteration_cost: + break + expected_opcode_count += gas_for_loop // iteration_cost + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + + benchmark_test( + target_opcode=Precompile.RIPEMD160, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) diff --git a/tests/benchmark/compute/precompile/test_sha256.py b/tests/benchmark/compute/precompile/test_sha256.py index def1d35bdae..43245a04e19 100644 --- a/tests/benchmark/compute/precompile/test_sha256.py +++ b/tests/benchmark/compute/precompile/test_sha256.py @@ -1,11 +1,19 @@ """Benchmark SHA256 precompile.""" +import math +import random + import pytest from execution_testing import ( + Alloc, BenchmarkTestFiller, + Block, + Bytes, Fork, JumpLoopGenerator, Op, + Transaction, + WhileGas, ) from ..helpers import Precompile, calculate_optimal_input_length @@ -60,3 +68,93 @@ def test_sha256_fixed_size( setup=Op.CODECOPY(0, 0, size), attack_block=attack_block ), ) + + +@pytest.mark.repricing +@pytest.mark.parametrize("size", [32, 256, 1024]) +def test_sha256_uncachable( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + size: int, +) -> None: + """Benchmark SHA256 with unique input per call.""" + gsc = fork.gas_costs() + intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() + + precompile_cost = ( + # static cost + gsc.GAS_PRECOMPILE_SHA256_BASE + # dynamic cost + + math.ceil(size / 32) * gsc.GAS_PRECOMPILE_SHA256_PER_WORD + ) + attack_block = Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=0x02, + args_size=size, + ret_size=0x20, + # gas accounting + address_warm=True, + inner_call_cost=precompile_cost, + ), + ) + + setup = Op.CALLDATACOPY( + 0, + 0, + Op.CALLDATASIZE, + # gas accounting + data_size=size, + old_memory_size=0, + new_memory_size=size, + ) + setup_cost = setup.gas_cost(fork) + + loop = WhileGas( + body=attack_block, + fork=fork, + extra_gas=precompile_cost, + ) + code = setup + loop + attack_contract_address = pre.deploy_contract(code=code) + + iteration_cost = loop.gas_cost(fork) + + txs: list[Transaction] = [] + remaining_gas = gas_benchmark_value + rng = random.Random(42) + expected_opcode_count = 0 + + while remaining_gas > 0: + per_tx_gas = min(tx_gas_limit, remaining_gas) + calldata = Bytes(rng.randbytes(size)) + + intrinsic = intrinsic_gas_calculator( + calldata=calldata, + return_cost_deducted_prior_execution=True, + ) + gas_for_loop = per_tx_gas - intrinsic - setup_cost + if gas_for_loop < iteration_cost: + break + expected_opcode_count += gas_for_loop // iteration_cost + + txs.append( + Transaction( + to=attack_contract_address, + sender=pre.fund_eoa(), + gas_limit=per_tx_gas, + data=calldata, + ) + ) + remaining_gas -= per_tx_gas + + benchmark_test( + target_opcode=Precompile.SHA256, + skip_gas_used_validation=True, + expected_receipt_status=1, + blocks=[Block(txs=txs)], + expected_opcode_count=expected_opcode_count, + ) From c8c246c8892fce58091e16b0b593e1dd4613673a Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Wed, 15 Apr 2026 03:56:42 -0300 Subject: [PATCH 014/186] feat(benchmark): Add deep-branch SLOAD stateful test (#2635) Signed-off-by: jsign --- .../depth_benchmarks/test_deep_branch.py | 457 ++++++++++++++---- 1 file changed, 365 insertions(+), 92 deletions(-) diff --git a/tests/benchmark/stateful/bloatnet/depth_benchmarks/test_deep_branch.py b/tests/benchmark/stateful/bloatnet/depth_benchmarks/test_deep_branch.py index b4d3fabc6d1..07f94e8d9be 100644 --- a/tests/benchmark/stateful/bloatnet/depth_benchmarks/test_deep_branch.py +++ b/tests/benchmark/stateful/bloatnet/depth_benchmarks/test_deep_branch.py @@ -1,5 +1,5 @@ """ -abstract: BloatNet worst-case attack benchmark for maximum SSTORE stress. +abstract: BloatNet worst-case depth benchmarks for deep SSTORE and SLOAD. This test implements a worst-case scenario for Ethereum block processing that exploits the computational complexity of Patricia Merkle Trie @@ -7,11 +7,12 @@ with shared prefixes, maximizing trie traversal depth. Key features: -- Attacks pre-deployed contracts via CREATE2 address derivation +- Accesses pre-deployed contracts via CREATE2 address derivation - Each contract has deep storage slots with configurable trie depth -- Executes optimized attack bytecode with multiple SSTORE operations +- Includes both a mutating `attack(uint256)` benchmark and a read-only + `getDeepest()` benchmark - Respects Fusaka tx gas limit (16M gas) and fills blocks fully -- Verifies attack success via a storage check in each of the attack contracts +- Verifies correctness via post-state checks or receipt-status validation Test parameters: - storage_depth: Depth of storage slots (e.g., 10, 11) @@ -44,6 +45,7 @@ TransactionWithCost, While, ) +from execution_testing.base_types import StorageRootType from pydantic import BaseModel, BeforeValidator, Field # Folder path to the submodule and mined assets @@ -53,6 +55,27 @@ # Arbitrary value written to storage slots during attack DEFAULT_ATTACK_VALUE = 42 +# ABI selectors for the mined contracts +ATTACK_SELECTOR = Hash(bytes.fromhex("64dd891a"), right_padding=True) +GET_DEEPEST_SELECTOR = Hash(bytes.fromhex("d9339cc3"), right_padding=True) + +# From .worst_case_miner/mined_assets +DEPTH_BENCHMARK_CASES = [ + (10, 3), + (10, 4), + (10, 5), + (10, 6), + (10, 7), + (11, 3), + (11, 4), + (11, 5), + (11, 6), + (11, 7), + (12, 3), + (12, 4), + (12, 5), +] + def get_mined_asset(filename: str) -> str: """ @@ -156,71 +179,100 @@ def attack_value(request: pytest.FixtureRequest) -> int: However during execute we should use a random value to guarantee the storage update that's required for the attack. """ - if request.config.pluginmanager.has_plugin( - "execution_testing.cli.pytest_commands.plugins.execute.execute" - ): + if is_execute_mode(request): return int(time.time()) return DEFAULT_ATTACK_VALUE -@pytest.mark.valid_from("Prague") -@pytest.mark.parametrize( - "storage_depth,account_depth", - [ - # From .worst_case_miner/mined_assets - (10, 3), - (10, 4), - (10, 5), - (10, 6), - (10, 7), - (11, 3), - (11, 4), - (11, 5), - (11, 6), - (11, 7), - (12, 3), - (12, 4), - (12, 5), - ], -) -def test_worst_depth_stateroot_recomp( - benchmark_test: BenchmarkTestFiller, - fork: Fork, +def is_execute_mode(request: pytest.FixtureRequest) -> bool: + """ + Return ``True`` when the test is running through the execute plugin. + """ + return request.config.pluginmanager.has_plugin( + "execution_testing.cli.pytest_commands.plugins.execute.execute" + ) + + +def get_factory_address(fork: Fork) -> Address: + """ + Return the deterministic deployment factory for the fork. + """ + return ( + fork.deterministic_factory_predeploy_address() + or DETERMINISTIC_FACTORY_ADDRESS + ) + + +def deploy_required_mined_contracts( + *, pre: Alloc, - gas_benchmark_value: int, + mined_contract_file: MinedContractFile, + contracts_required: int, storage_depth: int, account_depth: int, - attack_value: int, -) -> None: + attacked_storage_value: int | None = None, +) -> Alloc: """ - BloatNet worst-case SSTORE attack benchmark with pre-deployed contracts. + Deploy the required set of mined contracts and their auxiliary accounts. - This test: - 1. Derives CREATE2 addresses from initcode_hash + Nick's deployer - 2. Deploys AttackOrchestrator that calls attack() on each target - 3. Fills blocks with 16M gas transactions attacking contracts - 4. Adds a verification transaction at the end to confirm success + When ``attacked_storage_value`` is provided, return the post-state + assertions for the deepest slot update. Otherwise, return an empty post. + """ + if contracts_required > mined_contract_file.num_contracts: + raise RuntimeError( + "Depth benchmark requires more mined contracts than available for " + f"(storage_depth={storage_depth}, account_depth={account_depth}): " + f"required {contracts_required}, available " + f"{mined_contract_file.num_contracts}." + ) - Args: - benchmark_test: The benchmark test filler - fork: The fork to test on - pre: Pre-state allocation - gas_benchmark_value: Gas budget for benchmark - storage_depth: Depth of storage slots in the contract (e.g., 9) - account_depth: Depth of account address prefix sharing (e.g., 5) - attack_value: The value to be written to storage in each attack + post = Alloc({}) + for salt in range(contracts_required): + salted_contract_info = mined_contract_file.contracts[salt] + assert salted_contract_info.salt == salt, ( + f"Salt out of order: {salted_contract_info.salt} != {salt}" + ) - """ - # Load the mined contract file - mined_contract_file = MinedContractFile.load(storage_depth, account_depth) + storage: StorageRootType = dict.fromkeys( + mined_contract_file.storage_keys, 1 + ) + deployed_contract_address = pre.deterministic_deploy_contract( + deploy_code=mined_contract_file.deploy_code, + salt=Hash(salt), + initcode=mined_contract_file.initcode, + storage=storage, + ) + assert ( + deployed_contract_address == salted_contract_info.contract_address + ), ( + f"Contract address mismatch: {deployed_contract_address} != " + f"{salted_contract_info.contract_address}, salt: {salt}" + ) - # Generate the attack orchestrator - factory_address = ( - fork.deterministic_factory_predeploy_address() - or DETERMINISTIC_FACTORY_ADDRESS - ) + for auxiliary_account in salted_contract_info.auxiliary_accounts: + # Ensure the account exists in the state trie + pre.fund_address( + address=auxiliary_account, amount=1, minimum_balance=True + ) + + if attacked_storage_value is not None: + attacked_storage = storage.copy() + attacked_storage[mined_contract_file.storage_keys[-1]] = ( + attacked_storage_value + ) + post[salted_contract_info.contract_address] = Account( + storage=attacked_storage + ) - # Prepare attack contract + return post + + +def build_attack_orchestrator_bytecode( + factory_address: Address, +) -> IteratingBytecode: + """ + Build the mutating orchestrator that calls ``attack(uint256)``. + """ create2_preimage = Create2PreimageLayout( factory_address=factory_address, salt=Op.CALLDATALOAD(32), @@ -232,7 +284,7 @@ def test_worst_depth_stateroot_recomp( # Place ABI (`attack(uint256)`) in memory + Op.MSTORE( args_offset, - Hash(bytes.fromhex("64dd891a"), right_padding=True), + ATTACK_SELECTOR, old_memory_size=args_offset, new_memory_size=args_offset + 32, ) @@ -297,13 +349,177 @@ def test_worst_depth_stateroot_recomp( + Op.SWAP1 * 2 ) - attack_orchestrator_bytecode = IteratingBytecode( + return IteratingBytecode( setup=setup, iterating=iterating, cleanup=cleanup, iterating_subcall=inner_call_bytecode, ) + +def build_get_deepest_orchestrator_bytecode( + factory_address: Address, + *, + exact_expected_value: bool, +) -> IteratingBytecode: + """ + Build the read-only orchestrator that calls ``getDeepest()``. + """ + create2_preimage = Create2PreimageLayout( + factory_address=factory_address, + salt=Op.CALLDATALOAD(0), + init_code_hash=Op.CALLDATALOAD(64), + ) + args_offset = 96 + return_offset = 128 + success_offset = 160 + setup_memory_size = 192 + setup: Bytecode = ( + create2_preimage + + Op.MSTORE( + args_offset, + GET_DEEPEST_SELECTOR, + old_memory_size=args_offset, + new_memory_size=args_offset + 32, + ) + + Op.MSTORE( + success_offset, + 0, + old_memory_size=args_offset + 32, + new_memory_size=setup_memory_size, + ) + + Op.CALLDATALOAD(32) + ) + return_value_check = ( + Op.EQ(Op.MLOAD(return_offset), 1) + if exact_expected_value + else Op.ISZERO(Op.ISZERO(Op.MLOAD(return_offset))) + ) + + def assert_with_invalid(condition: Bytecode | Op) -> Bytecode: + """ + Jump over ``INVALID`` when the invariant holds. + """ + return ( + # PC pushes its own offset; +3 accounts for the + # remaining push encoding + ADD + JUMPI bytes that + # follow PC, and len(Op.INVALID) accounts for the + # INVALID byte to skip over, landing on JUMPDEST. + Op.JUMPI(Op.ADD(Op.PC, len(Op.INVALID) + 3), condition) + + Op.INVALID + + Op.JUMPDEST + ) + + iterating = While( + body=( + Op.MSTORE( + success_offset, + Op.STATICCALL( + address=create2_preimage.address_op(), + args_offset=args_offset, + args_size=4, + ret_offset=return_offset, + ret_size=32, + old_memory_size=setup_memory_size, + new_memory_size=setup_memory_size, + ), + old_memory_size=setup_memory_size, + new_memory_size=setup_memory_size, + ) + # ``Bytecode.gas_cost()`` is path-insensitive, so ``Conditional`` + # would charge the untaken failure branch and its extra jump + # scaffolding. This manual branch keeps that overhead minimal, + # and uses ``INVALID`` as the cheapest terminating failure path. + + assert_with_invalid( + condition=Op.AND( + Op.AND( + Op.MLOAD(success_offset), + Op.EQ(Op.RETURNDATASIZE, 32), + ), + return_value_check, + ) + ) + + create2_preimage.increment_salt_op() + ), + condition=Op.LT( + Op.MLOAD(create2_preimage.salt_offset), + Op.DUP1, + ), + ) + + # Gas accounting model for the Solidity dispatch path and getDeepest body. + # PUSH/DUP/SWAP variants are collapsed into gas-equivalent representatives. + inner_call_bytecode = ( + Op.MSTORE(new_memory_size=96) + + Op.CALLVALUE + + Op.DUP1 * 9 + + Op.ISZERO + + Op.JUMPI * 8 + + Op.JUMPDEST * 4 + + Op.POP + + Op.CALLDATASIZE + + Op.LT + + Op.PUSH0 + + Op.CALLDATALOAD + + Op.SHR + + Op.GT + + Op.EQ * 5 + + Op.PUSH1 * 24 + + Op.SLOAD(key_warm=False) + + Op.JUMP * 2 + + Op.MLOAD * 2 + + Op.SWAP1 * 3 + + Op.MSTORE(old_memory_size=96, new_memory_size=160) + + Op.ADD + + Op.SUB + + Op.RETURN + ) + + return IteratingBytecode( + setup=setup, + iterating=iterating, + cleanup=Op.STOP, + iterating_subcall=inner_call_bytecode, + ) + + +@pytest.mark.parametrize( + "storage_depth,account_depth", + DEPTH_BENCHMARK_CASES, +) +def test_worst_depth_stateroot_recomp( + benchmark_test: BenchmarkTestFiller, + fork: Fork, + pre: Alloc, + gas_benchmark_value: int, + storage_depth: int, + account_depth: int, + attack_value: int, +) -> None: + """ + BloatNet worst-case SSTORE attack benchmark with pre-deployed contracts. + + This test: + 1. Derives CREATE2 addresses from initcode_hash + Nick's deployer + 2. Deploys AttackOrchestrator that calls attack() on each target + 3. Fills blocks with 16M gas transactions attacking contracts + 4. Verifies the deepest-slot update through post-state assertions + + Args: + benchmark_test: The benchmark test filler + fork: The fork to test on + pre: Pre-state allocation + gas_benchmark_value: Gas budget for benchmark + storage_depth: Depth of storage slots in the contract (e.g., 9) + account_depth: Depth of account address prefix sharing (e.g., 5) + attack_value: The value to be written to storage in each attack + + """ + mined_contract_file = MinedContractFile.load(storage_depth, account_depth) + attack_orchestrator_bytecode = build_attack_orchestrator_bytecode( + get_factory_address(fork) + ) + # Deploy orchestrator to deterministic address attack_orchestrator_address = pre.deterministic_deploy_contract( deploy_code=attack_orchestrator_bytecode @@ -330,40 +546,14 @@ def calldata(iteration_count: int, start_iteration: int) -> bytes: ) ) - # Deploy all contracts required. - post = Alloc({}) - for salt in range(contracts_required): - if salt >= len(mined_contract_file.contracts): - raise RuntimeError( - f"Requested salt {salt} but only " - f"{len(mined_contract_file.contracts)} available" - ) - salted_contract_info = mined_contract_file.contracts[salt] - assert salted_contract_info.salt == salt, ( - f"Salt out of order: {salted_contract_info.salt} != {salt}" - ) - deployed_contract_address = pre.deterministic_deploy_contract( - deploy_code=mined_contract_file.deploy_code, - salt=Hash(salt), - initcode=mined_contract_file.initcode, - storage=dict.fromkeys(mined_contract_file.storage_keys, 1), - ) - assert ( - deployed_contract_address == salted_contract_info.contract_address - ), ( - f"Contract address mismatch: {deployed_contract_address} != " - f"{salted_contract_info.contract_address}, salt: {salt}" - ) - for auxiliary_account in salted_contract_info.auxiliary_accounts: - # Ensure the account exists in the state trie - pre.fund_address( - address=auxiliary_account, amount=1, minimum_balance=True - ) - - # Set the post expectations - storage = dict.fromkeys(mined_contract_file.storage_keys, 1) - storage[mined_contract_file.storage_keys[-1]] = attack_value - post[salted_contract_info.contract_address] = Account(storage=storage) + post = deploy_required_mined_contracts( + pre=pre, + mined_contract_file=mined_contract_file, + contracts_required=contracts_required, + storage_depth=storage_depth, + account_depth=account_depth, + attacked_storage_value=attack_value, + ) # Create an EOA with funds for the deployer sender = pre.fund_eoa() @@ -388,3 +578,86 @@ def calldata(iteration_count: int, start_iteration: int) -> bytes: post=post, expected_benchmark_gas_used=total_gas_cost, ) + + +@pytest.mark.parametrize( + "storage_depth,account_depth", + DEPTH_BENCHMARK_CASES, +) +def test_worst_depth_get_deepest( + benchmark_test: BenchmarkTestFiller, + fork: Fork, + pre: Alloc, + request: pytest.FixtureRequest, + gas_benchmark_value: int, + storage_depth: int, + account_depth: int, +) -> None: + """ + BloatNet worst-case SLOAD benchmark with deep CREATE2-derived contracts. + + This benchmark calls ``getDeepest()`` on pre-mined contracts and validates + inside the orchestrator that every call succeeds and returns the expected + value. Fill mode requires the exact constructor-initialized value ``1``, + while execute mode only requires a non-zero value to tolerate reused + deterministic deployments on a dirty chain. + """ + mined_contract_file = MinedContractFile.load(storage_depth, account_depth) + exact_expected_value = not is_execute_mode(request) + get_deepest_orchestrator_bytecode = ( + build_get_deepest_orchestrator_bytecode( + get_factory_address(fork), + exact_expected_value=exact_expected_value, + ) + ) + + orchestrator_address = pre.deterministic_deploy_contract( + deploy_code=get_deepest_orchestrator_bytecode + ) + print(f" Read orchestrator will be deployed at: {orchestrator_address}") + + def calldata(iteration_count: int, start_iteration: int) -> bytes: + end_iteration = start_iteration + iteration_count + return ( + Hash(start_iteration) + + Hash(end_iteration) + + mined_contract_file.initcode_hash + ) + + contracts_required = sum( + get_deepest_orchestrator_bytecode.tx_iterations_by_gas_limit( + fork=fork, + gas_limit=gas_benchmark_value, + start_iteration=0, + calldata=calldata, + ) + ) + + deploy_required_mined_contracts( + pre=pre, + mined_contract_file=mined_contract_file, + contracts_required=contracts_required, + storage_depth=storage_depth, + account_depth=account_depth, + ) + + sender = pre.fund_eoa() + read_txs: list[TransactionWithCost] = list( + get_deepest_orchestrator_bytecode.transactions_by_gas_limit( + fork=fork, + gas_limit=gas_benchmark_value, + start_iteration=0, + sender=sender, + to=orchestrator_address, + calldata=calldata, + ) + ) + + total_gas_cost = sum(tx.gas_cost for tx in read_txs) + + benchmark_test( + pre=pre, + blocks=[Block(txs=read_txs)], + expected_benchmark_gas_used=total_gas_cost, + expected_receipt_status=1, + ) From 132c09d48bce13d063cbaee5e490b13fa63726c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Wahrst=C3=A4tter?= <51536394+nerolation@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:51:53 +0200 Subject: [PATCH 015/186] feat(tests): add test for worst-case prefetcher performance (#2657) --- .../stateful/bloatnet/test_single_opcode.py | 374 +++++++++++++++++- 1 file changed, 364 insertions(+), 10 deletions(-) diff --git a/tests/benchmark/stateful/bloatnet/test_single_opcode.py b/tests/benchmark/stateful/bloatnet/test_single_opcode.py index 4256db613e0..06fe23911f6 100644 --- a/tests/benchmark/stateful/bloatnet/test_single_opcode.py +++ b/tests/benchmark/stateful/bloatnet/test_single_opcode.py @@ -9,7 +9,7 @@ from enum import Enum, auto from functools import partial -from typing import Callable, List +from typing import Callable, Generator, List import pytest from execution_testing import ( @@ -18,8 +18,12 @@ Address, Alloc, AuthorizationTuple, + BalAccountExpectation, + BalNonceChange, + BalStorageSlot, BenchmarkTestFiller, Block, + BlockAccessListExpectation, Bytecode, CreatePreimageLayout, Fork, @@ -58,28 +62,57 @@ ) -def delegate_and_set_slot0( +def _max_sloads_per_tx(tx_gas_limit: int, fork: Fork) -> int: + """ + Conservative upper bound on cold SLOADs that fit in a max-gas tx. + + Derived from the cold SLOAD cost (EIP-2929: 2100 gas) and used by + the bloated SLOAD benchmarks both as the inter-tx offset stride + (to keep consecutive txs' SLOAD ranges disjoint) and as the + per-target storage pre-load count. + """ + cold_sload_cost = Op.SLOAD(key_warm=False).gas_cost(fork) + return tx_gas_limit // cold_sload_cost + + +def _sender_generator( + pre: Alloc, distinct_senders: bool +) -> Generator[EOA, None, None]: + """ + Yield one sender per tx. + + In distinct mode, yields a fresh EOA per call. Otherwise, yields + the same shared sender for every call. Used by the bloated SLOAD + benchmarks so the BAL builder can group nonce changes by sender + uniformly regardless of mode. + """ + sender = pre.fund_eoa() + while True: + yield sender if not distinct_senders else pre.fund_eoa() + + +def delegate_with_calldata( pre: Alloc, authority: EOA, - setter_address: Address, - slot_0_value: Hash, + address: Address, + calldata: Hash, ) -> Transaction: """ - Create a tx that delegates the authority to the setter and calls - it with slot_0_value as calldata, writing it into slot 0. + Create a tx that delegates the authority and calls it with calldata. + The delegated code determines what happens with the calldata. The authority nonce is incremented in-place. """ tx = Transaction( gas_limit=100_000, to=authority, value=0, - data=slot_0_value, + data=calldata, sender=pre.fund_eoa(), authorization_list=[ AuthorizationTuple( chain_id=0, - address=setter_address, + address=address, nonce=authority.nonce, signer=authority, ), @@ -112,10 +145,10 @@ def run_bloated_eoa_benchmark( setter_address = pre.deploy_contract(code=Op.SSTORE(0, Op.CALLDATALOAD(0))) runtime_address = pre.deploy_contract(code=runtime_code) - init_tx = delegate_and_set_slot0( + init_tx = delegate_with_calldata( pre, authority, setter_address, slot_0_value ) - runtime_tx = delegate_and_set_slot0( + runtime_tx = delegate_with_calldata( pre, authority, runtime_address, Hash(0) ) @@ -220,6 +253,327 @@ def test_sload_bloated( ) +@pytest.mark.stub_parametrize("token_name", "bloated_eoa_") +@pytest.mark.parametrize("distinct_senders", [False, True]) +@pytest.mark.parametrize("existing_slots", [False, True]) +def test_sload_bloated_prefetch_miss( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + token_name: str, + existing_slots: bool, + distinct_senders: bool, +) -> None: + """ + Benchmark SLOAD with calldata-driven offsets to defeat prefetching. + + A small first transaction writes an initial offset into the + authority's slot 0 via calldata. Subsequent max-gas transactions + each read the previous offset from slot 0, immediately overwrite + slot 0 with a new offset from their own calldata, then SLOAD + sequentially from the previous offset. Because each transaction's + SLOAD range depends on state written by its predecessor, a + prefetcher that predicts SLOAD targets from pre-block state + without simulating intra-block writes will pre-warm incorrect + storage slots. The minimal first tx is load-bearing: it lives + inside the benchmark block so every subsequent max-gas tx reads + a slot 0 value that differs from the prefetcher's pre-block + snapshot, achieving a 100% miss rate. + + When ``distinct_senders`` is True every transaction uses a fresh + sender. This additionally defeats per-sender prewarm + serialization (e.g. Nethermind) that groups txs by sender and + runs them sequentially to propagate state changes — forcing + every tx's prewarm scope to restart from pre-block state. + """ + # Runtime: read old offset from slot 0, write new offset from + # calldata to slot 0, then SLOAD sequentially from old offset. + runtime_code = ( + Op.SLOAD(Op.PUSH0) + + Op.SSTORE(Op.PUSH0, Op.CALLDATALOAD(Op.PUSH0)) + + While( + body=(Op.DUP1 + Op.SLOAD + Op.POP + Op.PUSH1(1) + Op.ADD), + condition=Op.GT(Op.GAS, 0xFFFF), + ) + ) + + authority = pre.stub_eoa(token_name) + runtime_address = pre.deploy_contract(code=runtime_code) + + # Setup: delegate authority to the runtime contract. Slot 0 is + # left at 0 (the delegation tx's calldata) so the benchmark + # block's pre-state has slot 0 = 0; the first benchmark tx + # then plants base_offset in slot 0 inside the benchmark block, + # forcing the prefetcher's pre-block snapshot to disagree with + # the actual slot 0 value seen by every max-gas tx that follows. + delegation_tx = delegate_with_calldata( + pre, authority, runtime_address, Hash(0) + ) + + blocks: list[Block] = [Block(txs=[delegation_tx])] + + # Offset spacing: upper bound on SLOADs per tx ensures each + # transaction reads a completely disjoint slot range. + max_sloads_per_tx = _max_sloads_per_tx(tx_gas_limit, fork) + + # The base offset must be at least max_sloads_per_tx away from + # the pre-block slot 0 value (0) so the prefetcher's predicted + # SLOAD range is completely disjoint from the actual range. + base_offset = max_sloads_per_tx if existing_slots else START_SLOT + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=b"\xff" * 32, + ) + + # senders_iter yields one sender per tx (fresh per call in + # distinct mode, a single shared sender otherwise). The senders + # list collects one entry per tx so the BAL builder below can + # group nonce changes by sender uniformly. + senders_iter = _sender_generator(pre, distinct_senders) + senders: list[EOA] = [] + + gas_available = gas_benchmark_value + txs: list[Transaction] = [] + + # First transaction: minimal gas, only writes the initial + # offset. Gas limit ensures remaining gas after the SLOAD + + # SSTORE setup falls below the 0xFFFF loop threshold so the + # SLOAD loop does not run. This tx's job is to change slot 0 + # inside the benchmark block so every subsequent max-gas tx + # reads an offset the prefetcher's pre-block snapshot does + # not see, achieving a 100% prefetch miss rate on max-gas txs. + first_tx_gas = min(gas_available, intrinsic_gas + 30_000) + sender = next(senders_iter) + senders.append(sender) + txs.append( + Transaction( + gas_limit=first_tx_gas, + to=authority, + data=Hash(base_offset), + sender=sender, + ) + ) + gas_available -= first_tx_gas + + # Subsequent transactions: max gas, each shifts the offset + # so the next transaction SLOADs from a different range. + tx_index = 1 + while gas_available >= intrinsic_gas: + tx_gas = min(gas_available, tx_gas_limit) + new_offset = base_offset + tx_index * max_sloads_per_tx + sender = next(senders_iter) + senders.append(sender) + txs.append( + Transaction( + gas_limit=tx_gas, + to=authority, + data=Hash(new_offset), + sender=sender, + ) + ) + gas_available -= tx_gas + tx_index += 1 + + expectations: dict[Address, BalAccountExpectation] = { + authority: BalAccountExpectation( + storage_reads=[base_offset], + storage_changes=[ + BalStorageSlot( + slot=0, + validate_any_change=True, + ), + ], + ), + } + sender_nonces: dict[Address, list[BalNonceChange]] = {} + for i, s in enumerate(senders): + changes = sender_nonces.setdefault(s, []) + changes.append( + BalNonceChange( + block_access_index=i + 1, + post_nonce=len(changes) + 1, + ) + ) + for addr, nonces in sender_nonces.items(): + expectations[addr] = BalAccountExpectation(nonce_changes=nonces) + blocks.append( + Block( + txs=txs, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=expectations, + ), + ) + ) + + benchmark_test( + pre=pre, + blocks=blocks, + skip_gas_used_validation=True, + expected_receipt_status=True, + ) + + +@pytest.mark.parametrize("distinct_senders", [False, True]) +@pytest.mark.parametrize("existing_slots", [False, True]) +def test_sload_bloated_multi_contract( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + fork: Fork, + gas_benchmark_value: int, + tx_gas_limit: int, + existing_slots: bool, + distinct_senders: bool, +) -> None: + """ + Benchmark SLOAD across a distinct contract per transaction. + + Each transaction calls a freshly-deployed contract whose slot 0 + is pre-loaded with the starting offset; the contract then runs a + SLOAD loop over sequential slots until gas runs low. Unlike + test_sload_bloated_prefetch_miss which hammers one account's + storage trie via an EIP-7702 delegated EOA, every transaction + here opens a different storage trie, stressing cross-account + state access and state-trie breadth in a single block. + + Every target contract first CALLs a shared offset_holder + contract whose slot 0 is read, incremented, and written back. + This mirrors the first test's "same-contract slot 0" dependency + pattern via cross-contract CALL: every transaction forms a + read-after-write edge on offset_holder's slot 0, preventing + parallel execution. + + When ``distinct_senders`` is True every transaction uses a fresh + sender. This additionally exercises per-sender prewarm + serialization (e.g. Nethermind) differently than the shared- + sender case; we run both so clients can be measured in both + regimes. + """ + # Shared offset_holder: reads, increments, and writes its own + # slot 0. Every target CALLs this to create an inter-tx RAW + # dependency chain on a single shared storage slot. + offset_holder = pre.deploy_contract( + code=Op.SSTORE(0, Op.ADD(Op.SLOAD(0), 1)), + ) + + # Target runtime: CALL offset_holder (for the dependency), then + # run the same SLOAD loop as test_sload_bloated in its own + # storage. Final counter is written back to slot 0. + runtime_code = ( + Op.POP( + Op.CALL( + address=offset_holder, + ) + ) + + Op.SLOAD(Op.PUSH0) + + While( + body=(Op.DUP1 + Op.SLOAD + Op.POP + Op.PUSH1(1) + Op.ADD), + condition=Op.GT(Op.GAS, 0xFFFF), + ) + + Op.PUSH0 + + Op.SSTORE + ) + + base_offset = 1 if existing_slots else START_SLOT + max_sloads_per_tx = _max_sloads_per_tx(tx_gas_limit, fork) + + # Pre-load slot 0 with the starting offset. For existing_slots, + # also fill the slot range the loop will read so SLOADs land on + # populated entries rather than empty slots. A fresh Storage + # instance is built per deployment (below) so that every target + # gets an independent root dict, not an alias of the same one. + storage_data: Storage.StorageDictType = {0: base_offset} + if existing_slots: + for i in range(base_offset, base_offset + max_sloads_per_tx): + storage_data[i] = i + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()() + # Minimum per-tx gas ensuring the SLOAD loop runs at least one + # iteration so every target satisfies storage_reads=[base_offset]: + # intrinsic + CALL + offset_holder + setup + 0xFFFF loop threshold + # + one iteration + final SSTORE, with buffer. + min_tx_gas = intrinsic_gas + 130_000 + + # senders_iter yields one sender per tx (fresh per call in + # distinct mode, a single shared sender otherwise). The senders + # list collects one entry per tx so the BAL builder below can + # group nonce changes by sender uniformly. + senders_iter = _sender_generator(pre, distinct_senders) + senders: list[EOA] = [] + + gas_available = gas_benchmark_value + targets: list[Address] = [] + txs: list[Transaction] = [] + + # Each tx targets a freshly-deployed contract with identical code + # and storage layout. + while gas_available >= min_tx_gas: + tx_gas = min(gas_available, tx_gas_limit) + target = pre.deploy_contract( + code=runtime_code, + storage=Storage(storage_data), + ) + targets.append(target) + sender = next(senders_iter) + senders.append(sender) + txs.append( + Transaction( + gas_limit=tx_gas, + to=target, + sender=sender, + ) + ) + gas_available -= tx_gas + + expectations: dict[Address, BalAccountExpectation] = { + offset_holder: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=0, + validate_any_change=True, + ), + ], + ), + } + for t in targets: + expectations[t] = BalAccountExpectation( + storage_reads=[base_offset], + storage_changes=[ + BalStorageSlot( + slot=0, + validate_any_change=True, + ), + ], + ) + sender_nonces: dict[Address, list[BalNonceChange]] = {} + for i, s in enumerate(senders): + changes = sender_nonces.setdefault(s, []) + changes.append( + BalNonceChange( + block_access_index=i + 1, + post_nonce=len(changes) + 1, + ) + ) + for addr, nonces in sender_nonces.items(): + expectations[addr] = BalAccountExpectation(nonce_changes=nonces) + + blocks = [ + Block( + txs=txs, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=expectations, + ), + ) + ] + + benchmark_test( + pre=pre, + blocks=blocks, + skip_gas_used_validation=True, + expected_receipt_status=True, + ) + + @pytest.mark.repricing @pytest.mark.stub_parametrize("token_name", "bloated_eoa_") @pytest.mark.parametrize("write_new_value", [False, True]) From d206d4f2b8558d742b9ddd31407e69e5cf05e6cf Mon Sep 17 00:00:00 2001 From: felipe Date: Wed, 15 Apr 2026 06:08:05 -0600 Subject: [PATCH 016/186] feat: add more invalid BAL test cases; extend invalid case coverage (#2653) * feat: add more invalid BAL test cases; extend invalid case coverage * chore: align renames with test_cases.md * chore: align test_cases.md with implementations from audit * feat(tests): add missing / invalid coinbase BAL tests * chore: consolidate unused BAL exceptions * fix(tests): changes from comments on PR #2653 * fix(test,types): Fix bal_hash / block_access_list_hash mismatch for modifier * chore(test,types): If Header has a field and FixtureHeader doesn't, validate against this on apply --- .../client_clis/clis/besu.py | 11 +- .../client_clis/clis/erigon.py | 13 +- .../client_clis/clis/ethrex.py | 18 +- .../client_clis/clis/geth.py | 24 +- .../client_clis/clis/nethermind.py | 9 +- .../client_clis/clis/reth.py | 8 +- .../exceptions/exceptions/block.py | 9 - .../src/execution_testing/specs/blockchain.py | 33 +- .../test_types/block_types.py | 2 +- .../test_block_access_lists_invalid.py | 463 +++++++++++++++++- .../test_cases.md | 18 +- 11 files changed, 516 insertions(+), 92 deletions(-) diff --git a/packages/testing/src/execution_testing/client_clis/clis/besu.py b/packages/testing/src/execution_testing/client_clis/clis/besu.py index a48ec82f50e..ce0789cd399 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/besu.py +++ b/packages/testing/src/execution_testing/client_clis/clis/besu.py @@ -457,20 +457,11 @@ class BesuExceptionMapper(ExceptionMapper): r"Blob transaction has too many blobs: \d+|" r"Invalid Blob Count: \d+" ), - # BAL Exceptions: TODO - review once all clients completed. - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - r"Block access list hash mismatch, " - r"calculated:\s*(0x[a-f0-9]+)\s+header:\s*(0x[a-f0-9]+)|" - r"Block access list validation failed for block 0x[a-f0-9]+" - ), + # BAL Exceptions BlockException.INVALID_BAL_HASH: ( r"Block access list hash mismatch, " r"calculated:\s*(0x[a-f0-9]+)\s+header:\s*(0x[a-f0-9]+)" ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - r"Block access list hash mismatch, " - r"calculated:\s*(0x[a-f0-9]+)\s+header:\s*(0x[a-f0-9]+)" - ), BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED: ( r"Block access list validation failed for block 0x[a-f0-9]+" ), diff --git a/packages/testing/src/execution_testing/client_clis/clis/erigon.py b/packages/testing/src/execution_testing/client_clis/clis/erigon.py index 699fd4f5744..89c60c6319a 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/erigon.py +++ b/packages/testing/src/execution_testing/client_clis/clis/erigon.py @@ -94,22 +94,15 @@ class ErigonExceptionMapper(ExceptionMapper): BlockException.INVALID_STATE_ROOT: "invalid block: wrong trie root", BlockException.INVALID_RECEIPTS_ROOT: "receiptHash mismatch", BlockException.INVALID_LOG_BLOOM: "invalid bloom", - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - "block access list mismatch" - ), BlockException.INCORRECT_BLOCK_FORMAT: "invalid block access list", - BlockException.INVALID_BAL_EXTRA_ACCOUNT: "invalid block access list", BlockException.GAS_USED_OVERFLOW: "block gas used overflow", } mapping_regex = { - BlockException.INVALID_BLOCK_ACCESS_LIST: ( + BlockException.INVALID_BAL_HASH: ( r"invalid block access list|block access list mismatch" ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - r"block access list mismatch" - ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - r"invalid block access list" + BlockException.INVALID_BLOCK_ACCESS_LIST: ( + r"invalid block access list|block access list mismatch" ), BlockException.INCORRECT_BLOCK_FORMAT: (r"invalid block access list"), BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED: ( diff --git a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py index f3ad4741d79..d85a1e7ce86 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py +++ b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py @@ -41,14 +41,6 @@ class EthrexExceptionMapper(ExceptionMapper): "Block access list hash does not match the one in " "the header after executing" ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - "Block access list hash does not match the one in " - "the header after executing" - ), BlockException.INCORRECT_BLOCK_FORMAT: ( "not in strictly ascending order for" ), @@ -175,11 +167,7 @@ class EthrexExceptionMapper(ExceptionMapper): BlockException.RLP_BLOCK_LIMIT_EXCEEDED: ( r"Maximum block size exceeded.*" ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - r"Block access list accounts not in strictly ascending order.*|" - r"BAL validation failed: account .* was never accessed.*" - ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: (r"absent from BAL"), + BlockException.INVALID_BAL_HASH: r"BAL validation failed", BlockException.INVALID_BLOCK_ACCESS_LIST: ( r"Block access list contains index \d+ " r"exceeding max valid index \d+|" @@ -187,8 +175,10 @@ class EthrexExceptionMapper(ExceptionMapper): r"Block access list .+ not in strictly ascending order.*|" r"BAL validation failed for (tx \d+|system_tx|withdrawal): .*|" r"BAL validation failed: .*|" + r"absent from BAL|" r"Block access list slot .+ is in both " - r"storage_changes and storage_reads.*" + r"storage_changes and storage_reads.*|" + r"Invalid block hash" ), BlockException.INCORRECT_BLOCK_FORMAT: ( r"Block access list hash does not match " diff --git a/packages/testing/src/execution_testing/client_clis/clis/geth.py b/packages/testing/src/execution_testing/client_clis/clis/geth.py index 7fdedd348d6..25f0e0244e9 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/geth.py +++ b/packages/testing/src/execution_testing/client_clis/clis/geth.py @@ -111,12 +111,6 @@ class GethExceptionMapper(ExceptionMapper): BlockException.RLP_BLOCK_LIMIT_EXCEEDED: ( "block RLP-encoded size exceeds maximum" ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - "BAL change not reported in computed" - ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - "additional mutations compared to BAL" - ), BlockException.INVALID_BLOCK_ACCESS_LIST: "unequal", BlockException.INVALID_BASEFEE_PER_GAS: "invalid baseFee", BlockException.INVALID_BLOCK_TIMESTAMP_OLDER_THAN_PARENT: ( @@ -157,19 +151,17 @@ class GethExceptionMapper(ExceptionMapper): # # EELS definition for `is_valid_deposit_event_data`: # https://github.com/ethereum/execution-specs/blob/5ddb904fa7ba27daeff423e78466744c51e8cb6a/src/ethereum/forks/prague/requests.py#L51 - # BAL Exceptions: TODO - review once all clients completed. - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - r"invalid block access list:" - ), + # BAL Exceptions BlockException.INVALID_BAL_HASH: (r"invalid block access list:"), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - r"computed state diff contained mutated accounts " - r"which weren't reported in BAL|" - r"invalid block access list:" - ), BlockException.INVALID_BLOCK_ACCESS_LIST: ( r"difference between computed state diff and " - r"BAL entry for account|invalid block access list:" + r"BAL entry for account|" + r"invalid block access list:|" + r"computed state diff contained mutated accounts " + r"which weren't reported in BAL|" + r"BAL change not reported in computed|" + r"additional mutations compared to BAL|" + r"[bB][aA][lL] validation fail" ), BlockException.INCORRECT_BLOCK_FORMAT: (r"invalid block access list:"), BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED: ( diff --git a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py index 90745b6ac6b..918dd535939 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py +++ b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py @@ -437,15 +437,8 @@ class NethermindExceptionMapper(ExceptionMapper): # BAL Exceptions — specific exceptions have unique patterns, but # INVALID_BLOCK_ACCESS_LIST and INCORRECT_BLOCK_FORMAT intentionally # overlap because the test framework requires `want in got` matching. + # BAL Exceptions BlockException.INVALID_BAL_HASH: (r"InvalidBlockLevelAccessListHash:"), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - r"InvalidBlockLevelAccessList:.*missing account" - ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - r"InvalidBlockLevelAccessList:.*surplus changes" - r"|could not be parsed as a block: " - r"Error decoding block access list:" - ), BlockException.INVALID_BLOCK_ACCESS_LIST: ( r"InvalidBlockLevelAccessListHash:" r"|InvalidBlockLevelAccessList:" diff --git a/packages/testing/src/execution_testing/client_clis/clis/reth.py b/packages/testing/src/execution_testing/client_clis/clis/reth.py index 6a70ebcc5e9..454d5f9ffcb 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/reth.py +++ b/packages/testing/src/execution_testing/client_clis/clis/reth.py @@ -109,14 +109,8 @@ class RethExceptionMapper(ExceptionMapper): BlockException.GAS_USED_OVERFLOW: ( r"transaction gas limit \w+ is more than blocks available gas \w+" ), - # BAL Exceptions: TODO - review once all clients completed. - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - r"block access list hash mismatch" - ), + # BAL Exceptions BlockException.INVALID_BAL_HASH: (r"block access list hash mismatch"), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - r"block access list hash mismatch" - ), BlockException.INVALID_BLOCK_ACCESS_LIST: ( r"block access list hash mismatch" ), diff --git a/packages/testing/src/execution_testing/exceptions/exceptions/block.py b/packages/testing/src/execution_testing/exceptions/exceptions/block.py index eceb98b6336..bf8fec8ba7e 100644 --- a/packages/testing/src/execution_testing/exceptions/exceptions/block.py +++ b/packages/testing/src/execution_testing/exceptions/exceptions/block.py @@ -177,15 +177,6 @@ class BlockException(ExceptionBase): """Block's access list is invalid.""" INVALID_BAL_HASH = auto() """Block header's BAL hash does not match the computed BAL hash.""" - INVALID_BAL_EXTRA_ACCOUNT = auto() - """ - Block BAL contains an account change that is not present in the computed - BAL. - """ - INVALID_BAL_MISSING_ACCOUNT = auto() - """ - Block BAL is missing an account change that is present in the computed BAL. - """ BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED = auto() """ Block access list exceeds the gas limit constraint (EIP-7928). diff --git a/packages/testing/src/execution_testing/specs/blockchain.py b/packages/testing/src/execution_testing/specs/blockchain.py index ae467bbfa8c..61ab40360fd 100644 --- a/packages/testing/src/execution_testing/specs/blockchain.py +++ b/packages/testing/src/execution_testing/specs/blockchain.py @@ -164,7 +164,7 @@ class Header(CamelModel): excess_blob_gas: Removable | HexNumber | None = None parent_beacon_block_root: Removable | Hash | None = None requests_hash: Removable | Hash | None = None - bal_hash: Removable | Hash | None = None + block_access_list_hash: Removable | Hash | None = None REMOVE_FIELD: ClassVar[Removable] = Removable() """ @@ -216,12 +216,18 @@ def apply(self, target: FixtureHeader) -> FixtureHeader: """ Produce a fixture header copy with the set values from the modifier. """ - return target.copy( - **{ - k: (v if v is not Header.REMOVE_FIELD else None) - for k, v in self.model_dump(exclude_none=True).items() - } - ) + overrides = { + k: (v if v is not Header.REMOVE_FIELD else None) + for k, v in self.model_dump(exclude_none=True).items() + } + unknown = overrides.keys() - target.__class__.model_fields.keys() + if unknown: + raise ValueError( + f"Header fields {unknown} do not exist on " + f"{target.__class__.__name__}. Check for field name " + f"mismatches between Header and {target.__class__.__name__}." + ) + return target.copy(**overrides) def verify(self, target: FixtureHeader) -> None: """Verify that the header fields from self are as expected.""" @@ -334,7 +340,9 @@ def set_environment(self, env: Environment) -> Environment: not isinstance(self.requests_hash, Removable) and self.block_access_list is not None ): - new_env_values["bal_hash"] = self.block_access_list.keccak256() + new_env_values["block_access_list_hash"] = ( + self.block_access_list.keccak256() + ) new_env_values["block_access_list"] = self.block_access_list if ( not isinstance(self.block_access_list, Removable) @@ -723,11 +731,14 @@ def generate_block_data( "provided by the transition tool" ) - computed_bal_hash = Hash(t8n_bal.rlp.keccak256()) - assert computed_bal_hash == header.block_access_list_hash, ( + computed_block_access_list_hash = Hash(t8n_bal.rlp.keccak256()) + assert ( + computed_block_access_list_hash + == header.block_access_list_hash + ), ( "Block access list hash in header does not match the " f"computed hash from BAL: {header.block_access_list_hash} " - f"!= {computed_bal_hash}" + f"!= {computed_block_access_list_hash}" ) if block.rlp_modifier is not None: diff --git a/packages/testing/src/execution_testing/test_types/block_types.py b/packages/testing/src/execution_testing/test_types/block_types.py index 542df72440f..4d95a4e43f7 100644 --- a/packages/testing/src/execution_testing/test_types/block_types.py +++ b/packages/testing/src/execution_testing/test_types/block_types.py @@ -142,7 +142,7 @@ def strip_computed_fields(cls, data: Any) -> Any: extra_data: Bytes = Field(Bytes(b"\x00"), exclude=True) # EIP-7928: Block-level access lists - bal_hash: Hash | None = Field(None) + block_access_list_hash: Hash | None = Field(None) block_access_lists: Bytes | None = Field(None) @computed_field # type: ignore[prop-decorator] diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index f632d4e78af..5b86712e74b 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -21,6 +21,10 @@ BlockAccessListExpectation, BlockchainTestFiller, BlockException, + Environment, + Fork, + Hash, + Header, Initcode, Op, Storage, @@ -41,12 +45,17 @@ duplicate_storage_slot, insert_storage_read, modify_balance, + modify_code, modify_nonce, modify_storage, remove_accounts, remove_balances, + remove_code, remove_nonces, + remove_storage, + remove_storage_reads, reverse_accounts, + sort_accounts_by_address, swap_bal_indices, ) @@ -331,7 +340,7 @@ def test_bal_invalid_account( blocks=[ Block( txs=[tx], - exception=BlockException.INVALID_BAL_EXTRA_ACCOUNT, + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, expected_block_access_list=BlockAccessListExpectation( account_expectations={ sender: BalAccountExpectation( @@ -587,7 +596,7 @@ def test_bal_invalid_missing_account( blocks=[ Block( txs=[tx], - exception=BlockException.INVALID_BAL_MISSING_ACCOUNT, + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, expected_block_access_list=BlockAccessListExpectation( account_expectations={ sender: BalAccountExpectation( @@ -656,7 +665,7 @@ def test_bal_invalid_missing_withdrawal_account( amount=10, ) ], - exception=BlockException.INVALID_BAL_MISSING_ACCOUNT, + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( @@ -719,7 +728,7 @@ def test_bal_invalid_missing_withdrawal_account_empty_block( amount=10, ) ], - exception=BlockException.INVALID_BAL_MISSING_ACCOUNT, + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, expected_block_access_list=BlockAccessListExpectation( account_expectations={ charlie: BalAccountExpectation( @@ -1101,3 +1110,449 @@ def test_bal_invalid_duplicate_entries( ) ], ) + + +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +def test_bal_invalid_hash_mismatch( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test that clients reject blocks where the BAL hash in the header + does not match the actual BAL content. + + Unlike other invalid BAL tests which corrupt the BAL content while + keeping the header hash consistent with the corrupted data, this + test keeps the BAL valid but injects a wrong hash into the header + via rlp_modifier. + """ + sender = pre.fund_eoa(amount=10**18) + receiver = pre.fund_eoa(amount=0) + + tx = Transaction( + sender=sender, + to=receiver, + value=10**15, + gas_limit=21_000, + ) + + blockchain_test( + pre=pre, + post={ + sender: Account(balance=10**18, nonce=0), + receiver: None, + }, + blocks=[ + Block( + txs=[tx], + rlp_modifier=Header(block_access_list_hash=Hash(1)), + exception=[ + BlockException.INVALID_BAL_HASH, + BlockException.INVALID_BLOCK_HASH, + ], + ) + ], + ) + + +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +@pytest.mark.parametrize( + "modifier", + [ + pytest.param( + lambda oracle, **_: remove_storage(oracle), + id="missing_storage_change", + ), + pytest.param( + lambda oracle, **_: remove_storage_reads(oracle), + id="missing_storage_read", + ), + pytest.param( + lambda created, **_: remove_code(created), + id="missing_code_change", + ), + pytest.param( + lambda created, **_: modify_code( + created, block_access_index=1, code=b"\xde\xad" + ), + id="wrong_code_value", + ), + ], +) +def test_bal_invalid_field_entries( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + modifier: Callable, +) -> None: + """ + Test that clients reject blocks with missing or incorrect + field-level BAL entries. + + Oracle writes storage slot 1, reads storage slot 2, and CREATEs a + small contract. A valid BAL is created containing all changes, then + corrupted by the parameterized modifier: + + - missing_storage_change: Oracle's storage writes removed. + - missing_storage_read: Oracle's storage reads removed. + - missing_code_change: Created contract's code change removed. + - wrong_code_value: Created contract's deployed bytecode wrong. + """ + alice = pre.fund_eoa() + deploy_code = b"\x13\x37" + initcode = Initcode(deploy_code=deploy_code) + initcode_word = int.from_bytes(bytes(initcode).ljust(32, b"\x00"), "big") + oracle = pre.deploy_contract( + code=( + Op.SSTORE(1, 0x42) + + Op.SLOAD(2) + + Op.MSTORE(0, initcode_word) + + Op.CREATE(0, 0, len(initcode)) + ), + storage={2: 0x84}, + ) + created = compute_create_address(address=oracle, nonce=1) + + tx = Transaction( + sender=alice, + to=oracle, + value=100, + gas_limit=2_000_000, + ) + + blockchain_test( + pre=pre, + post=pre, + blocks=[ + Block( + txs=[tx], + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=1, + post_nonce=1, + ), + ], + ), + oracle: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, + post_balance=100, + ), + ], + storage_changes=[ + BalStorageSlot( + slot=1, + slot_changes=[ + BalStorageChange( + block_access_index=1, + post_value=0x42, + ), + ], + ), + ], + storage_reads=[2], + ), + created: BalAccountExpectation( + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=deploy_code, + ), + ], + ), + } + ).modify( + modifier( + oracle=oracle, + created=created, + ) + ), + ) + ], + ) + + +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +def test_bal_invalid_withdrawal_balance_value( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test that clients reject blocks where BAL contains an incorrect + balance value for an account modified only by a withdrawal. + + Charlie receives a 10 gwei withdrawal in an empty block. + BAL is corrupted by changing Charlie's post-balance to 999 instead + of the correct 10_000_000_000 (10 gwei in wei). + """ + charlie = pre.fund_eoa(amount=0) + + blockchain_test( + pre=pre, + post={ + charlie: None, + }, + blocks=[ + Block( + txs=[], + withdrawals=[ + Withdrawal( + index=0, + validator_index=0, + address=charlie, + amount=10, + ) + ], + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + charlie: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, + post_balance=10 * 10**9, + ) + ], + ), + } + ).modify( + modify_balance(charlie, block_access_index=1, balance=999) + ), + ) + ], + ) + + +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +def test_bal_invalid_missing_coinbase( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """ + Test that clients reject blocks where BAL is missing the + coinbase/fee recipient account. + + Alice sends 100 wei to Bob with gas_price > base_fee so the + coinbase (charlie) receives a non-zero tip. BAL is corrupted + by removing charlie's entry entirely. + """ + alice = pre.fund_eoa(amount=10**18) + bob = pre.fund_eoa(amount=0) + charlie = pre.fund_eoa(amount=0) + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=b"", + contract_creation=False, + access_list=[], + ) + gas_price = 0xA + + tx = Transaction( + sender=alice, + to=bob, + value=100, + gas_limit=intrinsic_gas + 1000, + gas_price=gas_price, + ) + + genesis_env = Environment(base_fee_per_gas=0x7) + base_fee_per_gas = fork.base_fee_per_gas_calculator()( + parent_base_fee_per_gas=int(genesis_env.base_fee_per_gas or 0), + parent_gas_used=0, + parent_gas_limit=genesis_env.gas_limit, + ) + tip = (gas_price - base_fee_per_gas) * intrinsic_gas + + blockchain_test( + pre=pre, + post={}, + genesis_environment=genesis_env, + blocks=[ + Block( + txs=[tx], + fee_recipient=charlie, + header_verify=Header(base_fee_per_gas=base_fee_per_gas), + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=1, post_nonce=1 + ) + ], + ), + bob: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=100 + ) + ], + ), + charlie: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=tip + ) + ], + ), + } + ).modify(remove_accounts(charlie)), + ) + ], + ) + + +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +def test_bal_invalid_coinbase_balance_value( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """ + Test that clients reject blocks where BAL contains an incorrect + balance value for the coinbase/fee recipient. + + Same setup as test_bal_invalid_missing_coinbase but the coinbase + entry is present with a wrong balance (999 instead of the + actual tip). + """ + alice = pre.fund_eoa(amount=10**18) + bob = pre.fund_eoa(amount=0) + charlie = pre.fund_eoa(amount=0) + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=b"", + contract_creation=False, + access_list=[], + ) + gas_price = 0xA + + tx = Transaction( + sender=alice, + to=bob, + value=100, + gas_limit=intrinsic_gas + 1000, + gas_price=gas_price, + ) + + genesis_env = Environment(base_fee_per_gas=0x7) + base_fee_per_gas = fork.base_fee_per_gas_calculator()( + parent_base_fee_per_gas=int(genesis_env.base_fee_per_gas or 0), + parent_gas_used=0, + parent_gas_limit=genesis_env.gas_limit, + ) + tip = (gas_price - base_fee_per_gas) * intrinsic_gas + + blockchain_test( + pre=pre, + post={}, + genesis_environment=genesis_env, + blocks=[ + Block( + txs=[tx], + fee_recipient=charlie, + header_verify=Header(base_fee_per_gas=base_fee_per_gas), + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=1, post_nonce=1 + ) + ], + ), + bob: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=100 + ) + ], + ), + charlie: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=tip + ) + ], + ), + } + ).modify( + modify_balance(charlie, block_access_index=1, balance=999) + ), + ) + ], + ) + + +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +@pytest.mark.parametrize( + "has_withdrawal", + [ + pytest.param(False, id="empty_block"), + pytest.param(True, id="withdrawal_only"), + ], +) +def test_bal_invalid_extraneous_coinbase( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + has_withdrawal: bool, +) -> None: + """ + Test that clients reject blocks where BAL contains a spurious + coinbase entry when the coinbase received no fees. + + Coinbase is only included in BAL when it receives transaction tips. + In blocks with no transactions, the coinbase receives nothing — + even if withdrawals modify other accounts' balances. + + - empty_block: No txs, no withdrawals. Only system contracts. + - withdrawal_only: No txs, one withdrawal to a different address. + Withdrawals don't pay fees, so coinbase is still untouched. + """ + coinbase = pre.fund_eoa(amount=0) + + withdrawals = None + post: dict = {} + if has_withdrawal: + recipient = pre.fund_eoa(amount=0) + withdrawals = [ + Withdrawal( + index=0, + validator_index=0, + address=recipient, + amount=10, + ) + ] + post[recipient] = None + + blockchain_test( + pre=pre, + post=post, + blocks=[ + Block( + txs=[], + fee_recipient=coinbase, + withdrawals=withdrawals, + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, + expected_block_access_list=BlockAccessListExpectation( + account_expectations={coinbase: None} + ).modify( + append_account(BalAccountChange(address=coinbase)), + sort_accounts_by_address(), + ), + ) + ], + ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 7221c867d23..dfaefa7ccf4 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -30,6 +30,10 @@ | `test_bal_fully_unmutated_account` | Ensure BAL captures account that has zero net mutations | Alice sends 0 wei to `Oracle` which writes same pre-existing value to storage | BAL MUST include Alice with `nonce_changes` and balance changes (gas), `Oracle` with `storage_reads` for accessed slot but empty `storage_changes`. | ✅ Completed | | `test_bal_net_zero_balance_transfer` | BAL includes accounts with net-zero balance change but excludes them from balance changes | Contract receives and sends same amount to recipient using CALL or SELFDESTRUCT | BAL **MUST** include contract in `account_changes` without `balance_changes` (net zero). BAL **MUST** record non-zero `balance_changes` for recipient. | ✅ Completed | | `test_bal_system_dequeue_consolidations_eip7251` | BAL tracks post-exec system dequeues for consolidations | Pre-populate EIP-7251 consolidation requests; produce a block where dequeues occur | BAL MUST include the 7251 system contract with `storage_changes` (queue slots 0–3) using `block_access_index = len(txs)`. | ✅ Completed | +| `test_bal_withdrawal_contract_cross_index` | Ensure withdrawal system contract shows storage changes at both tx and post-execution indices | Alice sends withdrawal request to EIP-7002 system contract. Slots 0x01 (count) and 0x03 (tail) are incremented during tx (index 1) and reset during post-execution dequeue (index 2). | BAL **MUST** include withdrawal request contract with `storage_changes` for slots 0x01 and 0x03, each with two `slot_changes`: one at `block_access_index=1` (tx) and one at `block_access_index=2` (post-exec). | ✅ Completed | +| `test_bal_consolidation_contract_cross_index` | Ensure consolidation system contract shows storage changes at both tx and post-execution indices | Alice sends consolidation request to EIP-7251 system contract. Slots 0x01 (count) and 0x03 (tail) are incremented during tx (index 1) and reset during post-execution dequeue (index 2). | BAL **MUST** include consolidation request contract with `storage_changes` for slots 0x01 and 0x03, each with two `slot_changes`: one at `block_access_index=1` (tx) and one at `block_access_index=2` (post-exec). | ✅ Completed | +| `test_bal_noop_write_filtering` | Ensure BAL filters NOOP storage writes (writing same value or 0 to empty slot) | Contract writes 0 to uninitialized slot 1 (noop), 42 to slot 2 (real change), 100 to slot 3 (same as pre-state, noop), 200 to slot 4 (different from pre-state 150, real change). | BAL **MUST** include `storage_changes` only for slots 2 and 4 (actual changes). Slots 1 and 3 **MUST NOT** appear in `storage_changes` (no-op writes filtered). | ✅ Completed | +| `test_bal_system_contract_noop_filtering` | Ensure system contract post-execution calls filter net-zero storage writes | Simple transfer that doesn't interact with system contracts. Post-execution system calls read withdrawal/consolidation contract slots 0-3 but don't modify them. | Withdrawal and consolidation system contracts **MUST** have `storage_reads` for slots 0x00-0x03 but **MUST NOT** have `storage_changes` (no actual modifications occurred). | ✅ Completed | | `test_bal_aborted_storage_access` | Ensure BAL captures storage access in aborted transactions correctly | Alice calls contract that reads storage slot `0x01`, writes to slot `0x02`, then aborts with `REVERT`/`INVALID` | BAL MUST include storage_reads for slots `0x01` and `0x02` (aborted writes become reads), empty storage_changes. Only nonce changes for Alice. | ✅ Completed | | `test_bal_aborted_account_access` | Ensure BAL captures account access in aborted transactions for all account accessing opcodes | Alice calls `AbortContract` that performs account access operations (`BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) on `TargetContract` and aborts via `REVERT`/`INVALID` | BAL MUST include Alice, `TargetContract`, and `AbortContract` in account_changes and nonce changes for Alice. | ✅ Completed | | `test_bal_pure_contract_call` | Ensure BAL captures contract access for pure computation calls | Alice calls `PureContract` that performs pure arithmetic (ADD operation) without storage or balance changes | BAL MUST include Alice and `PureContract` in `account_changes`, and `nonce_changes` for Alice. | ✅ Completed | @@ -45,7 +49,7 @@ | `test_bal_7702_invalid_nonce_authorization` | Ensure BAL handles failed authorization due to wrong nonce | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect nonce, causing silent authorization failure | BAL **MUST** include Alice with empty changes (account access), Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include `Oracle` (authorization failed, no delegation) | ✅ Completed | | `test_bal_7702_invalid_chain_id_authorization` | Ensure BAL handles failed authorization due to wrong chain id | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect chain id, causing authorization failure before account access | BAL **MUST** include Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include Alice (authorization fails before loading account) or `Oracle` (authorization failed, no delegation) | ✅ Completed | | `test_bal_7702_delegated_via_call_opcode` | Ensure BAL captures delegation target when a contract uses *CALL opcodes to call a delegated account | Pre-deployed contract `Alice` delegated to `Oracle`. `Caller` contract uses CALL/CALLCODE/DELEGATECALL/STATICCALL to call `Alice`. Bob sends transaction to `Caller`. | BAL **MUST** include Bob: `nonce_changes`. `Caller`: empty changes (account access). `Alice`: empty changes (account access - delegated account being called). `Oracle`: empty changes (delegation target access). | ✅ Completed | -| `test_bal_7702_null_address_delegation` | Ensure BAL does not record spurious code changes for net-zero code operations | Alice sends transaction with authorization delegating to NULL_ADDRESS (0x0), which sets code to `b""` on an account that already has `b""` code. Transaction sends 10 wei to Bob. | BAL **MUST** include Alice with `nonce_changes` (tx nonce + auth nonce increment) but **MUST NOT** include `code_changes` (setting `b"" -> b""` is net-zero and filtered out). Bob: `balance_changes` (receives 10 wei). This ensures net-zero code change is not recorded. | ✅ Completed | +| `test_bal_7702_null_address_delegation_no_code_change` | Ensure BAL does not record spurious code changes for net-zero code operations | Alice sends transaction with authorization delegating to NULL_ADDRESS (0x0), which sets code to `b""` on an account that already has `b""` code. Transaction sends 10 wei to Bob. | BAL **MUST** include Alice with `nonce_changes` (tx nonce + auth nonce increment) but **MUST NOT** include `code_changes` (setting `b"" -> b""` is net-zero and filtered out). Bob: `balance_changes` (receives 10 wei). This ensures net-zero code change is not recorded. | ✅ Completed | | `test_bal_7702_double_auth_reset` | Ensure BAL tracks multiple 7702 nonce increments but filters net-zero code change | Single transaction contains two EIP-7702 authorizations for `Alice`: (1) first auth sets delegation `0xef0100\|\|Oracle`, (2) second auth clears delegation back to empty. Transaction sends 10 wei to `Bob`. Two variants: (a) Self-funded: `Alice` is tx sender (one tx nonce bump + two auth bumps → nonce 0→3). (b) Sponsored: `Relayer` is tx sender (`Alice` only in auths → nonce 0→2 for `Alice`, plus one nonce bump for `Relayer`). | Variant (a): BAL **MUST** include `Alice` with `nonce_changes` 0→3. Variant (b): BAL **MUST** include `Alice` with `nonce_changes` 0→2 and `Relayer` with its own `nonce_changes`. For both variants, BAL **MUST NOT** include `code_changes` for `Alice` (net code is empty), **MUST** include `Bob` with `balance_changes` (receives 10 wei), and `Oracle` **MUST NOT** appear in BAL. | ✅ Completed | | `test_bal_7702_double_auth_swap` | Ensure BAL captures final code when double auth swaps delegation targets | `Relayer` sends transaction with two authorizations for Alice: (1) First auth sets delegation to `CONTRACT_A` at nonce=0, (2) Second auth changes delegation to `CONTRACT_B` at nonce=1. Transaction sends 10 wei to Bob. Per EIP-7702, only the last authorization takes effect. | BAL **MUST** include Alice with `nonce_changes` (both auths increment nonce to 2) and `code_changes` (final code is delegation designation for `CONTRACT_B`, not `CONTRACT_A`). Bob: `balance_changes` (receives 10 wei). Relayer: `nonce_changes`. Neither `CONTRACT_A` nor `CONTRACT_B` appear in BAL during delegation setup (never accessed). This ensures BAL shows final state, not intermediate changes. | ✅ Completed | | `test_bal_sstore_and_oog` | Ensure BAL handles OOG during SSTORE execution at various gas boundaries (EIP-2200 stipend and implicit SLOAD) | Alice calls contract that attempts `SSTORE` to cold slot `0x01`. Parameterized: (1) OOG at EIP-2200 stipend check (2300 gas after PUSH opcodes) - fails before implicit SLOAD, (2) OOG at stipend + 1 (2301 gas) - passes stipend check but fails after implicit SLOAD, (3) OOG at exact gas - 1, (4) Successful SSTORE with exact gas. | For case (1): BAL **MUST NOT** include slot `0x01` in `storage_reads` or `storage_changes` (fails before implicit SLOAD). For cases (2) and (3): BAL **MUST** include slot `0x01` in `storage_reads` (implicit SLOAD occurred) but **MUST NOT** include in `storage_changes` (write didn't complete). For case (4): BAL **MUST** include slot `0x01` in `storage_changes` only (successful write; read is filtered by builder). | ✅ Completed | @@ -99,13 +103,14 @@ | `test_bal_storage_write_read_same_frame` | Ensure BAL captures write precedence over read in same call frame (writes shadow reads) | Alice calls `Oracle` which writes (`SSTORE`) value `0x42` to slot `0x01`, then reads (`SLOAD`) from slot `0x01` in the same call frame | BAL **MUST** include `Oracle` with slot `0x01` in `storage_changes` showing final value `0x42`. Slot `0x01` **MUST NOT** appear in `storage_reads` (write shadows the subsequent read in same frame). | ✅ Completed | | `test_bal_storage_write_read_cross_frame` | Ensure BAL captures write precedence over read across call frames (writes shadow reads cross-frame) | Alice calls `Oracle`. First call reads slot `0x01` (sees initial value), writes `0x42` to slot `0x01`, then calls itself (via `CALL`, `DELEGATECALL`, or `CALLCODE`). Second call reads slot `0x01` (sees `0x42`) and exits. | BAL **MUST** include `Oracle` with slot `0x01` in `storage_changes` showing final value `0x42`. Slot `0x01` **MUST NOT** appear in `storage_reads` (write shadows both the read before it in same frame and the read in the recursive call). | ✅ Completed | | `test_bal_create_transaction_empty_code` | Ensure BAL does not record spurious code changes for CREATE transaction deploying empty code | Alice sends CREATE transaction with empty initcode (deploys code `b""`). Contract address gets nonce = 1 and code = `b""`. | BAL **MUST** include Alice with `nonce_changes` and created contract with `nonce_changes` but **MUST NOT** include `code_changes` for contract (setting `b"" -> b""` is net-zero). | ✅ Completed | -| `test_bal_cross_block_precompile_state_leak` | Ensure internal EVM state for precompile handling does not leak between blocks | Block 1: Alice calls RIPEMD-160 (0x03) with zero value (RIPEMD-160 must be pre-funded). Block 2: Bob's transaction triggers an exception (stack underflow). | BAL for Block 1 **MUST** include RIPEMD-160. BAL for Block 2 **MUST NOT** include RIPEMD-160 (never accessed in Block 2). Internal state from Parity Touch Bug (EIP-161) handling must be reset between blocks. | ✅ Completed | +| `test_bal_cross_block_ripemd160_state_leak` | Ensure internal EVM state for precompile handling does not leak between blocks | Block 1: Alice calls RIPEMD-160 (0x03) with zero value (RIPEMD-160 must be pre-funded). Block 2: Bob's transaction triggers an exception (stack underflow). | BAL for Block 1 **MUST** include RIPEMD-160. BAL for Block 2 **MUST NOT** include RIPEMD-160 (never accessed in Block 2). Internal state from Parity Touch Bug (EIP-161) handling must be reset between blocks. | ✅ Completed | | `test_bal_all_transaction_types` | Ensure BAL correctly captures state changes from all transaction types in a single block | Single block with 5 transactions: Type 0 (Legacy), Type 1 (EIP-2930 Access List), Type 2 (EIP-1559), Type 3 (EIP-4844 Blob), Type 4 (EIP-7702 Set Code). Each tx writes to contract storage. Note: Access list addresses are pre-warmed but NOT recorded in BAL (no state access). | BAL **MUST** include: (1) All 5 senders with `nonce_changes`. (2) Contracts 0-3 with `storage_changes`. (3) Alice (7702 target) with `nonce_changes`, `code_changes` (delegation), `storage_changes`. (4) Oracle (delegation source) with empty changes. | ✅ Completed | | `test_bal_create2_collision` | Ensure BAL handles CREATE2 address collision correctly | Factory contract (nonce=1, storage slot 0=0xDEAD) executes `CREATE2(salt=0, initcode)` targeting address that already has `code=STOP, nonce=1`. Pre-deploy contract at calculated CREATE2 target address before factory deployment. | BAL **MUST** include: (1) Factory with `nonce_changes` (1→2, incremented even on failed CREATE2), `storage_changes` for slot 0 (0xDEAD→0, stores failure). (2) Collision address with empty changes (accessed during collision check, no state changes). CREATE2 returns 0. Collision address **MUST NOT** have `nonce_changes` or `code_changes`. | ✅ Completed | | `test_bal_create_selfdestruct_to_self_with_call` | Ensure BAL handles init code that calls external contract then selfdestructs to itself | Factory executes `CREATE2` with endowment=100. Init code (embedded in factory via CODECOPY): (1) `CALL(Oracle, 0)` - Oracle writes to its storage slot 0x01. (2) `SSTORE(0x01, 0x42)` - write to own storage. (3) `SELFDESTRUCT(SELF)` - selfdestruct to own address. Contract created and destroyed in same tx. | BAL **MUST** include: (1) Factory with `nonce_changes`, `balance_changes` (loses 100). (2) Oracle with `storage_changes` for slot 0x01 (external call succeeded). (3) Created address with `storage_reads` for slot 0x01 (aborted write becomes read) - **MUST NOT** have `nonce_changes`, `code_changes`, `storage_changes`, or `balance_changes` (ephemeral contract, balance burned via SELFDESTRUCT to self). | ✅ Completed | | `test_bal_selfdestruct_to_7702_delegation` | Ensure BAL correctly handles SELFDESTRUCT to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Tx2: Victim contract (balance=100) executes `SELFDESTRUCT(Alice)`. Two separate transactions in same block. Note: Alice starts with initial balance which accumulates with selfdestruct. | BAL **MUST** include: (1) Alice at block_access_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at block_access_index=2 with `balance_changes` (receives selfdestruct). (3) Victim at block_access_index=2 with `balance_changes` (100→0). **Oracle MUST NOT appear in tx2** - per EVM spec, SELFDESTRUCT transfers balance without executing recipient code, so delegation target is never accessed. | ✅ Completed | | `test_bal_call_revert_insufficient_funds` | Ensure BAL handles CALL failure due to insufficient balance (not OOG) | Contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), CALL(target, value=1000), SSTORE(0x02, result)`. CALL fails because 1000 > 100. Target address 0xDEAD (pre-existing with non-zero balance to avoid pruning). Note: slot 0x02 must start non-zero so SSTORE(0) is a change. | BAL **MUST** include: (1) Contract with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, CALL returned failure). (2) Target (0xDEAD) **MUST** appear in BAL with empty changes - target is accessed before balance check fails. | ✅ Completed | | `test_bal_lexicographic_address_ordering` | Ensure BAL enforces strict lexicographic byte-wise ordering | Pre-fund three addresses with specific byte patterns: `addr_low = 0x0000...0001`, `addr_mid = 0x0000...0100`, `addr_high = 0x0100...0000`. Contract touches them in reverse order: `BALANCE(addr_high), BALANCE(addr_low), BALANCE(addr_mid)`. Additionally, include two endian-trap addresses that are byte-reversals of each other: `addr_endian_low = 0x0100000000000000000000000000000000000002`, `addr_endian_high = 0x0200000000000000000000000000000000000001`. Note: `reverse(addr_endian_low) = addr_endian_high`. Correct lexicographic order: `addr_endian_low < addr_endian_high` (0x01 < 0x02 at byte 0). If implementation incorrectly reverses bytes before comparing, it would get `addr_endian_low > addr_endian_high` (wrong). | BAL account list **MUST** be sorted lexicographically by address bytes: `addr_low` < `addr_mid` < `addr_high` < `addr_endian_low` < `addr_endian_high`, regardless of access order. The endian-trap addresses specifically catch byte-reversal bugs where addresses are compared with wrong byte order. Complements `test_bal_invalid_account_order` which tests rejection; this tests correct generation. | ✅ Completed | +| `test_bal_gas_limit_boundary` | Ensure BAL max items gas limit boundary is enforced for empty blocks | Empty block with gas limit set to the exact boundary where `bal_items <= block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM`. Parameterized: (1) at_boundary (gas limit = exact minimum, passes), (2) below_boundary (gas limit = exact minimum - 1, fails). | At boundary: block **MUST** be accepted. Below boundary: block **MUST** be rejected with `BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED` exception. | ✅ Completed | | `test_bal_transient_storage_not_tracked` | Ensure BAL excludes EIP-1153 transient storage operations | Contract executes: `TSTORE(0x01, 0x42)` (transient write), `TLOAD(0x01)` (transient read), `SSTORE(0x02, result)` (persistent write using transient value). | BAL **MUST** include slot 0x02 in `storage_changes` (persistent storage was modified). BAL **MUST NOT** include slot 0x01 in `storage_reads` or `storage_changes` (transient storage is not persisted, not needed for stateless execution). This verifies TSTORE/TLOAD don't pollute BAL. | ✅ Completed | | `test_bal_withdrawal_to_7702_delegation` | Ensure BAL correctly handles withdrawal to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Withdrawal: 10 gwei sent to Alice. Single block with tx + withdrawal. | BAL **MUST** include: (1) Alice at block_access_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at block_access_index=2 with `balance_changes` (receives withdrawal). **Oracle MUST NOT appear** - withdrawals credit balance without executing recipient code, so delegation target is never accessed. This complements `test_bal_selfdestruct_to_7702_delegation` (selfdestruct) and `test_bal_withdrawal_no_evm_execution` (withdrawal to contract). | ✅ Completed | | `test_init_collision_create_tx` | Ensure BAL tracks CREATE collisions correctly (pre-Amsterdam test with BAL) | CREATE transaction targeting address with existing storage aborts | BAL **MUST** show empty expectations for collision address (no changes occur due to abort) | ✅ Completed | @@ -128,6 +133,15 @@ | `test_bal_7002_request_from_contract` | Ensure BAL captures withdrawal request from contract with correct source address | Alice calls `RelayContract` which internally calls EIP-7002 system contract with withdrawal request. Withdrawal request should have `source_address = RelayContract` (not Alice). | BAL **MUST** include Alice with `nonce_changes` at `block_access_index=1`. BAL **MUST** include `RelayContract` with `balance_changes` (fee paid to system contract) at `block_access_index=1`. BAL **MUST** include system contract with `balance_changes`, `storage_reads`, and `storage_changes` (queue modified). Source address in withdrawal request **MUST** be `RelayContract`. Clean sweep: count and tail reset to 0 at `block_access_index=2`. | ✅ Completed | | `test_bal_7002_request_invalid` | Ensure BAL correctly handles invalid withdrawal request scenarios | Parameterized test with 8 invalid scenarios: (1) insufficient_fee (fee=0), (2) calldata_too_short (55 bytes), (3) calldata_too_long (57 bytes), (4) oog (insufficient gas), (5-7) invalid_call_type (DELEGATECALL/STATICCALL/CALLCODE), (8) contract_reverts. Tests both EOA and contract-based withdrawal requests. | BAL **MUST** include sender with `nonce_changes` at `block_access_index=1`. BAL **MUST** include system contract with `storage_reads` for slots: excess (slot 0), count (slot 1), head (slot 2), tail (slot 3). System contract **MUST NOT** have `storage_changes` (transaction failed, no queue modification). | ✅ Completed | | `test_bal_invalid_extraneous_entries` | Verify clients reject blocks with any type of extraneous BAL entries | Alice sends 100 wei to Oracle contract (which reads storage slot 0). Charlie is uninvolved in this transaction. A valid BAL is created containing nonce change for Alice, balance change and storage read for Oracle. The BAL is corrupted by adding various extraneous entries: (1) extra_nonce, (2) extra_balance, (3) extra_code, (4) extra_storage_write_touched (slot 0 - already read), (5) extra_storage_write_untouched (slot 1 - not accessed), (6) extra_storage_write_uninvolved_account (Charlie - uninvolved account), (7) extra_account_access (Charlie), (8) extra_storage_read (slot 999). Each tested at block_access_index 1 (same tx), 2 (system tx), 3 (out of bounds). | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** detect any extraneous entries in BAL. | ✅ Completed | +| `test_bal_invalid_duplicate_entries` | Verify clients reject blocks where BAL violates uniqueness constraints | Oracle writes storage, reads storage, and CREATEs a contract. BAL is corrupted with duplicate entries: (1) duplicate_nonce_change, (2) duplicate_balance_change, (3) duplicate_code_change, (4) duplicate_storage_slot, (5) duplicate_storage_read, (6) duplicate_slot_change, (7) storage_key_in_both_changes_and_reads. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Each `block_access_index` must appear at most once per change list, each storage key at most once in `storage_changes` and `storage_reads`, and no key in both. | ✅ Completed | +| `test_bal_invalid_missing_withdrawal_account` | Verify clients reject blocks where BAL is missing an account modified only by a withdrawal | Alice sends 5 wei to Bob (1 transaction). Charlie receives 10 gwei withdrawal. BAL modifier removes Charlie's entry entirely. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** detect that Charlie's balance was modified by the withdrawal but has no corresponding BAL entry. | ✅ Completed | +| `test_bal_invalid_missing_withdrawal_account_empty_block` | Verify clients reject blocks where BAL is missing a withdrawal-modified account in an empty block | Charlie receives 10 gwei withdrawal in block with no transactions. BAL modifier removes Charlie's entry entirely. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** detect withdrawal-modified accounts even when no transactions are present. | ✅ Completed | +| `test_bal_invalid_hash_mismatch` | Verify clients reject blocks where the BAL hash in the header does not match the actual BAL content | Alice sends value to Bob. BAL content is valid but header hash is overridden to a wrong value via `rlp_modifier`. Unlike other invalid BAL tests (which corrupt BAL content with matching hash), this keeps the BAL valid but injects a wrong header hash. | Block **MUST** be rejected with `INVALID_BAL_HASH` or `INVALID_BLOCK_HASH` exception. Clients **MUST** re-derive the BAL from block execution and compare its hash to the header, not just verify the BAL content is self-consistent. | ✅ Completed | +| `test_bal_invalid_field_entries` | Verify clients reject blocks with missing or incorrect field-level BAL entries | Oracle writes storage slot 1, reads storage slot 2, and CREATEs a small contract. A valid BAL is created, then corrupted by parameterized modifier: (1) missing_storage_change: Oracle's storage writes removed, (2) missing_storage_read: Oracle's storage reads removed, (3) missing_code_change: created contract's code change removed, (4) wrong_code_value: created contract's deployed bytecode changed to wrong value. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate all field-level BAL entries: storage writes, storage reads, and code changes. | ✅ Completed | +| `test_bal_invalid_withdrawal_balance_value` | Verify clients reject blocks where BAL has an incorrect balance value for a withdrawal-modified account | Charlie receives 10 gwei withdrawal in an empty block. BAL modifier changes Charlie's post-balance from the correct 10_000_000_000 wei to 999. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate withdrawal balance values match actual withdrawal amounts (including gwei-to-wei conversion). | ✅ Completed | +| `test_bal_invalid_missing_coinbase` | Verify clients reject blocks where BAL is missing the coinbase/fee recipient | Alice sends 100 wei to Bob with gas_price > base_fee so coinbase (charlie) receives a non-zero tip. BAL modifier removes charlie's entry entirely. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** include fee recipients that received tips in the BAL. | ✅ Completed | +| `test_bal_invalid_coinbase_balance_value` | Verify clients reject blocks where BAL has an incorrect balance for the coinbase/fee recipient | Same setup as test_bal_invalid_missing_coinbase. BAL modifier changes charlie's post-balance from the actual tip to 999. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate coinbase balance values match actual fee accounting (priority fee x gas used). | ✅ Completed | +| `test_bal_invalid_extraneous_coinbase` | Verify clients reject blocks with a spurious coinbase entry when coinbase received no fees | Parameterized: (1) empty_block: no txs, no withdrawals — only system contracts in valid BAL, (2) withdrawal_only: no txs, one withdrawal to a different address — withdrawals don't pay fees so coinbase is still untouched. BAL modifier appends spurious coinbase entry with empty changes. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Coinbase **MUST NOT** appear in BAL when it receives no transaction tips, even if the block has other state-modifying activity (withdrawals). | ✅ Completed | | `test_bal_2935_simple` | Ensure BAL captures EIP-2935 history storage writes during pre-execution system call alongside normal transactions | Block with 2 normal user transactions: Alice sends 10 wei to Charlie, Bob sends 10 wei to Charlie. At block start (pre-execution), `SYSTEM_ADDRESS` calls `HISTORY_STORAGE_ADDRESS` to store parent block hash. | BAL **MUST** include `HISTORY_STORAGE_ADDRESS` with `storage_changes` (ring buffer slot 0, empty `slot_changes` since parent hash is framework-computed); `SYSTEM_ADDRESS` **MUST NOT** be included in BAL. At `block_access_index=1`: Alice with `nonce_changes`, Charlie with `balance_changes` (10 wei). At `block_access_index=2`: Bob with `nonce_changes`, Charlie with `balance_changes` (20 wei total). | ✅ Completed | | `test_bal_2935_empty_block` | Ensure BAL captures EIP-2935 history storage writes in empty block | Block with no transactions. At block start (pre-execution), `SYSTEM_ADDRESS` calls `HISTORY_STORAGE_ADDRESS` to store parent block hash. | BAL **MUST** include `HISTORY_STORAGE_ADDRESS` with `storage_changes` (ring buffer slot 0, empty `slot_changes`); `SYSTEM_ADDRESS` **MUST NOT** be included in BAL. No transaction-related BAL entries. | ✅ Completed | | `test_bal_2935_query` | Ensure BAL captures storage reads when querying EIP-2935 historical block hashes (valid and invalid queries) with optional value transfer | Parameterized test: Block 1 (empty, stores genesis hash via system call). Block 2: Oracle contract queries `HISTORY_STORAGE_ADDRESS` with block number. Two block number scenarios (valid=0 genesis hash, invalid=1042 out of range) and value (0 or 100 wei). Valid query (block_number=0): reads genesis hash slot, oracle writes returned value. If value > 0, history storage contract receives balance. Invalid query (block_number=1042, out of range): reverts before storage access, oracle has implicit SLOAD recorded, value stays in oracle (not transferred to history storage). | Block 2 BAL **MUST** include: Valid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with `storage_reads` [slot 0] and `balance_changes` if value > 0, oracle with `storage_changes` (empty `slot_changes`). Invalid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes`, oracle with `storage_reads` [0], NO `storage_changes`, and `balance_changes` if value > 0 (value stays in oracle). Alice with `nonce_changes` at `block_access_index=1`. | ✅ Completed | From 64dc4ac9f2c5a52bde5a01c2023ee0225420fd4d Mon Sep 17 00:00:00 2001 From: Leo Lara Date: Thu, 16 Apr 2026 00:18:54 +0700 Subject: [PATCH 017/186] fix(test-plugins-filler): aggregate --verify-traces results across xdist workers (#2664) * Fix bug in verify-traces * Convert to pydantic models * Add Ignore stack and gas mode * Allow differences in return_data for no-stack comparators --- .../filler/tests/test_verify_traces.py | 273 +++++++++++++++++ .../plugins/filler/verify_traces.py | 90 +++++- .../client_clis/cli_types.py | 23 +- .../tests/test_trace_comparators.py | 287 ++++++++++++++++-- .../client_clis/trace_comparators.py | 64 +++- .../src/execution_testing/specs/state.py | 12 +- 6 files changed, 686 insertions(+), 63 deletions(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_verify_traces.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_verify_traces.py index 5682cddb71c..d9a5e4bab03 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_verify_traces.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_verify_traces.py @@ -2,13 +2,22 @@ import json from pathlib import Path +from typing import Any +from unittest.mock import MagicMock from execution_testing.cli.pytest_commands.plugins.filler.verify_traces import ( # noqa: E501 + TraceVerifier, _load_traces_from_dump_dir, + pytest_testnodedown, ) from execution_testing.client_clis.cli_types import ( Traces, ) +from execution_testing.client_clis.trace_comparators import ( + TraceComparisonResult, + TraceDifference, + TransactionCountMismatch, +) def _write_trace_file( @@ -93,3 +102,267 @@ def test_numeric_sorting_not_lexical(self, tmp_path: Path) -> None: assert len(result) == 3 # Verify they are in order 0, 2, 10 by checking the list # length — ordering is guaranteed by the implementation + + +def _make_trace_verifier( + json_formatter: Any = None, +) -> TraceVerifier: + """Construct a minimally-configured TraceVerifier for unit tests.""" + return TraceVerifier( + config=MagicMock(), + comparators=[], + formatter=MagicMock(), + baseline_dir=Path("/tmp/baseline"), + filler_path=Path("/tmp/filler"), + json_formatter=json_formatter, + ) + + +def _make_session(workeroutput: dict | None) -> Any: + """ + Build a fake pytest.Session. + + ``workeroutput=None`` simulates the controller (the attribute is + absent); a dict simulates a worker. + """ + config = MagicMock() + if workeroutput is None: + # Controller — `workeroutput` must NOT exist on config. + del config.workeroutput + else: + config.workeroutput = workeroutput + session = MagicMock() + session.config = config + return session + + +class TestXdistAggregation: + """ + Test xdist worker→controller aggregation. + + Background: ``TraceVerifier`` keeps results in an instance dict. + Under ``pytest-xdist -n N`` each worker has its own subprocess and + its own plugin instance, so the controller's instance is empty + unless workers explicitly forward their results. The plugin uses + ``config.workeroutput`` on workers and ``pytest_testnodedown`` on + the controller — these tests exercise that path without spinning + up real xdist subprocesses. + """ + + def test_worker_writes_results_to_workeroutput(self) -> None: + """Worker's pytest_sessionfinish stores results in workeroutput.""" + verifier = _make_trace_verifier() + verifier.test_results = { + "test_a": { + "exact": TraceComparisonResult(equivalent=True), + }, + "test_b": { + "exact": TraceComparisonResult( + equivalent=False, + differences=[ + TraceDifference( + transaction_index=0, + trace_line_index=3, + baseline="ADD", + current="MUL", + ), + ], + ), + }, + } + workeroutput: dict = {} + verifier.pytest_sessionfinish( + _make_session(workeroutput=workeroutput), 0 + ) + + payload = workeroutput["trace_verifier_results"] + assert set(payload.keys()) == {"test_a", "test_b"} + assert payload["test_a"]["exact"]["equivalent"] is True + assert payload["test_b"]["exact"]["equivalent"] is False + assert ( + payload["test_b"]["exact"]["differences"][0]["baseline"] == "ADD" + ) + + def test_controller_does_not_write_workeroutput(self) -> None: + """On the controller (no workeroutput attribute), hook is a no-op.""" + verifier = _make_trace_verifier() + verifier.test_results = { + "test_a": {"exact": TraceComparisonResult(equivalent=True)}, + } + # Should not raise even though config has no `workeroutput`. + verifier.pytest_sessionfinish(_make_session(workeroutput=None), 0) + + def test_worker_with_empty_results_does_not_write(self) -> None: + """A worker that ran no comparisons should not write a payload.""" + verifier = _make_trace_verifier() + workeroutput: dict = {} + verifier.pytest_sessionfinish( + _make_session(workeroutput=workeroutput), 0 + ) + assert "trace_verifier_results" not in workeroutput + + def test_pytest_testnodedown_merges_payload(self) -> None: + """Controller hook merges a worker's payload into the plugin.""" + controller_plugin = _make_trace_verifier() + + # Simulate the data a worker would send back. + worker_payload = { + "test_a": { + "exact": TraceComparisonResult(equivalent=True).model_dump( + mode="json" + ), + }, + "test_b": { + "exact-no-stack": TraceComparisonResult( + equivalent=False, + differences=[ + TransactionCountMismatch( + baseline_count=2, current_count=1 + ), + ], + ).model_dump(mode="json"), + }, + } + node = MagicMock() + node.workeroutput = {"trace_verifier_results": worker_payload} + node.config.pluginmanager.get_plugin.return_value = controller_plugin + + pytest_testnodedown(node, error=None) + + assert set(controller_plugin.test_results.keys()) == { + "test_a", + "test_b", + } + assert ( + controller_plugin.test_results["test_a"]["exact"].equivalent + is True + ) + diff_b = controller_plugin.test_results["test_b"][ + "exact-no-stack" + ].differences[0] + assert isinstance(diff_b, TransactionCountMismatch) + assert diff_b.baseline_count == 2 + assert diff_b.current_count == 1 + + def test_pytest_testnodedown_multiple_workers_aggregate(self) -> None: + """Two workers' payloads both land in the controller plugin.""" + controller_plugin = _make_trace_verifier() + + def _send(node_results: dict[str, TraceComparisonResult]) -> None: + payload = { + nodeid: {"exact": result.model_dump(mode="json")} + for nodeid, result in node_results.items() + } + node = MagicMock() + node.workeroutput = {"trace_verifier_results": payload} + node.config.pluginmanager.get_plugin.return_value = ( + controller_plugin + ) + pytest_testnodedown(node, error=None) + + _send( + { + "test_w0_a": TraceComparisonResult(equivalent=True), + "test_w0_b": TraceComparisonResult(equivalent=True), + } + ) + _send( + { + "test_w1_a": TraceComparisonResult(equivalent=True), + "test_w1_b": TraceComparisonResult(equivalent=True), + "test_w1_c": TraceComparisonResult(equivalent=True), + } + ) + + # The bug being fixed: prior to aggregation, the controller saw + # only one worker's slice (or none). All five nodeids must be + # present after merging both workers. + assert set(controller_plugin.test_results.keys()) == { + "test_w0_a", + "test_w0_b", + "test_w1_a", + "test_w1_b", + "test_w1_c", + } + + def test_pytest_testnodedown_no_payload_is_noop(self) -> None: + """Worker with no payload (didn't run any tests) is a no-op.""" + controller_plugin = _make_trace_verifier() + node = MagicMock() + node.workeroutput = {} + node.config.pluginmanager.get_plugin.return_value = controller_plugin + + pytest_testnodedown(node, error=None) + + assert controller_plugin.test_results == {} + + def test_pytest_testnodedown_no_plugin_registered(self) -> None: + """If the trace-verifier plugin isn't registered, hook is a no-op.""" + node = MagicMock() + node.workeroutput = { + "trace_verifier_results": { + "test_a": { + "exact": TraceComparisonResult(equivalent=True).model_dump( + mode="json" + ), + }, + }, + } + node.config.pluginmanager.get_plugin.return_value = None + # Should not raise. + pytest_testnodedown(node, error=None) + + +class TestWorkerTerminalSummarySkipped: + """Workers must not write the JSON / text report.""" + + def test_worker_skips_terminal_summary(self) -> None: + """`pytest_terminal_summary` is a no-op when workerinput is set.""" + json_formatter = MagicMock() + json_formatter.output_path = Path("/tmp/report.json") + verifier = _make_trace_verifier(json_formatter=json_formatter) + verifier.test_results = { + "test_a": {"exact": TraceComparisonResult(equivalent=True)}, + } + + terminalreporter = MagicMock() + worker_config = MagicMock() + # Workers have `workerinput`; controllers don't. + worker_config.workerinput = {"workerid": "gw0"} + + verifier.pytest_terminal_summary( + terminalreporter, exitstatus=0, config=worker_config + ) + + json_formatter.write.assert_not_called() + terminalreporter.write_sep.assert_not_called() + + def test_controller_writes_terminal_summary(self) -> None: + """Controller (no workerinput) writes the report normally.""" + json_formatter = MagicMock() + json_formatter.output_path = Path("/tmp/report.json") + text_formatter = MagicMock() + text_formatter.format_summary.return_value = "summary line" + verifier = TraceVerifier( + config=MagicMock(), + comparators=[], + formatter=text_formatter, + baseline_dir=Path("/tmp/baseline"), + filler_path=Path("/tmp/filler"), + json_formatter=json_formatter, + ) + verifier.test_results = { + "test_a": {"exact": TraceComparisonResult(equivalent=True)}, + } + + terminalreporter = MagicMock() + controller_config = MagicMock() + # Controllers don't have `workerinput`. + del controller_config.workerinput + + verifier.pytest_terminal_summary( + terminalreporter, exitstatus=0, config=controller_config + ) + + json_formatter.write.assert_called_once_with(verifier.test_results) + terminalreporter.write_sep.assert_called() diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/verify_traces.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/verify_traces.py index 56847ed0765..2608182d044 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/verify_traces.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/verify_traces.py @@ -3,7 +3,7 @@ from __future__ import annotations from pathlib import Path -from typing import Any, Generator +from typing import Any, Generator, Protocol import pytest from _pytest.terminal import TerminalReporter @@ -27,6 +27,21 @@ TracesDiffReportFormatter, ) + +class _XdistWorkerNode(Protocol): + """ + Subset of ``xdist.workermanage.WorkerController`` we depend on. + + Defined here as a Protocol because ``xdist`` ships without a + ``py.typed`` marker, so importing its concrete class would force a + ``# type: ignore`` on every consumer. We only need ``workeroutput`` + (the worker→controller dict) and ``config.pluginmanager``. + """ + + workeroutput: dict[str, Any] + config: pytest.Config + + # --------------------------------------------------------------------------- # Baseline loading # --------------------------------------------------------------------------- @@ -245,13 +260,55 @@ def pytest_runtest_makereport( if results: self.test_results[item.nodeid] = results + @pytest.hookimpl + def pytest_sessionfinish( + self, + session: pytest.Session, + exitstatus: int, # noqa: ARG002 + ) -> None: + """ + Forward results from each xdist worker to the controller. + + Each xdist worker runs in its own subprocess with its own + ``TraceVerifier`` instance, so ``self.test_results`` only holds + the tests that *this* worker ran. Without this hook the + controller's plugin instance would receive nothing and the + terminal/JSON report would only reflect a single worker's slice + of the data. + + ``config.workeroutput`` is xdist's documented channel for + marshalling per-worker state back to the controller, where it is + consumed by the module-level ``pytest_testnodedown`` hook below. + Only workers have ``workeroutput``; on the controller this hook + is a no-op. + """ + config = session.config + if not hasattr(config, "workeroutput"): + return + if not self.test_results: + return + config.workeroutput["trace_verifier_results"] = { + nodeid: { + comp_name: result.model_dump(mode="json") + for comp_name, result in comps.items() + } + for nodeid, comps in self.test_results.items() + } + def pytest_terminal_summary( self, terminalreporter: TerminalReporter, exitstatus: int, # noqa: ARG002 - config: pytest.Config, # noqa: ARG002 + config: pytest.Config, ) -> None: """Print the aggregated trace verification report.""" + # Workers run their own terminal summary, but the aggregated + # view only exists on the controller. Skip on workers so they + # neither print a partial summary nor race to overwrite the + # JSON file. + if hasattr(config, "workerinput"): + return + if not self.test_results: return @@ -265,3 +322,32 @@ def pytest_terminal_summary( terminalreporter.write_line( f"JSON report written to: {self.json_formatter.output_path}" ) + + +# --------------------------------------------------------------------------- +# xdist controller-side aggregation +# --------------------------------------------------------------------------- + + +def pytest_testnodedown(node: _XdistWorkerNode, error: object | None) -> None: + """ + Merge one worker's trace verification results into the controller. + + Called on the controller (master) when each xdist worker finishes. + The worker has serialized its ``test_results`` into + ``node.workeroutput`` (see ``TraceVerifier.pytest_sessionfinish``); + here we deserialize and merge them into the controller-side plugin + instance so ``pytest_terminal_summary`` sees the combined view. + """ + del error + payload = getattr(node, "workeroutput", {}).get("trace_verifier_results") + if not payload: + return + plugin = node.config.pluginmanager.get_plugin("trace-verifier") + if plugin is None: + return + for nodeid, comps in payload.items(): + plugin.test_results[nodeid] = { + comp_name: TraceComparisonResult.model_validate(result_dict) + for comp_name, result_dict in comps.items() + } diff --git a/packages/testing/src/execution_testing/client_clis/cli_types.py b/packages/testing/src/execution_testing/client_clis/cli_types.py index 21d89279870..41b74c73198 100644 --- a/packages/testing/src/execution_testing/client_clis/cli_types.py +++ b/packages/testing/src/execution_testing/client_clis/cli_types.py @@ -185,7 +185,7 @@ def compare( self, other: Self, exclude_fields: set[str] | None = None, - enable_post_processing: bool = False, + ignore_gas_differences: bool = False, ) -> List[TraceFieldDiff]: """ Compare traces and return per-line differing fields. @@ -196,6 +196,15 @@ def compare( When exclude_fields is None, no fields are excluded. Pass an explicit set to skip fields (e.g. {"gas", "gas_cost"}). + + ``ignore_gas_differences`` toggles two gas-specific tolerances + that cannot be expressed through ``exclude_fields``: + + - The top-level ``gas_used`` total check is skipped (it is not a + per-line field, so excluding ``gas`` cannot silence it). + - ``Op.GAS`` results are scrubbed from the stack before per-line + comparison, so a differing gas value pushed by ``GAS`` does + not leak into a stack diff. """ line_exclude = exclude_fields or set() diffs: List[TraceFieldDiff] = [] @@ -219,7 +228,7 @@ def compare( ) ) - if not enable_post_processing and self.gas_used != other.gas_used: + if not ignore_gas_differences and self.gas_used != other.gas_used: diffs.append( TraceFieldDiff( None, @@ -230,7 +239,7 @@ def compare( own_traces = self.traces.copy() other_traces = other.traces.copy() - if enable_post_processing: + if ignore_gas_differences: TransactionTraces.remove_gas(own_traces) TransactionTraces.remove_gas(other_traces) @@ -244,13 +253,13 @@ def compare( return diffs def are_equivalent( - self, other: Self, enable_post_processing: bool + self, other: Self, ignore_gas_differences: bool ) -> bool: """Return True if the only difference is the gas counter.""" diffs = self.compare( other, exclude_fields={"gas", "gas_cost"}, - enable_post_processing=enable_post_processing, + ignore_gas_differences=ignore_gas_differences, ) for diff in diffs: if diff.line_index is None: @@ -286,7 +295,7 @@ def append(self, item: TransactionTraces) -> None: self.root.append(item) def are_equivalent( - self, other: Self | None, enable_post_processing: bool + self, other: Self | None, ignore_gas_differences: bool ) -> bool: """Return True if the only difference is the gas counter.""" if other is None: @@ -295,7 +304,7 @@ def are_equivalent( return False for i in range(len(self.root)): if not self.root[i].are_equivalent( - other.root[i], enable_post_processing + other.root[i], ignore_gas_differences ): logger.debug(f"Trace file {i} is not equivalent.") return False diff --git a/packages/testing/src/execution_testing/client_clis/tests/test_trace_comparators.py b/packages/testing/src/execution_testing/client_clis/tests/test_trace_comparators.py index 14f0c643b38..4c12c3c2bde 100644 --- a/packages/testing/src/execution_testing/client_clis/tests/test_trace_comparators.py +++ b/packages/testing/src/execution_testing/client_clis/tests/test_trace_comparators.py @@ -204,6 +204,85 @@ def test_not_equivalent_when_differences_exist(self) -> None: assert len(result.differences) == 1 +class TestTraceComparisonResultDictRoundTrip: + """ + Test pydantic serialization round-trip used by xdist worker transfer. + + ``model_dump(mode="json")`` → ``model_validate`` must preserve field + values AND the concrete subclass of each ``TraceDifference`` entry; + the ``kind`` discriminator is what lets ``model_validate`` pick the + right class. + """ + + def test_round_trip_equivalent_result(self) -> None: + """An equivalent (no-diff) result round-trips through dict.""" + result = TraceComparisonResult(equivalent=True, differences=[]) + restored = TraceComparisonResult.model_validate( + result.model_dump(mode="json") + ) + assert restored == result + + def test_round_trip_with_trace_difference(self) -> None: + """A result with a TraceDifference round-trips identically.""" + result = TraceComparisonResult( + equivalent=False, + differences=[ + TraceDifference( + transaction_index=1, + trace_line_index=4, + baseline="PUSH1 (pc=0xa)", + current="PUSH1 (pc=0x14)", + ), + ], + ) + restored = TraceComparisonResult.model_validate( + result.model_dump(mode="json") + ) + assert restored == result + assert type(restored.differences[0]) is TraceDifference + + def test_round_trip_with_transaction_count_mismatch(self) -> None: + """A TransactionCountMismatch retains its subclass identity.""" + result = TraceComparisonResult( + equivalent=False, + differences=[ + TransactionCountMismatch( + baseline_count=3, + current_count=2, + ), + ], + ) + restored = TraceComparisonResult.model_validate( + result.model_dump(mode="json") + ) + assert restored == result + diff = restored.differences[0] + assert isinstance(diff, TransactionCountMismatch) + assert diff.baseline_count == 3 + assert diff.current_count == 2 + + def test_round_trip_mixed_difference_types(self) -> None: + """A mix of TraceDifference and subclass entries round-trips.""" + result = TraceComparisonResult( + equivalent=False, + differences=[ + TransactionCountMismatch(baseline_count=2, current_count=1), + TraceDifference( + transaction_index=0, + trace_line_index=7, + baseline="ADD", + current="MUL", + ), + ], + ) + restored = TraceComparisonResult.model_validate( + result.model_dump(mode="json") + ) + assert restored == result + assert isinstance(restored.differences[0], TransactionCountMismatch) + assert type(restored.differences[1]) is TraceDifference + + class TestTraceComparatorType: """Test TraceComparatorType enum.""" @@ -213,6 +292,10 @@ class TestTraceComparatorType: (TraceComparatorType.EXACT, "exact"), (TraceComparatorType.EXACT_NO_GAS, "exact-no-gas"), (TraceComparatorType.EXACT_NO_STACK, "exact-no-stack"), + ( + TraceComparatorType.EXACT_NO_STACK_NO_GAS_NO_GAS_COST, + "exact-no-stack-no-gas-no-gas-cost", + ), (TraceComparatorType.GAS_EXHAUSTION, "gas-exhaustion"), ], ) @@ -306,6 +389,10 @@ class TestCreateComparator: (TraceComparatorType.EXACT, "exact"), (TraceComparatorType.EXACT_NO_GAS, "exact-no-gas"), (TraceComparatorType.EXACT_NO_STACK, "exact-no-stack"), + ( + TraceComparatorType.EXACT_NO_STACK_NO_GAS_NO_GAS_COST, + "exact-no-stack-no-gas-no-gas-cost", + ), (TraceComparatorType.GAS_EXHAUSTION, "gas-exhaustion"), ], ) @@ -381,25 +468,27 @@ def test_different_output(self) -> None: for d in diffs ) - def test_different_gas_used_without_post_processing(self) -> None: - """Different gas_used is reported when not post-processing.""" + def test_different_gas_used_reported_by_default(self) -> None: + """gas_used differences are reported when not ignoring gas.""" baseline = _make_transaction_traces() current = _make_transaction_traces() baseline.gas_used = HexNumber(0x5208) current.gas_used = HexNumber(0x6000) - diffs = baseline.compare(current, enable_post_processing=False) + diffs = baseline.compare(current, ignore_gas_differences=False) assert any( d.line_index is None and "gas_used" in d.baseline_fields for d in diffs ) - def test_different_gas_used_with_post_processing(self) -> None: - """Different gas_used is ignored when post-processing.""" + def test_different_gas_used_ignored_with_ignore_gas_differences( + self, + ) -> None: + """gas_used differences are silenced when ignoring gas.""" baseline = _make_transaction_traces() current = _make_transaction_traces() baseline.gas_used = HexNumber(0x5208) current.gas_used = HexNumber(0x6000) - diffs = baseline.compare(current, enable_post_processing=True) + diffs = baseline.compare(current, ignore_gas_differences=True) assert not any( d.line_index is None and "gas_used" in d.baseline_fields for d in diffs @@ -442,8 +531,10 @@ def test_exclude_fields_all_diffs_excluded(self) -> None: diffs = baseline.compare(current, exclude_fields={"gas", "gas_cost"}) assert diffs == [] - def test_post_processing_removes_gas_stack_pollution(self) -> None: - """GAS opcode stack pollution is cleaned with post-processing.""" + def test_ignore_gas_differences_removes_gas_stack_pollution( + self, + ) -> None: + """``Op.GAS`` stack pollution is scrubbed when ignoring gas.""" # GAS opcode pushes remaining gas onto stack; next line has it gas_line = _make_trace_line( pc=0, op=0x5A, op_name="GAS", depth=1, stack=[] @@ -465,22 +556,23 @@ def test_post_processing_removes_gas_stack_pollution(self) -> None: ) baseline = _make_transaction_traces([gas_line, next_line_baseline]) current = _make_transaction_traces([gas_line, next_line_current]) - # Without post-processing: stack differs - diffs_no_pp = baseline.compare( + # Without gas-tolerance: the differing GAS result leaks into the + # stack comparison. + diffs_strict = baseline.compare( current, exclude_fields={"gas", "gas_cost"}, - enable_post_processing=False, + ignore_gas_differences=False, ) - assert len(diffs_no_pp) == 1 - assert "stack" in diffs_no_pp[0].baseline_fields + assert len(diffs_strict) == 1 + assert "stack" in diffs_strict[0].baseline_fields - # With post-processing: GAS result nullified, equivalent - diffs_pp = baseline.compare( + # With gas-tolerance: the GAS result is nullified, equivalent. + diffs_tolerant = baseline.compare( current, exclude_fields={"gas", "gas_cost"}, - enable_post_processing=True, + ignore_gas_differences=True, ) - assert diffs_pp == [] + assert diffs_tolerant == [] class TestTransactionTracesAreEquivalentRegression: @@ -489,7 +581,7 @@ class TestTransactionTracesAreEquivalentRegression: def test_identical_traces_equivalent(self) -> None: """Identical traces are equivalent.""" tx = _make_transaction_traces() - assert tx.are_equivalent(tx, enable_post_processing=False) + assert tx.are_equivalent(tx, ignore_gas_differences=False) def test_different_length_not_equivalent(self) -> None: """Different lengths are not equivalent.""" @@ -498,7 +590,7 @@ def test_different_length_not_equivalent(self) -> None: ) current = _make_transaction_traces([_make_trace_line()]) assert not baseline.are_equivalent( - current, enable_post_processing=False + current, ignore_gas_differences=False ) def test_different_output_not_equivalent(self) -> None: @@ -506,40 +598,40 @@ def test_different_output_not_equivalent(self) -> None: baseline = _make_transaction_traces(output="0xaa") current = _make_transaction_traces(output="0xbb") assert not baseline.are_equivalent( - current, enable_post_processing=False + current, ignore_gas_differences=False ) def test_gas_only_difference_is_equivalent(self) -> None: """Gas-only difference is equivalent (gas excluded by default).""" baseline = _make_transaction_traces([_make_trace_line(gas=0x100)]) current = _make_transaction_traces([_make_trace_line(gas=0x200)]) - assert baseline.are_equivalent(current, enable_post_processing=False) + assert baseline.are_equivalent(current, ignore_gas_differences=False) def test_pc_difference_not_equivalent(self) -> None: """Non-gas field difference is not equivalent.""" baseline = _make_transaction_traces([_make_trace_line(pc=0)]) current = _make_transaction_traces([_make_trace_line(pc=5)]) assert not baseline.are_equivalent( - current, enable_post_processing=False + current, ignore_gas_differences=False ) - def test_gas_used_checked_without_post_processing(self) -> None: - """gas_used difference is caught without post-processing.""" + def test_gas_used_checked_by_default(self) -> None: + """gas_used difference is caught when not ignoring gas.""" baseline = _make_transaction_traces() current = _make_transaction_traces() baseline.gas_used = HexNumber(0x5208) current.gas_used = HexNumber(0x6000) assert not baseline.are_equivalent( - current, enable_post_processing=False + current, ignore_gas_differences=False ) - def test_gas_used_ignored_with_post_processing(self) -> None: - """gas_used difference is ignored with post-processing.""" + def test_gas_used_ignored_when_ignore_gas_differences(self) -> None: + """gas_used difference is silenced when ignoring gas.""" baseline = _make_transaction_traces() current = _make_transaction_traces() baseline.gas_used = HexNumber(0x5208) current.gas_used = HexNumber(0x6000) - assert baseline.are_equivalent(current, enable_post_processing=True) + assert baseline.are_equivalent(current, ignore_gas_differences=True) class TestExactComparator: @@ -742,7 +834,7 @@ def test_output_mismatch( def test_gas_used_difference_is_equivalent( self, comparator: FieldExclusionTraceComparator ) -> None: - """gas_used difference is ignored (post-processing enabled).""" + """gas_used difference is ignored (gas-tolerance enabled).""" baseline = _make_transaction_traces() current = _make_transaction_traces() baseline.gas_used = HexNumber(0x5208) @@ -814,6 +906,19 @@ def test_stack_difference_is_equivalent( result = comparator.compare_transaction_traces(baseline, current, 0) assert result.equivalent is True + def test_return_data_difference_is_equivalent( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """Traces differing only in return_data are equivalent.""" + baseline = _make_transaction_traces( + [_make_trace_line(return_data="0xaa")] + ) + current = _make_transaction_traces( + [_make_trace_line(return_data="0xbb")] + ) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is True + def test_gas_difference_detected( self, comparator: FieldExclusionTraceComparator ) -> None: @@ -947,16 +1052,35 @@ def test_stack_and_gas_difference_is_equivalent( result = comparator.compare_transaction_traces(baseline, current, 0) assert result.equivalent is True - def test_gas_used_difference_detected( + def test_return_data_difference_is_equivalent( self, comparator: FieldExclusionTraceComparator ) -> None: - """gas_used difference is detected.""" + """Inherits the ``return_data`` exclusion from ``exact-no-stack``.""" + baseline = _make_transaction_traces( + [_make_trace_line(return_data="0xaa")] + ) + current = _make_transaction_traces( + [_make_trace_line(return_data="0xbb")] + ) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is True + + def test_gas_used_difference_tolerated( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """ + gas_used difference is tolerated. + + Excluding per-line ``gas`` implies accepting a different total + gas_used: per-step gas deltas sum to gas_used, so a comparator + that accepts per-step differences must accept the total too. + """ baseline = _make_transaction_traces() current = _make_transaction_traces() baseline.gas_used = HexNumber(0x5208) current.gas_used = HexNumber(0x6000) result = comparator.compare_transaction_traces(baseline, current, 0) - assert result.equivalent is False + assert result.equivalent is True def test_pc_difference_detected( self, comparator: FieldExclusionTraceComparator @@ -1013,6 +1137,105 @@ def test_output_mismatch( assert "0xaa" in result.differences[0].baseline +# --------------------------------------------------------------------------- +# ExactNoStackNoGasNoGasCost config +# --------------------------------------------------------------------------- + + +class TestExactNoStackNoGasNoGasCostComparator: + """Test FieldExclusionTraceComparator with the gas_cost-tolerant config.""" + + @pytest.fixture() + def comparator(self) -> FieldExclusionTraceComparator: + """Return an exact-no-stack-no-gas-no-gas-cost comparator.""" + return create_comparator( + TraceComparatorType.EXACT_NO_STACK_NO_GAS_NO_GAS_COST + ) # type: ignore[return-value] + + def test_identical_traces_are_equivalent( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """Two identical TransactionTraces are equivalent.""" + tx = _make_transaction_traces() + result = comparator.compare_transaction_traces(tx, tx, 0) + assert result.equivalent is True + assert result.differences == [] + + def test_gas_cost_difference_is_equivalent( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """Traces differing only in gas_cost are equivalent.""" + baseline = _make_transaction_traces([_make_trace_line(gas_cost=0x3)]) + current = _make_transaction_traces([_make_trace_line(gas_cost=0x5)]) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is True + + def test_stack_gas_and_gas_cost_difference_is_equivalent( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """Traces differing in all three excluded fields are equivalent.""" + baseline = _make_transaction_traces( + [_make_trace_line(stack=[0x1, 0x2], gas=0x100, gas_cost=0x3)] + ) + current = _make_transaction_traces( + [_make_trace_line(stack=[0xA, 0xB], gas=0x200, gas_cost=0x5)] + ) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is True + + def test_return_data_difference_is_equivalent( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """Inherits the ``return_data`` exclusion from ``exact-no-stack``.""" + baseline = _make_transaction_traces( + [_make_trace_line(return_data="0xaa")] + ) + current = _make_transaction_traces( + [_make_trace_line(return_data="0xbb")] + ) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is True + + def test_pc_difference_detected( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """Non-excluded field diffs are still detected.""" + baseline = _make_transaction_traces([_make_trace_line(pc=0)]) + current = _make_transaction_traces([_make_trace_line(pc=5)]) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is False + assert "pc" in result.differences[0].baseline + + def test_op_name_difference_detected( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """op_name differences are still detected.""" + baseline = _make_transaction_traces( + [_make_trace_line(op_name="PUSH1")] + ) + current = _make_transaction_traces([_make_trace_line(op_name="PUSH2")]) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is False + assert "op_name" in result.differences[0].baseline + + def test_gas_used_difference_tolerated( + self, comparator: FieldExclusionTraceComparator + ) -> None: + """ + gas_used difference is tolerated. + + Matches ``EXACT_NO_STACK_NO_GAS``: per-step gas deltas sum to + gas_used, so a comparator that accepts per-step differences + must accept the total too. + """ + baseline = _make_transaction_traces() + current = _make_transaction_traces() + baseline.gas_used = HexNumber(0x5208) + current.gas_used = HexNumber(0x6000) + result = comparator.compare_transaction_traces(baseline, current, 0) + assert result.equivalent is True + + # --------------------------------------------------------------------------- # GasExhaustionTraceComparator # --------------------------------------------------------------------------- diff --git a/packages/testing/src/execution_testing/client_clis/trace_comparators.py b/packages/testing/src/execution_testing/client_clis/trace_comparators.py index 33b78664631..8e2d6ac5f88 100644 --- a/packages/testing/src/execution_testing/client_clis/trace_comparators.py +++ b/packages/testing/src/execution_testing/client_clis/trace_comparators.py @@ -1,9 +1,12 @@ """Trace comparators for verifying EVM execution traces against a baseline.""" from abc import ABC, abstractmethod -from dataclasses import dataclass, field from enum import StrEnum +from typing import Annotated, Literal, Union +from pydantic import Field + +from execution_testing.base_types import EthereumTestBaseModel from execution_testing.client_clis.cli_types import ( TraceLine, Traces, @@ -18,6 +21,7 @@ class TraceComparatorType(StrEnum): EXACT_NO_GAS = "exact-no-gas" EXACT_NO_STACK = "exact-no-stack" EXACT_NO_STACK_NO_GAS = "exact-no-stack-no-gas" + EXACT_NO_STACK_NO_GAS_NO_GAS_COST = "exact-no-stack-no-gas-no-gas-cost" GAS_EXHAUSTION = "gas-exhaustion" @@ -38,20 +42,24 @@ def _format_trace_line_diff( return f"{trace_line.op_name} ({fields_str})" -@dataclass -class TraceDifference: +class TraceDifference(EthereumTestBaseModel): """A difference between baseline and current trace at a specific line.""" + # Tag used by the discriminated union in ``TraceComparisonResult`` so + # that serialization (``model_dump``) and deserialization + # (``model_validate``) pick the correct concrete subclass when + # differences are round-tripped — e.g. across xdist workers. + kind: Literal["trace_difference"] = "trace_difference" transaction_index: int trace_line_index: int baseline: str current: str -@dataclass class TransactionCountMismatch(TraceDifference): """Structural mismatch: different number of transactions.""" + kind: Literal["transaction_count_mismatch"] = "transaction_count_mismatch" # type: ignore[assignment] transaction_index: int = 0 trace_line_index: int = -1 baseline: str = "" @@ -60,12 +68,17 @@ class TransactionCountMismatch(TraceDifference): current_count: int = 0 -@dataclass -class TraceComparisonResult: +AnyTraceDifference = Annotated[ + Union[TraceDifference, TransactionCountMismatch], + Field(discriminator="kind"), +] + + +class TraceComparisonResult(EthereumTestBaseModel): """Result of comparing two Traces objects.""" equivalent: bool - differences: list[TraceDifference] = field(default_factory=list) + differences: list[AnyTraceDifference] = Field(default_factory=list) class TraceComparator(ABC): @@ -122,7 +135,7 @@ def _build_result_from_compare( current: TransactionTraces, transaction_index: int, exclude_fields: set[str] | None = None, - enable_post_processing: bool = False, + ignore_gas_differences: bool = False, ) -> TraceComparisonResult: """ Build a TraceComparisonResult from TransactionTraces.compare(). @@ -133,7 +146,7 @@ def _build_result_from_compare( raw_diffs = baseline.compare( current, exclude_fields=exclude_fields, - enable_post_processing=enable_post_processing, + ignore_gas_differences=ignore_gas_differences, ) if not raw_diffs: return TraceComparisonResult(equivalent=True) @@ -172,11 +185,11 @@ def __init__( self, comparator_name: str, exclude_fields: set[str] | None = None, - enable_post_processing: bool = False, + ignore_gas_differences: bool = False, ) -> None: self._name = comparator_name self._exclude_fields = exclude_fields - self._enable_post_processing = enable_post_processing + self._ignore_gas_differences = ignore_gas_differences @property def name(self) -> str: @@ -195,7 +208,7 @@ def compare_transaction_traces( current, transaction_index, exclude_fields=self._exclude_fields, - enable_post_processing=self._enable_post_processing, + ignore_gas_differences=self._ignore_gas_differences, ) @@ -285,10 +298,29 @@ def compare_transaction_traces( TraceComparatorType, tuple[set[str] | None, bool], ] = { + # The tuple is ``(exclude_fields, ignore_gas_differences)``. The + # flag is set for any comparator that tolerates a per-line ``gas`` + # difference: per-step gas deltas sum into ``gas_used``, so a + # comparator that accepts per-step differences must also skip the + # ``gas_used`` total check (and scrub ``Op.GAS`` stack results) to + # avoid spurious diffs. TraceComparatorType.EXACT: (None, False), TraceComparatorType.EXACT_NO_GAS: ({"gas"}, True), - TraceComparatorType.EXACT_NO_STACK: ({"stack"}, False), - TraceComparatorType.EXACT_NO_STACK_NO_GAS: ({"gas", "stack"}, False), + # ``return_data`` is bundled with ``stack`` because clients differ + # in when/how they populate the post-call return buffer in traces. + # Tests that already tolerate stack differences want to tolerate this too. + # The ``no-stack`` variants below inherit this exclusion so that + # each comparator remains strictly more permissive than the one + # above it in the chain. + TraceComparatorType.EXACT_NO_STACK: ({"stack", "return_data"}, False), + TraceComparatorType.EXACT_NO_STACK_NO_GAS: ( + {"gas", "stack", "return_data"}, + True, + ), + TraceComparatorType.EXACT_NO_STACK_NO_GAS_NO_GAS_COST: ( + {"gas", "stack", "gas_cost", "return_data"}, + True, + ), } @@ -299,12 +331,12 @@ def create_comparator( if comparator_type == TraceComparatorType.GAS_EXHAUSTION: return GasExhaustionTraceComparator() if comparator_type in _FIELD_EXCLUSION_CONFIGS: - exclude_fields, post_processing = _FIELD_EXCLUSION_CONFIGS[ + exclude_fields, ignore_gas_differences = _FIELD_EXCLUSION_CONFIGS[ comparator_type ] return FieldExclusionTraceComparator( comparator_type.value, exclude_fields=exclude_fields, - enable_post_processing=post_processing, + ignore_gas_differences=ignore_gas_differences, ) raise ValueError(f"Unknown comparator type: {comparator_type}") diff --git a/packages/testing/src/execution_testing/specs/state.py b/packages/testing/src/execution_testing/specs/state.py index 8dc22daf170..bead9b2a932 100644 --- a/packages/testing/src/execution_testing/specs/state.py +++ b/packages/testing/src/execution_testing/specs/state.py @@ -132,7 +132,7 @@ def verify_modified_gas_limit( current_gas_limit: int, pre_alloc: Alloc, env: Environment, - enable_post_processing: bool, + ignore_gas_differences: bool, ) -> bool: """Verify a new lower gas limit yields the same transaction outcome.""" base_traces = base_tool_result.traces @@ -161,7 +161,7 @@ def verify_modified_gas_limit( ) if not base_traces.are_equivalent( modified_tool_output.result.traces, - enable_post_processing, + ignore_gas_differences, ): logger.debug( f"Traces are not equivalent (gas_limit={current_gas_limit})" @@ -402,7 +402,7 @@ def make_state_test_fixture( self.operation_mode == OpMode.OPTIMIZE_GAS or self.operation_mode == OpMode.OPTIMIZE_GAS_POST_PROCESSING ): - enable_post_processing = ( + ignore_gas_differences = ( self.operation_mode == OpMode.OPTIMIZE_GAS_POST_PROCESSING ) base_tool_output = transition_tool_output @@ -422,7 +422,7 @@ def make_state_test_fixture( current_gas_limit=self.tx.gas_limit - 1, pre_alloc=pre_alloc, env=env, - enable_post_processing=enable_post_processing, + ignore_gas_differences=ignore_gas_differences, ): minimum_gas_limit = 0 maximum_gas_limit = int(self.tx.gas_limit) @@ -438,7 +438,7 @@ def make_state_test_fixture( current_gas_limit=current_gas_limit, pre_alloc=pre_alloc, env=env, - enable_post_processing=enable_post_processing, + ignore_gas_differences=ignore_gas_differences, ): maximum_gas_limit = current_gas_limit else: @@ -462,7 +462,7 @@ def make_state_test_fixture( current_gas_limit=minimum_gas_limit, pre_alloc=pre_alloc, env=env, - enable_post_processing=enable_post_processing, + ignore_gas_differences=ignore_gas_differences, ) gas_optimization = current_gas_limit else: From 6fe032f152ad9592ae4c24a2cabc31c19d53fbe0 Mon Sep 17 00:00:00 2001 From: Felix H Date: Mon, 13 Apr 2026 12:12:23 +0200 Subject: [PATCH 018/186] feat(test-forks): Devnet merging script feat: switch back to original branch after creating devnet branch, makes local testing easier (i usually delete the devnet branch and try again, but that doesn't work when i am on it) feat: devnet script optimization to avoid merge conflicts feat: mario feedback --- .github/scripts/build_devnet_branch.py | 416 ++++++++++++++++++ .../forks/forks/eips/amsterdam/__init__.py | 51 +++ .../execution_testing/forks/forks/forks.py | 3 +- 3 files changed, 469 insertions(+), 1 deletion(-) create mode 100644 .github/scripts/build_devnet_branch.py diff --git a/.github/scripts/build_devnet_branch.py b/.github/scripts/build_devnet_branch.py new file mode 100644 index 00000000000..a8d07cae8b8 --- /dev/null +++ b/.github/scripts/build_devnet_branch.py @@ -0,0 +1,416 @@ +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "click", +# ] +# /// +"""Build a devnet branch by merging EIP branches onto a fork base.""" + +from __future__ import annotations + +import os +import re +import shlex +import subprocess +import sys +from collections.abc import Sequence + +import click + +EIP_PATTERN = re.compile(r"^[0-9]+(?:\+[0-9]+)*$") +CANONICAL_REMOTE_SUFFIXES = ( + "ethereum/execution-specs", + "ethereum/execution-specs.git", +) + + +def run_git( + args: Sequence[str], + *, + check: bool = True, + capture_output: bool = False, +) -> subprocess.CompletedProcess[str]: + """Run a git command and optionally capture its output.""" + command = ["git", *args] + print(f"+ {shlex.join(command)}") + return subprocess.run( + command, + check=check, + text=True, + capture_output=capture_output, + ) + + +def run_command(args: Sequence[str]) -> None: + """Run a generic subprocess command.""" + print(f"+ {shlex.join(args)}") + env = None + if len(args) >= 2 and args[0] == "uv" and args[1] == "run": + env = os.environ.copy() + env.pop("VIRTUAL_ENV", None) + subprocess.run(args, check=True, text=True, env=env) + + +def run_static_checks_suite() -> None: + """Run the static checks used for devnet assembly, excluding codespell.""" + commands = [ + ["uv", "run", "ruff", "check"], + ["uv", "run", "ruff", "format", "--check"], + ["uv", "run", "mypy"], + ["uv", "run", "ethereum-spec-lint"], + ["uv", "lock", "--check"], + ] + # Keep local and CI dry-runs deterministic: do not invoke actionlint, + # pyflakes, or shellcheck from this script, since those are external tools + # that may or may not be installed in a given environment. + for command in commands: + run_command(command) + + +def parse_eip_numbers(raw_eip_numbers: str) -> list[str]: + """Parse a comma-separated list of EIP numbers.""" + eip_numbers: list[str] = [] + for raw_eip in raw_eip_numbers.split(","): + eip = raw_eip.strip() + if not eip: + continue + if EIP_PATTERN.fullmatch(eip) is None: + raise ValueError( + f"Invalid EIP number '{eip}'. " + "Expected digits optionally joined by '+'." + ) + eip_numbers.append(eip) + if not eip_numbers: + raise ValueError("No EIP numbers were provided.") + return eip_numbers + + +def ensure_clean_tracked_worktree() -> None: + """Refuse to rewrite branches when tracked changes are present.""" + result = run_git( + ["status", "--short", "--untracked-files=no"], + capture_output=True, + ) + tracked_changes = [ + line + for line in result.stdout.splitlines() + if line.strip() and not line[3:].startswith(".github/") + ] + if tracked_changes: + raise RuntimeError( + "Tracked changes outside .github/ are present in the worktree. " + "Commit, stash, or discard them before building a devnet branch." + ) + + +def ensure_valid_branch_name(branch: str) -> None: + """Validate a branch name with git's ref-format checks.""" + run_git(["check-ref-format", "--branch", branch]) + + +def get_git_output(args: Sequence[str]) -> str: + """Run a git command and return its stdout.""" + result = run_git(args, capture_output=True) + return result.stdout.strip() + + +def get_current_branch() -> str | None: + """Return the current branch name, or None when HEAD is detached.""" + result = run_git( + ["branch", "--show-current"], + check=False, + capture_output=True, + ) + current_branch = result.stdout.strip() + return current_branch or None + + +def merge_in_progress() -> bool: + """Return True when the repository has an in-progress merge.""" + result = run_git( + ["rev-parse", "-q", "--verify", "MERGE_HEAD"], + check=False, + capture_output=True, + ) + return result.returncode == 0 + + +def detect_canonical_remote() -> str: + """Find the remote pointing to ethereum/execution-specs.""" + remote_names = get_git_output(["remote"]).splitlines() + matching_remotes: list[str] = [] + + for remote_name in remote_names: + remote_url = get_git_output(["remote", "get-url", remote_name]) + normalized_url = remote_url.rstrip("/") + if normalized_url.endswith(CANONICAL_REMOTE_SUFFIXES): + matching_remotes.append(remote_name) + + if not matching_remotes: + raise RuntimeError( + "Could not find a git remote for ethereum/execution-specs. " + "Pass --remote explicitly." + ) + + if len(matching_remotes) > 1: + matches = ", ".join(sorted(matching_remotes)) + raise RuntimeError( + "Found multiple git remotes for ethereum/execution-specs: " + f"{matches}. Pass --remote explicitly." + ) + + selected_remote = matching_remotes[0] + print(f"Using canonical remote {selected_remote}") + return selected_remote + + +def ensure_remote_branch_exists(remote: str, branch: str) -> None: + """Ensure a remote-tracking branch exists locally after fetch.""" + remote_branch_ref = f"refs/remotes/{remote}/{branch}" + try: + run_git(["show-ref", "--verify", "--quiet", remote_branch_ref]) + except subprocess.CalledProcessError as error: + raise RuntimeError( + f"Missing remote branch {remote}/{branch}." + ) from error + + +def local_branch_exists(branch: str) -> bool: + """Return True if a local branch exists.""" + result = run_git( + ["show-ref", "--verify", "--quiet", f"refs/heads/{branch}"], + check=False, + ) + return result.returncode == 0 + + +def resolve_branch_ref( + *, + branch: str, + remote: str, + use_local_branches: bool, +) -> str: + """Resolve a branch to either a local branch or a remote-tracking ref.""" + if use_local_branches and local_branch_exists(branch): + print(f"Using local branch {branch}") + return branch + + ensure_remote_branch_exists(remote, branch) + remote_branch_ref = f"{remote}/{branch}" + print(f"Using remote branch {remote_branch_ref}") + return remote_branch_ref + + +def create_devnet_branch( + devnet_branch: str, + fork_ref: str, +) -> None: + """Reset the local devnet branch to the fork base.""" + print(f"Creating {devnet_branch} from {fork_ref}") + run_git(["checkout", "-B", devnet_branch, fork_ref]) + + +def restore_original_branch(original_branch: str | None) -> None: + """Switch back to the starting branch when one was recorded.""" + if original_branch is None: + print( + "Started from a detached HEAD; " + "leaving the current checkout in place" + ) + return + + current_branch = get_current_branch() + if current_branch == original_branch: + print(f"Already on original branch {original_branch}") + return + + print(f"Switching back to original branch {original_branch}") + run_git(["checkout", original_branch]) + + +def abort_in_progress_merge() -> None: + """Abort an in-progress merge so the original branch can be restored.""" + if not merge_in_progress(): + return + + print("Aborting in-progress merge before restoring the original branch") + run_git(["merge", "--abort"]) + + +def merge_eip_branch( + devnet_branch: str, + eip_branch: str, + eip_ref: str, +) -> None: + """Merge one EIP branch into the current devnet branch.""" + message = f"Merge {eip_branch} into {devnet_branch}" + print(f"Merging {eip_ref} into {devnet_branch}") + try: + run_git( + [ + "merge", + "--no-ff", + "--no-edit", + "-m", + message, + eip_ref, + ] + ) + except subprocess.CalledProcessError as error: + raise RuntimeError( + "Merge conflict while building the devnet branch. " + "Resolve the conflict locally, or run " + "`git merge --abort` to clean up." + ) from error + + +def push_branch(remote: str, devnet_branch: str) -> None: + """Push the assembled devnet branch to the remote.""" + print(f"Pushing {devnet_branch} to {remote}") + run_git(["push", "--force-with-lease", remote, devnet_branch]) + + +@click.command() +@click.option( + "--fork", + required=True, + help="Fork name, for example 'amsterdam'.", +) +@click.option( + "--devnet-name", + required=True, + help=("Devnet name suffix, for example 'bal/3' to build devnets/bal/3."), +) +@click.option( + "--eip-numbers", + required=True, + help="Comma-separated EIP numbers, e.g. '8024,7843,7708,7778'.", +) +@click.option( + "--remote", + default=None, + help=( + "Git remote containing the fork, EIP, and devnet branches. " + "Defaults to the remote whose URL points to " + "ethereum/execution-specs." + ), +) +@click.option( + "--push", + is_flag=True, + default=False, + help=( + "Push the assembled devnet branch back to the remote " + "with --force-with-lease." + ), +) +@click.option( + "--run-static-checks", + is_flag=True, + default=False, + help="Run static checks before pushing, excluding codespell.", +) +@click.option( + "--use-local-branches", + is_flag=True, + default=False, + help=( + "Prefer existing local fork and EIP branches when present. " + "Otherwise fall back to the remote." + ), +) +def main( + fork: str, + devnet_name: str, + eip_numbers: str, + remote: str | None, + push: bool, + run_static_checks: bool, + use_local_branches: bool, +) -> None: + """Build a devnet branch from a fork base and EIP branches.""" + devnet_branch = f"devnets/{devnet_name}" + original_branch: str | None = None + restore_original_branch_at_exit = False + build_error: str | None = None + restore_failed = False + + try: + original_branch = get_current_branch() + resolved_remote = remote or detect_canonical_remote() + parsed_eip_numbers = parse_eip_numbers(eip_numbers) + fork_branch = f"forks/{fork}" + + ensure_clean_tracked_worktree() + ensure_valid_branch_name(devnet_branch) + ensure_valid_branch_name(fork_branch) + + eip_branches = [ + f"eips/{fork}/eip-{eip_number}" + for eip_number in parsed_eip_numbers + ] + for eip_branch in eip_branches: + ensure_valid_branch_name(eip_branch) + + run_git(["fetch", resolved_remote, "--prune"]) + + fork_ref = resolve_branch_ref( + branch=fork_branch, + remote=resolved_remote, + use_local_branches=use_local_branches, + ) + eip_refs = { + eip_branch: resolve_branch_ref( + branch=eip_branch, + remote=resolved_remote, + use_local_branches=use_local_branches, + ) + for eip_branch in eip_branches + } + + create_devnet_branch(devnet_branch, fork_ref) + restore_original_branch_at_exit = True + + for eip_branch in eip_branches: + merge_eip_branch(devnet_branch, eip_branch, eip_refs[eip_branch]) + + if run_static_checks: + print("Running static checks on the assembled devnet branch") + run_static_checks_suite() + + if push: + push_branch(resolved_remote, devnet_branch) + except ( + RuntimeError, + ValueError, + subprocess.CalledProcessError, + ) as error: + build_error = str(error) + print(f"Error: {build_error}", file=sys.stderr) + finally: + if restore_original_branch_at_exit: + try: + if build_error is not None: + abort_in_progress_merge() + restore_original_branch(original_branch) + except subprocess.CalledProcessError as error: + target = original_branch or "the original branch" + print( + f"Error: Failed to switch back to {target}: {error}", + file=sys.stderr, + ) + restore_failed = True + + if restore_failed: + raise SystemExit(1) + + if build_error is not None: + if "merge conflict" in build_error.lower(): + print("THERE WERE MERGE CONFLICTS") + raise SystemExit(1) + + print(f"Successfully built {devnet_branch}") + + +if __name__ == "__main__": + main() diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/__init__.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/__init__.py index eea9ab260e0..66ece88871c 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/__init__.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/__init__.py @@ -1 +1,52 @@ """Listings of all EIPs for Amsterdam fork.""" + +from __future__ import annotations + +import importlib +import inspect +import pkgutil +import re +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from execution_testing.forks.base_fork import BaseFork + +__all__ = ["AmsterdamEIPs"] + +if TYPE_CHECKING: + + class AmsterdamEIPs(BaseFork): + """Typing-only stand-in for Amsterdam EIP mixins.""" + + pass +else: + _prefix = __name__ + "." + _amsterdam_eips = [] + + for _importer, _modname, _ispkg in pkgutil.iter_modules( + __path__, prefix=_prefix + ): + if _ispkg or not re.search(r"\.eip_\d+$", _modname): + continue + + _module = importlib.import_module(_modname) + + for _name, _obj in inspect.getmembers(_module, inspect.isclass): + if re.match(r"^EIP\d+$", _name) and _obj.__module__ == _modname: + _amsterdam_eips.append(_obj) + + _amsterdam_eips.sort(key=lambda cls: int(cls.__name__[3:])) + + class _AmsterdamEIPsSentinel: + """Expand to the currently available Amsterdam EIP mixins.""" + + def __mro_entries__( + self, + bases: tuple[type, ...], + ) -> tuple[type, ...]: + del bases + return tuple(_amsterdam_eips) + + AmsterdamEIPs = _AmsterdamEIPsSentinel() # type: ignore[misc] + + del _importer, _ispkg, _modname, _module, _name, _obj, _prefix diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index f7e31c237f8..7452d952d98 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -34,6 +34,7 @@ ) from ..gas_costs import GasCosts from . import eips +from .eips.amsterdam import AmsterdamEIPs from .helpers import ceiling_division @@ -1508,7 +1509,7 @@ class BPO5( class Amsterdam( - eips.EIP7928, + AmsterdamEIPs, BPO2, deployed=False, ): From 363df20673de012c69cd927c80faf8d22854fcd3 Mon Sep 17 00:00:00 2001 From: Felix H Date: Tue, 14 Apr 2026 11:53:01 +0200 Subject: [PATCH 019/186] refactor(specs): Add `count_tokens_in_data` helper fix: 7976 and 7981 devnet merger fix, extract count_tokens_in_data and restructure floor calc refactor: 8037+7981 harmonization, add zero-valued access list token scaffolding fix: add comment --- src/ethereum/forks/amsterdam/transactions.py | 44 ++++++++++++++------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/ethereum/forks/amsterdam/transactions.py b/src/ethereum/forks/amsterdam/transactions.py index da7dfd13f5e..03c5c32b803 100644 --- a/src/ethereum/forks/amsterdam/transactions.py +++ b/src/ethereum/forks/amsterdam/transactions.py @@ -581,8 +581,8 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]: """ from .vm.interpreter import MAX_INIT_CODE_SIZE - intrinsic_gas, calldata_floor_gas_cost = calculate_intrinsic_cost(tx) - if max(intrinsic_gas, calldata_floor_gas_cost) > tx.gas: + intrinsic_gas, data_floor_gas_cost = calculate_intrinsic_cost(tx) + if max(intrinsic_gas, data_floor_gas_cost) > tx.gas: raise InsufficientTransactionGasError("Insufficient gas") if U256(tx.nonce) >= U256(U64.MAX_VALUE): raise NonceOverflowError("Nonce too high") @@ -591,7 +591,7 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]: if tx.gas > TX_MAX_GAS_LIMIT: raise TransactionGasLimitExceededError("Gas limit too high") - return intrinsic_gas, calldata_floor_gas_cost + return intrinsic_gas, data_floor_gas_cost def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: @@ -622,14 +622,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT from .vm.gas import init_code_cost - num_zeros = Uint(tx.data.count(0)) - num_non_zeros = ulen(tx.data) - num_zeros - - tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) - # EIP-7623 floor price (note: no EVM costs) - calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE - ) + tokens_in_calldata = count_tokens_in_data(tx.data) data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD @@ -639,6 +632,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: create_cost = Uint(0) access_list_cost = Uint(0) + tokens_in_access_list = Uint(0) if has_access_list(tx): for access in tx.access_list: access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS @@ -646,10 +640,24 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY ) + # Data token floor cost for access list bytes. + access_list_cost += tokens_in_access_list * GAS_TX_DATA_TOKEN_FLOOR + auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + # Floor tokens from calldata. + floor_tokens_in_calldata = tokens_in_calldata + + # Total floor tokens. + total_floor_tokens = floor_tokens_in_calldata + tokens_in_access_list + + # Floor gas cost (EIP-7623: minimum gas for data-heavy transactions). + data_floor_gas_cost = ( + total_floor_tokens * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + ) + return ( Uint( GAS_TX_BASE @@ -658,10 +666,22 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: + access_list_cost + auth_cost ), - calldata_floor_gas_cost, + data_floor_gas_cost, ) +def count_tokens_in_data(data: bytes) -> Uint: + """ + Count the data tokens in arbitrary input bytes. + + Zero bytes count as 1 token; non-zero bytes count as 4 tokens. + """ + num_zeros = Uint(data.count(0)) + num_non_zeros = ulen(data) - num_zeros + + return num_zeros + num_non_zeros * Uint(4) + + def recover_sender(chain_id: U64, tx: Transaction) -> Address: """ Extracts the sender address from a transaction. From 8bd536b9c0a80a6743e5defaf5254b509e30a858 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 16 Apr 2026 10:26:40 +0200 Subject: [PATCH 020/186] feat(doc,test-benchmark): re-enable benchmark tests in test case reference (#2666) --- docs/scripts/gen_test_case_reference.py | 25 +++--- .../filler/gen_test_doc/gen_test_doc.py | 83 +++++++++++++------ .../__init__.py | 1 + 3 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 tests/benchmark/compute/eip7928_block_level_access_lists/__init__.py diff --git a/docs/scripts/gen_test_case_reference.py b/docs/scripts/gen_test_case_reference.py index a38899ae35c..ba2a00b38f5 100644 --- a/docs/scripts/gen_test_case_reference.py +++ b/docs/scripts/gen_test_case_reference.py @@ -29,21 +29,20 @@ logger = logging.getLogger("mkdocs") -# If docs are generated while FAST_DOCS is true, then use "tests/frontier" -# otherwise use "tests" +# If docs are generated while FAST_DOCS is true, then use "tests/frontier"; +# otherwise use "tests". Benchmark tests are opted in via --include-benchmark +# in full mode only. # # USAGE 1 (use fast mode): # export FAST_DOCS=true && uv run mkdocs serve # USAGE 2 (use fast mode + hide side-effect warnings): # export FAST_DOCS=true && uv run mkdocs serve 2>&1 | sed '/is not found among documentation files/d' #noqa: E501 -test_arg = "tests" -fast_mode = getenv("FAST_DOCS") -if fast_mode is not None: - if fast_mode.lower() == "true": - print( - "-" * 40, "\nWill generate docs using FAST_DOCS mode.\n" + "-" * 40 - ) - test_arg = "tests/frontier" +fast_mode = (getenv("FAST_DOCS") or "").lower() == "true" +if fast_mode: + print("-" * 40, "\nWill generate docs using FAST_DOCS mode.\n" + "-" * 40) + test_arg = "tests/frontier" +else: + test_arg = "tests" args = [ "--override-ini", @@ -60,10 +59,12 @@ "--skip-index", "--ignore=tests/ported_static", "-m", - "not blockchain_test_engine and not benchmark", + "not blockchain_test_engine", "-s", - test_arg, ] +if not fast_mode: + args.append("--include-benchmark") +args.append(test_arg) runner = CliRunner() logger.info( diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py index e9c97ea97f0..f5eab27ac65 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py @@ -42,6 +42,7 @@ import glob import logging import os +import re import sys import textwrap from collections import defaultdict @@ -53,7 +54,7 @@ from jinja2 import Environment, FileSystemLoader, StrictUndefined from pytest import Item -from execution_testing.forks import get_forks +from execution_testing.forks import ALL_TRANSITION_FORKS, get_forks from execution_testing.specs import BaseTest from execution_testing.tools.utility.versioning import ( generate_github_url, @@ -251,6 +252,17 @@ def __init__(self, config: pytest.Config) -> None: self.deployed_forks = [ fork.name() for fork in get_forks() if fork.is_deployed() ] + # Map each transition fork's name to the base fork it ends at so that + # cases parametrized as a transition fork (e.g. + # `BPO2ToAmsterdamAtTime15k`) count toward the fork they transition + # into (`Amsterdam`). + self._transition_to_base: Dict[str, str] = { + fork.name(): fork.transitions_to().name() + for fork in ALL_TRANSITION_FORKS + } + self._fork_newness: Dict[str, int] = { + fork.name(): i for i, fork in enumerate(get_forks()) + } self._setup_logger() self.jinja2_env = Environment( loader=FileSystemLoader("docs/templates"), @@ -266,6 +278,10 @@ def __init__(self, config: pytest.Config) -> None: # the complete set of pages and their properties self.page_props: PagePropsLookup = {} + def _base_fork(self, fork_name: str) -> str: + """Return the base fork name, resolving transition forks.""" + return self._transition_to_base.get(fork_name, fork_name) + @pytest.hookimpl(hookwrapper=True, trylast=True) def pytest_collection_modifyitems( self, config: pytest.Config, items: List[pytest.Item] @@ -461,26 +477,36 @@ def create_function_page_props( # valid_from marker, separated by a comma. Take the last. valid_from_fork = valid_from_marker.args[0].split(",")[-1] - target_or_valid_fork = ( - self.target_fork - if valid_from_fork in self.deployed_forks - else valid_from_fork - ) - test_type = get_test_function_test_type(items[0]) - - test_case_count = len( - [ - case - for case in test_cases - if case.fork == target_or_valid_fork - and case.fixture_type == test_type - ] - ) - benchmark_dir = ( Path(items[0].config.rootpath) / "tests" / "benchmark" ) is_benchmark = benchmark_dir in Path(items[0].fspath).parents + test_type = get_test_function_test_type(items[0]) + + # Pick the displayed fork from the collected cases: the latest + # base fork any case is parametrized for, with transition forks + # resolved to the fork they transition into. Fall back to + # `valid_from_fork` when nothing was collected. + base_forks = {self._base_fork(case.fork) for case in test_cases} + if base_forks: + target_or_valid_fork = max( + base_forks, + key=lambda f: self._fork_newness.get(f, -1), + ) + else: + target_or_valid_fork = valid_from_fork + + # Count unique parametrizations at the displayed fork. + # `case.params` already excludes `fork` and the fixture-type key + # (see `skip_params` above), so a parametrization that produces + # several fixture formats (e.g. benchmark -> `blockchain_test` + # and `blockchain_test_engine`) collapses to a single case. + unique_params = { + tuple(sorted(case.params.items())) + for case in test_cases + if self._base_fork(case.fork) == target_or_valid_fork + } + test_case_count = len(unique_params) self.function_page_props[function_id] = FunctionPageProps( title=get_test_function_name(items[0]), @@ -554,7 +580,12 @@ def add_directory_page_props(self) -> None: Path(*module_path_parts[: i + 1]) for i in range(len(module_path_parts)) ) + benchmark_root = self.source_dir / "benchmark" for directory in sub_paths: + is_benchmark = ( + directory == benchmark_root + or benchmark_root in directory.parents + ) directory_fork_name = ( directory.relative_to(self.source_dir).parts[0].capitalize() if directory != self.source_dir @@ -564,13 +595,6 @@ def add_directory_page_props(self) -> None: fork = self.target_fork else: fork = directory_fork_name - - is_benchmark = any( - module_page.is_benchmark - for module_page in self.module_page_props.values() - if directory in module_page.path.parents - or module_page.path.parent == directory - ) self.page_props[str(directory)] = DirectoryPageProps( title=sanitize_string_title(str(directory.name)), path=directory, @@ -650,10 +674,19 @@ def update_mkdocs_nav(self) -> None: Add the generated 'Test Case Reference' entries to the mkdocs navigation menu. """ + + # Fork directories on disk are snake_case (e.g. `tangerine_whistle`) + # but `fork.name()` is CamelCase (`TangerineWhistle`). + def _dir_name(fork_name: str) -> str: + s1 = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", fork_name) + return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s1).lower() + fork_order = { - fork.name().lower(): i + _dir_name(fork.name()): i for i, fork in enumerate(reversed(get_forks())) } + # Benchmark entries sort above all fork entries. + fork_order["benchmark"] = -1 def sort_by_fork_deployment_and_path(x: PageProps) -> Tuple[Any, ...]: """ diff --git a/tests/benchmark/compute/eip7928_block_level_access_lists/__init__.py b/tests/benchmark/compute/eip7928_block_level_access_lists/__init__.py new file mode 100644 index 00000000000..d02b97d33f6 --- /dev/null +++ b/tests/benchmark/compute/eip7928_block_level_access_lists/__init__.py @@ -0,0 +1 @@ +"""EIP-7928 Block-level Access List benchmark tests.""" From 2bc7c79b6f5cec6a27d5de173daab5482dfdac00 Mon Sep 17 00:00:00 2001 From: felix Date: Thu, 16 Apr 2026 20:08:07 +0200 Subject: [PATCH 021/186] feat(tests): improve robustness for EIP-7981 (#2696) Co-authored-by: spencer-tb --- .../stEIP2930/test_transaction_costs.py | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/tests/ported_static/stEIP2930/test_transaction_costs.py b/tests/ported_static/stEIP2930/test_transaction_costs.py index 5a0eb77edbb..65245a0c468 100644 --- a/tests/ported_static/stEIP2930/test_transaction_costs.py +++ b/tests/ported_static/stEIP2930/test_transaction_costs.py @@ -18,7 +18,7 @@ StateTestFiller, Transaction, ) -from execution_testing.forks import Fork +from execution_testing.forks import Amsterdam, Fork from execution_testing.specs.static_state.expect_section import ( resolve_expect_post, ) @@ -143,7 +143,16 @@ def test_transaction_costs( ) pre[sender] = Account(balance=0x5FA9C18) - expect_entries_: list[dict] = [ + expect_entries: list[dict] = [ + # EIP-7981 changes access list costs in Amsterdam+. Balance is a + # placeholder; the expected value is computed dynamically below. + # Ordered first so Amsterdam+ forks match here instead of the + # entries below. + { + "indexes": {"data": -1, "gas": -1, "value": -1}, + "network": [">=Amsterdam"], + "result": {sender: Account(balance=0)}, + }, { "indexes": {"data": [0, 1], "gas": -1, "value": -1}, "network": ["Cancun"], @@ -181,7 +190,7 @@ def test_transaction_costs( }, ] - post, _exc = resolve_expect_post(expect_entries_, d, g, v, fork) + post, _exc = resolve_expect_post(expect_entries, d, g, v, fork) tx_data = [ Bytes("00"), @@ -455,4 +464,25 @@ def test_transaction_costs( error=_exc, ) + # EIP-7981 (access list repricing) activates in Amsterdam. Compute the + # expected balance dynamically from the fork's intrinsic cost calculator + # rather than hardcoding values that change as EIP-7981 evolves. Past + # forks keep their original hardcoded values above. + if _exc is None and fork >= Amsterdam: + sender_pre = pre[sender] + assert sender_pre is not None + gas_price = int(tx.gas_price or tx.max_fee_per_gas or 0) + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=tx.data, + contract_creation=tx.to is None, + access_list=tx.access_list, + ) + post[sender] = Account( + balance=( + int(sender_pre.balance) + - int(tx.value) + - intrinsic_gas * gas_price + ), + ) + state_test(env=env, pre=pre, post=post, tx=tx) From 71fe4d68c217aec3b10169ed5be44279f03e7bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Fri, 17 Apr 2026 15:31:01 +0800 Subject: [PATCH 022/186] chore: remove unused stateful benchmark (#2686) --- .../stateful/bloatnet/test_account_query.py | 283 +------- .../stateful/bloatnet/test_bloatnet.py | 6 - .../stateful/bloatnet/test_single_opcode.py | 686 ------------------ 3 files changed, 1 insertion(+), 974 deletions(-) delete mode 100755 tests/benchmark/stateful/bloatnet/test_bloatnet.py diff --git a/tests/benchmark/stateful/bloatnet/test_account_query.py b/tests/benchmark/stateful/bloatnet/test_account_query.py index d011dc7bead..bbcaa785d7b 100644 --- a/tests/benchmark/stateful/bloatnet/test_account_query.py +++ b/tests/benchmark/stateful/bloatnet/test_account_query.py @@ -12,298 +12,17 @@ - BALANCE """ -from typing import Any, Dict, List +from typing import Any import pytest from execution_testing import ( - AccessList, Account, Alloc, BenchmarkTestFiller, - Block, - Bytecode, - Create2PreimageLayout, - Fork, - Hash, - IteratingBytecode, JumpLoopGenerator, Op, - ParameterSet, - TestPhaseManager, - While, ) -from tests.benchmark.compute.helpers import ( - ContractDeploymentTransaction, - CustomSizedContractFactory, -) - - -def generate_account_query_params() -> List[ParameterSet]: - """ - Generate valid parameter combinations for test_account_query. - - Returns tuples of: (opcode, access_warm, mem_size, code_size, value_sent) - """ - all_mem_sizes = [0, 32, 256, 1024] - all_code_sizes = [0, 32, 256, 1024] - all_access_warm = [True, False] - all_value_sent = [0, 1] - - params = [] - - # BALANCE, EXTCODESIZE, EXTCODEHASH: - # only mem_size=0, code_size=0, value_sent=0 - for opcode in [Op.BALANCE, Op.EXTCODESIZE, Op.EXTCODEHASH]: - for access_warm in all_access_warm: - params.append(pytest.param(opcode, access_warm, 0, 0, 0)) - - # EXTCODECOPY: all mem_size, all code_size, value_sent=0 - for access_warm in all_access_warm: - for mem_size in all_mem_sizes: - for code_size in all_code_sizes: - params.append( - pytest.param( - Op.EXTCODECOPY, access_warm, mem_size, code_size, 0 - ) - ) - # Add None (max_code_size) separately with custom ID - params.append( - pytest.param( - Op.EXTCODECOPY, - access_warm, - mem_size, - None, - 0, - id=f"EXTCODECOPY-{access_warm}-{mem_size}-max_code_size-0", - ) - ) - - # CALL, CALLCODE: all mem_size, code_size=0, all value_sent - for opcode in [Op.CALL, Op.CALLCODE]: - for access_warm in all_access_warm: - for mem_size in all_mem_sizes: - for value_sent in all_value_sent: - params.append( - pytest.param( - opcode, access_warm, mem_size, 0, value_sent - ) - ) - - # STATICCALL, DELEGATECALL: all mem_size, code_size=0, value_sent=0 - for opcode in [Op.STATICCALL, Op.DELEGATECALL]: - for access_warm in all_access_warm: - for mem_size in all_mem_sizes: - params.append( - pytest.param(opcode, access_warm, mem_size, 0, 0) - ) - - return params - - -@pytest.mark.parametrize( - "opcode,access_warm,mem_size,code_size,value_sent", - generate_account_query_params(), -) -def test_account_query( - benchmark_test: BenchmarkTestFiller, - pre: Alloc, - fork: Fork, - opcode: Op, - access_warm: bool, - mem_size: int, - code_size: int, - value_sent: int, - gas_benchmark_value: int, - fixed_opcode_count: int | None, -) -> None: - """Benchmark scenario of accessing max-code size bytecode.""" - attack_gas_limit = gas_benchmark_value - - # Create the max-sized fork-dependent contract factory. - custom_sized_contract_factory = CustomSizedContractFactory( - pre=pre, fork=fork, contract_size=code_size - ) - factory_address = custom_sized_contract_factory.address() - initcode = custom_sized_contract_factory.initcode - - # Prepare the attack iterating bytecode. - # Setup is just placing the CREATE2 Preimage in memory. - create2_preimage = Create2PreimageLayout( - factory_address=factory_address, - salt=Op.CALLDATALOAD(0), - init_code_hash=initcode.keccak256(), - ) - setup_code: Bytecode = create2_preimage - - if mem_size > 96: - setup_code += Op.MSTORE8( - mem_size - 1, - 0, - # Gas accounting - old_memory_size=96, - new_memory_size=mem_size, - ) - - if opcode == Op.EXTCODECOPY: - attack_call = Op.EXTCODECOPY( - address=create2_preimage.address_op(), - dest_offset=0, - size=mem_size, - # Gas accounting - data_size=mem_size, - address_warm=access_warm, - ) - elif opcode in (Op.CALL, Op.CALLCODE): - # CALL and CALLCODE accept value parameter - attack_call = Op.POP( - opcode( - address=create2_preimage.address_op(), - value=value_sent, - args_size=mem_size, - # Gas accounting - address_warm=access_warm, - new_memory_size=max(mem_size, 96), - value_transfer=value_sent > 0, - ) - ) - elif opcode in (Op.STATICCALL, Op.DELEGATECALL): - # STATICCALL and DELEGATECALL don't have value parameter - attack_call = Op.POP( - opcode( - address=create2_preimage.address_op(), - args_size=mem_size, - # Gas accounting - address_warm=access_warm, - new_memory_size=max(mem_size, 96), - ) - ) - else: - # BALANCE, EXTCODESIZE, EXTCODEHASH - attack_call = Op.POP( - opcode( - address=create2_preimage.address_op(), - # Gas accounting - address_warm=access_warm, - ) - ) - - loop_code = While( - body=attack_call + create2_preimage.increment_salt_op(), - ) - - attack_code = IteratingBytecode( - setup=setup_code, - iterating=loop_code, - # Since the target contract is guaranteed to have a STOP as the first - # instruction, we can use a STOP as the iterating subcall code. - iterating_subcall=Op.STOP, - ) - - # Calldata generator for each transaction of the iterating bytecode. - def calldata(iteration_count: int, start_iteration: int) -> bytes: - del iteration_count - # We only pass the start iteration index as calldata for this bytecode - return Hash(start_iteration) - - # Access list generator for warm access tests. - # When access_warm=True, include all contract addresses that will be - # accessed in each transaction to warm them up via access list. - # Note: This access list generation is very expensive due to the binary - # search, which builds different access lists using the same elements - # over and over. Caching the elements helps a bit. - access_list_cache: Dict[int, AccessList] = {} - - def access_list_generator( - iteration_count: int, start_iteration: int - ) -> list[AccessList] | None: - if not access_warm: - return None - return [ - access_list_cache.setdefault( - i, - AccessList( - address=custom_sized_contract_factory.created_contract_address( - salt=i - ), - storage_keys=[], - ), - ) - for i in range(start_iteration, start_iteration + iteration_count) - ] - - attack_address = pre.deploy_contract(code=attack_code, balance=10**21) - - # Calculate the number of contracts to be targeted. - if fixed_opcode_count is not None: - # Fixed opcode count mode - num_contracts = int(fixed_opcode_count * 1000) - else: - # Gas limit mode - num_contracts = sum( - attack_code.tx_iterations_by_gas_limit( - fork=fork, - gas_limit=attack_gas_limit, - calldata=calldata, - access_list=access_list_generator, - ) - ) - - # Deploy num_contracts via multiple txs (each capped by tx gas limit). - post = {} - with TestPhaseManager.setup(): - setup_sender = pre.fund_eoa() - contracts_deployment_txs: List[ContractDeploymentTransaction] = [] - for contract_creating_tx in ( - custom_sized_contract_factory.transactions_by_total_contract_count( - fork=fork, - sender=setup_sender, - contract_count=num_contracts, - ) - ): - contracts_deployment_txs.append(contract_creating_tx) - if custom_sized_contract_factory.contract_size > 0: - post[contract_creating_tx.deployed_contracts[-1]] = Account( - nonce=1 - ) - - with TestPhaseManager.execution(): - attack_sender = pre.fund_eoa() - if fixed_opcode_count is not None: - attack_txs = list( - attack_code.transactions_by_total_iteration_count( - fork=fork, - total_iterations=int(fixed_opcode_count * 1000), - sender=attack_sender, - to=attack_address, - calldata=calldata, - access_list=access_list_generator, - ) - ) - else: - attack_txs = list( - attack_code.transactions_by_gas_limit( - fork=fork, - gas_limit=attack_gas_limit, - sender=attack_sender, - to=attack_address, - calldata=calldata, - access_list=access_list_generator, - ) - ) - total_gas_cost = sum(tx.gas_cost for tx in attack_txs) - - benchmark_test( - pre=pre, - post=post, - blocks=[ - Block(txs=contracts_deployment_txs), - Block(txs=attack_txs), - ], - target_opcode=opcode, - expected_benchmark_gas_used=total_gas_cost, - ) - @pytest.mark.repricing( empty_code=True, diff --git a/tests/benchmark/stateful/bloatnet/test_bloatnet.py b/tests/benchmark/stateful/bloatnet/test_bloatnet.py deleted file mode 100755 index e489de3aafe..00000000000 --- a/tests/benchmark/stateful/bloatnet/test_bloatnet.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -abstract: Tests benchmark worst-case bloatnet scenarios. - Tests benchmark worst-case bloatnet scenarios. - -Tests running worst-case bloatnet scenarios for benchmarking purposes. -""" diff --git a/tests/benchmark/stateful/bloatnet/test_single_opcode.py b/tests/benchmark/stateful/bloatnet/test_single_opcode.py index 06fe23911f6..3e67019d9c3 100644 --- a/tests/benchmark/stateful/bloatnet/test_single_opcode.py +++ b/tests/benchmark/stateful/bloatnet/test_single_opcode.py @@ -41,11 +41,8 @@ from execution_testing.base_types.base_types import Number from tests.benchmark.stateful.helpers import ( - ALLOWANCE_SELECTOR, APPROVE_SELECTOR, BALANCEOF_SELECTOR, - DECREMENT_COUNTER_CONDITION, - MINT_SELECTOR, CacheStrategy, build_cache_strategy_blocks, ) @@ -795,176 +792,6 @@ def test_sload_erc20_generic( # - Simulates real-world contract state accumulation over time -@pytest.mark.repricing -@pytest.mark.stub_parametrize( - "erc20_stub", "test_sload_empty_erc20_balanceof_" -) -@pytest.mark.parametrize("existing_slots", [False, True]) -@pytest.mark.parametrize("cache_strategy", list(CacheStrategy)) -def test_sload_erc20_balanceof( - benchmark_test: BenchmarkTestFiller, - pre: Alloc, - fork: Fork, - gas_benchmark_value: int, - tx_gas_limit: int, - erc20_stub: str, - existing_slots: bool, - cache_strategy: CacheStrategy, -) -> None: - """Benchmark SLOAD using ERC20 balanceOf on bloatnet.""" - # Stub Account - erc20_address = pre.deploy_contract( - code=Bytecode(), - stub=erc20_stub, - ) - - # MEM[0] = function selector - # MEM[32] = starting address offset - setup = ( - Op.MSTORE( - 0, - BALANCEOF_SELECTOR, - # gas accounting - old_memory_size=0, - new_memory_size=32, - ) - + Op.MSTORE( - 32, - Op.CALLDATALOAD(32), # Address Offset - # gas accounting - old_memory_size=32, - new_memory_size=64, - ) - + Op.CALLDATALOAD(0) # [num_calls] - ) - - call_balance_of = Op.POP( - Op.CALL( - address=erc20_address, - value=0, - args_offset=32 - 4, - args_size=32 + 4, - ret_offset=0, - ret_size=0, - # gas accounting - address_warm=True, - ) - ) - - cache_loop = ( - call_balance_of - if cache_strategy == CacheStrategy.CACHE_TX - else Bytecode() - ) - - loop = While( - body=call_balance_of - # Do the same call again for the cached variant - + cache_loop - + Op.MSTORE(32, Op.ADD(Op.MLOAD(32), 1)), - condition=DECREMENT_COUNTER_CONDITION, - ) - - # Contract Deployment - code = setup + loop - attack_contract_address = pre.deploy_contract(code=code) - - # Gas Accounting - setup_cost = setup.gas_cost(fork) - loop_cost = loop.gas_cost(fork) - - access_list = [AccessList(address=erc20_address, storage_keys=[])] - intrinsic_gas_with_access_list = ( - fork.transaction_intrinsic_cost_calculator()( - access_list=access_list, - calldata=b"\xff" * 64, - ) - ) - - # ERC20 balanceOf bytecode structure: - function_dispatch = ( - # Selector dispatch - Op.PUSH4(BALANCEOF_SELECTOR) - + Op.EQ - + Op.JUMPI - # Function body - + Op.JUMPDEST - + Op.MSTORE(0, Op.CALLDATALOAD(4)) - + Op.MSTORE(32, 0) - + Op.MSTORE( - 0, - Op.SLOAD( - Op.SHA3( - 0, - 64, - # gas accounting - data_size=64, - old_memory_size=0, - new_memory_size=64, - ) - ), - ) - + Op.RETURN(0, 32) - ) - - function_dispatch_cost = function_dispatch.gas_cost(fork) - - # Transaction Loops - txs = [] - cache_txs = [] - gas_remaining = gas_benchmark_value - # Start offset - slot_offset = 1 if existing_slots else START_SLOT - - while gas_remaining > intrinsic_gas_with_access_list: - gas_available = min(gas_remaining, tx_gas_limit) - - if gas_available < intrinsic_gas_with_access_list + setup_cost: - break - - num_calls = ( - gas_available - intrinsic_gas_with_access_list - setup_cost - ) // (function_dispatch_cost + loop_cost) - - if num_calls == 0: - break - - calldata = Hash(num_calls) + Hash(slot_offset) - - if cache_strategy == CacheStrategy.CACHE_PREVIOUS_BLOCK: - with TestPhaseManager.setup(): - # For block-level caching, - # we need to warm the slot in a separate transaction - cache_txs.append( - Transaction( - gas_limit=gas_available, - data=calldata, - to=attack_contract_address, - sender=pre.fund_eoa(), - access_list=access_list, - ) - ) - - with TestPhaseManager.execution(): - txs.append( - Transaction( - gas_limit=gas_available, - data=calldata, - to=attack_contract_address, - sender=pre.fund_eoa(), - access_list=access_list, - ) - ) - - gas_remaining -= gas_available - slot_offset += num_calls - - blocks = build_cache_strategy_blocks(cache_strategy, txs, cache_txs) - # FIXME: this should not use gas validation as this one should OOG - # If it does not OOG, the gas calculation is too high, it should be too low - benchmark_test(pre=pre, blocks=blocks, skip_gas_used_validation=True) - - @pytest.mark.stub_parametrize("erc20_stub", "test_sstore_erc20_approve_") def test_sstore_erc20_generic( benchmark_test: BenchmarkTestFiller, @@ -1056,519 +883,6 @@ def test_sstore_erc20_generic( ) -@pytest.mark.repricing -@pytest.mark.parametrize("cache_strategy", list(CacheStrategy)) -@pytest.mark.stub_parametrize("erc20_stub", "test_sstore_erc20_approve_") -@pytest.mark.parametrize("write_new_value", [False, True]) -@pytest.mark.parametrize("existing_slot", [True, False]) -def test_sstore_erc20_approve( - benchmark_test: BenchmarkTestFiller, - pre: Alloc, - fork: Fork, - gas_benchmark_value: int, - tx_gas_limit: int, - erc20_stub: str, - write_new_value: bool, - existing_slot: bool, - cache_strategy: CacheStrategy, -) -> None: - """Benchmark SSTORE using ERC20 approve on bloatnet.""" - sender = EOA( - key=0x90655B60A56E01389173510C3DDF1B969803A9F41844BF344CBF3D1AC3A80845, - # nonce fetched from the pre-deployed state on the network - nonce=45344, - ) - pre.fund_address(address=sender, amount=10**9) - assert Address(sender) == Address( - 0x6C2624662DC514A69955E9A6A195ECE23ACED5A0 - ), "EOA address mismatch" - - # Stub Account - erc20_address = pre.deploy_contract( - code=Bytecode(), - stub=erc20_stub, - ) - - # MEM[0] = function selector - # MEM[32] = starting address offset - setup = ( - Op.MSTORE( - 0, - APPROVE_SELECTOR, - # gas accounting - old_memory_size=0, - new_memory_size=32, - ) - + Op.MSTORE( - 32, - Op.CALLDATALOAD(32), # Address Offset - # gas accounting - old_memory_size=32, - new_memory_size=64, - ) - + Op.CALLDATALOAD(0) # [num_calls] - ) - - value_to_write: Bytecode | int - if write_new_value: - # non-zero, avoids refund and always differs from existing values - value_to_write = 1 - else: - value_to_write = Op.MLOAD(32) if existing_slot else 0 - - call_approve = Op.MSTORE(64, value_to_write) + Op.POP( - Op.CALL( - address=erc20_address, - value=0, - args_offset=28, - args_size=68, - ret_offset=0, - ret_size=0, - # gas accounting - address_warm=True, - ) - ) - - cache_warmup = Bytecode() - if cache_strategy == CacheStrategy.CACHE_TX: - # Call allowance(ADDRESS, spender) to warm the allowance - # storage slot that approve will later write to. - # Memory: save spender→[64], put ADDRESS→[32], - # set allowance selector, call, then restore. - cache_warmup = ( - Op.MSTORE(64, Op.MLOAD(32)) - + Op.MSTORE(32, Op.ADDRESS) - + Op.MSTORE(0, ALLOWANCE_SELECTOR) - + Op.POP( - Op.CALL( - address=erc20_address, - value=0, - args_offset=28, - args_size=68, - ret_offset=0, - ret_size=0, - # gas accounting - address_warm=True, - ) - ) - + Op.MSTORE(0, APPROVE_SELECTOR) - + Op.MSTORE(32, Op.MLOAD(64)) - ) - - loop = While( - body=cache_warmup - + call_approve - + Op.MSTORE(32, Op.ADD(Op.MLOAD(32), 1)), - condition=DECREMENT_COUNTER_CONDITION, - ) - - # Contract Deployment - code = setup + loop - attack_contract_address = pre.deploy_contract(code=code) - - # Gas Accounting - setup_cost = setup.gas_cost(fork) - loop_cost = loop.gas_cost(fork) - access_list = [AccessList(address=erc20_address, storage_keys=[])] - # Delegate sender to attack_contract_address once in setup - delegation_tx = Transaction( - gas_limit=100_000, - to=sender, - value=0, - sender=pre.fund_eoa(), - authorization_list=[ - AuthorizationTuple( - chain_id=0, - address=attack_contract_address, - nonce=sender.nonce, - signer=sender, - ), - ], - ) - sender.nonce = Number(sender.nonce + 1) - intrinsic_gas_with_access_list = ( - fork.transaction_intrinsic_cost_calculator()( - access_list=access_list, - calldata=b"\xff" * 64, - ) - ) - - # This dispatch is something close to the minimal amount - # of code to run for a contract only implementing approve - # It will therefore greatly underestimate the gas of any ERC20 - # contract because all of them have much more overhead in practice - # (also function selector at the entry point of the contract) - function_dispatch = ( - # Selector dispatch - Op.PUSH4(APPROVE_SELECTOR) - + Op.EQ - + Op.JUMPI - # Function body - + Op.JUMPDEST - + Op.CALLDATALOAD(4) - + Op.CALLDATALOAD(36) - + Op.MSTORE(0, Op.CALLER) - + Op.MSTORE(32, 1) - + Op.MSTORE( - 32, - Op.SHA3( - 0, - 64, - # gas accounting - data_size=64, - old_memory_size=0, - new_memory_size=64, - ), - ) - + Op.MSTORE(0, Op.CALLDATALOAD(4)) - + Op.SHA3( - 0, - 64, - # gas accounting - data_size=64, - ) - + ( - Op.DUP1 - + Op.SLOAD.with_metadata(key_warm=False) - + Op.POP - + Op.SSTORE.with_metadata(key_warm=True) - if cache_strategy == CacheStrategy.CACHE_TX - else Op.SSTORE.with_metadata(key_warm=False) - ) - # Return true - + Op.MSTORE(0, 1) - + Op.RETURN(0, 32) - ) - - function_dispatch_cost = function_dispatch.gas_cost(fork) - - with TestPhaseManager.setup(): - delegation_block = Block(txs=[delegation_tx]) - - if cache_strategy == CacheStrategy.CACHE_TX: - # Add allowance dispatch cost for the warmup call. - # allowance(owner, spender) computes the same double- - # keccak slot as approve but does SLOAD + RETURN. - function_dispatch_allowance = ( - Op.PUSH4(ALLOWANCE_SELECTOR) - + Op.EQ - + Op.JUMPI - + Op.JUMPDEST - + Op.CALLDATALOAD(4) - + Op.CALLDATALOAD(36) - + Op.MSTORE(0, Op.CALLDATALOAD(4)) - + Op.MSTORE(32, 1) - + Op.MSTORE( - 32, - Op.SHA3( - 0, - 64, - # gas accounting - data_size=64, - old_memory_size=0, - new_memory_size=64, - ), - ) - + Op.MSTORE(0, Op.CALLDATALOAD(36)) - + Op.SHA3( - 0, - 64, - # gas accounting - data_size=64, - ) - + Op.SLOAD - + Op.PUSH0 - + Op.MSTORE - + Op.RETURN(0, 32) - ) - function_dispatch_cost += function_dispatch_allowance.gas_cost(fork) - - # Transaction Loops - gas_remaining = gas_benchmark_value - # This sender is a stub account, the first initialized - # slot is 371 on perfnet. The initialized slots range - # is 371-45139; existing slots fall within that range. - slot_offset = 371 if existing_slot else START_SLOT - - # Collect tx params first, then build Transaction objects - # so that nonces are allocated contiguously per block. - tx_params: list[tuple[int, bytes]] = [] - while gas_remaining > intrinsic_gas_with_access_list: - gas_available = min(gas_remaining, tx_gas_limit) - - if gas_available < intrinsic_gas_with_access_list + setup_cost: - break - - num_calls = ( - gas_available - intrinsic_gas_with_access_list - setup_cost - ) // (function_dispatch_cost + loop_cost) - - if num_calls == 0: - break - - calldata = Hash(num_calls) + Hash(slot_offset) - tx_params.append((gas_available, calldata)) - - gas_remaining -= gas_available - slot_offset += num_calls - - cache_txs = [] - if cache_strategy == CacheStrategy.CACHE_PREVIOUS_BLOCK: - with TestPhaseManager.setup(): - for gas_available, calldata in tx_params: - cache_txs.append( - Transaction( - gas_limit=gas_available, - data=calldata, - to=sender, - sender=sender, - access_list=access_list, - ) - ) - - txs = [] - with TestPhaseManager.execution(): - for gas_available, calldata in tx_params: - txs.append( - Transaction( - gas_limit=gas_available, - data=calldata, - to=sender, - sender=sender, - access_list=access_list, - ) - ) - - blocks = [delegation_block] + build_cache_strategy_blocks( - cache_strategy, txs, cache_txs - ) - # TODO: this test can currently not estimate the gas used - # It will also overestimate the num_calls it can make to an unknown - # ERC20 contract and will therefore OOG - # (this actually passes the gas check as it consumes all gas and - # thus also the expected gas) - # TODO: find out how to tackle this. We do not want to OOG - # because the state root is part of the calculation - # NOTE: this is not crucial for gas repricing tests - # as the mint variant is used there. - benchmark_test( - pre=pre, blocks=blocks, skip_gas_used_validation=True - ) # FIXME: temp skips - - -def build_call_memory_setup( - selector: int, - *args: Bytecode | int, -) -> Bytecode: - """ - Build ABI-encoded memory layout for a contract call. - - MEM[0] = selector (4 bytes, right-aligned in 32-byte word) - MEM[32] = args[0] - MEM[64] = args[1] ... - """ - bytecode = Op.MSTORE( - 0, - selector, - old_memory_size=0, - new_memory_size=32, - ) - for i, arg in enumerate(args): - offset = 32 * (i + 1) - bytecode += Op.MSTORE( - offset, - arg, - old_memory_size=offset, - new_memory_size=offset + 32, - ) - return bytecode - - -def build_external_call( - address: Address, - num_args: int, - *, - address_warm: bool = True, -) -> Bytecode: - """ - Build POP(CALL(...)) using standard ABI memory layout at offset 0. - - args_offset = 28 (selector at byte 28 of the 32-byte word) - args_size = 4 + 32 * num_args - """ - return Op.POP( - Op.CALL( - address=address, - value=0, - args_offset=32 - 4, - args_size=4 + 32 * num_args, - ret_offset=0, - ret_size=0, - address_warm=address_warm, - ) - ) - - -@pytest.mark.repricing -@pytest.mark.stub_parametrize("erc20_stub", "test_sstore_erc20_mint_") -@pytest.mark.parametrize("existing_slots", [False, True]) -@pytest.mark.parametrize("cache_strategy", list(CacheStrategy)) -@pytest.mark.parametrize("no_change", [False, True]) -def test_sstore_erc20_mint( - benchmark_test: BenchmarkTestFiller, - pre: Alloc, - fork: Fork, - gas_benchmark_value: int, - tx_gas_limit: int, - erc20_stub: str, - existing_slots: bool, - cache_strategy: CacheStrategy, - no_change: bool, -) -> None: - """ - Benchmark SSTORE using ERC20 mint on bloatnet. - This targets very specific code and is meant to be - temporary for the gas repricings effort, to be replaced - by a robust benchmark which does not depend on specific - conditions like in this benchmark. - This contract calls mint() on an ERC20 contract - which supports the mint() function. It is intended - to be used with ERC20 contracts bloated via bloatStorage. - The mint will increase the total supply and the target account. - """ - # The gas threshold is the minimum amount necessary - # of gas to re-enter the While loop. - # This must be high enough to ensure the tx - # does not go out-of-gas. - # This can be improved to an actual value by calculating - # the gas used of the second call to the unknown ERC20 contract - # and then adding the gas used for the code after the loop - # (this can be calculated) as extra. - gas_threshold = 100_000 - - # Storage key to read and write address pointer to - slot_offset = 0 - - # Start slot - start_slot = 1 if existing_slots else START_SLOT - - # Stub Account - erc20_address = pre.deploy_contract( - code=Bytecode(), - stub=erc20_stub, - ) - - mint_amount = 0 if no_change else 1 - - # MEM[0] = function selector - # MEM[32] = target address - # MEM[64] = mint amount - mint_mem_setup = build_call_memory_setup( - MINT_SELECTOR, Op.SLOAD(slot_offset), mint_amount - ) - mint_erc20_call = build_external_call(erc20_address, 2) - - # MEM[0] = function selector - # MEM[32] = target address - balance_mem_setup = build_call_memory_setup( - BALANCEOF_SELECTOR, Op.SLOAD(slot_offset) - ) - balance_erc20_call = build_external_call(erc20_address, 1) - - attack_code = mint_erc20_call - if cache_strategy == CacheStrategy.CACHE_TX: - # Warm up storage slot via balanceOf - attack_code = ( - Op.MSTORE(0, BALANCEOF_SELECTOR) - + balance_erc20_call - + Op.MSTORE(0, MINT_SELECTOR) - + mint_erc20_call - ) - - loop_code = While( - body=attack_code + Op.MSTORE(32, Op.ADD(Op.MLOAD(32), 1)), - condition=Op.GT(Op.GAS, gas_threshold), - ) - - cleanup = Op.SSTORE(slot_offset, Op.MLOAD(32)) - - # Contract Deployment - attack_code = mint_mem_setup + loop_code + cleanup - attack_contract_address = pre.deploy_contract( - code=attack_code, - storage={slot_offset: start_slot}, - ) - - prewarm_contract_address = attack_contract_address - if cache_strategy == CacheStrategy.CACHE_PREVIOUS_BLOCK: - # TODO: calls balanceOf in previous block because - # mint will change the balance of the account - # This will SLOAD it in previous block and should - # put this into cache. - # Alternatively could also call mint(addr,0) - # on that. Not sure which is better. - # Call mint(addr, 0) because a nonzero value would - # edit the value, and would also create a slot - # if it was non-existent before. In attack block - # in non-existent test it would then suddenly - # be existent which is not the target scenario there. - warmup_setup = balance_mem_setup - - warmup_attack_loop = While( - body=balance_erc20_call + Op.MSTORE(32, Op.ADD(Op.MLOAD(32), 1)), - condition=Op.GT(Op.GAS, gas_threshold), - ) - - warmup_block = warmup_setup + warmup_attack_loop + cleanup - - prewarm_contract_address = pre.deploy_contract( - code=warmup_block, - storage={slot_offset: start_slot}, - ) - - # Transaction Loops - gas_limits = [] - gas_remaining = gas_benchmark_value - intrinsic_gas_cost = fork.transaction_intrinsic_cost_calculator()() - while gas_remaining >= intrinsic_gas_cost + gas_threshold: - gas_limit = min(gas_remaining, tx_gas_limit) - gas_limits.append(gas_limit) - gas_remaining -= gas_limit - - cache_txs: List[Transaction] = [] - if cache_strategy == CacheStrategy.CACHE_PREVIOUS_BLOCK: - with TestPhaseManager.setup(): - cache_txs = [ - Transaction( - gas_limit=g, - to=prewarm_contract_address, - sender=pre.fund_eoa(), - ) - for g in gas_limits - ] - - with TestPhaseManager.execution(): - txs = [ - Transaction( - gas_limit=g, to=attack_contract_address, sender=pre.fund_eoa() - ) - for g in gas_limits - ] - - blocks = build_cache_strategy_blocks(cache_strategy, txs, cache_txs) - - benchmark_test( - pre=pre, - blocks=blocks, - # NOTE: this specifically targets bloatnet code so the - # gas calculation could technically be done by inlining - # the bytecode. This test is temporary and will be removed - # after (or during) gas repricing effort is done. See - # https://github.com/ethereum/execution-specs/issues/2411 - skip_gas_used_validation=True, - ) - - def create_sstore_initializer(init_val: int) -> IteratingBytecode: """ Create a contract that initializes storage slots from calldata parameters. From 40461a628755688dcd9ef1049d0f9cd2d06e879e Mon Sep 17 00:00:00 2001 From: spencer Date: Fri, 17 Apr 2026 10:52:55 +0100 Subject: [PATCH 023/186] feat(ci, test-fill): make `--generate-all-formats` optional via `feature.yaml` (#2702) * feat(fill): make --generate-all-formats opt-in via feature.yaml Tarball output (.tar.gz) no longer auto-enables --generate-all-formats. Release features declare the flag explicitly in fill-params; benchmark and benchmark_fast opt in, mainnet and bal do not. * style(test-fill): ruff format test_generate_all_formats.py --- .github/actions/build-fixtures/action.yaml | 2 +- .github/configs/feature.yaml | 4 +- .../filling_tests_command_line.md | 8 +--- docs/running_tests/releases.md | 8 ++-- .../cli/pytest_commands/fill.py | 28 ------------ .../filler/tests/test_generate_all_formats.py | 32 ++++++-------- .../plugins/shared/fixture_output.py | 8 ---- .../cli/tests/test_generate_all_formats.py | 44 ++++--------------- 8 files changed, 30 insertions(+), 104 deletions(-) diff --git a/.github/actions/build-fixtures/action.yaml b/.github/actions/build-fixtures/action.yaml index f3b1d003c68..0c2f197e216 100644 --- a/.github/actions/build-fixtures/action.yaml +++ b/.github/actions/build-fixtures/action.yaml @@ -44,7 +44,7 @@ runs: if [ -n "$IS_SPLIT" ]; then OUTPUT_ARG="--output=fixtures_${{ inputs.release_name }}" - FORK_ARGS="--generate-all-formats --from=${{ inputs.from_fork }} --until=${{ inputs.until_fork }}" + FORK_ARGS="--from=${{ inputs.from_fork }} --until=${{ inputs.until_fork }}" else OUTPUT_ARG="--output=fixtures_${{ inputs.release_name }}.tar.gz" FORK_ARGS="" diff --git a/.github/configs/feature.yaml b/.github/configs/feature.yaml index eeb63f272f7..ab8aa27da2c 100644 --- a/.github/configs/feature.yaml +++ b/.github/configs/feature.yaml @@ -5,12 +5,12 @@ mainnet: benchmark: evm-type: benchmark - fill-params: --fork=Osaka --gas-benchmark-values 1,5,10,30,60,100,150 ./tests/benchmark/compute --maxprocesses=30 --dist=worksteal + fill-params: --fork=Osaka --generate-all-formats --gas-benchmark-values 1,5,10,30,60,100,150 ./tests/benchmark/compute --maxprocesses=30 --dist=worksteal feature_only: true benchmark_fast: evm-type: benchmark - fill-params: --fork=Osaka --gas-benchmark-values 100 ./tests/benchmark/compute + fill-params: --fork=Osaka --generate-all-formats --gas-benchmark-values 100 ./tests/benchmark/compute feature_only: true bal: diff --git a/docs/filling_tests/filling_tests_command_line.md b/docs/filling_tests/filling_tests_command_line.md index 50bba2986e3..b4aae3cc727 100644 --- a/docs/filling_tests/filling_tests_command_line.md +++ b/docs/filling_tests/filling_tests_command_line.md @@ -101,13 +101,9 @@ This flag automatically performs a two-phase execution: 1. **Phase 1**: Generates pre-allocation groups for optimization. 2. **Phase 2**: Generates all supported fixture formats (`StateFixture`, `BlockchainFixture`, `BlockchainEngineFixture`, `BlockchainEngineXFixture`, etc.). -!!! tip "Automatic enabling with tarball output" - When using tarball output (`.tar.gz` files), the `--generate-all-formats` flag is automatically enabled: +!!! note "Tarball output requires explicit opt-in" + Tarball output (`.tar.gz` files) does **not** imply `--generate-all-formats`. Pass the flag explicitly to include the pre-allocation group formats: ```console - # Automatically enables --generate-all-formats due to .tar.gz output - uv run fill --output=fixtures.tar.gz tests/shanghai/ - - # Equivalent to: uv run fill --generate-all-formats --output=fixtures.tar.gz tests/shanghai/ ``` diff --git a/docs/running_tests/releases.md b/docs/running_tests/releases.md index 057f2302bc3..9907c64a81c 100644 --- a/docs/running_tests/releases.md +++ b/docs/running_tests/releases.md @@ -102,13 +102,11 @@ For standard releases, two tarballs are available: I.e., `fixtures_develop` are a superset of `fixtures_stable`. -!!! tip "Generating tarballs directly via `--output` includes all fixture formats" - When generating fixtures for release, specifying tarball output automatically enables all fixture formats: +!!! tip "Release features opt into all fixture formats via `feature.yaml`" + Tarball output (`.tar.gz`) does not by itself include the pre-allocation group formats (`BlockchainEngineXFixture`, `BlockchainEngineStatefulFixture`). A release feature requests them by adding `--generate-all-formats` to its `fill-params` in `.github/configs/feature.yaml`: ```console - # Automatically enables --generate-all-formats due to .tar.gz output - uv run fill --output=fixtures_stable.tar.gz tests/ + uv run fill --generate-all-formats --output=fixtures_stable.tar.gz tests/ ``` - This ensures that all fixture formats are included in the tarball release. ### Pre-Release and Devnet Releases diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/fill.py b/packages/testing/src/execution_testing/cli/pytest_commands/fill.py index a0d42c19c4d..842935b65b5 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/fill.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/fill.py @@ -45,9 +45,6 @@ def create_executions( # Check if we need two-phase execution if self._should_use_two_phase_execution(processed_args): - processed_args = self._ensure_generate_all_formats_for_tarball( - processed_args - ) return self._create_two_phase_executions(processed_args) elif "--use-pre-alloc-groups" in processed_args: # Only phase 2: using existing pre-allocation groups @@ -203,33 +200,8 @@ def _should_use_two_phase_execution(self, args: List[str]) -> bool: return ( "--generate-pre-alloc-groups" in args or "--generate-all-formats" in args - or self._is_tarball_output(args) ) - def _ensure_generate_all_formats_for_tarball( - self, args: List[str] - ) -> List[str]: - """Auto-add --generate-all-formats for tarball output.""" - if ( - self._is_tarball_output(args) - and "--generate-all-formats" not in args - ): - return args + ["--generate-all-formats"] - return args - - def _is_tarball_output(self, args: List[str]) -> bool: - """Check if output argument specifies a tarball (.tar.gz) path.""" - from pathlib import Path - - for i, arg in enumerate(args): - if arg.startswith("--output="): - output_path = Path(arg.split("=", 1)[1]) - return str(output_path).endswith(".tar.gz") - elif arg == "--output" and i + 1 < len(args): - output_path = Path(args[i + 1]) - return str(output_path).endswith(".tar.gz") - return False - def _is_watch_mode(self, args: List[str]) -> bool: """Check if any watch flag is present in arguments.""" return any(flag in args for flag in ["--watch", "--watcherfall"]) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_generate_all_formats.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_generate_all_formats.py index 21e7b268067..ea5a4f52007 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_generate_all_formats.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_generate_all_formats.py @@ -54,22 +54,21 @@ def getoption(self, option: str) -> Any: assert fixture_output.output_path.name == "test" -def test_tarball_output_auto_enables_generate_all_formats() -> None: +def test_tarball_output_does_not_auto_enable_generate_all_formats() -> None: """ - Test that tarball output (.tar.gz) automatically enables - should_generate_all_formats. + Test that tarball output (.tar.gz) alone does not enable + should_generate_all_formats; the flag must be set explicitly. """ - # Mock pytest config object with tarball output class MockConfig: def getoption(self, option: str) -> Any: option_values = { - "output": "/tmp/fixtures.tar.gz", # Tarball output + "output": "/tmp/fixtures.tar.gz", "single_fixture_per_file": False, "clean": False, "generate_pre_alloc_groups": False, "use_pre_alloc_groups": False, - "generate_all_formats": False, # Explicitly False + "generate_all_formats": False, } return option_values.get(option, False) @@ -78,27 +77,25 @@ def getoption(self, option: str) -> Any: config # type: ignore ) - # Should auto-enable should_generate_all_formats due to tarball output - assert fixture_output.should_generate_all_formats is True + assert fixture_output.should_generate_all_formats is False assert fixture_output.is_tarball is True def test_regular_output_does_not_auto_enable_generate_all_formats() -> None: """ - Test that regular directory output doesn't auto-enable - should_generate_all_formats. + Test that regular directory output doesn't enable + should_generate_all_formats without the explicit flag. """ - # Mock pytest config object with regular output class MockConfig: def getoption(self, option: str) -> Any: option_values = { - "output": "/tmp/fixtures", # Regular directory output + "output": "/tmp/fixtures", "single_fixture_per_file": False, "clean": False, "generate_pre_alloc_groups": False, "use_pre_alloc_groups": False, - "generate_all_formats": False, # Explicitly False + "generate_all_formats": False, } return option_values.get(option, False) @@ -107,27 +104,25 @@ def getoption(self, option: str) -> Any: config # type: ignore ) - # Should remain False for regular directory output assert fixture_output.should_generate_all_formats is False assert fixture_output.is_tarball is False -def test_explicit_generate_all_formats_overrides_tarball_auto_enable() -> None: +def test_explicit_generate_all_formats_with_tarball() -> None: """ Test that explicitly setting should_generate_all_formats=True works with tarball output. """ - # Mock pytest config object with tarball output and explicit flag class MockConfig: def getoption(self, option: str) -> Any: option_values = { - "output": "/tmp/fixtures.tar.gz", # Tarball output + "output": "/tmp/fixtures.tar.gz", "single_fixture_per_file": False, "clean": False, "generate_pre_alloc_groups": False, "use_pre_alloc_groups": False, - "generate_all_formats": True, # Explicitly True + "generate_all_formats": True, } return option_values.get(option, False) @@ -136,6 +131,5 @@ def getoption(self, option: str) -> Any: config # type: ignore ) - # Should be True (both explicitly set and auto-enabled) assert fixture_output.should_generate_all_formats is True assert fixture_output.is_tarball is True diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/fixture_output.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/fixture_output.py index 166744f15fe..b55f276e76f 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/fixture_output.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/fixture_output.py @@ -288,14 +288,6 @@ def from_config(cls, config: pytest.Config) -> "FixtureOutput": output_path = Path(config.getoption("output")) should_generate_all_formats = config.getoption("generate_all_formats") - # Auto-enable --generate-all-formats for tarball output - # Use same logic as is_tarball property - if ( - output_path.suffix == ".gz" - and output_path.with_suffix("").suffix == ".tar" - ): - should_generate_all_formats = True - return cls( output_path=output_path, single_fixture_per_file=config.getoption( diff --git a/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py b/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py index e108ad63bc7..e30e9f15ce9 100644 --- a/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py +++ b/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py @@ -114,9 +114,10 @@ def test_single_phase_without_flags() -> None: assert "--generate-all-formats" not in execution.args -def test_tarball_output_auto_enables_generate_all_formats() -> None: +def test_tarball_output_without_flag_stays_single_phase() -> None: """ - Test that tarball output automatically enables --generate-all-formats. + Test that tarball output without --generate-all-formats is single-phase + and does not inject the flag. """ command = FillCommand() @@ -124,19 +125,13 @@ def test_tarball_output_auto_enables_generate_all_formats() -> None: pytest_args = ["--output=fixtures.tar.gz", "tests/somedir/"] executions = command.create_executions(pytest_args) - # Should trigger two-phase execution due to tarball output - assert len(executions) == 2 - - # Phase 1: Should have --generate-pre-alloc-groups - phase1_args = executions[0].args - assert "--generate-pre-alloc-groups" in phase1_args + assert len(executions) == 1 + execution = executions[0] - # Phase 2: Should have --generate-all-formats (auto-added) and --use-pre- - # alloc-groups - phase2_args = executions[1].args - assert "--generate-all-formats" in phase2_args - assert "--use-pre-alloc-groups" in phase2_args - assert "--output=fixtures.tar.gz" in phase2_args + assert "--generate-pre-alloc-groups" not in execution.args + assert "--use-pre-alloc-groups" not in execution.args + assert "--generate-all-formats" not in execution.args + assert "--output=fixtures.tar.gz" in execution.args def test_tarball_output_with_explicit_generate_all_formats() -> None: @@ -182,24 +177,3 @@ def test_regular_output_does_not_auto_trigger_two_phase() -> None: assert "--generate-pre-alloc-groups" not in execution.args assert "--use-pre-alloc-groups" not in execution.args assert "--generate-all-formats" not in execution.args - - -def test_tarball_output_detection_various_formats() -> None: - """Test tarball output detection with various argument formats.""" - command = FillCommand() - - # Test --output=file.tar.gz format - args1 = ["--output=test.tar.gz", "tests/somedir/"] - assert command._is_tarball_output(args1) is True - - # Test --output file.tar.gz format - args2 = ["--output", "test.tar.gz", "tests/somedir/"] - assert command._is_tarball_output(args2) is True - - # Test regular directory - args3 = ["--output=test/", "tests/somedir/"] - assert command._is_tarball_output(args3) is False - - # Test no output argument - args4 = ["tests/somedir/"] - assert command._is_tarball_output(args4) is False From c3462e030f7e2cebe93688d15d2423dcf16fc8cc Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Fri, 17 Apr 2026 08:47:06 -0600 Subject: [PATCH 024/186] feat(test-forks): Gas-limit-aware `Fork`, fork-aware `Environment` (#2690) Co-authored-by: spencer-tb --- .../plugins/execute/execute.py | 7 +- .../pytest_commands/plugins/filler/filler.py | 8 ++- .../filler/gen_test_doc/gen_test_doc.py | 2 +- .../plugins/filler/static_filler.py | 2 +- .../pytest_commands/plugins/forks/forks.py | 16 +++-- .../tests/test_fork_parametrizer_types.py | 23 ++++--- .../plugins/shared/benchmarking.py | 18 ++++-- .../plugins/shared/execute_fill.py | 64 ++++++++++++++++++- .../src/execution_testing/forks/base_fork.py | 55 ++++++++++++++-- .../forks/tests/test_forks.py | 23 +++++++ .../forks/transition_base_fork.py | 26 +++++++- 11 files changed, 207 insertions(+), 37 deletions(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py index f5c567627bb..9a15a9c3ecc 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py @@ -851,10 +851,13 @@ def pytest_collection_modifyitems( if isinstance(item, EIPSpecTestItem): continue params: Dict[str, Any] = item.callspec.params # type: ignore - if "fork" not in params or params["fork"] is None: + if ( + "parametrized_fork" not in params + or params["parametrized_fork"] is None + ): items_for_removal.append(i) continue - fork: Fork | TransitionFork = params["fork"] + fork: Fork | TransitionFork = params["parametrized_fork"] spec_type, execute_format = get_spec_format_for_item(params) assert issubclass(execute_format, BaseExecute) markers = list(item.iter_markers()) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py index 5a733c09ad5..1b1bdb1d7b2 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py @@ -1922,10 +1922,14 @@ def pytest_collection_modifyitems( params = item.callspec.params elif hasattr(item, "params"): params = item.params - if not params or "fork" not in params or params["fork"] is None: + if ( + not params + or "parametrized_fork" not in params + or params["parametrized_fork"] is None + ): items_for_removal.append(i) continue - fork: Fork | TransitionFork = params["fork"] + fork: Fork | TransitionFork = params["parametrized_fork"] spec_type, fixture_format = get_spec_format_for_item(params) if isinstance(fixture_format, NotSetType): items_for_removal.append(i) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py index f5eab27ac65..88a0e586066 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py @@ -446,7 +446,7 @@ def create_function_page_props( ) for value in values ] - fork = item.callspec.params.get("fork").name() # type: ignore + fork = item.callspec.params.get("parametrized_fork").name() # type: ignore test_type = get_test_function_test_type(item) test_type_value = item.callspec.params.get(test_type) fixture_type = test_type_value.format_name # type: ignore diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py index 08b2195410f..c6d4ea6ecf5 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py @@ -275,7 +275,7 @@ def collect(self: "FillerFile") -> Generator["FillerTestItem", None, None]: ps_id = fixture_format_parameter_set.id test_id = f"fork_{fork.name()}-{ps_id}" if "fork" in func_parameters: - params["fork"] = fork + params["parametrized_fork"] = fork if "pre" in func_parameters: fixturenames.append("pre") if "request" in func_parameters: diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py index 2dc7336f6e8..6f1bb468a18 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py @@ -118,7 +118,7 @@ def __init__( marks = [] self.fork_covariant_parameters = [ ForkCovariantParameter( - names=["fork"], + names=["parametrized_fork"], values=[ pytest.param( fork, @@ -671,7 +671,7 @@ def pytest_report_header(config: pytest.Config, start_path: Any) -> List[str]: @pytest.fixture(autouse=True) -def fork(request: pytest.FixtureRequest) -> None: +def parametrized_fork(request: pytest.FixtureRequest) -> None: """Parametrize test cases by fork.""" pass @@ -1234,7 +1234,9 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: ], ) ] - metafunc.parametrize("fork", pytest_params, scope="function") + metafunc.parametrize( + "parametrized_fork", pytest_params, scope="function" + ) return # Get the intersection between the test's validity marker and the current @@ -1243,7 +1245,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: test_fork_set & metafunc.config.selected_fork_set # type: ignore ) - if "fork" not in metafunc.fixturenames: + if "parametrized_fork" not in metafunc.fixturenames: return unsupported_forks: Set[Fork | TransitionFork] = ( @@ -1266,7 +1268,9 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: ], ) ] - metafunc.parametrize("fork", pytest_params, scope="function") + metafunc.parametrize( + "parametrized_fork", pytest_params, scope="function" + ) else: pytest_params = [] for fork in sorted(intersection_set): @@ -1570,7 +1574,7 @@ def pytest_collection_modifyitems( continue # --- validity markers --- - fork = params.get("fork") + fork = params.get("parametrized_fork") if fork is None: continue diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py index cb1aa6da1f3..381eb4712fd 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py @@ -19,7 +19,7 @@ [ pytest.param( [ForkParametrizer(fork=Frontier)], - ["fork"], + ["parametrized_fork"], [pytest.param(Frontier)], id="only_fork", ), @@ -34,7 +34,7 @@ ], ) ], - ["fork", "some_value"], + ["parametrized_fork", "some_value"], [pytest.param(Frontier, 1)], id="fork_with_single_covariant_parameter", ), @@ -50,7 +50,7 @@ ], ) ], - ["fork", "some_value"], + ["parametrized_fork", "some_value"], [pytest.param(Frontier, 1), pytest.param(Frontier, 2)], id="fork_with_single_covariant_parameter_multiple_values", ), @@ -69,7 +69,7 @@ ], ) ], - ["fork", "some_value"], + ["parametrized_fork", "some_value"], [ pytest.param(Frontier, 1, marks=[pytest.mark.some_mark]), pytest.param(Frontier, 2), @@ -90,7 +90,7 @@ ], ) ], - ["fork", "some_value", "another_value"], + ["parametrized_fork", "some_value", "another_value"], [pytest.param(Frontier, 1, 2)], id="fork_with_multiple_covariant_parameters", ), @@ -109,7 +109,7 @@ ], ) ], - ["fork", "some_value", "another_value"], + ["parametrized_fork", "some_value", "another_value"], [pytest.param(Frontier, 1, 2), pytest.param(Frontier, 1, 3)], id="fork_with_multiple_covariant_parameters_multiple_values", ), @@ -128,7 +128,7 @@ ], ) ], - ["fork", "some_value", "another_value"], + ["parametrized_fork", "some_value", "another_value"], [pytest.param(Frontier, 1, "a"), pytest.param(Frontier, 2, "b")], id="fork_with_single_multi_value_covariant_parameter_multiple_values", ), @@ -155,7 +155,7 @@ ) ], [ - "fork", + "parametrized_fork", "some_value", "another_value", "yet_another_value", @@ -191,7 +191,12 @@ ], ) ], - ["fork", "shared_value", "different_value_1", "different_value_2"], + [ + "parametrized_fork", + "shared_value", + "different_value_1", + "different_value_2", + ], [ pytest.param(Frontier, 1, "a", "x"), pytest.param(Frontier, 2, "b", "y"), diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py index 2a47ed80365..ed98551a10e 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py @@ -553,16 +553,26 @@ def _is_benchmark_test(request: pytest.FixtureRequest) -> bool: @pytest.fixture -def genesis_environment(request: pytest.FixtureRequest) -> Environment: +def env_gas_limit(request: pytest.FixtureRequest) -> int: """Return an Environment with appropriate gas limit.""" if _is_benchmark_test(request): - return Environment(gas_limit=BENCHMARKING_MAX_GAS) + return BENCHMARKING_MAX_GAS + return EnvironmentDefaults.gas_limit + + +@pytest.fixture +def genesis_environment( + request: pytest.FixtureRequest, env_gas_limit: int +) -> Environment: + """Return an Environment with appropriate gas limit.""" + if _is_benchmark_test(request): + return Environment(gas_limit=env_gas_limit) return Environment() @pytest.fixture -def env(request: pytest.FixtureRequest) -> Environment: +def env(request: pytest.FixtureRequest, env_gas_limit: int) -> Environment: """Return an Environment with appropriate gas limit.""" if _is_benchmark_test(request): - return Environment(gas_limit=BENCHMARKING_MAX_GAS) + return Environment(gas_limit=env_gas_limit) return Environment() diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py index d827d96927a..8b33474dfc4 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py @@ -2,8 +2,10 @@ Shared pytest fixtures and hooks for EEST generation modes (fill and execute). """ +from __future__ import annotations + from pathlib import Path -from typing import Dict, List, Tuple +from typing import TYPE_CHECKING, Dict, List, Tuple import pytest from pytest import StashKey @@ -15,11 +17,20 @@ LabeledExecuteFormat, ) from execution_testing.fixtures import BaseFixture, LabeledFixtureFormat + +if TYPE_CHECKING: + from execution_testing.forks import Fork, TransitionFork +import sys + from execution_testing.logging import get_logger from execution_testing.rpc import EthRPC from execution_testing.specs import BaseTest from execution_testing.specs.base import OpMode -from execution_testing.test_types import EOA, Alloc, ChainConfig +from execution_testing.test_types import ( + EOA, + Alloc, + ChainConfig, +) from ..shared.address_stubs import AddressStubs, StubEOA from ..shared.helpers import get_rpc_endpoint @@ -310,9 +321,58 @@ def pytest_make_parametrize_id( readable test ids for the generated tests. """ del config + if argname == "parametrized_fork": + return f"fork_{val}" return f"{argname}_{val}" +@pytest.fixture(scope="function") +def fork( + parametrized_fork: Fork | TransitionFork, + monkeypatch: pytest.MonkeyPatch, + env_gas_limit: int, +) -> Fork | TransitionFork: + """ + Return a per-test fork variant whose ``_env_gas_limit`` tracks the + ``Environment.gas_limit`` used by the test. + """ + fork_variant = parametrized_fork.with_env_gas_limit(env_gas_limit) + + # Now we monkey-patch the `Environment` class with one that is aware of + # the fork that the test is using, and will update its `_env_gas_limit` + # automatically. + # TODO: This should not be necessary, we should treat the `env` object the + # same way we do `pre` and force it to be a singleton in the test's + # context. + from execution_testing.test_types.block_types import ( + Environment as OriginalEnvironment, + ) + + class _ForkAwareEnvironment(OriginalEnvironment): + """Transparently syncs ``gas_limit`` back to the fork variant.""" + + def model_post_init(self, __context: object) -> None: + super().model_post_init(__context) + fork_variant._env_gas_limit = int(self.gas_limit) + + def __setattr__(self, name: str, value: object) -> None: + super().__setattr__(name, value) + if name == "gas_limit": + fork_variant._env_gas_limit = int(self.gas_limit) + + # Replace Environment in every module that imported the original class + # so that both `Environment(...)` in test code and in conftest fixtures + # create _ForkAwareEnvironment instances. + for mod in list(sys.modules.values()): + try: + if getattr(mod, "Environment", None) is OriginalEnvironment: + monkeypatch.setattr(mod, "Environment", _ForkAwareEnvironment) + except Exception: + continue + + return fork_variant + + SPEC_TYPES_PARAMETERS: List[str] = list(BaseTest.spec_types.keys()) diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index c074c3da840..a36f55ae1c1 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -198,35 +198,54 @@ def _maybe_transitioned(fork_cls: "BaseForkMeta") -> "BaseForkMeta": @staticmethod def _is_subclass_of(a: "BaseForkMeta", b: "BaseForkMeta") -> bool: """ - Check if `a` is a subclass of `b`, taking fork transitions into - account. + Check if `a` is a subclass of `b`, taking fork transitions and + variants (created by `with_env_gas_limit`) into account. """ + # Resolve variants to canonical identity so comparisons between + # a variant and a canonical descendant fork work as expected. + a = BaseForkMeta._identity(a) + b = BaseForkMeta._identity(b) a = BaseForkMeta._maybe_transitioned(a) b = BaseForkMeta._maybe_transitioned(b) return issubclass(a, b) + @staticmethod + def _identity(fork_cls: "BaseForkMeta") -> "BaseForkMeta": + """Return the canonical fork class, resolving variants.""" + base = getattr(fork_cls, "_base_fork", None) + return base if base is not None else fork_cls + + def __eq__(cls, other: object) -> bool: + """Compare fork identity, treating variants as equal to parents.""" + if not isinstance(other, BaseForkMeta): + return NotImplemented + return BaseForkMeta._identity(cls) is BaseForkMeta._identity(other) + + def __hash__(cls) -> int: + """Hash by canonical fork identity.""" + return id(BaseForkMeta._identity(cls)) + def __gt__(cls, other: "BaseForkMeta") -> bool: """Compare if a fork is newer than some other fork (cls > other).""" - return cls is not other and BaseForkMeta._is_subclass_of(cls, other) + return cls != other and BaseForkMeta._is_subclass_of(cls, other) def __ge__(cls, other: "BaseForkMeta") -> bool: """ Compare if a fork is newer than or equal to some other fork (cls >= other). """ - return cls is other or BaseForkMeta._is_subclass_of(cls, other) + return cls == other or BaseForkMeta._is_subclass_of(cls, other) def __lt__(cls, other: "BaseForkMeta") -> bool: """Compare if a fork is older than some other fork (cls < other).""" - # "Older" means other is a subclass of cls, but not the same. - return cls is not other and BaseForkMeta._is_subclass_of(other, cls) + return cls != other and BaseForkMeta._is_subclass_of(other, cls) def __le__(cls, other: "BaseForkMeta") -> bool: """ Compare if a fork is older than or equal to some other fork (cls <= other). """ - return cls is other or BaseForkMeta._is_subclass_of(other, cls) + return cls == other or BaseForkMeta._is_subclass_of(other, cls) class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta): @@ -246,6 +265,10 @@ class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta): _ruleset_name: ClassVar[Optional[str]] = None _fork_by_timestamp: ClassVar[bool] = False _blob_constants: ClassVar[Dict[str, int]] = {} + + # Environment overrides (set on variants created by with_env_gas_limit) + _base_fork: ClassVar[Optional[Type["BaseFork"]]] = None + _env_gas_limit: ClassVar[int] = 0 _deployed: ClassVar[bool] = True _enabled_eips: ClassVar[Set[int]] = set() _enabling_forks: ClassVar[Set[Type["BaseFork"]]] = set() @@ -1109,6 +1132,24 @@ def children(cls) -> Set[Type["BaseFork"]]: """Return the children forks.""" return set(cls._children) + @classmethod + def with_env_gas_limit(cls, env_gas_limit: int) -> Type["BaseFork"]: + """Return a new fork class with the specified environment gas limit.""" + new_cls = type(cls.__name__, (cls,), {}) + # __init_subclass__ resets per-class overrides; restore from parent. + new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] + new_cls._base_fork = cls._base_fork or cls # type: ignore[attr-defined] + new_cls._transition_tool_name = ( # type: ignore[attr-defined] + cls._transition_tool_name + ) + new_cls._solc_name = cls._solc_name # type: ignore[attr-defined] + new_cls._ignore = cls._ignore # type: ignore[attr-defined] + new_cls._bpo_fork = cls._bpo_fork # type: ignore[attr-defined] + new_cls._ruleset_name = cls._ruleset_name # type: ignore[attr-defined] + # Prevent the variant from appearing in fork traversals. + cls._children.discard(new_cls) + return new_cls + @classmethod @abstractmethod def build_default_block_header( diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index 8d9cec7882c..a1a2d3d8e28 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -24,6 +24,7 @@ Paris, Prague, Shanghai, + SpuriousDragon, ) from ..forks.transition import ( BerlinToLondonAt5, @@ -731,3 +732,25 @@ def test_eips() -> None: # noqa: D103 assert not Paris.is_eip_enabled(3675, 3855) assert not Paris.is_eip_enabled(3855, 3675) assert Shanghai.is_eip_enabled(3855) + + +def test_fork_variant_ordering() -> None: + """ + Variants from `with_env_gas_limit` must compare consistently with + their canonical parent: equal to the parent, ordered identically + against other canonical forks. + """ + variant = London.with_env_gas_limit(30_000_000) + + assert variant == London + assert hash(variant) == hash(London) + + assert variant > SpuriousDragon + assert variant >= SpuriousDragon + assert variant < Cancun + assert variant <= Cancun + + assert not (variant > London) + assert not (variant < London) + assert variant >= London + assert variant <= London diff --git a/packages/testing/src/execution_testing/forks/transition_base_fork.py b/packages/testing/src/execution_testing/forks/transition_base_fork.py index 3dca0cb1d31..8f5c45aa0a0 100644 --- a/packages/testing/src/execution_testing/forks/transition_base_fork.py +++ b/packages/testing/src/execution_testing/forks/transition_base_fork.py @@ -75,6 +75,7 @@ class TransitionBaseClass(metaclass=TransitionBaseMetaClass): at_block: ClassVar[int] = 0 at_timestamp: ClassVar[int] = 0 _ignore: ClassVar[bool] = False + _env_gas_limit: ClassVar[int] = 0 @classmethod def fork_at( @@ -106,6 +107,18 @@ def ruleset(cls) -> Dict[str, int]: """ raise Exception("Not implemented") + @classmethod + def with_env_gas_limit( + cls, env_gas_limit: int + ) -> Type["TransitionBaseClass"]: + """ + Return a new transition fork class with the specified environment + gas limit. + """ + new_cls = type(cls.__name__, (cls,), {}) + new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] + return new_cls + def transition_fork( to_fork: Type[BaseFork], @@ -134,23 +147,30 @@ class NewTransitionClass( ): _ignore = ignore + @classmethod + def _propagate_env(cls, fork: Type[BaseFork]) -> Type[BaseFork]: + if cls._env_gas_limit: + return fork.with_env_gas_limit(cls._env_gas_limit) + return fork + @classmethod def transitions_to(cls) -> Type[BaseFork]: - return to_fork + return cls._propagate_env(to_fork) @classmethod def transitions_from(cls) -> Type[BaseFork]: - return from_fork + return cls._propagate_env(from_fork) @classmethod def fork_at( cls, *, block_number: int = 0, timestamp: int = 0 ) -> Type[BaseFork]: - return ( + fork = ( to_fork if block_number >= at_block and timestamp >= at_timestamp else from_fork ) + return cls._propagate_env(fork) @classmethod def name(cls) -> str: From e8f01a69d055409e4f91fbec6f9e264c8cd77174 Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Sat, 18 Apr 2026 19:12:38 +0300 Subject: [PATCH 025/186] feat(spec-specs, tests): add account-only BAL invalid test (#2712) * test: Add account-only BAL invalid test * refactor(test): parametrize missing account test / DRY --------- Co-authored-by: Felipe Selmo --- .../test_block_access_lists_invalid.py | 86 ++++++++++++------- .../test_cases.md | 2 +- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index 5b86712e74b..df7332b4212 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -570,51 +570,79 @@ def test_bal_invalid_complex_corruption( @pytest.mark.valid_from("Amsterdam") @pytest.mark.exception_test +@pytest.mark.parametrize( + "scenario", + ["balance_change", "access_only"], +) def test_bal_invalid_missing_account( blockchain_test: BlockchainTestFiller, pre: Alloc, + scenario: str, ) -> None: """ - Test that clients reject blocks where BAL is missing an entire account. + Test that clients reject blocks where BAL omits an account that was + touched during block execution. + + Covers both the case where the omitted account has a balance change + (value transfer recipient) and the access-only case (account read via + ``BALANCE`` with no state change). """ sender = pre.fund_eoa(amount=10**18) - receiver = pre.fund_eoa(amount=0) - - tx = Transaction( - sender=sender, - to=receiver, - value=10**15, - gas_limit=21_000, + sender_expectation = BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ) + if scenario == "balance_change": + omitted = pre.fund_eoa(amount=0) + tx = Transaction( + sender=sender, + to=omitted, + value=10**15, + gas_limit=21_000, + ) + post: dict = { + sender: Account(balance=10**18, nonce=0), + omitted: None, + } + account_expectations: dict = { + sender: sender_expectation, + omitted: BalAccountExpectation( + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10**15) + ], + ), + } + elif scenario == "access_only": + omitted = pre.fund_eoa(amount=1) + checker = pre.deploy_contract(code=Op.BALANCE(omitted)) + tx = Transaction( + sender=sender, + to=checker, + gas_limit=100_000, + ) + post = { + sender: Account(balance=10**18, nonce=0), + omitted: Account(balance=1), + checker: Account(), + } + account_expectations = { + sender: sender_expectation, + checker: BalAccountExpectation.empty(), + omitted: BalAccountExpectation.empty(), + } + else: + raise ValueError(f"Unknown scenario: {scenario}") + blockchain_test( pre=pre, - post={ - sender: Account(balance=10**18, nonce=0), - receiver: None, - }, + post=post, blocks=[ Block( txs=[tx], exception=BlockException.INVALID_BLOCK_ACCESS_LIST, expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - sender: BalAccountExpectation( - nonce_changes=[ - BalNonceChange( - block_access_index=1, post_nonce=1 - ) - ], - ), - receiver: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=10**15 - ) - ], - ), - } - ).modify(remove_accounts(receiver)), + account_expectations=account_expectations, + ).modify(remove_accounts(omitted)), ) ], ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index dfaefa7ccf4..d9696576559 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -79,7 +79,7 @@ | `test_bal_invalid_duplicate_account` | Verify clients reject blocks with duplicate account entries in BAL | Alice sends transaction; BAL modifier duplicates Alice's account entry | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** ensure each account appears at most once in BAL. | ✅ Completed | | `test_bal_invalid_account_order` | Verify clients reject blocks with incorrect account ordering in BAL | Alice sends transaction to Bob; BAL modifier reverses account order (BAL requires sorted order) | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate accounts are in canonical sorted order. | ✅ Completed | | `test_bal_invalid_complex_corruption` | Verify clients reject blocks with multiple BAL corruptions | Alice calls contract with storage writes; BAL has multiple issues: wrong account, missing nonce, wrong storage value | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** detect any corruption regardless of other issues. | ✅ Completed | -| `test_bal_invalid_missing_account` | Verify clients reject blocks with missing required account entries in BAL | Alice sends transaction to Bob; BAL modifier removes Bob's account entry (recipient should be included) | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate all accessed accounts are present. | ✅ Completed | +| `test_bal_invalid_missing_account` | Verify clients reject blocks whose BAL omits an account that was touched during block execution | Parameterized test: `balance_change` — Alice sends a value transfer to Bob; BAL modifier removes Bob's entry (recipient had a balance change). `access_only` — Alice calls a contract that executes `BALANCE` against a target account without changing it; BAL modifier removes the target account's entry (accessed-but-unchanged). | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate all accessed accounts are present, including accessed-but-unchanged accounts with empty change lists. | ✅ Completed | | `test_bal_invalid_balance_value` | Verify clients reject blocks with incorrect balance values in BAL | Alice sends value to Bob; BAL modifier changes balance to incorrect value | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate balance change values match actual state transitions. | ✅ Completed | | `test_bal_empty_block_no_coinbase` | Ensure BAL correctly handles empty blocks without including coinbase | Block with 0 transactions, no withdrawals. System contracts may perform operations (EIP-2935 parent hash, EIP-4788 beacon root if active). | BAL **MUST NOT** include the coinbase/fee recipient (receives no fees). BAL **MAY** include system contract addresses (EIP-2935 `HISTORY_STORAGE_ADDRESS`, EIP-4788 `BEACON_ROOTS_ADDRESS`) with `storage_changes` at `block_access_index=0` (pre-execution system operations). | ✅ Completed | | `test_bal_coinbase_zero_tip` | Ensure BAL includes coinbase even when priority fee is zero | Block with 1 transaction: Alice sends 5 wei to Bob with priority fee = 0 (base fee burned post-EIP-1559) | BAL **MUST** include Alice with `balance_changes` (gas cost) and `nonce_changes`. BAL **MUST** include Bob with `balance_changes`. BAL **MUST** include coinbase with empty changes. | ✅ Completed | From 554bd418ba77f543940ca3b460c365c575eb72bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Wahrst=C3=A4tter?= <51536394+nerolation@users.noreply.github.com> Date: Mon, 20 Apr 2026 09:11:42 +0200 Subject: [PATCH 026/186] feat(spec-specs, tests): EIP-7928 - Update BAL index to uint64 (#2713) --- src/ethereum/forks/amsterdam/block_access_lists.py | 4 ++-- tests/amsterdam/eip7928_block_level_access_lists/spec.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ethereum/forks/amsterdam/block_access_lists.py b/src/ethereum/forks/amsterdam/block_access_lists.py index c6bcf176886..38cc698b10f 100644 --- a/src/ethereum/forks/amsterdam/block_access_lists.py +++ b/src/ethereum/forks/amsterdam/block_access_lists.py @@ -18,7 +18,7 @@ from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes32 from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U16, U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint from ethereum.crypto.hash import Hash32, keccak256 from ethereum.state import EMPTY_CODE_HASH, Account, Address, PreState @@ -46,7 +46,7 @@ Bytecode associated with an [`Account`](ref:ethereum.state.Account). """ -BlockAccessIndex: TypeAlias = U16 +BlockAccessIndex: TypeAlias = U64 """ Position within the set of all changes in a [`Block`]. diff --git a/tests/amsterdam/eip7928_block_level_access_lists/spec.py b/tests/amsterdam/eip7928_block_level_access_lists/spec.py index 89a73baad7a..bbb875d8b54 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/spec.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/spec.py @@ -39,6 +39,6 @@ class Spec: HASH_SIZE: int = 32 # Hash size in bytes # Numeric type limits - MAX_TX_INDEX: int = 2**16 - 1 # uint16 max value + MAX_TX_INDEX: int = 2**64 - 1 # uint64 max value MAX_BALANCE: int = 2**128 - 1 # uint128 max value MAX_NONCE: int = 2**64 - 1 # uint64 max value From 668cde5e1842a0e8683c7a313b690762e0237dde Mon Sep 17 00:00:00 2001 From: Alexey Osipov Date: Mon, 20 Apr 2026 12:53:31 +0300 Subject: [PATCH 027/186] feat(spec-specs, tests): add system address BAL tests (#2715) Co-authored-by: spencer-tb --- .../test_block_access_lists_invalid.py | 41 ++++++++++++ .../test_block_access_lists_opcodes.py | 64 +++++++++++++++++++ .../test_cases.md | 2 + 3 files changed, 107 insertions(+) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index df7332b4212..72175a18c11 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -60,6 +60,10 @@ ) from .spec import ref_spec_7928 +from .test_block_access_lists_eip4788 import ( + SYSTEM_ADDRESS, + beacon_root_system_call_expectations, +) REFERENCE_SPEC_GIT_PATH = ref_spec_7928.git_path REFERENCE_SPEC_VERSION = ref_spec_7928.version @@ -774,6 +778,43 @@ def test_bal_invalid_missing_withdrawal_account_empty_block( ) +@pytest.mark.valid_from("Amsterdam") +@pytest.mark.exception_test +def test_bal_invalid_surplus_system_address_from_system_call( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test that clients reject a BAL that includes SYSTEM_ADDRESS solely because + it was the synthetic caller of a pre-execution system operation. + """ + block_timestamp = 12 + beacon_root = Hash(0xABCDEF) + + blockchain_test( + pre=pre, + post={}, + blocks=[ + Block( + txs=[], + parent_beacon_block_root=beacon_root, + timestamp=block_timestamp, + exception=BlockException.INVALID_BLOCK_ACCESS_LIST, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=beacon_root_system_call_expectations( + block_timestamp, + beacon_root, + ) + ).modify( + append_account( + BalAccountChange(address=SYSTEM_ADDRESS), + ) + ), + ) + ], + ) + + @pytest.mark.valid_from("Amsterdam") @pytest.mark.exception_test def test_bal_invalid_balance_value( diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index 68321d8e3b1..3daa969304a 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -41,6 +41,7 @@ ) from .spec import ref_spec_7928 +from .test_block_access_lists_eip4788 import SYSTEM_ADDRESS REFERENCE_SPEC_GIT_PATH = ref_spec_7928.git_path REFERENCE_SPEC_VERSION = ref_spec_7928.version @@ -321,6 +322,69 @@ def test_bal_balance_and_oog( ) +@pytest.mark.parametrize( + "access_opcode", + [ + pytest.param(lambda target: Op.BALANCE(target), id="balance"), + pytest.param(lambda target: Op.EXTCODESIZE(target), id="extcodesize"), + pytest.param(lambda target: Op.EXTCODEHASH(target), id="extcodehash"), + pytest.param( + lambda target: Op.EXTCODECOPY(target, 0, 0, 0), + id="extcodecopy", + ), + pytest.param(lambda target: Op.CALL(address=target), id="call"), + pytest.param( + lambda target: Op.STATICCALL(address=target), + id="staticcall", + ), + ], +) +def test_bal_account_touch_system_address( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + access_opcode: Callable[[Address], Bytecode], +) -> None: + """ + Ensure a regular transaction that explicitly touches SYSTEM_ADDRESS via + an account-accessing opcode includes SYSTEM_ADDRESS as an account-only + BAL entry. + + This confirms that SYSTEM_ADDRESS is only excluded from the BAL when it + appears as the synthetic caller of a pre-execution system call; a real + EVM state access from user code MUST still land in the BAL. + """ + alice = pre.fund_eoa() + pre.fund_address(SYSTEM_ADDRESS, amount=1) + + toucher = pre.deploy_contract(code=access_opcode(SYSTEM_ADDRESS) + Op.STOP) + + tx = Transaction( + sender=alice, + to=toucher, + gas_limit=200_000, + ) + + block = Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + toucher: BalAccountExpectation.empty(), + SYSTEM_ADDRESS: BalAccountExpectation.empty(), + } + ), + ) + + blockchain_test( + pre=pre, + blocks=[block], + post={ + alice: Account(nonce=1), + toucher: Account(), + SYSTEM_ADDRESS: Account(balance=1), + }, + ) + + @pytest.mark.parametrize( "fails_at_extcodesize", [True, False], diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index d9696576559..90669a3833c 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -56,6 +56,7 @@ | `test_bal_sstore_static_context` | SSTORE in static context must not leak storage reads into BAL | Contract A STATICCALLs Contract B which attempts `SSTORE`. Parametrized: `original_value` (0, nonzero) to catch clients that perform the implicit SLOAD before the static check. | Contract B IS in BAL (accessed via STATICCALL) but **MUST NOT** have `storage_reads`. | ✅ Completed | | `test_bal_sload_and_oog` | Ensure BAL handles OOG during SLOAD execution correctly | Alice calls contract that attempts `SLOAD` from cold slot `0x01`. Parameterized: (1) OOG at SLOAD opcode (insufficient gas), (2) Successful SLOAD execution. | For OOG case: BAL **MUST NOT** contain slot `0x01` in `storage_reads` since storage wasn't accessed. For success case: BAL **MUST** contain slot `0x01` in `storage_reads`. | ✅ Completed | | `test_bal_balance_and_oog` | Ensure BAL handles OOG during BALANCE opcode execution correctly | Alice calls contract that attempts `BALANCE` opcode on cold target account. Parameterized: (1) OOG at BALANCE opcode (insufficient gas), (2) Successful BALANCE execution. | For OOG case: BAL **MUST NOT** include target account (wasn't accessed). For success case: BAL **MUST** include target account in `account_changes`. | ✅ Completed | +| `test_bal_account_touch_system_address` | Ensure BAL includes `SYSTEM_ADDRESS` when a regular transaction touches it via any account-accessing opcode | Alice calls a contract that executes one of `BALANCE`, `EXTCODESIZE`, `EXTCODEHASH`, `EXTCODECOPY`, `CALL`, or `STATICCALL` against `SYSTEM_ADDRESS`. Parametrized over the six opcodes. | BAL **MUST** include `SYSTEM_ADDRESS` as an account-only entry for every opcode because the address experienced a real EVM state access. This is distinct from excluding the synthetic system-operation caller. | ✅ Completed | | `test_bal_extcodesize_and_oog` | Ensure BAL handles OOG during EXTCODESIZE opcode execution correctly | Alice calls contract that attempts `EXTCODESIZE` opcode on cold target contract. Parameterized: (1) OOG at EXTCODESIZE opcode (insufficient gas), (2) Successful EXTCODESIZE execution. | For OOG case: BAL **MUST NOT** include target contract (wasn't accessed). For success case: BAL **MUST** include target contract in `account_changes`. | ✅ Completed | | `test_bal_delegatecall_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated DELEGATECALL | Parametrized: target warm/cold, memory expansion, OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | | `test_bal_delegatecall_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for DELEGATECALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, memory expansion, OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | @@ -142,6 +143,7 @@ | `test_bal_invalid_missing_coinbase` | Verify clients reject blocks where BAL is missing the coinbase/fee recipient | Alice sends 100 wei to Bob with gas_price > base_fee so coinbase (charlie) receives a non-zero tip. BAL modifier removes charlie's entry entirely. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** include fee recipients that received tips in the BAL. | ✅ Completed | | `test_bal_invalid_coinbase_balance_value` | Verify clients reject blocks where BAL has an incorrect balance for the coinbase/fee recipient | Same setup as test_bal_invalid_missing_coinbase. BAL modifier changes charlie's post-balance from the actual tip to 999. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Clients **MUST** validate coinbase balance values match actual fee accounting (priority fee x gas used). | ✅ Completed | | `test_bal_invalid_extraneous_coinbase` | Verify clients reject blocks with a spurious coinbase entry when coinbase received no fees | Parameterized: (1) empty_block: no txs, no withdrawals — only system contracts in valid BAL, (2) withdrawal_only: no txs, one withdrawal to a different address — withdrawals don't pay fees so coinbase is still untouched. BAL modifier appends spurious coinbase entry with empty changes. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST` exception. Coinbase **MUST NOT** appear in BAL when it receives no transaction tips, even if the block has other state-modifying activity (withdrawals). | ✅ Completed | +| `test_bal_invalid_surplus_system_address_from_system_call` | Verify clients reject a BAL containing `SYSTEM_ADDRESS` solely due to a system operation caller | Empty block with an EIP-4788 pre-execution system call to `BEACON_ROOTS_ADDRESS`. Helper `beacon_root_system_call_expectations` builds the valid baseline BAL: `BEACON_ROOTS_ADDRESS` has timestamp/root storage changes at `block_access_index=0`, while `SYSTEM_ADDRESS` is marked absent (`None`). The fixture BAL is then corrupted by appending an empty `SYSTEM_ADDRESS` entry. | Block **MUST** be rejected with `INVALID_BLOCK_ACCESS_LIST`. The synthetic system caller address **MUST NOT** be accepted unless it experienced an actual state access. | ✅ Completed | | `test_bal_2935_simple` | Ensure BAL captures EIP-2935 history storage writes during pre-execution system call alongside normal transactions | Block with 2 normal user transactions: Alice sends 10 wei to Charlie, Bob sends 10 wei to Charlie. At block start (pre-execution), `SYSTEM_ADDRESS` calls `HISTORY_STORAGE_ADDRESS` to store parent block hash. | BAL **MUST** include `HISTORY_STORAGE_ADDRESS` with `storage_changes` (ring buffer slot 0, empty `slot_changes` since parent hash is framework-computed); `SYSTEM_ADDRESS` **MUST NOT** be included in BAL. At `block_access_index=1`: Alice with `nonce_changes`, Charlie with `balance_changes` (10 wei). At `block_access_index=2`: Bob with `nonce_changes`, Charlie with `balance_changes` (20 wei total). | ✅ Completed | | `test_bal_2935_empty_block` | Ensure BAL captures EIP-2935 history storage writes in empty block | Block with no transactions. At block start (pre-execution), `SYSTEM_ADDRESS` calls `HISTORY_STORAGE_ADDRESS` to store parent block hash. | BAL **MUST** include `HISTORY_STORAGE_ADDRESS` with `storage_changes` (ring buffer slot 0, empty `slot_changes`); `SYSTEM_ADDRESS` **MUST NOT** be included in BAL. No transaction-related BAL entries. | ✅ Completed | | `test_bal_2935_query` | Ensure BAL captures storage reads when querying EIP-2935 historical block hashes (valid and invalid queries) with optional value transfer | Parameterized test: Block 1 (empty, stores genesis hash via system call). Block 2: Oracle contract queries `HISTORY_STORAGE_ADDRESS` with block number. Two block number scenarios (valid=0 genesis hash, invalid=1042 out of range) and value (0 or 100 wei). Valid query (block_number=0): reads genesis hash slot, oracle writes returned value. If value > 0, history storage contract receives balance. Invalid query (block_number=1042, out of range): reverts before storage access, oracle has implicit SLOAD recorded, value stays in oracle (not transferred to history storage). | Block 2 BAL **MUST** include: Valid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with `storage_reads` [slot 0] and `balance_changes` if value > 0, oracle with `storage_changes` (empty `slot_changes`). Invalid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes`, oracle with `storage_reads` [0], NO `storage_changes`, and `balance_changes` if value > 0 (value stays in oracle). Alice with `nonce_changes` at `block_access_index=1`. | ✅ Completed | From 464f61d45f1d903562c4924a1a487c0df4247ad7 Mon Sep 17 00:00:00 2001 From: Leo Lara Date: Mon, 20 Apr 2026 17:26:21 +0700 Subject: [PATCH 028/186] feat(test-client-clis): tolerate missing trace file for rejected txs (#2709) --- .../src/execution_testing/client_clis/transition_tool.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/testing/src/execution_testing/client_clis/transition_tool.py b/packages/testing/src/execution_testing/client_clis/transition_tool.py index 99874f296df..aad9f89a921 100644 --- a/packages/testing/src/execution_testing/client_clis/transition_tool.py +++ b/packages/testing/src/execution_testing/client_clis/transition_tool.py @@ -266,6 +266,13 @@ def collect_traces( for i, r in enumerate(receipts): trace_file_name = f"trace-{i}-{r.transaction_hash}.jsonl" trace_file_path = temp_dir_path / trace_file_name + if not trace_file_path.exists(): + # Transaction was rejected mid-processing (e.g. EIP-3607 + # collision): the receipt exists but the tracer's + # TransactionEnd event never fired, so no trace file was + # written. Record an empty trace for this tx. + traces.append(TransactionTraces(traces=[])) + continue if debug_output_path: shutil.copy( trace_file_path, From 0345cf1feead986c867d07b7d47c40b510f2e249 Mon Sep 17 00:00:00 2001 From: junbyjun1238 Date: Mon, 20 Apr 2026 19:33:24 +0900 Subject: [PATCH 029/186] Open feat(tests): tighten invalid-path BAL coverage for EIP-2935 and EIP-4788 (#2716) Co-authored-by: spencer-tb --- .../test_block_access_lists_eip2935.py | 14 +- .../test_block_access_lists_eip4788.py | 126 +++++++++++++++++- .../test_cases.md | 1 + 3 files changed, 131 insertions(+), 10 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip2935.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip2935.py index f4409671c9c..72ca12b5de7 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip2935.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip2935.py @@ -226,11 +226,13 @@ def test_bal_2935_query( [block_hash_slot] if is_valid else [] ) - # Add balance changes if value is transferred and query is valid - if value > 0 and is_valid: - account_expectations[HISTORY_STORAGE_ADDRESS].balance_changes = [ - BalBalanceChange(block_access_index=1, post_balance=value) - ] + # Balance changes for callee: credited if valid, must be empty if invalid + if value > 0: + account_expectations[HISTORY_STORAGE_ADDRESS].balance_changes = ( + [BalBalanceChange(block_access_index=1, post_balance=value)] + if is_valid + else [] + ) account_expectations[alice] = BalAccountExpectation( nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], @@ -426,6 +428,8 @@ def test_bal_2935_invalid_calldata_size( account_expectations = block_hash_system_call_expectations(1) # History storage contract reverts before any storage access account_expectations[HISTORY_STORAGE_ADDRESS].storage_reads = [] + if value > 0: + account_expectations[HISTORY_STORAGE_ADDRESS].balance_changes = [] account_expectations[alice] = BalAccountExpectation( nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4788.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4788.py index 02c0c6fdd96..65e0b376dc7 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4788.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4788.py @@ -321,11 +321,13 @@ def test_bal_4788_query( else [timestamp_slot] ) - # Add balance changes if value is transferred - if value > 0 and is_valid: - account_expectations[BEACON_ROOTS_ADDRESS].balance_changes = [ - BalBalanceChange(block_access_index=1, post_balance=value) - ] + # Balance changes for callee: credited if valid, must be empty if invalid + if value > 0: + account_expectations[BEACON_ROOTS_ADDRESS].balance_changes = ( + [BalBalanceChange(block_access_index=1, post_balance=value)] + if is_valid + else [] + ) # Add transaction-specific expectations account_expectations[alice] = BalAccountExpectation( @@ -386,6 +388,120 @@ def test_bal_4788_query( ) +@pytest.mark.parametrize( + "calldata_size", + [ + pytest.param(0, id="empty_calldata"), + pytest.param(31, id="calldata_too_short"), + pytest.param(33, id="calldata_too_long"), + ], +) +@pytest.mark.parametrize( + "value", + [ + pytest.param(0, id="no_value"), + pytest.param(100, id="with_value"), + ], +) +def test_bal_4788_invalid_calldata_size( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + fork: Fork, + calldata_size: int, + value: int, +) -> None: + """ + Ensure BAL correctly handles EIP-4788 queries with invalid calldata size. + + EIP-4788 requires exactly 32 bytes of calldata (a timestamp). Any other + size causes immediate revert before any storage access occurs. + + Test scenarios with and without value transfer: + 1. Empty calldata (0 bytes): Reverts immediately + 2. Too short (31 bytes): Reverts before storage access + 3. Too long (33 bytes): Reverts before storage access + """ + alice = pre.fund_eoa() + + block_timestamp = 12 + beacon_root = Hash(0xABCDEF) + + # Contract that calls beacon roots contract with variable-size calldata + # and stores returned beacon root in slot 0 + query_code = ( + Op.CALLDATACOPY(0, 0, calldata_size) + + Op.CALL( + Spec.BEACON_ROOTS_CALL_GAS, + BEACON_ROOTS_ADDRESS, + Op.CALLVALUE, + 0, + calldata_size, + 32, + 32, + ) + + Op.SSTORE(0, Op.MLOAD(32)) + ) + query_contract = pre.deploy_contract(query_code) + + # Pad calldata to requested size + calldata = b"\x00" * calldata_size + + tx = Transaction( + sender=alice, + to=query_contract, + data=calldata, + value=value, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + account_expectations = beacon_root_system_call_expectations( + block_timestamp, beacon_root + ) + # Beacon roots contract reverts before any storage access + account_expectations[BEACON_ROOTS_ADDRESS].storage_reads = [] + if value > 0: + account_expectations[BEACON_ROOTS_ADDRESS].balance_changes = [] + + account_expectations[alice] = BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + ) + + account_expectations[query_contract] = BalAccountExpectation( + # SSTORE(0, 0) is a no-op write, becomes implicit read + storage_reads=[0], + storage_changes=[], + # Value stays in query contract when call reverts + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=value) + ] + if value > 0 + else [], + ) + + block = Block( + txs=[tx], + parent_beacon_block_root=beacon_root, + timestamp=block_timestamp, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations + ), + ) + + post_state: dict[Address, Account] = { + alice: Account(nonce=1), + query_contract: Account(storage={0: 0}), + } + + if value > 0: + post_state[query_contract] = Account(storage={0: 0}, balance=value) + + blockchain_test( + pre=pre, + blocks=[block], + post=post_state, + ) + + def test_bal_4788_selfdestruct_to_beacon_root( pre: Alloc, blockchain_test: BlockchainTestFiller, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 90669a3833c..dd307611502 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -126,6 +126,7 @@ | `test_bal_4788_simple` | Ensure BAL captures beacon root storage writes during pre-execution system call | Block with 2 normal user transactions: Alice sends 10 wei to Charlie, Bob sends 10 wei to Charlie. At block start (pre-execution), `SYSTEM_ADDRESS` calls `BEACON_ROOTS_ADDRESS` to store parent beacon root | BAL **MUST** include at `block_access_index=0`: `BEACON_ROOTS_ADDRESS` with two `storage_changes` (timestamp slot and beacon root slot); `SYSTEM_ADDRESS` **MUST NOT** be included in BAL. At `block_access_index=1`: Alice with `nonce_changes`, Charlie with `balance_changes` (10 wei). At `block_access_index=2`: Bob with `nonce_changes`, Charlie with `balance_changes` (20 wei total). | ✅ Completed | | `test_bal_4788_empty_block` | Ensure BAL captures beacon root storage writes in empty block | Block with no transactions. At block start (pre-execution), `SYSTEM_ADDRESS` calls `BEACON_ROOTS_ADDRESS` to store parent beacon root | BAL **MUST** include at `block_access_index=0`: `BEACON_ROOTS_ADDRESS` with two `storage_changes` (timestamp slot and beacon root slot); `SYSTEM_ADDRESS` **MUST NOT** be included in BAL. No transaction-related BAL entries. | ✅ Completed | | `test_bal_4788_query` | Ensure BAL captures storage reads when querying beacon root (valid and invalid queries) with optional value transfer | Parameterized test: Block 1 stores beacon root at timestamp 12. Block 2 queries with three timestamp scenarios (valid=12, invalid non-zero=42, invalid zero=0) and value (0 or 100 wei). Valid query (timestamp=12): reads both timestamp and root slots, writes returned value. If value > 0, beacon root contract receives balance. Invalid query with non-zero timestamp (timestamp=42): reads only timestamp slot before reverting, query contract has implicit SLOAD recorded (SSTORE reverts), no value transferred. Invalid query with zero timestamp (timestamp=0): reverts immediately without any storage access, query contract has implicit SLOAD recorded, no value transferred. | Block 1 BAL: System call writes. Block 2 BAL **MUST** include at `block_access_index=0`: System call writes for block 2. Valid case (timestamp=12) at `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with `storage_reads` [timestamp_slot, root_slot] and `balance_changes` if value > 0, query contract with `storage_changes`. Invalid non-zero case (timestamp=42) at `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with `storage_reads` [timestamp_slot only] and NO `balance_changes` (reverted), query contract with `storage_reads` [0] and NO `storage_changes`. Invalid zero case (timestamp=0) at `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes`, query contract with `storage_reads` [0] and NO `storage_changes`. | ✅ Completed | +| `test_bal_4788_invalid_calldata_size` | Ensure BAL correctly handles EIP-4788 queries with invalid calldata size | Parameterized test: Query contract calls `BEACON_ROOTS_ADDRESS` with variable-size calldata (0, 31, or 33 bytes) and value (0 or 100 wei). EIP-4788 requires exactly 32 bytes of calldata; any other size reverts before any storage access. | BAL **MUST** include at `block_access_index=0`: `BEACON_ROOTS_ADDRESS` with `storage_changes` from system call. At `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes` (value not transferred), query contract with `storage_reads` [0] (implicit from no-op SSTORE) and NO `storage_changes`. If value > 0, query contract retains balance. Alice with `nonce_changes`. | ✅ Completed | | `test_bal_4788_selfdestruct_to_beacon_root` | Ensure BAL captures `SELFDESTRUCT` to beacon root address alongside system call storage writes | Single block: Pre-execution system call writes beacon root to storage. Transaction: Alice calls contract (pre-funded with 100 wei) that selfdestructs with `BEACON_ROOTS_ADDRESS` as beneficiary. | BAL **MUST** include at `block_access_index=0`: `BEACON_ROOTS_ADDRESS` with `storage_changes` (timestamp and root slots from system call). At `block_access_index=1`: Alice with `nonce_changes`, contract with `balance_changes` (100→0), `BEACON_ROOTS_ADDRESS` with `balance_changes` (receives 100 wei). | ✅ Completed | | `test_bal_selfdestruct_send_to_sender` | Ensure BAL tracks SELFDESTRUCT sending all funds back to the tx sender (no burn) | Pre-state: contract `C` exists from a prior transaction with non-empty code and balance = 100 wei. EOA `Alice` sends a transaction calling `C`. `C`’s code executes `SELFDESTRUCT(Alice)`. Under EIP-6780, because `C` was not created in this transaction, SELFDESTRUCT does not delete code or storage; it only transfers the entire 100 wei balance from `C` to `Alice`. Final post-state: `C` still exists with the same code and balance = 0; `Alice`’s balance increased by 100 wei (ignoring gas for this test). | BAL **MUST** include `Alice` with `nonce_changes` (tx sender) and `balance_changes` reflecting receipt of 100 wei, and **MUST** include `C` with `balance_changes` 100→0 and no `code_changes`. BAL **MUST NOT** include any other accounts. This test ensures SELFDESTRUCT-to-sender is modeled as a pure value transfer (no burn, no code deletion). | 🟡 Planned | | `test_bal_7002_clean_sweep` | Ensure BAL correctly tracks "clean sweep" where all withdrawal requests are dequeued in same block (requests ≤ MAX). Parameterized: (1) pubkey first 32 bytes zero / non-zero, (2) amount zero / non-zero | Alice sends transaction to `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS` with 1 withdrawal request. Validator pubkey has either first 32 bytes zero or non-zero. Amount is either zero or non-zero. Since 1 ≤ MAX_WITHDRAWAL_REQUESTS_PER_BLOCK, post-execution system call dequeues all requests ("clean sweep"), resetting head and tail to 0. | BAL **MUST** include Alice with `nonce_changes` at `block_access_index=1`. `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS` **MUST** have: `balance_changes` at `block_access_index=1` (receives fee), `storage_reads` for excess, head, and slot 5 (first 32 bytes of pubkey) if zero. At `block_access_index=1` (tx enqueue): `storage_changes` for count (0→1), tail (0→1), slot 4 (source address), slot 5 (first 32 bytes, **ONLY** if non-zero), slot 6. At `block_access_index=2` (post-exec dequeue): `storage_changes` for count (1→0), tail (1→0). Clean sweep invariant: when all requests dequeued, both head and tail reset to 0. | ✅ Completed | From 4c47daacfbe2e5ae95d79753b131acc904eceda7 Mon Sep 17 00:00:00 2001 From: spencer Date: Mon, 20 Apr 2026 17:07:02 +0200 Subject: [PATCH 030/186] feat(tests): prepare `test_scenarios` and `test_all_opcodes` for EIP-8037 (#2727) --- tests/frontier/opcodes/test_all_opcodes.py | 5 +++++ tests/frontier/scenarios/test_scenarios.py | 8 +++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/frontier/opcodes/test_all_opcodes.py b/tests/frontier/opcodes/test_all_opcodes.py index d2c7e39bc48..35c8be2953f 100644 --- a/tests/frontier/opcodes/test_all_opcodes.py +++ b/tests/frontier/opcodes/test_all_opcodes.py @@ -218,6 +218,11 @@ def constant_gas_opcodes(fork: Fork) -> Generator[ParameterSet, None, None]: # SSTORE - untestable due to 2300 gas stipend rule if opcode == Op.SSTORE: continue + # EIP-8037: CREATE/CREATE2 have a state gas component charged from + # the state reservoir that cannot be measured via the GAS opcode + # delta used by gas_test. Excluded to keep the test meaningful. + if fork.is_eip_enabled(8037) and opcode in (Op.CREATE, Op.CREATE2): + continue if opcode.gas_cost(fork) == 0: # zero constant gas opcodes - untestable continue diff --git a/tests/frontier/scenarios/test_scenarios.py b/tests/frontier/scenarios/test_scenarios.py index 4888c137043..f5cd856e97a 100644 --- a/tests/frontier/scenarios/test_scenarios.py +++ b/tests/frontier/scenarios/test_scenarios.py @@ -221,11 +221,9 @@ def test_scenarios( 1, hint=f"runner result {scenario.name}" ) - tx_max_gas = ( - 7_000_000 - if test_program.id == ProgramInvalidOpcode().id - else 1_000_000 - ) + tx_max_gas = 1_000_000 + if test_program.id == ProgramInvalidOpcode().id: + tx_max_gas = 10_000_000 if fork.is_eip_enabled(8037) else 7_000_000 if scenario.category == "double_call_combinations": tx_max_gas *= 2 From 97c13c14cce1ff6955ef3a9e6dd6b1c74e4ccc57 Mon Sep 17 00:00:00 2001 From: felipe Date: Mon, 20 Apr 2026 09:12:21 -0600 Subject: [PATCH 031/186] refactor: use uint32 instead of uint64 for block access index (#2730) --- src/ethereum/forks/amsterdam/block_access_lists.py | 4 ++-- tests/amsterdam/eip7928_block_level_access_lists/spec.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ethereum/forks/amsterdam/block_access_lists.py b/src/ethereum/forks/amsterdam/block_access_lists.py index 38cc698b10f..095a9832dc8 100644 --- a/src/ethereum/forks/amsterdam/block_access_lists.py +++ b/src/ethereum/forks/amsterdam/block_access_lists.py @@ -18,7 +18,7 @@ from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes32 from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U32, U64, U256, Uint from ethereum.crypto.hash import Hash32, keccak256 from ethereum.state import EMPTY_CODE_HASH, Account, Address, PreState @@ -46,7 +46,7 @@ Bytecode associated with an [`Account`](ref:ethereum.state.Account). """ -BlockAccessIndex: TypeAlias = U64 +BlockAccessIndex: TypeAlias = U32 """ Position within the set of all changes in a [`Block`]. diff --git a/tests/amsterdam/eip7928_block_level_access_lists/spec.py b/tests/amsterdam/eip7928_block_level_access_lists/spec.py index bbb875d8b54..2eac6b26b3b 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/spec.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/spec.py @@ -39,6 +39,6 @@ class Spec: HASH_SIZE: int = 32 # Hash size in bytes # Numeric type limits - MAX_TX_INDEX: int = 2**64 - 1 # uint64 max value + MAX_TX_INDEX: int = 2**32 - 1 # uint32 max value MAX_BALANCE: int = 2**128 - 1 # uint128 max value MAX_NONCE: int = 2**64 - 1 # uint64 max value From 5502bd80829eabc5e6c585bdfbc7f55c69901f26 Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 20 Apr 2026 18:30:19 +0200 Subject: [PATCH 032/186] refactor(spec-specs): add opcode gas constants (#2396) * refactor(spec-specs): add opcode gas constants * refactor(spec-specs): renamed GAS_BLOBHASH_OPCODE to GAS_BLOBHASH to more clearly differentiate between intermediate constants and existing ones * refactor(testing): add per-opcode gas constants to GasCosts Add 39 GAS_OPCODE_* fields to the GasCosts dataclass and update opcode_gas_map() in all forks to reference per-opcode fields instead of shared tier constants. * refactor: move post-frontier opcodes * refactor: added gas tiers for the test code * refactor: use gas module refs for opcode constants * refactor: correct GAS_OPCODE_DUP_N to GAS_OPCODE_DUP * refactor: correct GAS_OPCODE_SWAP_N to GAS_OPCODE_SWAP * fix: static checks * refactor: amsterdam conversion to encapsulate Gas Constants in class * refactor: frontier conversion to encapsulate Gas Constants in class * refactor: berlin conversion to encapsulate Gas Constants in class * refactor: byzantium conversion to encapsulate Gas Constants in class * refactor: cancun conversion to encapsulate Gas Constants in class * refactor: constantinople conversion to encapsulate Gas Constants in class * refactor: fix bad spelling of Belrin (Berlin) * refactor: homestead and dao conversion to encapsulate Gas Constants in class * refactor: tangerine_whistle conversion to encapsulate Gas Constants in class * refactor: spurious_dragon conversion to encapsulate Gas Constants in class * refactor: istanbul and muir glacier conversion to encapsulate Gas Constants in class * refactor: london, arrow glacier, and muir glacier conversion to encapsulate Gas Constants in class * refactor: paris conversion to encapsulate Gas Constants in class * refactor: shanghai conversion to encapsulate Gas Constants in class * refactor: prague conversion to encapsulate Gas Constants in class * refactor: osaka conversion to encapsulate Gas Constants in class * refactor: BPO1 conversion to encapsulate Gas Constants in class * refactor: BPO2 conversion to encapsulate Gas Constants in class * refactor: BPO3 conversion to encapsulate Gas Constants in class * refactor: BPO4 conversion to encapsulate Gas Constants in class * refactor: BPO5 conversion to encapsulate Gas Constants in class * refactor: GAS_OPCODE_PUSH_N -> GAS_OPCODE_PUSH * feat: add COINBASE opcode gas constant * refactor: align formatting of a docstring * fix: code review comments * refactor:GAS_BLOCK_HASH => GAS_OPCODE_BLOCKHASH * refactor:GAS_JUMPDEST => GAS_OPCODE_JUMPDEST * refactor:GAS_BLOBHASH => GAS_OPCODE_BLOBHASH * refactor:GAS_OPCODE => OPCODE * refactor: drop GAS_ prefix for opcode, precompile, and refund consts * refactor: remove GAS_ prefix from remaining non-module-level constants * refactor: group tier gas constants * refactor: remove GAS_ prefix in all test code + clean up * refactor: alt_bn128 now uses precompile gas constants in spec * reafactor(spec): reorganize gas.py, refactor two constant names * refactor: COPY=>OPCODE_COPY_PER_WORD * refactor: MEMORY=>MEMORY_PER_WORD * refactor: CREATE=>CREATE_BASE * refactor: EXPONENTIATION=>OPCODE_EXP_BASE, EXPONENTIATION_PER_BYTE OPCODE_EXP_PER_BYTE * refactor: KECCAK256=>OPCODE_KECCAK256_BASE, KECCAK256_PER_WORD=>OPCODE_KECCAK256_PER_WORD * refactor: KECCAK256=>OPCODE_KECCAK256_BASE, KECCAK256_PER_WORD=>OPCODE_KECCAK256_PER_WORD * refactor: SELF_DESTRUCT=>OPCODE_SELFDESTRUCT_BASE, SELF_DESTRUCT_NEW_ACCOUNT=>OPCODE_SELF_DESTRUCT_NEW_ACCOUNT * refactor: forgot KECCAK256 and LOG in test code * refactor: EXTERNAL=>OPCODE_EXTERNAL_BASE, BALANCE=>OPCODE_BALANCE * refactor: added _BASE suffix to CALLDATACOPY, CODECOPY, MLOAD, MSTORE, MSTORE8 * refactor: RETURN_DATA_COPY=>OPCODE_RETURNDATACOPY_PER_WORD * refactor: last few opcode refactors * fix: merge fixes * refactor: move transaction gas constatns with other gas constants for repricing mechanism. * refactor: add missing opcode gas constants and replace usage in functions * fix: cr comment misplacement * refactor: fix post-merge regressions * fix: merge fixes * fix tests --------- Co-authored-by: Sam Wilson --- .../plugins/execute/pre_alloc.py | 10 +- .../forks/forks/eips/amsterdam/eip_7928.py | 2 +- .../forks/forks/eips/berlin/eip_2930.py | 6 +- .../forks/forks/eips/byzantium/eip_196.py | 4 +- .../forks/forks/eips/byzantium/eip_197.py | 4 +- .../forks/forks/eips/byzantium/eip_211.py | 4 +- .../forks/forks/eips/cancun/eip_1153.py | 4 +- .../forks/forks/eips/cancun/eip_4844.py | 4 +- .../forks/forks/eips/cancun/eip_5656.py | 2 +- .../forks/forks/eips/cancun/eip_7516.py | 2 +- .../forks/eips/constantinople/eip_1014.py | 4 +- .../forks/eips/constantinople/eip_145.py | 6 +- .../forks/forks/eips/homestead/eip_2.py | 2 +- .../forks/forks/eips/istanbul/eip_1108.py | 8 +- .../forks/forks/eips/istanbul/eip_1344.py | 2 +- .../forks/forks/eips/istanbul/eip_152.py | 2 +- .../forks/forks/eips/istanbul/eip_1884.py | 2 +- .../forks/forks/eips/istanbul/eip_2028.py | 2 +- .../forks/forks/eips/london/eip_3198.py | 2 +- .../forks/forks/eips/osaka/eip_7939.py | 2 +- .../forks/forks/eips/osaka/eip_7951.py | 2 +- .../forks/forks/eips/prague/eip_2537.py | 16 +- .../forks/forks/eips/prague/eip_7623.py | 10 +- .../forks/forks/eips/prague/eip_7702.py | 8 +- .../forks/forks/eips/shanghai/eip_3855.py | 2 +- .../forks/forks/eips/shanghai/eip_3860.py | 4 +- .../forks/eips/spurious_dragon/eip_161.py | 4 +- .../execution_testing/forks/forks/forks.py | 375 ++++++++++-------- .../src/execution_testing/forks/gas_costs.py | 217 ++++++---- .../forks/tests/test_opcode_gas_costs.py | 193 +++++---- .../tools/utility/generators.py | 18 +- .../forks/amsterdam/block_access_lists.py | 6 +- src/ethereum/forks/amsterdam/fork.py | 27 +- src/ethereum/forks/amsterdam/transactions.py | 60 +-- .../forks/amsterdam/vm/eoa_delegation.py | 10 +- src/ethereum/forks/amsterdam/vm/gas.py | 257 ++++++++---- .../amsterdam/vm/instructions/arithmetic.py | 30 +- .../amsterdam/vm/instructions/bitwise.py | 23 +- .../forks/amsterdam/vm/instructions/block.py | 16 +- .../amsterdam/vm/instructions/comparison.py | 17 +- .../amsterdam/vm/instructions/control_flow.py | 15 +- .../amsterdam/vm/instructions/environment.py | 102 +++-- .../forks/amsterdam/vm/instructions/keccak.py | 10 +- .../forks/amsterdam/vm/instructions/log.py | 10 +- .../forks/amsterdam/vm/instructions/memory.py | 19 +- .../forks/amsterdam/vm/instructions/stack.py | 15 +- .../amsterdam/vm/instructions/storage.py | 41 +- .../forks/amsterdam/vm/instructions/system.py | 48 +-- .../forks/amsterdam/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/arrow_glacier/fork.py | 11 +- .../forks/arrow_glacier/transactions.py | 47 +-- src/ethereum/forks/arrow_glacier/vm/gas.py | 185 +++++++-- .../vm/instructions/arithmetic.py | 30 +- .../arrow_glacier/vm/instructions/bitwise.py | 21 +- .../arrow_glacier/vm/instructions/block.py | 16 +- .../vm/instructions/comparison.py | 17 +- .../vm/instructions/control_flow.py | 15 +- .../vm/instructions/environment.py | 71 ++-- .../arrow_glacier/vm/instructions/keccak.py | 10 +- .../arrow_glacier/vm/instructions/log.py | 10 +- .../arrow_glacier/vm/instructions/memory.py | 11 +- .../arrow_glacier/vm/instructions/stack.py | 13 +- .../arrow_glacier/vm/instructions/storage.py | 37 +- .../arrow_glacier/vm/instructions/system.py | 52 ++- .../forks/arrow_glacier/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 7 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/berlin/fork.py | 23 +- src/ethereum/forks/berlin/transactions.py | 47 +-- src/ethereum/forks/berlin/vm/gas.py | 186 ++++++--- .../berlin/vm/instructions/arithmetic.py | 30 +- .../forks/berlin/vm/instructions/bitwise.py | 21 +- .../forks/berlin/vm/instructions/block.py | 16 +- .../berlin/vm/instructions/comparison.py | 17 +- .../berlin/vm/instructions/control_flow.py | 15 +- .../berlin/vm/instructions/environment.py | 69 ++-- .../forks/berlin/vm/instructions/keccak.py | 10 +- .../forks/berlin/vm/instructions/log.py | 10 +- .../forks/berlin/vm/instructions/memory.py | 11 +- .../forks/berlin/vm/instructions/stack.py | 13 +- .../forks/berlin/vm/instructions/storage.py | 37 +- .../forks/berlin/vm/instructions/system.py | 49 +-- src/ethereum/forks/berlin/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../berlin/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/bpo1/fork.py | 27 +- src/ethereum/forks/bpo1/transactions.py | 58 +-- src/ethereum/forks/bpo1/vm/eoa_delegation.py | 10 +- src/ethereum/forks/bpo1/vm/gas.py | 252 ++++++++---- .../forks/bpo1/vm/instructions/arithmetic.py | 30 +- .../forks/bpo1/vm/instructions/bitwise.py | 23 +- .../forks/bpo1/vm/instructions/block.py | 16 +- .../forks/bpo1/vm/instructions/comparison.py | 17 +- .../bpo1/vm/instructions/control_flow.py | 15 +- .../forks/bpo1/vm/instructions/environment.py | 76 ++-- .../forks/bpo1/vm/instructions/keccak.py | 10 +- .../forks/bpo1/vm/instructions/log.py | 10 +- .../forks/bpo1/vm/instructions/memory.py | 19 +- .../forks/bpo1/vm/instructions/stack.py | 15 +- .../forks/bpo1/vm/instructions/storage.py | 41 +- .../forks/bpo1/vm/instructions/system.py | 49 +-- src/ethereum/forks/bpo1/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../bpo1/vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../bpo1/vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../bpo1/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/bpo2/fork.py | 27 +- src/ethereum/forks/bpo2/transactions.py | 58 +-- src/ethereum/forks/bpo2/vm/eoa_delegation.py | 10 +- src/ethereum/forks/bpo2/vm/gas.py | 252 ++++++++---- .../forks/bpo2/vm/instructions/arithmetic.py | 30 +- .../forks/bpo2/vm/instructions/bitwise.py | 20 +- .../forks/bpo2/vm/instructions/block.py | 16 +- .../forks/bpo2/vm/instructions/comparison.py | 14 +- .../bpo2/vm/instructions/control_flow.py | 12 +- .../forks/bpo2/vm/instructions/environment.py | 76 ++-- .../forks/bpo2/vm/instructions/keccak.py | 10 +- .../forks/bpo2/vm/instructions/log.py | 10 +- .../forks/bpo2/vm/instructions/memory.py | 19 +- .../forks/bpo2/vm/instructions/stack.py | 12 +- .../forks/bpo2/vm/instructions/storage.py | 44 +- .../forks/bpo2/vm/instructions/system.py | 48 +-- src/ethereum/forks/bpo2/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../bpo2/vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 13 +- .../bls12_381/bls12_381_g2.py | 13 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../bpo2/vm/precompiled_contracts/identity.py | 10 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 10 +- .../bpo2/vm/precompiled_contracts/sha256.py | 10 +- src/ethereum/forks/bpo3/fork.py | 27 +- src/ethereum/forks/bpo3/transactions.py | 58 +-- src/ethereum/forks/bpo3/vm/eoa_delegation.py | 10 +- src/ethereum/forks/bpo3/vm/gas.py | 252 ++++++++---- .../forks/bpo3/vm/instructions/arithmetic.py | 30 +- .../forks/bpo3/vm/instructions/bitwise.py | 20 +- .../forks/bpo3/vm/instructions/block.py | 16 +- .../forks/bpo3/vm/instructions/comparison.py | 14 +- .../bpo3/vm/instructions/control_flow.py | 12 +- .../forks/bpo3/vm/instructions/environment.py | 76 ++-- .../forks/bpo3/vm/instructions/keccak.py | 10 +- .../forks/bpo3/vm/instructions/log.py | 10 +- .../forks/bpo3/vm/instructions/memory.py | 19 +- .../forks/bpo3/vm/instructions/stack.py | 12 +- .../forks/bpo3/vm/instructions/storage.py | 44 +- .../forks/bpo3/vm/instructions/system.py | 48 +-- src/ethereum/forks/bpo3/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../bpo3/vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../bpo3/vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../bpo3/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/bpo4/fork.py | 27 +- src/ethereum/forks/bpo4/transactions.py | 58 +-- src/ethereum/forks/bpo4/vm/eoa_delegation.py | 10 +- src/ethereum/forks/bpo4/vm/gas.py | 252 ++++++++---- .../forks/bpo4/vm/instructions/arithmetic.py | 30 +- .../forks/bpo4/vm/instructions/bitwise.py | 23 +- .../forks/bpo4/vm/instructions/block.py | 16 +- .../forks/bpo4/vm/instructions/comparison.py | 17 +- .../bpo4/vm/instructions/control_flow.py | 15 +- .../forks/bpo4/vm/instructions/environment.py | 76 ++-- .../forks/bpo4/vm/instructions/keccak.py | 10 +- .../forks/bpo4/vm/instructions/log.py | 10 +- .../forks/bpo4/vm/instructions/memory.py | 19 +- .../forks/bpo4/vm/instructions/stack.py | 15 +- .../forks/bpo4/vm/instructions/storage.py | 41 +- .../forks/bpo4/vm/instructions/system.py | 49 +-- src/ethereum/forks/bpo4/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../bpo4/vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../bpo4/vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../bpo4/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/bpo5/fork.py | 27 +- src/ethereum/forks/bpo5/transactions.py | 58 +-- src/ethereum/forks/bpo5/vm/eoa_delegation.py | 10 +- src/ethereum/forks/bpo5/vm/gas.py | 252 ++++++++---- .../forks/bpo5/vm/instructions/arithmetic.py | 30 +- .../forks/bpo5/vm/instructions/bitwise.py | 23 +- .../forks/bpo5/vm/instructions/block.py | 16 +- .../forks/bpo5/vm/instructions/comparison.py | 17 +- .../bpo5/vm/instructions/control_flow.py | 15 +- .../forks/bpo5/vm/instructions/environment.py | 76 ++-- .../forks/bpo5/vm/instructions/keccak.py | 10 +- .../forks/bpo5/vm/instructions/log.py | 10 +- .../forks/bpo5/vm/instructions/memory.py | 19 +- .../forks/bpo5/vm/instructions/stack.py | 15 +- .../forks/bpo5/vm/instructions/storage.py | 41 +- .../forks/bpo5/vm/instructions/system.py | 49 +-- src/ethereum/forks/bpo5/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../bpo5/vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../bpo5/vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../bpo5/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/byzantium/fork.py | 11 +- src/ethereum/forks/byzantium/transactions.py | 33 +- src/ethereum/forks/byzantium/vm/gas.py | 178 +++++++-- .../byzantium/vm/instructions/arithmetic.py | 30 +- .../byzantium/vm/instructions/bitwise.py | 15 +- .../forks/byzantium/vm/instructions/block.py | 14 +- .../byzantium/vm/instructions/comparison.py | 17 +- .../byzantium/vm/instructions/control_flow.py | 15 +- .../byzantium/vm/instructions/environment.py | 59 +-- .../forks/byzantium/vm/instructions/keccak.py | 10 +- .../forks/byzantium/vm/instructions/log.py | 10 +- .../forks/byzantium/vm/instructions/memory.py | 11 +- .../forks/byzantium/vm/instructions/stack.py | 13 +- .../byzantium/vm/instructions/storage.py | 13 +- .../forks/byzantium/vm/instructions/system.py | 37 +- .../forks/byzantium/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 10 +- .../vm/precompiled_contracts/ripemd160.py | 10 +- .../vm/precompiled_contracts/sha256.py | 10 +- src/ethereum/forks/cancun/fork.py | 11 +- src/ethereum/forks/cancun/transactions.py | 47 +-- src/ethereum/forks/cancun/vm/gas.py | 217 +++++++--- .../cancun/vm/instructions/arithmetic.py | 30 +- .../forks/cancun/vm/instructions/bitwise.py | 21 +- .../forks/cancun/vm/instructions/block.py | 16 +- .../cancun/vm/instructions/comparison.py | 17 +- .../cancun/vm/instructions/control_flow.py | 15 +- .../cancun/vm/instructions/environment.py | 76 ++-- .../forks/cancun/vm/instructions/keccak.py | 10 +- .../forks/cancun/vm/instructions/log.py | 10 +- .../forks/cancun/vm/instructions/memory.py | 19 +- .../forks/cancun/vm/instructions/stack.py | 15 +- .../forks/cancun/vm/instructions/storage.py | 41 +- .../forks/cancun/vm/instructions/system.py | 48 +-- src/ethereum/forks/cancun/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 10 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 10 +- .../cancun/vm/precompiled_contracts/sha256.py | 10 +- src/ethereum/forks/constantinople/fork.py | 11 +- .../forks/constantinople/transactions.py | 33 +- src/ethereum/forks/constantinople/vm/gas.py | 183 ++++++--- .../vm/instructions/arithmetic.py | 30 +- .../constantinople/vm/instructions/bitwise.py | 21 +- .../constantinople/vm/instructions/block.py | 14 +- .../vm/instructions/comparison.py | 17 +- .../vm/instructions/control_flow.py | 15 +- .../vm/instructions/environment.py | 62 +-- .../constantinople/vm/instructions/keccak.py | 10 +- .../constantinople/vm/instructions/log.py | 10 +- .../constantinople/vm/instructions/memory.py | 11 +- .../constantinople/vm/instructions/stack.py | 13 +- .../constantinople/vm/instructions/storage.py | 13 +- .../constantinople/vm/instructions/system.py | 42 +- .../forks/constantinople/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/dao_fork/fork.py | 11 +- src/ethereum/forks/dao_fork/transactions.py | 33 +- src/ethereum/forks/dao_fork/vm/gas.py | 176 ++++++-- .../dao_fork/vm/instructions/arithmetic.py | 30 +- .../forks/dao_fork/vm/instructions/bitwise.py | 15 +- .../forks/dao_fork/vm/instructions/block.py | 14 +- .../dao_fork/vm/instructions/comparison.py | 17 +- .../dao_fork/vm/instructions/control_flow.py | 15 +- .../dao_fork/vm/instructions/environment.py | 47 ++- .../forks/dao_fork/vm/instructions/keccak.py | 10 +- .../forks/dao_fork/vm/instructions/log.py | 10 +- .../forks/dao_fork/vm/instructions/memory.py | 11 +- .../forks/dao_fork/vm/instructions/stack.py | 13 +- .../forks/dao_fork/vm/instructions/storage.py | 13 +- .../forks/dao_fork/vm/instructions/system.py | 15 +- src/ethereum/forks/dao_fork/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/frontier/fork.py | 23 +- src/ethereum/forks/frontier/transactions.py | 26 +- src/ethereum/forks/frontier/vm/gas.py | 174 ++++++-- .../frontier/vm/instructions/arithmetic.py | 30 +- .../forks/frontier/vm/instructions/bitwise.py | 15 +- .../forks/frontier/vm/instructions/block.py | 14 +- .../frontier/vm/instructions/comparison.py | 17 +- .../frontier/vm/instructions/control_flow.py | 15 +- .../frontier/vm/instructions/environment.py | 47 ++- .../forks/frontier/vm/instructions/keccak.py | 10 +- .../forks/frontier/vm/instructions/log.py | 10 +- .../forks/frontier/vm/instructions/memory.py | 11 +- .../forks/frontier/vm/instructions/stack.py | 13 +- .../forks/frontier/vm/instructions/storage.py | 13 +- .../forks/frontier/vm/instructions/system.py | 12 +- src/ethereum/forks/frontier/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/gray_glacier/fork.py | 11 +- .../forks/gray_glacier/transactions.py | 47 +-- src/ethereum/forks/gray_glacier/vm/gas.py | 185 +++++++-- .../vm/instructions/arithmetic.py | 30 +- .../gray_glacier/vm/instructions/bitwise.py | 21 +- .../gray_glacier/vm/instructions/block.py | 16 +- .../vm/instructions/comparison.py | 17 +- .../vm/instructions/control_flow.py | 15 +- .../vm/instructions/environment.py | 71 ++-- .../gray_glacier/vm/instructions/keccak.py | 10 +- .../forks/gray_glacier/vm/instructions/log.py | 10 +- .../gray_glacier/vm/instructions/memory.py | 11 +- .../gray_glacier/vm/instructions/stack.py | 13 +- .../gray_glacier/vm/instructions/storage.py | 37 +- .../gray_glacier/vm/instructions/system.py | 46 +-- .../forks/gray_glacier/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/homestead/fork.py | 11 +- src/ethereum/forks/homestead/transactions.py | 33 +- src/ethereum/forks/homestead/vm/gas.py | 176 ++++++-- .../homestead/vm/instructions/arithmetic.py | 30 +- .../homestead/vm/instructions/bitwise.py | 15 +- .../forks/homestead/vm/instructions/block.py | 14 +- .../homestead/vm/instructions/comparison.py | 17 +- .../homestead/vm/instructions/control_flow.py | 15 +- .../homestead/vm/instructions/environment.py | 47 ++- .../forks/homestead/vm/instructions/keccak.py | 10 +- .../forks/homestead/vm/instructions/log.py | 10 +- .../forks/homestead/vm/instructions/memory.py | 11 +- .../forks/homestead/vm/instructions/stack.py | 13 +- .../homestead/vm/instructions/storage.py | 13 +- .../forks/homestead/vm/instructions/system.py | 15 +- .../forks/homestead/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/istanbul/fork.py | 23 +- src/ethereum/forks/istanbul/transactions.py | 33 +- src/ethereum/forks/istanbul/vm/gas.py | 188 ++++++--- .../istanbul/vm/instructions/arithmetic.py | 30 +- .../forks/istanbul/vm/instructions/bitwise.py | 21 +- .../forks/istanbul/vm/instructions/block.py | 16 +- .../istanbul/vm/instructions/comparison.py | 17 +- .../istanbul/vm/instructions/control_flow.py | 15 +- .../istanbul/vm/instructions/environment.py | 65 +-- .../forks/istanbul/vm/instructions/keccak.py | 10 +- .../forks/istanbul/vm/instructions/log.py | 10 +- .../forks/istanbul/vm/instructions/memory.py | 11 +- .../forks/istanbul/vm/instructions/stack.py | 13 +- .../forks/istanbul/vm/instructions/storage.py | 28 +- .../forks/istanbul/vm/instructions/system.py | 42 +- src/ethereum/forks/istanbul/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/london/fork.py | 11 +- src/ethereum/forks/london/transactions.py | 47 +-- src/ethereum/forks/london/vm/gas.py | 185 +++++++-- .../london/vm/instructions/arithmetic.py | 30 +- .../forks/london/vm/instructions/bitwise.py | 21 +- .../forks/london/vm/instructions/block.py | 16 +- .../london/vm/instructions/comparison.py | 17 +- .../london/vm/instructions/control_flow.py | 15 +- .../london/vm/instructions/environment.py | 71 ++-- .../forks/london/vm/instructions/keccak.py | 10 +- .../forks/london/vm/instructions/log.py | 10 +- .../forks/london/vm/instructions/memory.py | 11 +- .../forks/london/vm/instructions/stack.py | 13 +- .../forks/london/vm/instructions/storage.py | 37 +- .../forks/london/vm/instructions/system.py | 46 +-- src/ethereum/forks/london/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../london/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/muir_glacier/fork.py | 23 +- .../forks/muir_glacier/transactions.py | 33 +- src/ethereum/forks/muir_glacier/vm/gas.py | 188 ++++++--- .../vm/instructions/arithmetic.py | 30 +- .../muir_glacier/vm/instructions/bitwise.py | 21 +- .../muir_glacier/vm/instructions/block.py | 16 +- .../vm/instructions/comparison.py | 17 +- .../vm/instructions/control_flow.py | 15 +- .../vm/instructions/environment.py | 65 +-- .../muir_glacier/vm/instructions/keccak.py | 10 +- .../forks/muir_glacier/vm/instructions/log.py | 10 +- .../muir_glacier/vm/instructions/memory.py | 11 +- .../muir_glacier/vm/instructions/stack.py | 13 +- .../muir_glacier/vm/instructions/storage.py | 28 +- .../muir_glacier/vm/instructions/system.py | 42 +- .../forks/muir_glacier/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/osaka/fork.py | 27 +- src/ethereum/forks/osaka/transactions.py | 58 +-- src/ethereum/forks/osaka/vm/eoa_delegation.py | 10 +- src/ethereum/forks/osaka/vm/gas.py | 252 ++++++++---- .../forks/osaka/vm/instructions/arithmetic.py | 30 +- .../forks/osaka/vm/instructions/bitwise.py | 23 +- .../forks/osaka/vm/instructions/block.py | 16 +- .../forks/osaka/vm/instructions/comparison.py | 17 +- .../osaka/vm/instructions/control_flow.py | 15 +- .../osaka/vm/instructions/environment.py | 76 ++-- .../forks/osaka/vm/instructions/keccak.py | 10 +- .../forks/osaka/vm/instructions/log.py | 10 +- .../forks/osaka/vm/instructions/memory.py | 19 +- .../forks/osaka/vm/instructions/stack.py | 15 +- .../forks/osaka/vm/instructions/storage.py | 46 +-- .../forks/osaka/vm/instructions/system.py | 61 +-- src/ethereum/forks/osaka/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../osaka/vm/precompiled_contracts/blake2f.py | 7 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/p256verify.py | 4 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../osaka/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/paris/fork.py | 11 +- src/ethereum/forks/paris/transactions.py | 47 +-- src/ethereum/forks/paris/vm/gas.py | 185 +++++++-- .../forks/paris/vm/instructions/arithmetic.py | 30 +- .../forks/paris/vm/instructions/bitwise.py | 21 +- .../forks/paris/vm/instructions/block.py | 16 +- .../forks/paris/vm/instructions/comparison.py | 17 +- .../paris/vm/instructions/control_flow.py | 15 +- .../paris/vm/instructions/environment.py | 71 ++-- .../forks/paris/vm/instructions/keccak.py | 10 +- .../forks/paris/vm/instructions/log.py | 10 +- .../forks/paris/vm/instructions/memory.py | 11 +- .../forks/paris/vm/instructions/stack.py | 13 +- .../forks/paris/vm/instructions/storage.py | 37 +- .../forks/paris/vm/instructions/system.py | 46 +-- src/ethereum/forks/paris/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../paris/vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../paris/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/prague/fork.py | 23 +- src/ethereum/forks/prague/transactions.py | 58 +-- .../forks/prague/vm/eoa_delegation.py | 10 +- src/ethereum/forks/prague/vm/gas.py | 233 ++++++++--- .../prague/vm/instructions/arithmetic.py | 30 +- .../forks/prague/vm/instructions/bitwise.py | 21 +- .../forks/prague/vm/instructions/block.py | 16 +- .../prague/vm/instructions/comparison.py | 17 +- .../prague/vm/instructions/control_flow.py | 15 +- .../prague/vm/instructions/environment.py | 76 ++-- .../forks/prague/vm/instructions/keccak.py | 10 +- .../forks/prague/vm/instructions/log.py | 10 +- .../forks/prague/vm/instructions/memory.py | 19 +- .../forks/prague/vm/instructions/stack.py | 15 +- .../forks/prague/vm/instructions/storage.py | 41 +- .../forks/prague/vm/instructions/system.py | 48 +-- src/ethereum/forks/prague/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../bls12_381/bls12_381_g1.py | 10 +- .../bls12_381/bls12_381_g2.py | 10 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../precompiled_contracts/point_evaluation.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../prague/vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/shanghai/fork.py | 11 +- src/ethereum/forks/shanghai/transactions.py | 47 +-- src/ethereum/forks/shanghai/vm/gas.py | 190 ++++++--- .../shanghai/vm/instructions/arithmetic.py | 33 +- .../forks/shanghai/vm/instructions/bitwise.py | 18 +- .../forks/shanghai/vm/instructions/block.py | 16 +- .../shanghai/vm/instructions/comparison.py | 14 +- .../shanghai/vm/instructions/control_flow.py | 12 +- .../shanghai/vm/instructions/environment.py | 71 ++-- .../forks/shanghai/vm/instructions/keccak.py | 10 +- .../forks/shanghai/vm/instructions/log.py | 10 +- .../forks/shanghai/vm/instructions/memory.py | 11 +- .../forks/shanghai/vm/instructions/stack.py | 12 +- .../forks/shanghai/vm/instructions/storage.py | 40 +- .../forks/shanghai/vm/instructions/system.py | 48 +-- src/ethereum/forks/shanghai/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 12 +- .../vm/precompiled_contracts/blake2f.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 10 +- .../vm/precompiled_contracts/ripemd160.py | 10 +- .../vm/precompiled_contracts/sha256.py | 10 +- src/ethereum/forks/spurious_dragon/fork.py | 11 +- .../forks/spurious_dragon/transactions.py | 33 +- src/ethereum/forks/spurious_dragon/vm/gas.py | 170 ++++++-- .../vm/instructions/arithmetic.py | 30 +- .../vm/instructions/bitwise.py | 15 +- .../spurious_dragon/vm/instructions/block.py | 14 +- .../vm/instructions/comparison.py | 17 +- .../vm/instructions/control_flow.py | 15 +- .../vm/instructions/environment.py | 47 ++- .../spurious_dragon/vm/instructions/keccak.py | 10 +- .../spurious_dragon/vm/instructions/log.py | 10 +- .../spurious_dragon/vm/instructions/memory.py | 11 +- .../spurious_dragon/vm/instructions/stack.py | 13 +- .../vm/instructions/storage.py | 13 +- .../spurious_dragon/vm/instructions/system.py | 35 +- .../forks/spurious_dragon/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum/forks/tangerine_whistle/fork.py | 11 +- .../forks/tangerine_whistle/transactions.py | 33 +- .../forks/tangerine_whistle/vm/gas.py | 170 ++++++-- .../vm/instructions/arithmetic.py | 30 +- .../vm/instructions/bitwise.py | 15 +- .../vm/instructions/block.py | 14 +- .../vm/instructions/comparison.py | 17 +- .../vm/instructions/control_flow.py | 15 +- .../vm/instructions/environment.py | 47 ++- .../vm/instructions/keccak.py | 10 +- .../tangerine_whistle/vm/instructions/log.py | 10 +- .../vm/instructions/memory.py | 11 +- .../vm/instructions/stack.py | 13 +- .../vm/instructions/storage.py | 13 +- .../vm/instructions/system.py | 35 +- .../forks/tangerine_whistle/vm/interpreter.py | 4 +- .../vm/precompiled_contracts/ecrecover.py | 4 +- .../vm/precompiled_contracts/identity.py | 7 +- .../vm/precompiled_contracts/ripemd160.py | 7 +- .../vm/precompiled_contracts/sha256.py | 7 +- src/ethereum_spec_tools/new_fork/builder.py | 14 +- .../test_block_access_lists.py | 4 +- .../test_block_access_lists_opcodes.py | 8 +- .../compute/instruction/test_system.py | 2 +- .../compute/precompile/test_alt_bn128.py | 16 +- .../compute/precompile/test_blake2f.py | 4 +- .../compute/precompile/test_bls12_381.py | 10 +- .../compute/precompile/test_identity.py | 8 +- .../compute/precompile/test_p256verify.py | 2 +- .../precompile/test_point_evaluation.py | 8 +- .../compute/precompile/test_ripemd160.py | 8 +- .../compute/precompile/test_sha256.py | 8 +- .../scenario/test_transaction_types.py | 18 +- .../stateful/bloatnet/test_multi_opcode.py | 8 +- .../eip2929_gas_cost_increases/test_create.py | 4 +- tests/byzantium/eip196_ec_add_mul/conftest.py | 4 +- tests/byzantium/eip196_ec_add_mul/test_gas.py | 4 +- tests/byzantium/eip197_ec_pairing/conftest.py | 4 +- tests/byzantium/eip197_ec_pairing/test_gas.py | 4 +- .../test_point_evaluation_precompile.py | 10 +- .../test_point_evaluation_precompile_gas.py | 6 +- tests/frontier/opcodes/test_call.py | 10 +- .../test_call_and_callcode_gas_calculation.py | 8 +- tests/json_loader/test_tools_new_fork.py | 2 +- .../test_tx_gas_limit.py | 4 +- .../conftest.py | 2 +- .../test_p256verify.py | 6 +- .../test_p256verify_before_fork.py | 2 +- .../eip2537_bls_12_381_precompiles/spec.py | 16 +- .../eip7623_increase_calldata_cost/spec.py | 4 +- tests/prague/eip7702_set_code_tx/spec.py | 2 +- tests/prague/eip7702_set_code_tx/test_gas.py | 4 +- .../eip7702_set_code_tx/test_set_code_txs.py | 15 +- .../test_eip150_selfdestruct.py | 38 +- 622 files changed, 8822 insertions(+), 7014 deletions(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py index 65d9e100ca6..306b6c143fd 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py @@ -348,10 +348,8 @@ def _deterministic_deploy_contract( raise ValueError( f"initcode too large {len(initcode)} > {max_initcode_size}" ) - deploy_gas_limit = gas_costs.GAS_TX_BASE + gas_costs.GAS_TX_CREATE - deploy_gas_limit += ( - len(deploy_code) * gas_costs.GAS_CODE_DEPOSIT_PER_BYTE - ) + deploy_gas_limit = gas_costs.TX_BASE + gas_costs.TX_CREATE + deploy_gas_limit += len(deploy_code) * gas_costs.CODE_DEPOSIT_PER_BYTE deploy_gas_limit += memory_expansion_gas_calculator( new_bytes=len(initcode) ) @@ -445,7 +443,7 @@ def _deploy_contract( initcode_prefix = Bytecode() - deploy_gas_limit = gas_costs.GAS_TX_BASE + gas_costs.GAS_TX_CREATE + deploy_gas_limit = gas_costs.TX_BASE + gas_costs.TX_CREATE if len(storage.root) > 0: initcode_prefix += sum( @@ -462,7 +460,7 @@ def _deploy_contract( if len(code) > max_code_size: raise ValueError(f"code too large: {len(code)} > {max_code_size}") - deploy_gas_limit += len(code) * gas_costs.GAS_CODE_DEPOSIT_PER_BYTE + deploy_gas_limit += len(code) * gas_costs.CODE_DEPOSIT_PER_BYTE prepared_initcode = Initcode( deploy_code=code, initcode_prefix=initcode_prefix diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py index 5e46e0ccb95..d4b1b9a6e17 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py @@ -36,7 +36,7 @@ def gas_costs(cls) -> GasCosts: """ return replace( super(EIP7928, cls).gas_costs(), - GAS_BLOCK_ACCESS_LIST_ITEM=2000, + BLOCK_ACCESS_LIST_ITEM=2000, ) @classmethod diff --git a/packages/testing/src/execution_testing/forks/forks/eips/berlin/eip_2930.py b/packages/testing/src/execution_testing/forks/forks/eips/berlin/eip_2930.py index 7544ae1580a..7dede0ace15 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/berlin/eip_2930.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/berlin/eip_2930.py @@ -55,11 +55,9 @@ def fn( ) if access_list is not None: for access in access_list: - intrinsic_cost += gas_costs.GAS_TX_ACCESS_LIST_ADDRESS + intrinsic_cost += gas_costs.TX_ACCESS_LIST_ADDRESS for _ in access.storage_keys: - intrinsic_cost += ( - gas_costs.GAS_TX_ACCESS_LIST_STORAGE_KEY - ) + intrinsic_cost += gas_costs.TX_ACCESS_LIST_STORAGE_KEY return intrinsic_cost return fn diff --git a/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_196.py b/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_196.py index 2d7178efdca..343e8ba9947 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_196.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_196.py @@ -30,6 +30,6 @@ def gas_costs(cls) -> GasCosts: """Set gas costs for BN254 addition and multiplication.""" return replace( super(EIP196, cls).gas_costs(), - GAS_PRECOMPILE_ECADD=500, - GAS_PRECOMPILE_ECMUL=40_000, + PRECOMPILE_ECADD=500, + PRECOMPILE_ECMUL=40_000, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_197.py b/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_197.py index 55a4e60c34c..4d18dc85b3e 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_197.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_197.py @@ -29,6 +29,6 @@ def gas_costs(cls) -> GasCosts: """Set gas costs for BN254 pairing check.""" return replace( super(EIP197, cls).gas_costs(), - GAS_PRECOMPILE_ECPAIRING_BASE=100_000, - GAS_PRECOMPILE_ECPAIRING_PER_POINT=80_000, + PRECOMPILE_ECPAIRING_BASE=100_000, + PRECOMPILE_ECPAIRING_PER_POINT=80_000, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_211.py b/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_211.py index 51b958f741e..d8e053c26ef 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_211.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/byzantium/eip_211.py @@ -24,9 +24,9 @@ def opcode_gas_map( base_map = super(EIP211, cls).opcode_gas_map() return { **base_map, - Opcodes.RETURNDATASIZE: gas_costs.GAS_BASE, + Opcodes.RETURNDATASIZE: gas_costs.BASE, Opcodes.RETURNDATACOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy(gas_costs.VERY_LOW, gas_costs), memory_expansion_calculator, ), } diff --git a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_1153.py b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_1153.py index 0481a794842..c98a22bc3f4 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_1153.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_1153.py @@ -26,8 +26,8 @@ def opcode_gas_map( base_map = super(EIP1153, cls).opcode_gas_map() return { **base_map, - Opcodes.TLOAD: gas_costs.GAS_WARM_SLOAD, - Opcodes.TSTORE: gas_costs.GAS_WARM_SLOAD, + Opcodes.TLOAD: gas_costs.WARM_SLOAD, + Opcodes.TSTORE: gas_costs.WARM_SLOAD, } @classmethod diff --git a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_4844.py b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_4844.py index ac6733817e6..9774befab96 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_4844.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_4844.py @@ -189,7 +189,7 @@ def gas_costs(cls) -> GasCosts: """On Cancun, the point evaluation precompile gas cost is set.""" return replace( super(EIP4844, cls).gas_costs(), - GAS_PRECOMPILE_POINT_EVALUATION=50_000, + PRECOMPILE_POINT_EVALUATION=50_000, ) @classmethod @@ -208,7 +208,7 @@ def opcode_gas_map( base_map = super(EIP4844, cls).opcode_gas_map() # Add Cancun-specific opcodes - return {**base_map, Opcodes.BLOBHASH: gas_costs.GAS_VERY_LOW} + return {**base_map, Opcodes.BLOBHASH: gas_costs.VERY_LOW} @classmethod def valid_opcodes(cls) -> List[Opcodes]: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_5656.py b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_5656.py index a3d0190c6f3..3365f3c2296 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_5656.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_5656.py @@ -27,7 +27,7 @@ def opcode_gas_map( return { **base_map, Opcodes.MCOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy(gas_costs.VERY_LOW, gas_costs), memory_expansion_calculator, ), } diff --git a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_7516.py b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_7516.py index 87fde9fc426..194e3e27852 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_7516.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/cancun/eip_7516.py @@ -29,7 +29,7 @@ def opcode_gas_map( # Add Cancun-specific opcodes return { **base_map, - Opcodes.BLOBBASEFEE: gas_costs.GAS_BASE, + Opcodes.BLOBBASEFEE: gas_costs.BASE, } @classmethod diff --git a/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_1014.py b/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_1014.py index 5dacb5b54cd..01201e0559a 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_1014.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_1014.py @@ -26,9 +26,9 @@ def _calculate_create2_gas( init_code_size = metadata["init_code_size"] init_code_words = (init_code_size + 31) // 32 - hash_gas = gas_costs.GAS_KECCAK256_PER_WORD * init_code_words + hash_gas = gas_costs.OPCODE_KECCACK256_PER_WORD * init_code_words - return gas_costs.GAS_CREATE + hash_gas + return gas_costs.OPCODE_CREATE_BASE + hash_gas @classmethod def create_opcodes(cls) -> List[Opcodes]: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_145.py b/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_145.py index 2ca9ca345c6..6a1b1cd854a 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_145.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/constantinople/eip_145.py @@ -25,9 +25,9 @@ def opcode_gas_map( base_map = super(EIP145, cls).opcode_gas_map() return { **base_map, - Opcodes.SHL: gas_costs.GAS_VERY_LOW, - Opcodes.SHR: gas_costs.GAS_VERY_LOW, - Opcodes.SAR: gas_costs.GAS_VERY_LOW, + Opcodes.SHL: gas_costs.VERY_LOW, + Opcodes.SHR: gas_costs.VERY_LOW, + Opcodes.SAR: gas_costs.VERY_LOW, } @classmethod diff --git a/packages/testing/src/execution_testing/forks/forks/eips/homestead/eip_2.py b/packages/testing/src/execution_testing/forks/forks/eips/homestead/eip_2.py index 29007094e3d..811094f0a98 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/homestead/eip_2.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/homestead/eip_2.py @@ -43,7 +43,7 @@ def fn( authorization_list_or_count=authorization_list_or_count, ) if contract_creation: - intrinsic_cost += gas_costs.GAS_TX_CREATE + intrinsic_cost += gas_costs.TX_CREATE return intrinsic_cost return fn diff --git a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1108.py b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1108.py index 6d45947dc1f..512a2c2c44f 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1108.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1108.py @@ -18,8 +18,8 @@ def gas_costs(cls) -> GasCosts: """Reduce BN254 precompile gas costs.""" return replace( super(EIP1108, cls).gas_costs(), - GAS_PRECOMPILE_ECADD=150, - GAS_PRECOMPILE_ECMUL=6000, - GAS_PRECOMPILE_ECPAIRING_BASE=45_000, - GAS_PRECOMPILE_ECPAIRING_PER_POINT=34_000, + PRECOMPILE_ECADD=150, + PRECOMPILE_ECMUL=6000, + PRECOMPILE_ECPAIRING_BASE=45_000, + PRECOMPILE_ECPAIRING_PER_POINT=34_000, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1344.py b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1344.py index 89a7272f497..207aae46994 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1344.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1344.py @@ -24,7 +24,7 @@ def opcode_gas_map( """Add CHAINID opcode gas cost.""" gas_costs = cls.gas_costs() base_map = super(EIP1344, cls).opcode_gas_map() - return {**base_map, Opcodes.CHAINID: gas_costs.GAS_BASE} + return {**base_map, Opcodes.CHAINID: gas_costs.BASE} @classmethod def valid_opcodes(cls) -> List[Opcodes]: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_152.py b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_152.py index 9979cc4076d..e8451f88fdf 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_152.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_152.py @@ -28,5 +28,5 @@ def gas_costs(cls) -> GasCosts: """Set BLAKE2F per-round gas cost.""" return replace( super(EIP152, cls).gas_costs(), - GAS_PRECOMPILE_BLAKE2F_PER_ROUND=1, + PRECOMPILE_BLAKE2F_PER_ROUND=1, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1884.py b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1884.py index f434b90a56e..b79a3c1e4fa 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1884.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_1884.py @@ -23,7 +23,7 @@ def opcode_gas_map( """Add SELFBALANCE opcode gas cost.""" gas_costs = cls.gas_costs() base_map = super(EIP1884, cls).opcode_gas_map() - return {**base_map, Opcodes.SELFBALANCE: gas_costs.GAS_LOW} + return {**base_map, Opcodes.SELFBALANCE: gas_costs.LOW} @classmethod def valid_opcodes(cls) -> List[Opcodes]: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_2028.py b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_2028.py index 6dbb2446b43..ca6fed863ed 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_2028.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/istanbul/eip_2028.py @@ -20,5 +20,5 @@ def gas_costs(cls) -> GasCosts: """Reduce non-zero calldata byte gas cost to 16.""" return replace( super(EIP2028, cls).gas_costs(), - GAS_TX_DATA_PER_NON_ZERO=16, + TX_DATA_PER_NON_ZERO=16, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/london/eip_3198.py b/packages/testing/src/execution_testing/forks/forks/eips/london/eip_3198.py index 5be886c92f5..df8e3f1373d 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/london/eip_3198.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/london/eip_3198.py @@ -24,7 +24,7 @@ def opcode_gas_map( """Add BASEFEE opcode gas cost.""" gas_costs = cls.gas_costs() base_map = super(EIP3198, cls).opcode_gas_map() - return {**base_map, Opcodes.BASEFEE: gas_costs.GAS_BASE} + return {**base_map, Opcodes.BASEFEE: gas_costs.BASE} @classmethod def valid_opcodes(cls) -> List[Opcodes]: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7939.py b/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7939.py index 88b5a23e783..c53935a4d4d 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7939.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7939.py @@ -25,7 +25,7 @@ def opcode_gas_map( base_map = super(EIP7939, cls).opcode_gas_map() return { **base_map, - Opcodes.CLZ: gas_costs.GAS_LOW, + Opcodes.CLZ: gas_costs.LOW, } @classmethod diff --git a/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7951.py b/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7951.py index 1729515f158..e80674d2725 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7951.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/osaka/eip_7951.py @@ -35,5 +35,5 @@ def gas_costs(cls) -> GasCosts: """Set the P256VERIFY precompile gas cost.""" return replace( super(EIP7951, cls).gas_costs(), - GAS_PRECOMPILE_P256VERIFY=6_900, + PRECOMPILE_P256VERIFY=6_900, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_2537.py b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_2537.py index 92702858ed6..d0cb4edc70b 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_2537.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_2537.py @@ -47,12 +47,12 @@ def gas_costs(cls) -> GasCosts: """Add gas costs for BLS12-381 precompiles.""" return replace( super(EIP2537, cls).gas_costs(), - GAS_PRECOMPILE_BLS_G1ADD=375, - GAS_PRECOMPILE_BLS_G1MUL=12_000, - GAS_PRECOMPILE_BLS_G1MAP=5_500, - GAS_PRECOMPILE_BLS_G2ADD=600, - GAS_PRECOMPILE_BLS_G2MUL=22_500, - GAS_PRECOMPILE_BLS_G2MAP=23_800, - GAS_PRECOMPILE_BLS_PAIRING_BASE=37_700, - GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR=32_600, + PRECOMPILE_BLS_G1ADD=375, + PRECOMPILE_BLS_G1MUL=12_000, + PRECOMPILE_BLS_G1MAP=5_500, + PRECOMPILE_BLS_G2ADD=600, + PRECOMPILE_BLS_G2MUL=22_500, + PRECOMPILE_BLS_G2MAP=23_800, + PRECOMPILE_BLS_PAIRING_BASE=37_700, + PRECOMPILE_BLS_PAIRING_PER_PAIR=32_600, ) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py index 894ac85b433..1a073f11a92 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py @@ -29,8 +29,8 @@ def gas_costs(cls) -> GasCosts: """Add standard and floor token costs for calldata.""" return replace( super(EIP7623, cls).gas_costs(), - GAS_TX_DATA_TOKEN_STANDARD=4, - GAS_TX_DATA_TOKEN_FLOOR=10, + TX_DATA_TOKEN_STANDARD=4, + TX_DATA_TOKEN_FLOOR=10, ) @classmethod @@ -47,8 +47,8 @@ def fn(*, data: BytesConvertible, floor: bool = False) -> int: num_non_zeros = len(raw) - num_zeros tokens = num_zeros + num_non_zeros * 4 if floor: - return tokens * gas_costs.GAS_TX_DATA_TOKEN_FLOOR - return tokens * gas_costs.GAS_TX_DATA_TOKEN_STANDARD + return tokens * gas_costs.TX_DATA_TOKEN_FLOOR + return tokens * gas_costs.TX_DATA_TOKEN_STANDARD return fn @@ -65,7 +65,7 @@ def transaction_data_floor_cost_calculator( def fn(*, data: BytesConvertible) -> int: return ( calldata_gas_calculator(data=data, floor=True) - + gas_costs.GAS_TX_BASE + + gas_costs.TX_BASE ) return fn diff --git a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py index 1904b135f6a..d19fd6009c1 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py @@ -33,7 +33,7 @@ def gas_costs(cls) -> GasCosts: """Add gas costs for authorization operations.""" return replace( super(EIP7702, cls).gas_costs(), - GAS_AUTH_PER_EMPTY_ACCOUNT=25_000, + AUTH_PER_EMPTY_ACCOUNT=25_000, REFUND_AUTH_PER_EXISTING_ACCOUNT=12_500, ) @@ -50,9 +50,9 @@ def _calculate_call_gas( if metadata["delegated_address"] or metadata["delegated_address_warm"]: if metadata["delegated_address_warm"]: - base_cost += gas_costs.GAS_WARM_ACCESS + base_cost += gas_costs.WARM_ACCESS else: - base_cost += gas_costs.GAS_COLD_ACCOUNT_ACCESS + base_cost += gas_costs.COLD_ACCOUNT_ACCESS return base_cost @@ -89,7 +89,7 @@ def fn( ) intrinsic_cost += ( authorization_list_or_count - * gas_costs.GAS_AUTH_PER_EMPTY_ACCOUNT + * gas_costs.AUTH_PER_EMPTY_ACCOUNT ) return intrinsic_cost diff --git a/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3855.py b/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3855.py index cf734cb3f3d..fd6586dfa71 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3855.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3855.py @@ -26,7 +26,7 @@ def opcode_gas_map( base_map = super(EIP3855, cls).opcode_gas_map() return { **base_map, - Opcodes.PUSH0: gas_costs.GAS_BASE, + Opcodes.PUSH0: gas_costs.BASE, } @classmethod diff --git a/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3860.py b/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3860.py index c5e52708bce..128c162cc9d 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3860.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_3860.py @@ -36,7 +36,7 @@ def _calculate_create_gas( init_code_size = metadata["init_code_size"] init_code_words = (init_code_size + 31) // 32 - init_code_gas = gas_costs.GAS_CODE_INIT_PER_WORD * init_code_words + init_code_gas = gas_costs.CODE_INIT_PER_WORD * init_code_words return base_cost + init_code_gas @@ -55,6 +55,6 @@ def _calculate_create2_gas( init_code_size = metadata["init_code_size"] init_code_words = (init_code_size + 31) // 32 - init_code_gas = gas_costs.GAS_CODE_INIT_PER_WORD * init_code_words + init_code_gas = gas_costs.CODE_INIT_PER_WORD * init_code_words return base_cost + init_code_gas diff --git a/packages/testing/src/execution_testing/forks/forks/eips/spurious_dragon/eip_161.py b/packages/testing/src/execution_testing/forks/forks/eips/spurious_dragon/eip_161.py index 6a5b61d919c..2806276fb3e 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/spurious_dragon/eip_161.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/spurious_dragon/eip_161.py @@ -26,9 +26,9 @@ def _calculate_call_gas( metadata = opcode.metadata if "value_transfer" in metadata: if metadata["value_transfer"]: - base_cost += gas_costs.GAS_CALL_VALUE + base_cost += gas_costs.CALL_VALUE if metadata["account_new"]: - base_cost += gas_costs.GAS_NEW_ACCOUNT + base_cost += gas_costs.NEW_ACCOUNT elif metadata["account_new"]: raise ValueError("Account new requires value transfer") diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 7452d952d98..d1d6cd06143 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -32,7 +32,7 @@ TransactionDataFloorCostCalculator, TransactionIntrinsicCostCalculator, ) -from ..gas_costs import GasCosts +from ..gas_costs import BASE, HIGH, LOW, MID, VERY_LOW, GasCosts from . import eips from .eips.amsterdam import AmsterdamEIPs from .helpers import ceiling_division @@ -98,73 +98,118 @@ def gas_costs(cls) -> GasCosts: Return dataclass with the defined gas costs constants for genesis. """ return GasCosts( - GAS_JUMPDEST=1, - GAS_BASE=2, - GAS_VERY_LOW=3, - GAS_LOW=5, - GAS_MID=8, - GAS_HIGH=10, - GAS_WARM_ACCESS=100, - GAS_COLD_ACCOUNT_ACCESS=2_600, - GAS_TX_ACCESS_LIST_ADDRESS=2_400, - GAS_TX_ACCESS_LIST_STORAGE_KEY=1_900, - GAS_WARM_SLOAD=100, - GAS_COLD_STORAGE_ACCESS=2_100, - GAS_STORAGE_SET=20_000, - GAS_COLD_STORAGE_WRITE=5_000, - GAS_STORAGE_RESET=2_900, + # Tiers + BASE=BASE, + VERY_LOW=VERY_LOW, + LOW=LOW, + MID=MID, + HIGH=HIGH, + # Access + WARM_ACCESS=100, + COLD_ACCOUNT_ACCESS=2_600, + WARM_SLOAD=100, + COLD_STORAGE_ACCESS=2_100, + # Storage + STORAGE_SET=20_000, + COLD_STORAGE_WRITE=5_000, + STORAGE_RESET=2_900, + # Call + CALL_VALUE=9_000, + CALL_STIPEND=2_300, + NEW_ACCOUNT=25_000, + # Contract Creation + CODE_DEPOSIT_PER_BYTE=200, + CODE_INIT_PER_WORD=2, + # Authorization + AUTH_PER_EMPTY_ACCOUNT=0, + # Utility + MEMORY_PER_WORD=3, + # Transactions + TX_BASE=21_000, + TX_ACCESS_LIST_ADDRESS=2_400, + TX_ACCESS_LIST_STORAGE_KEY=1_900, + TX_DATA_PER_ZERO=4, + TX_DATA_PER_NON_ZERO=68, + TX_CREATE=32_000, + # Refunds REFUND_STORAGE_CLEAR=4_800, - GAS_SELF_DESTRUCT=5_000, - GAS_CREATE=32_000, - GAS_CODE_DEPOSIT_PER_BYTE=200, - GAS_CODE_INIT_PER_WORD=2, - GAS_CALL_VALUE=9_000, - GAS_CALL_STIPEND=2_300, - GAS_NEW_ACCOUNT=25_000, - GAS_EXPONENTIATION=10, - GAS_EXPONENTIATION_PER_BYTE=50, - GAS_MEMORY=3, - GAS_TX_DATA_PER_ZERO=4, - GAS_TX_DATA_PER_NON_ZERO=68, - GAS_TX_BASE=21_000, - GAS_TX_CREATE=32_000, - GAS_LOG=375, - GAS_LOG_DATA_PER_BYTE=8, - GAS_LOG_TOPIC=375, - GAS_KECCAK256=30, - GAS_KECCAK256_PER_WORD=6, - GAS_COPY=3, - GAS_BLOCK_HASH=20, - GAS_PRECOMPILE_ECRECOVER=3_000, - GAS_PRECOMPILE_SHA256_BASE=60, - GAS_PRECOMPILE_SHA256_PER_WORD=12, - GAS_PRECOMPILE_RIPEMD160_BASE=600, - GAS_PRECOMPILE_RIPEMD160_PER_WORD=120, - GAS_PRECOMPILE_IDENTITY_BASE=15, - GAS_PRECOMPILE_IDENTITY_PER_WORD=3, + REFUND_AUTH_PER_EXISTING_ACCOUNT=0, + # Precompiles + PRECOMPILE_ECRECOVER=3_000, + PRECOMPILE_SHA256_BASE=60, + PRECOMPILE_SHA256_PER_WORD=12, + PRECOMPILE_RIPEMD160_BASE=600, + PRECOMPILE_RIPEMD160_PER_WORD=120, + PRECOMPILE_IDENTITY_BASE=15, + PRECOMPILE_IDENTITY_PER_WORD=3, + # Static Opcodes + OPCODE_ADD=VERY_LOW, + OPCODE_SUB=VERY_LOW, + OPCODE_MUL=LOW, + OPCODE_DIV=LOW, + OPCODE_SDIV=LOW, + OPCODE_MOD=LOW, + OPCODE_SMOD=LOW, + OPCODE_ADDMOD=MID, + OPCODE_MULMOD=MID, + OPCODE_SIGNEXTEND=LOW, + OPCODE_LT=VERY_LOW, + OPCODE_GT=VERY_LOW, + OPCODE_SLT=VERY_LOW, + OPCODE_SGT=VERY_LOW, + OPCODE_EQ=VERY_LOW, + OPCODE_ISZERO=VERY_LOW, + OPCODE_AND=VERY_LOW, + OPCODE_OR=VERY_LOW, + OPCODE_XOR=VERY_LOW, + OPCODE_NOT=VERY_LOW, + OPCODE_BYTE=VERY_LOW, + OPCODE_JUMP=MID, + OPCODE_JUMPI=HIGH, + OPCODE_JUMPDEST=1, + OPCODE_CALLDATALOAD=VERY_LOW, + OPCODE_BLOCKHASH=20, + OPCODE_COINBASE=BASE, + OPCODE_PUSH=VERY_LOW, + OPCODE_DUP=VERY_LOW, + OPCODE_SWAP=VERY_LOW, + # Dynamic Opcode Components + OPCODE_CALLDATACOPY_BASE=VERY_LOW, + OPCODE_CODECOPY_BASE=VERY_LOW, + OPCODE_MLOAD_BASE=VERY_LOW, + OPCODE_MSTORE_BASE=VERY_LOW, + OPCODE_MSTORE8_BASE=VERY_LOW, + OPCODE_SELFDESTRUCT_BASE=5_000, + OPCODE_COPY_PER_WORD=3, + OPCODE_CREATE_BASE=32_000, + OPCODE_EXP_BASE=10, + OPCODE_EXP_PER_BYTE=50, + OPCODE_LOG_BASE=375, + OPCODE_LOG_DATA_PER_BYTE=8, + OPCODE_LOG_TOPIC=375, + OPCODE_KECCAK256_BASE=30, + OPCODE_KECCACK256_PER_WORD=6, # Zero-initialized: introduced in later forks, set via # replace() in the fork that activates them. - GAS_TX_DATA_TOKEN_STANDARD=0, - GAS_TX_DATA_TOKEN_FLOOR=0, - GAS_AUTH_PER_EMPTY_ACCOUNT=0, - REFUND_AUTH_PER_EXISTING_ACCOUNT=0, - GAS_PRECOMPILE_ECADD=0, - GAS_PRECOMPILE_ECMUL=0, - GAS_PRECOMPILE_ECPAIRING_BASE=0, - GAS_PRECOMPILE_ECPAIRING_PER_POINT=0, - GAS_PRECOMPILE_BLAKE2F_BASE=0, - GAS_PRECOMPILE_BLAKE2F_PER_ROUND=0, - GAS_PRECOMPILE_POINT_EVALUATION=0, - GAS_PRECOMPILE_BLS_G1ADD=0, - GAS_PRECOMPILE_BLS_G1MUL=0, - GAS_PRECOMPILE_BLS_G1MAP=0, - GAS_PRECOMPILE_BLS_G2ADD=0, - GAS_PRECOMPILE_BLS_G2MUL=0, - GAS_PRECOMPILE_BLS_G2MAP=0, - GAS_PRECOMPILE_BLS_PAIRING_BASE=0, - GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR=0, - GAS_PRECOMPILE_P256VERIFY=0, - GAS_BLOCK_ACCESS_LIST_ITEM=0, + TX_DATA_TOKEN_STANDARD=0, + TX_DATA_TOKEN_FLOOR=0, + PRECOMPILE_ECADD=0, + PRECOMPILE_ECMUL=0, + PRECOMPILE_ECPAIRING_BASE=0, + PRECOMPILE_ECPAIRING_PER_POINT=0, + PRECOMPILE_BLAKE2F_BASE=0, + PRECOMPILE_BLAKE2F_PER_ROUND=0, + PRECOMPILE_POINT_EVALUATION=0, + PRECOMPILE_BLS_G1ADD=0, + PRECOMPILE_BLS_G1MUL=0, + PRECOMPILE_BLS_G1MAP=0, + PRECOMPILE_BLS_G2ADD=0, + PRECOMPILE_BLS_G2MUL=0, + PRECOMPILE_BLS_G2MAP=0, + PRECOMPILE_BLS_PAIRING_BASE=0, + PRECOMPILE_BLS_PAIRING_PER_PAIR=0, + PRECOMPILE_P256VERIFY=0, + BLOCK_ACCESS_LIST_ITEM=0, ) @classmethod @@ -233,9 +278,9 @@ def wrapper(opcode: OpcodeBase) -> int: # Add account access cost based on warmth if opcode.metadata["address_warm"]: - access_cost = gas_costs.GAS_WARM_ACCESS + access_cost = gas_costs.WARM_ACCESS else: - access_cost = gas_costs.GAS_COLD_ACCOUNT_ACCESS + access_cost = gas_costs.COLD_ACCOUNT_ACCESS return base_cost + access_cost @@ -253,7 +298,8 @@ def _with_data_copy( Args: base_gas: Either a constant gas cost (int) or a callable that calculates it - gas_costs: The gas costs dataclass for accessing GAS_COPY + gas_costs: The gas costs dataclass for accessing + OPCODE_COPY_PER_WORD Returns: A callable that calculates base_gas + copy_cost @@ -270,7 +316,7 @@ def wrapper(opcode: OpcodeBase) -> int: # Add copy cost based on data size data_size = opcode.metadata["data_size"] word_count = (data_size + 31) // 32 - copy_cost = gas_costs.GAS_COPY * word_count + copy_cost = gas_costs.OPCODE_COPY_PER_WORD * word_count return base_cost + copy_cost @@ -298,60 +344,62 @@ def opcode_gas_map( return { # Stop and arithmetic operations Opcodes.STOP: 0, - Opcodes.ADD: gas_costs.GAS_VERY_LOW, - Opcodes.MUL: gas_costs.GAS_LOW, - Opcodes.SUB: gas_costs.GAS_VERY_LOW, - Opcodes.DIV: gas_costs.GAS_LOW, - Opcodes.SDIV: gas_costs.GAS_LOW, - Opcodes.MOD: gas_costs.GAS_LOW, - Opcodes.SMOD: gas_costs.GAS_LOW, - Opcodes.ADDMOD: gas_costs.GAS_MID, - Opcodes.MULMOD: gas_costs.GAS_MID, + Opcodes.ADD: gas_costs.OPCODE_ADD, + Opcodes.MUL: gas_costs.OPCODE_MUL, + Opcodes.SUB: gas_costs.OPCODE_SUB, + Opcodes.DIV: gas_costs.OPCODE_DIV, + Opcodes.SDIV: gas_costs.OPCODE_SDIV, + Opcodes.MOD: gas_costs.OPCODE_MOD, + Opcodes.SMOD: gas_costs.OPCODE_SMOD, + Opcodes.ADDMOD: gas_costs.OPCODE_ADDMOD, + Opcodes.MULMOD: gas_costs.OPCODE_MULMOD, Opcodes.EXP: lambda op: ( - gas_costs.GAS_EXPONENTIATION - + gas_costs.GAS_EXPONENTIATION_PER_BYTE + gas_costs.OPCODE_EXP_BASE + + gas_costs.OPCODE_EXP_PER_BYTE * ((op.metadata["exponent"].bit_length() + 7) // 8) ), - Opcodes.SIGNEXTEND: gas_costs.GAS_LOW, + Opcodes.SIGNEXTEND: gas_costs.OPCODE_SIGNEXTEND, # Comparison & bitwise logic operations - Opcodes.LT: gas_costs.GAS_VERY_LOW, - Opcodes.GT: gas_costs.GAS_VERY_LOW, - Opcodes.SLT: gas_costs.GAS_VERY_LOW, - Opcodes.SGT: gas_costs.GAS_VERY_LOW, - Opcodes.EQ: gas_costs.GAS_VERY_LOW, - Opcodes.ISZERO: gas_costs.GAS_VERY_LOW, - Opcodes.AND: gas_costs.GAS_VERY_LOW, - Opcodes.OR: gas_costs.GAS_VERY_LOW, - Opcodes.XOR: gas_costs.GAS_VERY_LOW, - Opcodes.NOT: gas_costs.GAS_VERY_LOW, - Opcodes.BYTE: gas_costs.GAS_VERY_LOW, + Opcodes.LT: gas_costs.OPCODE_LT, + Opcodes.GT: gas_costs.OPCODE_GT, + Opcodes.SLT: gas_costs.OPCODE_SLT, + Opcodes.SGT: gas_costs.OPCODE_SGT, + Opcodes.EQ: gas_costs.OPCODE_EQ, + Opcodes.ISZERO: gas_costs.OPCODE_ISZERO, + Opcodes.AND: gas_costs.OPCODE_AND, + Opcodes.OR: gas_costs.OPCODE_OR, + Opcodes.XOR: gas_costs.OPCODE_XOR, + Opcodes.NOT: gas_costs.OPCODE_NOT, + Opcodes.BYTE: gas_costs.OPCODE_BYTE, # SHA3 Opcodes.SHA3: cls._with_memory_expansion( lambda op: ( - gas_costs.GAS_KECCAK256 - + gas_costs.GAS_KECCAK256_PER_WORD + gas_costs.OPCODE_KECCAK256_BASE + + gas_costs.OPCODE_KECCACK256_PER_WORD * ((op.metadata["data_size"] + 31) // 32) ), memory_expansion_calculator, ), # Environmental information - Opcodes.ADDRESS: gas_costs.GAS_BASE, + Opcodes.ADDRESS: gas_costs.BASE, Opcodes.BALANCE: cls._with_account_access(0, gas_costs), - Opcodes.ORIGIN: gas_costs.GAS_BASE, - Opcodes.CALLER: gas_costs.GAS_BASE, - Opcodes.CALLVALUE: gas_costs.GAS_BASE, - Opcodes.CALLDATALOAD: gas_costs.GAS_VERY_LOW, - Opcodes.CALLDATASIZE: gas_costs.GAS_BASE, + Opcodes.ORIGIN: gas_costs.BASE, + Opcodes.CALLER: gas_costs.BASE, + Opcodes.CALLVALUE: gas_costs.BASE, + Opcodes.CALLDATALOAD: gas_costs.OPCODE_CALLDATALOAD, + Opcodes.CALLDATASIZE: gas_costs.BASE, Opcodes.CALLDATACOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy( + gas_costs.OPCODE_CALLDATACOPY_BASE, gas_costs + ), memory_expansion_calculator, ), - Opcodes.CODESIZE: gas_costs.GAS_BASE, + Opcodes.CODESIZE: gas_costs.BASE, Opcodes.CODECOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy(gas_costs.OPCODE_CODECOPY_BASE, gas_costs), memory_expansion_calculator, ), - Opcodes.GASPRICE: gas_costs.GAS_BASE, + Opcodes.GASPRICE: gas_costs.BASE, Opcodes.EXTCODESIZE: cls._with_account_access(0, gas_costs), Opcodes.EXTCODECOPY: cls._with_memory_expansion( cls._with_data_copy( @@ -361,94 +409,97 @@ def opcode_gas_map( memory_expansion_calculator, ), # Block information - Opcodes.BLOCKHASH: gas_costs.GAS_BLOCK_HASH, - Opcodes.COINBASE: gas_costs.GAS_BASE, - Opcodes.TIMESTAMP: gas_costs.GAS_BASE, - Opcodes.NUMBER: gas_costs.GAS_BASE, - Opcodes.PREVRANDAO: gas_costs.GAS_BASE, - Opcodes.GASLIMIT: gas_costs.GAS_BASE, + Opcodes.BLOCKHASH: gas_costs.OPCODE_BLOCKHASH, + Opcodes.COINBASE: gas_costs.OPCODE_COINBASE, + Opcodes.TIMESTAMP: gas_costs.BASE, + Opcodes.NUMBER: gas_costs.BASE, + Opcodes.PREVRANDAO: gas_costs.BASE, + Opcodes.GASLIMIT: gas_costs.BASE, # Stack, memory, storage and flow operations - Opcodes.POP: gas_costs.GAS_BASE, + Opcodes.POP: gas_costs.BASE, Opcodes.MLOAD: cls._with_memory_expansion( - gas_costs.GAS_VERY_LOW, memory_expansion_calculator + gas_costs.OPCODE_MLOAD_BASE, + memory_expansion_calculator, ), Opcodes.MSTORE: cls._with_memory_expansion( - gas_costs.GAS_VERY_LOW, memory_expansion_calculator + gas_costs.OPCODE_MSTORE_BASE, + memory_expansion_calculator, ), Opcodes.MSTORE8: cls._with_memory_expansion( - gas_costs.GAS_VERY_LOW, memory_expansion_calculator + gas_costs.OPCODE_MSTORE8_BASE, + memory_expansion_calculator, ), Opcodes.SLOAD: lambda op: ( - gas_costs.GAS_WARM_SLOAD + gas_costs.WARM_SLOAD if op.metadata["key_warm"] - else gas_costs.GAS_COLD_STORAGE_ACCESS + else gas_costs.COLD_STORAGE_ACCESS ), Opcodes.SSTORE: lambda op: cls._calculate_sstore_gas( op, gas_costs ), - Opcodes.JUMP: gas_costs.GAS_MID, - Opcodes.JUMPI: gas_costs.GAS_HIGH, - Opcodes.PC: gas_costs.GAS_BASE, - Opcodes.MSIZE: gas_costs.GAS_BASE, - Opcodes.GAS: gas_costs.GAS_BASE, - Opcodes.JUMPDEST: gas_costs.GAS_JUMPDEST, + Opcodes.JUMP: gas_costs.OPCODE_JUMP, + Opcodes.JUMPI: gas_costs.OPCODE_JUMPI, + Opcodes.PC: gas_costs.BASE, + Opcodes.MSIZE: gas_costs.BASE, + Opcodes.GAS: gas_costs.BASE, + Opcodes.JUMPDEST: gas_costs.OPCODE_JUMPDEST, # Push operations (PUSH1 through PUSH32) **{ - getattr(Opcodes, f"PUSH{i}"): gas_costs.GAS_VERY_LOW + getattr(Opcodes, f"PUSH{i}"): gas_costs.OPCODE_PUSH for i in range(1, 33) }, # Dup operations (DUP1 through DUP16) **{ - getattr(Opcodes, f"DUP{i}"): gas_costs.GAS_VERY_LOW + getattr(Opcodes, f"DUP{i}"): gas_costs.OPCODE_DUP for i in range(1, 17) }, # Swap operations (SWAP1 through SWAP16) **{ - getattr(Opcodes, f"SWAP{i}"): gas_costs.GAS_VERY_LOW + getattr(Opcodes, f"SWAP{i}"): gas_costs.OPCODE_SWAP for i in range(1, 17) }, # Logging operations Opcodes.LOG0: cls._with_memory_expansion( lambda op: ( - gas_costs.GAS_LOG - + gas_costs.GAS_LOG_DATA_PER_BYTE + gas_costs.OPCODE_LOG_BASE + + gas_costs.OPCODE_LOG_DATA_PER_BYTE * op.metadata["data_size"] ), memory_expansion_calculator, ), Opcodes.LOG1: cls._with_memory_expansion( lambda op: ( - gas_costs.GAS_LOG - + gas_costs.GAS_LOG_DATA_PER_BYTE + gas_costs.OPCODE_LOG_BASE + + gas_costs.OPCODE_LOG_DATA_PER_BYTE * op.metadata["data_size"] - + gas_costs.GAS_LOG_TOPIC + + gas_costs.OPCODE_LOG_TOPIC ), memory_expansion_calculator, ), Opcodes.LOG2: cls._with_memory_expansion( lambda op: ( - gas_costs.GAS_LOG - + gas_costs.GAS_LOG_DATA_PER_BYTE + gas_costs.OPCODE_LOG_BASE + + gas_costs.OPCODE_LOG_DATA_PER_BYTE * op.metadata["data_size"] - + gas_costs.GAS_LOG_TOPIC * 2 + + gas_costs.OPCODE_LOG_TOPIC * 2 ), memory_expansion_calculator, ), Opcodes.LOG3: cls._with_memory_expansion( lambda op: ( - gas_costs.GAS_LOG - + gas_costs.GAS_LOG_DATA_PER_BYTE + gas_costs.OPCODE_LOG_BASE + + gas_costs.OPCODE_LOG_DATA_PER_BYTE * op.metadata["data_size"] - + gas_costs.GAS_LOG_TOPIC * 3 + + gas_costs.OPCODE_LOG_TOPIC * 3 ), memory_expansion_calculator, ), Opcodes.LOG4: cls._with_memory_expansion( lambda op: ( - gas_costs.GAS_LOG - + gas_costs.GAS_LOG_DATA_PER_BYTE + gas_costs.OPCODE_LOG_BASE + + gas_costs.OPCODE_LOG_DATA_PER_BYTE * op.metadata["data_size"] - + gas_costs.GAS_LOG_TOPIC * 4 + + gas_costs.OPCODE_LOG_TOPIC * 4 ), memory_expansion_calculator, ), @@ -571,15 +622,13 @@ def _calculate_sstore_refund( # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - refund += ( - gas_costs.GAS_STORAGE_SET - gas_costs.GAS_WARM_SLOAD - ) + refund += gas_costs.STORAGE_SET - gas_costs.WARM_SLOAD else: # Slot was originally non-empty and was UPDATED earlier refund += ( - gas_costs.GAS_COLD_STORAGE_WRITE - - gas_costs.GAS_COLD_STORAGE_ACCESS - - gas_costs.GAS_WARM_SLOAD + gas_costs.COLD_STORAGE_WRITE + - gas_costs.COLD_STORAGE_ACCESS + - gas_costs.WARM_SLOAD ) return refund @@ -597,20 +646,18 @@ def _calculate_sstore_gas( current_value = original_value new_value = metadata["new_value"] - gas_cost = ( - 0 if metadata["key_warm"] else gas_costs.GAS_COLD_STORAGE_ACCESS - ) + gas_cost = 0 if metadata["key_warm"] else gas_costs.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += gas_costs.GAS_STORAGE_SET + gas_cost += gas_costs.STORAGE_SET else: gas_cost += ( - gas_costs.GAS_COLD_STORAGE_WRITE - - gas_costs.GAS_COLD_STORAGE_ACCESS + gas_costs.COLD_STORAGE_WRITE + - gas_costs.COLD_STORAGE_ACCESS ) else: - gas_cost += gas_costs.GAS_WARM_SLOAD + gas_cost += gas_costs.WARM_SLOAD return gas_cost @@ -625,9 +672,9 @@ def _calculate_call_gas( # Base cost depends on address warmth if metadata["address_warm"]: - base_cost = gas_costs.GAS_WARM_ACCESS + base_cost = gas_costs.WARM_ACCESS else: - base_cost = gas_costs.GAS_COLD_ACCOUNT_ACCESS + base_cost = gas_costs.COLD_ACCOUNT_ACCESS if metadata["inner_call_cost"]: return base_cost + metadata["inner_call_cost"] @@ -640,7 +687,7 @@ def _calculate_create_gas( ) -> int: """CREATE gas is constant at Frontier.""" del opcode - return gas_costs.GAS_CREATE + return gas_costs.OPCODE_CREATE_BASE @classmethod def _calculate_create2_gas( @@ -662,7 +709,7 @@ def _calculate_return_gas( # Code deposit cost when returning from initcode code_deposit_size = metadata["code_deposit_size"] - return gas_costs.GAS_CODE_DEPOSIT_PER_BYTE * code_deposit_size + return gas_costs.CODE_DEPOSIT_PER_BYTE * code_deposit_size @classmethod def _calculate_selfdestruct_gas( @@ -671,15 +718,15 @@ def _calculate_selfdestruct_gas( """Calculate SELFDESTRUCT gas cost based on metadata.""" metadata = opcode.metadata - base_cost = gas_costs.GAS_SELF_DESTRUCT + base_cost = gas_costs.OPCODE_SELFDESTRUCT_BASE # Check if the beneficiary is cold if not metadata["address_warm"]: - base_cost += gas_costs.GAS_COLD_ACCOUNT_ACCESS + base_cost += gas_costs.COLD_ACCOUNT_ACCESS # Check if creating a new account if metadata["account_new"]: - base_cost += gas_costs.GAS_NEW_ACCOUNT + base_cost += gas_costs.NEW_ACCOUNT return base_cost @@ -698,7 +745,7 @@ def fn(*, new_bytes: int, previous_bytes: int = 0) -> int: previous_words = ceiling_division(previous_bytes, 32) def c(w: int) -> int: - return (gas_costs.GAS_MEMORY * w) + ((w * w) // 512) + return (gas_costs.MEMORY_PER_WORD * w) + ((w * w) // 512) return c(new_words) - c(previous_words) @@ -719,8 +766,8 @@ def fn(*, data: BytesConvertible, floor: bool = False) -> int: num_zeros = raw.count(0) num_non_zeros = len(raw) - num_zeros return ( - num_zeros * gas_costs.GAS_TX_DATA_PER_ZERO - + num_non_zeros * gas_costs.GAS_TX_DATA_PER_NON_ZERO + num_zeros * gas_costs.TX_DATA_PER_ZERO + + num_non_zeros * gas_costs.TX_DATA_PER_NON_ZERO ) return fn @@ -798,11 +845,11 @@ def fn( f"Authorizations are not supported in {cls.name()}" ) - intrinsic_cost: int = gas_costs.GAS_TX_BASE + intrinsic_cost: int = gas_costs.TX_BASE if contract_creation: intrinsic_cost += ( - gas_costs.GAS_CODE_INIT_PER_WORD + gas_costs.CODE_INIT_PER_WORD * ceiling_division(len(Bytes(calldata)), 32) ) diff --git a/packages/testing/src/execution_testing/forks/gas_costs.py b/packages/testing/src/execution_testing/forks/gas_costs.py index c41b6519d8d..7e637b1d37c 100644 --- a/packages/testing/src/execution_testing/forks/gas_costs.py +++ b/packages/testing/src/execution_testing/forks/gas_costs.py @@ -2,92 +2,147 @@ from dataclasses import dataclass +# Common Gas Cost Tiers +BASE = 2 +VERY_LOW = 3 +LOW = 5 +MID = 8 +HIGH = 10 + @dataclass(kw_only=True, frozen=True) class GasCosts: """Class that contains the gas cost constants for any fork.""" - GAS_JUMPDEST: int - GAS_BASE: int - GAS_VERY_LOW: int - GAS_LOW: int - GAS_MID: int - GAS_HIGH: int - GAS_WARM_ACCESS: int - GAS_COLD_ACCOUNT_ACCESS: int - GAS_TX_ACCESS_LIST_ADDRESS: int - GAS_TX_ACCESS_LIST_STORAGE_KEY: int - GAS_WARM_SLOAD: int - GAS_COLD_STORAGE_ACCESS: int - GAS_STORAGE_SET: int - GAS_COLD_STORAGE_WRITE: int - GAS_STORAGE_RESET: int - - GAS_SELF_DESTRUCT: int - GAS_CREATE: int - - GAS_CODE_DEPOSIT_PER_BYTE: int - GAS_CODE_INIT_PER_WORD: int - - GAS_CALL_VALUE: int - GAS_CALL_STIPEND: int - GAS_NEW_ACCOUNT: int - - GAS_EXPONENTIATION: int - GAS_EXPONENTIATION_PER_BYTE: int - - GAS_MEMORY: int - GAS_TX_BASE: int - GAS_TX_CREATE: int - GAS_TX_DATA_PER_ZERO: int - GAS_TX_DATA_PER_NON_ZERO: int - GAS_TX_DATA_TOKEN_STANDARD: int - GAS_TX_DATA_TOKEN_FLOOR: int - - GAS_LOG: int - GAS_LOG_DATA_PER_BYTE: int - GAS_LOG_TOPIC: int - - GAS_KECCAK256: int - GAS_KECCAK256_PER_WORD: int - - GAS_COPY: int - GAS_BLOCK_HASH: int - - GAS_AUTH_PER_EMPTY_ACCOUNT: int - - # Precompiled contract gas constants - GAS_PRECOMPILE_ECRECOVER: int - GAS_PRECOMPILE_SHA256_BASE: int - GAS_PRECOMPILE_SHA256_PER_WORD: int - GAS_PRECOMPILE_RIPEMD160_BASE: int - GAS_PRECOMPILE_RIPEMD160_PER_WORD: int - GAS_PRECOMPILE_IDENTITY_BASE: int - GAS_PRECOMPILE_IDENTITY_PER_WORD: int - - GAS_PRECOMPILE_ECADD: int - GAS_PRECOMPILE_ECMUL: int - GAS_PRECOMPILE_ECPAIRING_BASE: int - GAS_PRECOMPILE_ECPAIRING_PER_POINT: int - - GAS_PRECOMPILE_BLAKE2F_BASE: int - GAS_PRECOMPILE_BLAKE2F_PER_ROUND: int - - GAS_PRECOMPILE_POINT_EVALUATION: int - - GAS_PRECOMPILE_BLS_G1ADD: int - GAS_PRECOMPILE_BLS_G1MUL: int - GAS_PRECOMPILE_BLS_G1MAP: int - GAS_PRECOMPILE_BLS_G2ADD: int - GAS_PRECOMPILE_BLS_G2MUL: int - GAS_PRECOMPILE_BLS_G2MAP: int - GAS_PRECOMPILE_BLS_PAIRING_BASE: int - GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR: int - - GAS_PRECOMPILE_P256VERIFY: int - - # Refund constants + # Tiers + BASE: int + VERY_LOW: int + LOW: int + MID: int + HIGH: int + + # Access + WARM_ACCESS: int + COLD_ACCOUNT_ACCESS: int + WARM_SLOAD: int + COLD_STORAGE_ACCESS: int + + # Storage + STORAGE_SET: int + COLD_STORAGE_WRITE: int + STORAGE_RESET: int + + # Call + CALL_VALUE: int + CALL_STIPEND: int + NEW_ACCOUNT: int + + # Contract Creation + CODE_DEPOSIT_PER_BYTE: int + CODE_INIT_PER_WORD: int + + # Authorization + AUTH_PER_EMPTY_ACCOUNT: int + + # Utility + MEMORY_PER_WORD: int + + # Transactions + TX_BASE: int + TX_CREATE: int + TX_DATA_PER_ZERO: int + TX_DATA_PER_NON_ZERO: int + TX_DATA_TOKEN_STANDARD: int + TX_DATA_TOKEN_FLOOR: int + TX_ACCESS_LIST_ADDRESS: int + TX_ACCESS_LIST_STORAGE_KEY: int + + # Refunds REFUND_STORAGE_CLEAR: int REFUND_AUTH_PER_EXISTING_ACCOUNT: int - GAS_BLOCK_ACCESS_LIST_ITEM: int + # Precompiles + PRECOMPILE_ECRECOVER: int + PRECOMPILE_SHA256_BASE: int + PRECOMPILE_SHA256_PER_WORD: int + PRECOMPILE_RIPEMD160_BASE: int + PRECOMPILE_RIPEMD160_PER_WORD: int + PRECOMPILE_IDENTITY_BASE: int + PRECOMPILE_IDENTITY_PER_WORD: int + PRECOMPILE_ECADD: int + PRECOMPILE_ECMUL: int + PRECOMPILE_ECPAIRING_BASE: int + PRECOMPILE_ECPAIRING_PER_POINT: int + PRECOMPILE_BLAKE2F_BASE: int + PRECOMPILE_BLAKE2F_PER_ROUND: int + PRECOMPILE_POINT_EVALUATION: int + PRECOMPILE_BLS_G1ADD: int + PRECOMPILE_BLS_G1MUL: int + PRECOMPILE_BLS_G1MAP: int + PRECOMPILE_BLS_G2ADD: int + PRECOMPILE_BLS_G2MUL: int + PRECOMPILE_BLS_G2MAP: int + PRECOMPILE_BLS_PAIRING_BASE: int + PRECOMPILE_BLS_PAIRING_PER_PAIR: int + PRECOMPILE_P256VERIFY: int + + # Block Access Lists + BLOCK_ACCESS_LIST_ITEM: int + + # Opcodes + OPCODE_ADD: int + OPCODE_SUB: int + OPCODE_MUL: int + OPCODE_DIV: int + OPCODE_SDIV: int + OPCODE_MOD: int + OPCODE_SMOD: int + OPCODE_ADDMOD: int + OPCODE_MULMOD: int + OPCODE_SIGNEXTEND: int + OPCODE_LT: int + OPCODE_GT: int + OPCODE_SLT: int + OPCODE_SGT: int + OPCODE_EQ: int + OPCODE_ISZERO: int + OPCODE_AND: int + OPCODE_OR: int + OPCODE_XOR: int + OPCODE_NOT: int + OPCODE_BYTE: int + OPCODE_JUMP: int + OPCODE_JUMPI: int + OPCODE_JUMPDEST: int + OPCODE_CALLDATALOAD: int + OPCODE_BLOCKHASH: int + OPCODE_COINBASE: int + OPCODE_PUSH: int + OPCODE_DUP: int + OPCODE_SWAP: int + + # Dynamic Opcode Components + OPCODE_CALLDATACOPY_BASE: int + OPCODE_CODECOPY_BASE: int + OPCODE_MLOAD_BASE: int + OPCODE_MSTORE_BASE: int + OPCODE_MSTORE8_BASE: int + OPCODE_SELFDESTRUCT_BASE: int + OPCODE_COPY_PER_WORD: int + OPCODE_CREATE_BASE: int + OPCODE_EXP_BASE: int + OPCODE_EXP_PER_BYTE: int + OPCODE_LOG_BASE: int + OPCODE_LOG_DATA_PER_BYTE: int + OPCODE_LOG_TOPIC: int + OPCODE_KECCAK256_BASE: int + OPCODE_KECCACK256_PER_WORD: int + + # Defined post-Frontier + OPCODE_SHL: int = 0 + OPCODE_SHR: int = 0 + OPCODE_SAR: int = 0 + OPCODE_RETURNDATACOPY_BASE: int = 0 + OPCODE_BLOBHASH: int = 0 + OPCODE_MCOPY_BASE: int = 0 + OPCODE_CLZ: int = 0 diff --git a/packages/testing/src/execution_testing/forks/tests/test_opcode_gas_costs.py b/packages/testing/src/execution_testing/forks/tests/test_opcode_gas_costs.py index 39fb7ac2279..472b499edd0 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_opcode_gas_costs.py +++ b/packages/testing/src/execution_testing/forks/tests/test_opcode_gas_costs.py @@ -15,55 +15,55 @@ Osaka, Op.MSTORE(new_memory_size=1), Osaka.memory_expansion_gas_calculator()(new_bytes=1) - + Osaka.gas_costs().GAS_VERY_LOW, + + Osaka.gas_costs().VERY_LOW, id="mstore_memory_expansion", ), pytest.param( Osaka, Op.SSTORE, - Osaka.gas_costs().GAS_STORAGE_SET - + Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS, + Osaka.gas_costs().STORAGE_SET + + Osaka.gas_costs().COLD_STORAGE_ACCESS, id="sstore_defaults", ), pytest.param( Osaka, Op.SSTORE(key_warm=True), - Osaka.gas_costs().GAS_STORAGE_SET, + Osaka.gas_costs().STORAGE_SET, id="sstore_warm_key", ), # EXP tests pytest.param( Osaka, Op.EXP(exponent=0), - Osaka.gas_costs().GAS_EXPONENTIATION, + Osaka.gas_costs().OPCODE_EXP_BASE, id="exp_zero_exponent", ), pytest.param( Osaka, Op.EXP(exponent=0xFFFFFF), # 3 bytes - Osaka.gas_costs().GAS_EXPONENTIATION - + Osaka.gas_costs().GAS_EXPONENTIATION_PER_BYTE * 3, + Osaka.gas_costs().OPCODE_EXP_BASE + + Osaka.gas_costs().OPCODE_EXP_PER_BYTE * 3, id="exp_three_bytes", ), pytest.param( Osaka, Op.EXP(exponent=0x1FFFFFF), # 3 bytes - Osaka.gas_costs().GAS_EXPONENTIATION - + Osaka.gas_costs().GAS_EXPONENTIATION_PER_BYTE * 4, + Osaka.gas_costs().OPCODE_EXP_BASE + + Osaka.gas_costs().OPCODE_EXP_PER_BYTE * 4, id="exp_three_bytes_plus_one_bit", ), # SHA3 tests pytest.param( Osaka, Op.SHA3(data_size=0), - Osaka.gas_costs().GAS_KECCAK256, + Osaka.gas_costs().OPCODE_KECCAK256_BASE, id="sha3_zero_data", ), pytest.param( Osaka, Op.SHA3(data_size=64, new_memory_size=96), - Osaka.gas_costs().GAS_KECCAK256 - + Osaka.gas_costs().GAS_KECCAK256_PER_WORD * 2 + Osaka.gas_costs().OPCODE_KECCAK256_BASE + + Osaka.gas_costs().OPCODE_KECCACK256_PER_WORD * 2 + Osaka.memory_expansion_gas_calculator()(new_bytes=96), id="sha3_with_data_and_memory", ), @@ -71,21 +71,21 @@ pytest.param( Osaka, Op.BALANCE(address_warm=False), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS, id="balance_cold_address", ), pytest.param( Osaka, Op.BALANCE(address_warm=True), - Osaka.gas_costs().GAS_WARM_ACCESS, + Osaka.gas_costs().WARM_ACCESS, id="balance_warm_address", ), # CALLDATACOPY tests pytest.param( Osaka, Op.CALLDATACOPY(data_size=32, new_memory_size=32), - Osaka.gas_costs().GAS_VERY_LOW - + Osaka.gas_costs().GAS_COPY * 1 + Osaka.gas_costs().VERY_LOW + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 1 + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="calldatacopy_one_word", ), @@ -94,8 +94,8 @@ Op.CALLDATACOPY( data_size=64, new_memory_size=64, old_memory_size=32 ), - Osaka.gas_costs().GAS_VERY_LOW - + Osaka.gas_costs().GAS_COPY * 2 + Osaka.gas_costs().VERY_LOW + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 2 + Osaka.memory_expansion_gas_calculator()( new_bytes=64, previous_bytes=32 ), @@ -105,8 +105,8 @@ pytest.param( Osaka, Op.CODECOPY(data_size=96, new_memory_size=96), - Osaka.gas_costs().GAS_VERY_LOW - + Osaka.gas_costs().GAS_COPY * 3 + Osaka.gas_costs().VERY_LOW + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 3 + Osaka.memory_expansion_gas_calculator()(new_bytes=96), id="codecopy_three_words", ), @@ -114,13 +114,13 @@ pytest.param( Osaka, Op.EXTCODESIZE(address_warm=False), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS, id="extcodesize_cold", ), pytest.param( Osaka, Op.EXTCODESIZE(address_warm=True), - Osaka.gas_costs().GAS_WARM_ACCESS, + Osaka.gas_costs().WARM_ACCESS, id="extcodesize_warm", ), # EXTCODECOPY tests @@ -129,8 +129,8 @@ Op.EXTCODECOPY( address_warm=True, data_size=32, new_memory_size=32 ), - Osaka.gas_costs().GAS_WARM_ACCESS - + Osaka.gas_costs().GAS_COPY * 1 + Osaka.gas_costs().WARM_ACCESS + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 1 + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="extcodecopy_warm", ), @@ -139,8 +139,8 @@ Op.EXTCODECOPY( address_warm=False, data_size=64, new_memory_size=64 ), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS - + Osaka.gas_costs().GAS_COPY * 2 + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 2 + Osaka.memory_expansion_gas_calculator()(new_bytes=64), id="extcodecopy_cold", ), @@ -148,21 +148,21 @@ pytest.param( Osaka, Op.EXTCODEHASH(address_warm=False), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS, id="extcodehash_cold", ), pytest.param( Osaka, Op.EXTCODEHASH(address_warm=True), - Osaka.gas_costs().GAS_WARM_ACCESS, + Osaka.gas_costs().WARM_ACCESS, id="extcodehash_warm", ), # RETURNDATACOPY tests pytest.param( Osaka, Op.RETURNDATACOPY(data_size=32, new_memory_size=32), - Osaka.gas_costs().GAS_VERY_LOW - + Osaka.gas_costs().GAS_COPY * 1 + Osaka.gas_costs().VERY_LOW + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 1 + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="returndatacopy", ), @@ -170,7 +170,7 @@ pytest.param( Osaka, Op.MLOAD(new_memory_size=32), - Osaka.gas_costs().GAS_VERY_LOW + Osaka.gas_costs().VERY_LOW + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="mload_memory_expansion", ), @@ -178,7 +178,7 @@ pytest.param( Osaka, Op.MSTORE8(new_memory_size=1), - Osaka.gas_costs().GAS_VERY_LOW + Osaka.gas_costs().VERY_LOW + Osaka.memory_expansion_gas_calculator()(new_bytes=1), id="mstore8_memory_expansion", ), @@ -186,29 +186,29 @@ pytest.param( Osaka, Op.SLOAD(key_warm=False), - Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS, + Osaka.gas_costs().COLD_STORAGE_ACCESS, id="sload_cold", ), pytest.param( Osaka, Op.SLOAD(key_warm=True), - Osaka.gas_costs().GAS_WARM_SLOAD, + Osaka.gas_costs().WARM_SLOAD, id="sload_warm", ), # MCOPY tests pytest.param( Osaka, Op.MCOPY(data_size=32, new_memory_size=32), - Osaka.gas_costs().GAS_VERY_LOW - + Osaka.gas_costs().GAS_COPY * 1 + Osaka.gas_costs().VERY_LOW + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 1 + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="mcopy_one_word", ), pytest.param( Osaka, Op.MCOPY(data_size=96, new_memory_size=128, old_memory_size=64), - Osaka.gas_costs().GAS_VERY_LOW - + Osaka.gas_costs().GAS_COPY * 3 + Osaka.gas_costs().VERY_LOW + + Osaka.gas_costs().OPCODE_COPY_PER_WORD * 3 + Osaka.memory_expansion_gas_calculator()( new_bytes=128, previous_bytes=64 ), @@ -218,8 +218,8 @@ pytest.param( Osaka, Op.LOG0(data_size=32, new_memory_size=32), - Osaka.gas_costs().GAS_LOG - + Osaka.gas_costs().GAS_LOG_DATA_PER_BYTE * 32 + Osaka.gas_costs().OPCODE_LOG_BASE + + Osaka.gas_costs().OPCODE_LOG_DATA_PER_BYTE * 32 + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="log0", ), @@ -227,9 +227,9 @@ pytest.param( Osaka, Op.LOG1(data_size=64, new_memory_size=64), - Osaka.gas_costs().GAS_LOG - + Osaka.gas_costs().GAS_LOG_DATA_PER_BYTE * 64 - + Osaka.gas_costs().GAS_LOG_TOPIC + Osaka.gas_costs().OPCODE_LOG_BASE + + Osaka.gas_costs().OPCODE_LOG_DATA_PER_BYTE * 64 + + Osaka.gas_costs().OPCODE_LOG_TOPIC + Osaka.memory_expansion_gas_calculator()(new_bytes=64), id="log1", ), @@ -237,9 +237,9 @@ pytest.param( Osaka, Op.LOG2(data_size=128, new_memory_size=128), - Osaka.gas_costs().GAS_LOG - + Osaka.gas_costs().GAS_LOG_DATA_PER_BYTE * 128 - + Osaka.gas_costs().GAS_LOG_TOPIC * 2 + Osaka.gas_costs().OPCODE_LOG_BASE + + Osaka.gas_costs().OPCODE_LOG_DATA_PER_BYTE * 128 + + Osaka.gas_costs().OPCODE_LOG_TOPIC * 2 + Osaka.memory_expansion_gas_calculator()(new_bytes=128), id="log2", ), @@ -247,9 +247,9 @@ pytest.param( Osaka, Op.LOG3(data_size=256, new_memory_size=256), - Osaka.gas_costs().GAS_LOG - + Osaka.gas_costs().GAS_LOG_DATA_PER_BYTE * 256 - + Osaka.gas_costs().GAS_LOG_TOPIC * 3 + Osaka.gas_costs().OPCODE_LOG_BASE + + Osaka.gas_costs().OPCODE_LOG_DATA_PER_BYTE * 256 + + Osaka.gas_costs().OPCODE_LOG_TOPIC * 3 + Osaka.memory_expansion_gas_calculator()(new_bytes=256), id="log3", ), @@ -257,9 +257,9 @@ pytest.param( Osaka, Op.LOG4(data_size=512, new_memory_size=512), - Osaka.gas_costs().GAS_LOG - + Osaka.gas_costs().GAS_LOG_DATA_PER_BYTE * 512 - + Osaka.gas_costs().GAS_LOG_TOPIC * 4 + Osaka.gas_costs().OPCODE_LOG_BASE + + Osaka.gas_costs().OPCODE_LOG_DATA_PER_BYTE * 512 + + Osaka.gas_costs().OPCODE_LOG_TOPIC * 4 + Osaka.memory_expansion_gas_calculator()(new_bytes=512), id="log4", ), @@ -267,9 +267,9 @@ pytest.param( Osaka, Op.CREATE(init_code_size=100, new_memory_size=100), - Osaka.gas_costs().GAS_CREATE + Osaka.gas_costs().OPCODE_CREATE_BASE # (100 + 31) // 32 = 4 - + Osaka.gas_costs().GAS_CODE_INIT_PER_WORD * 4 + + Osaka.gas_costs().CODE_INIT_PER_WORD * 4 + Osaka.memory_expansion_gas_calculator()(new_bytes=100), id="create_with_initcode", ), @@ -277,9 +277,9 @@ pytest.param( Osaka, Op.CREATE2(init_code_size=64, new_memory_size=64), - Osaka.gas_costs().GAS_CREATE - + Osaka.gas_costs().GAS_CODE_INIT_PER_WORD * 2 - + Osaka.gas_costs().GAS_KECCAK256_PER_WORD * 2 + Osaka.gas_costs().OPCODE_CREATE_BASE + + Osaka.gas_costs().CODE_INIT_PER_WORD * 2 + + Osaka.gas_costs().OPCODE_KECCACK256_PER_WORD * 2 + Osaka.memory_expansion_gas_calculator()(new_bytes=64), id="create2_with_initcode_and_hash", ), @@ -289,15 +289,15 @@ Op.CALL( address_warm=True, value_transfer=False, new_memory_size=64 ), - Osaka.gas_costs().GAS_WARM_ACCESS + Osaka.gas_costs().WARM_ACCESS + Osaka.memory_expansion_gas_calculator()(new_bytes=64), id="call_warm_no_value", ), pytest.param( Osaka, Op.CALL(address_warm=False, delegated_address=True), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS - + Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + + Osaka.gas_costs().COLD_ACCOUNT_ACCESS, id="call_cold_delegated_address", ), pytest.param( @@ -307,22 +307,22 @@ delegated_address=True, delegated_address_warm=True, ), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS - + Osaka.gas_costs().GAS_WARM_ACCESS, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + + Osaka.gas_costs().WARM_ACCESS, id="call_warm_delegated_address", ), pytest.param( Osaka, Op.CALL(address_warm=False, value_transfer=True, account_new=True), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS - + Osaka.gas_costs().GAS_CALL_VALUE - + Osaka.gas_costs().GAS_NEW_ACCOUNT, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + + Osaka.gas_costs().CALL_VALUE + + Osaka.gas_costs().NEW_ACCOUNT, id="call_cold_account_new", ), pytest.param( Homestead, Op.CALL(address_warm=False, value_transfer=True, account_new=True), - Homestead.gas_costs().GAS_COLD_ACCOUNT_ACCESS, + Homestead.gas_costs().COLD_ACCOUNT_ACCESS, id="call_cold_account_new_homestead", ), pytest.param( @@ -333,8 +333,8 @@ account_new=False, new_memory_size=32, ), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS - + Osaka.gas_costs().GAS_CALL_VALUE + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + + Osaka.gas_costs().CALL_VALUE + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="call_cold_with_value", ), @@ -346,9 +346,9 @@ account_new=True, new_memory_size=32, ), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS - + Osaka.gas_costs().GAS_CALL_VALUE - + Osaka.gas_costs().GAS_NEW_ACCOUNT + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + + Osaka.gas_costs().CALL_VALUE + + Osaka.gas_costs().NEW_ACCOUNT + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="call_cold_new_account", ), @@ -358,7 +358,7 @@ Op.CALLCODE( address_warm=True, value_transfer=False, new_memory_size=32 ), - Osaka.gas_costs().GAS_WARM_ACCESS + Osaka.gas_costs().WARM_ACCESS + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="callcode_warm", ), @@ -366,14 +366,14 @@ pytest.param( Osaka, Op.DELEGATECALL(address_warm=True, new_memory_size=32), - Osaka.gas_costs().GAS_WARM_ACCESS + Osaka.gas_costs().WARM_ACCESS + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="delegatecall_warm", ), pytest.param( Osaka, Op.DELEGATECALL(address_warm=False, new_memory_size=64), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS + Osaka.gas_costs().COLD_ACCOUNT_ACCESS + Osaka.memory_expansion_gas_calculator()(new_bytes=64), id="delegatecall_cold", ), @@ -381,14 +381,14 @@ pytest.param( Osaka, Op.STATICCALL(address_warm=True, new_memory_size=32), - Osaka.gas_costs().GAS_WARM_ACCESS + Osaka.gas_costs().WARM_ACCESS + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="staticcall_warm", ), pytest.param( Osaka, Op.STATICCALL(address_warm=False, new_memory_size=0), - Osaka.gas_costs().GAS_COLD_ACCOUNT_ACCESS, + Osaka.gas_costs().COLD_ACCOUNT_ACCESS, id="staticcall_cold_no_memory", ), # RETURN tests @@ -401,7 +401,7 @@ pytest.param( Osaka, Op.RETURN(code_deposit_size=100, new_memory_size=32), - Osaka.gas_costs().GAS_CODE_DEPOSIT_PER_BYTE * 100 + Osaka.gas_costs().CODE_DEPOSIT_PER_BYTE * 100 + Osaka.memory_expansion_gas_calculator()(new_bytes=32), id="return_with_code_deposit", ), @@ -416,7 +416,7 @@ pytest.param( Osaka, Op.CLZ, - Osaka.gas_costs().GAS_LOW, + Osaka.gas_costs().LOW, id="clz_osaka", ), ], @@ -432,20 +432,19 @@ def test_opcode_gas_costs(fork: Fork, opcode: Op, expected_cost: int) -> None: pytest.param( Osaka, Op.ADD + Op.SUB, - Osaka.gas_costs().GAS_VERY_LOW * 2, + Osaka.gas_costs().VERY_LOW * 2, id="sum_of_opcodes", ), pytest.param( Osaka, Op.ADD(1, 1), - Osaka.gas_costs().GAS_VERY_LOW * 3, + Osaka.gas_costs().VERY_LOW * 3, id="opcode_with_args", ), pytest.param( Osaka, Op.SSTORE(1, 2, key_warm=True), - Osaka.gas_costs().GAS_STORAGE_SET - + Osaka.gas_costs().GAS_VERY_LOW * 2, + Osaka.gas_costs().STORAGE_SET + Osaka.gas_costs().VERY_LOW * 2, id="opcode_with_metadata", ), ], @@ -540,69 +539,69 @@ def test_bytecode_refunds( # noqa: D103 pytest.param( Osaka, Op.SSTORE(key_warm=True, original_value=0, new_value=0), - Osaka.gas_costs().GAS_WARM_SLOAD, + Osaka.gas_costs().WARM_SLOAD, id="sstore_noop_zero_warm", # 0 → 0 ), pytest.param( Osaka, Op.SSTORE(key_warm=False, original_value=0, new_value=0), - Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS - + Osaka.gas_costs().GAS_WARM_SLOAD, + Osaka.gas_costs().COLD_STORAGE_ACCESS + + Osaka.gas_costs().WARM_SLOAD, id="sstore_noop_zero_cold", # 0 → 0 ), pytest.param( Osaka, Op.SSTORE(key_warm=True, original_value=5, new_value=5), - Osaka.gas_costs().GAS_WARM_SLOAD, + Osaka.gas_costs().WARM_SLOAD, id="sstore_noop_nonzero_warm", # 5 → 5 ), pytest.param( Osaka, Op.SSTORE(key_warm=False, original_value=5, new_value=5), - Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS - + Osaka.gas_costs().GAS_WARM_SLOAD, + Osaka.gas_costs().COLD_STORAGE_ACCESS + + Osaka.gas_costs().WARM_SLOAD, id="sstore_noop_nonzero_cold", # 5 → 5 ), # Create storage: 0 → X (original == 0) pytest.param( Osaka, Op.SSTORE(key_warm=True, new_value=5), - Osaka.gas_costs().GAS_STORAGE_SET, + Osaka.gas_costs().STORAGE_SET, id="sstore_create_warm", # 0 → 5 ), pytest.param( Osaka, Op.SSTORE(key_warm=False, new_value=5), - Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS - + Osaka.gas_costs().GAS_STORAGE_SET, + Osaka.gas_costs().COLD_STORAGE_ACCESS + + Osaka.gas_costs().STORAGE_SET, id="sstore_create_cold", # 0 → 5 ), # Modify storage: X → Y (original != 0, new != 0, new != original) pytest.param( Osaka, Op.SSTORE(key_warm=True, original_value=5, new_value=7), - Osaka.gas_costs().GAS_STORAGE_RESET, + Osaka.gas_costs().STORAGE_RESET, id="sstore_modify_warm", # 5 → 7 ), pytest.param( Osaka, Op.SSTORE(key_warm=False, original_value=5, new_value=7), - Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS - + Osaka.gas_costs().GAS_STORAGE_RESET, + Osaka.gas_costs().COLD_STORAGE_ACCESS + + Osaka.gas_costs().STORAGE_RESET, id="sstore_modify_cold", # 5 → 7 ), # Clear storage: X → 0 (original != 0, new == 0) pytest.param( Osaka, Op.SSTORE(key_warm=True, original_value=5, new_value=0), - Osaka.gas_costs().GAS_STORAGE_RESET, + Osaka.gas_costs().STORAGE_RESET, id="sstore_clear_warm", # 5 → 0 ), pytest.param( Osaka, Op.SSTORE(key_warm=False, original_value=5, new_value=0), - Osaka.gas_costs().GAS_COLD_STORAGE_ACCESS - + Osaka.gas_costs().GAS_STORAGE_RESET, + Osaka.gas_costs().COLD_STORAGE_ACCESS + + Osaka.gas_costs().STORAGE_RESET, id="sstore_clear_cold", # 5 → 0 ), ], diff --git a/packages/testing/src/execution_testing/tools/utility/generators.py b/packages/testing/src/execution_testing/tools/utility/generators.py index f2e725e1dc9..78a9f172c51 100644 --- a/packages/testing/src/execution_testing/tools/utility/generators.py +++ b/packages/testing/src/execution_testing/tools/utility/generators.py @@ -358,9 +358,9 @@ def wrapper( # code will only work once, so if the system contract is re- # executed in a subsequent block, it will consume less gas. gas_used_per_storage = ( - gas_costs.GAS_STORAGE_SET - + gas_costs.GAS_COLD_STORAGE_ACCESS - + (gas_costs.GAS_VERY_LOW * 2) + gas_costs.STORAGE_SET + + gas_costs.COLD_STORAGE_ACCESS + + (gas_costs.VERY_LOW * 2) ) modified_system_contract_code += sum( Op.SSTORE(i, 1) @@ -369,9 +369,9 @@ def wrapper( # If the gas limit is not divisible by the gas used per # storage, we need to add some NO-OP (JUMPDEST) to the code # that each consume 1 gas. - assert gas_costs.GAS_JUMPDEST == 1, ( + assert gas_costs.OPCODE_JUMPDEST == 1, ( "JUMPDEST gas cost should be 1, but got " - f"{gas_costs.GAS_JUMPDEST}. Generator " + f"{gas_costs.OPCODE_JUMPDEST}. Generator " "`generate_system_contract_error_test` needs updating." ) modified_system_contract_code += sum( @@ -506,13 +506,13 @@ def gas_test( # 2 times GAS, POP, CALL, 6 times PUSH1 - instructions charged for at every # gas run gas_costs = fork.gas_costs() - opcode_gas_cost = gas_costs.GAS_BASE - opcode_pop_cost = gas_costs.GAS_BASE - opcode_push_cost = gas_costs.GAS_VERY_LOW + opcode_gas_cost = gas_costs.BASE + opcode_pop_cost = gas_costs.BASE + opcode_push_cost = gas_costs.VERY_LOW gas_single_gas_run = ( 2 * opcode_gas_cost + opcode_pop_cost - + gas_costs.GAS_WARM_ACCESS + + gas_costs.WARM_ACCESS + 6 * opcode_push_cost ) address_legacy_harness = pre.deploy_contract( diff --git a/src/ethereum/forks/amsterdam/block_access_lists.py b/src/ethereum/forks/amsterdam/block_access_lists.py index 095a9832dc8..96ab1fdb431 100644 --- a/src/ethereum/forks/amsterdam/block_access_lists.py +++ b/src/ethereum/forks/amsterdam/block_access_lists.py @@ -744,7 +744,7 @@ def validate_block_access_list_gas_limit( The total number of items (addresses + unique storage keys) must not exceed ``block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM``. """ - from .vm.gas import GAS_BLOCK_ACCESS_LIST_ITEM + from .vm.gas import GasCosts bal_items = Uint(0) for account in block_access_list: @@ -762,9 +762,9 @@ def validate_block_access_list_gas_limit( # Count each unique storage key as one item bal_items += Uint(len(unique_slots)) - if bal_items > block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM: + if bal_items > block_gas_limit // GasCosts.BLOCK_ACCESS_LIST_ITEM: raise BlockAccessListGasLimitExceededError( f"Block access list exceeds gas limit, {bal_items} items " f"exceeds limit of " - f"{block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM}." + f"{block_gas_limit // GasCosts.BLOCK_ACCESS_LIST_ITEM}." ) diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index c5dbc499c23..e673bc3d8fd 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -95,8 +95,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -106,15 +105,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" GWEI_TO_WEI = U256(10**9) @@ -1122,14 +1119,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1145,12 +1142,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/amsterdam/transactions.py b/src/ethereum/forks/amsterdam/transactions.py index 03c5c32b803..2436773d645 100644 --- a/src/ethereum/forks/amsterdam/transactions.py +++ b/src/ethereum/forks/amsterdam/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -608,7 +571,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -619,15 +582,14 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost tokens_in_calldata = count_tokens_in_data(tx.data) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) @@ -635,17 +597,19 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_access_list = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) # Data token floor cost for access list bytes. - access_list_cost += tokens_in_access_list * GAS_TX_DATA_TOKEN_FLOOR + access_list_cost += tokens_in_access_list * GasCosts.TX_DATA_TOKEN_FLOOR auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) # Floor tokens from calldata. floor_tokens_in_calldata = tokens_in_calldata @@ -655,12 +619,12 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: # Floor gas cost (EIP-7623: minimum gas for data-heavy transactions). data_floor_gas_cost = ( - total_floor_tokens * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + total_floor_tokens * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/amsterdam/vm/eoa_delegation.py b/src/ethereum/forks/amsterdam/vm/eoa_delegation.py index 602afef3c1f..6262f42a0bc 100644 --- a/src/ethereum/forks/amsterdam/vm/eoa_delegation.py +++ b/src/ethereum/forks/amsterdam/vm/eoa_delegation.py @@ -21,14 +21,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -149,9 +148,9 @@ def calculate_delegation_cost( delegated_address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if delegated_address in evm.accessed_addresses: - delegation_gas_cost = GAS_WARM_ACCESS + delegation_gas_cost = GasCosts.WARM_ACCESS else: - delegation_gas_cost = GAS_COLD_ACCOUNT_ACCESS + delegation_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS return True, delegated_address, delegation_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(tx_state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index 6807cba420b..b5ef8974d3e 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -25,67 +25,172 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(14) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(21) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) - -GAS_BLOCK_ACCESS_LIST_ITEM = Uint(2000) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(14) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(21) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + + # Block Access Lists + BLOCK_ACCESS_LIST_ITEM = Uint(2000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcode Components + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -106,8 +211,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -176,7 +281,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -231,7 +336,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -303,7 +408,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas( @@ -336,21 +441,23 @@ def calculate_excess_blob_gas( base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -369,7 +476,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -390,9 +497,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py b/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py b/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py index cc6fa2fbb23..7674d3c720f 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +265,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/block.py b/src/ethereum/forks/amsterdam/vm/instructions/block.py index e563a2e96e8..8c93840b384 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/block.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/comparison.py b/src/ethereum/forks/amsterdam/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/comparison.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py b/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/amsterdam/vm/instructions/environment.py b/src/ethereum/forks/amsterdam/vm/instructions/environment.py index f5f89bdfa59..431cd3ba4c6 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/environment.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -75,12 +68,11 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - is_cold_access = address not in evm.accessed_addresses - gas_cost = GAS_COLD_ACCOUNT_ACCESS if is_cold_access else GAS_WARM_ACCESS - if is_cold_access: + if address in evm.accessed_addresses: + charge_gas(evm, GasCosts.WARM_ACCESS) + else: evm.accessed_addresses.add(address) - - charge_gas(evm, gas_cost) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -108,7 +100,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -131,7 +123,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -154,7 +146,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -178,7 +170,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -203,7 +195,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -232,11 +224,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -261,7 +256,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -290,11 +285,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -319,7 +317,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -342,14 +340,11 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - is_cold_access = address not in evm.accessed_addresses - access_gas_cost = ( - GAS_COLD_ACCOUNT_ACCESS if is_cold_access else GAS_WARM_ACCESS - ) - if is_cold_access: + if address in evm.accessed_addresses: + charge_gas(evm, GasCosts.WARM_ACCESS) + else: evm.accessed_addresses.add(address) - - charge_gas(evm, access_gas_cost) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION tx_state = evm.message.tx_env.state @@ -381,19 +376,18 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - is_cold_access = address not in evm.accessed_addresses - access_gas_cost = ( - GAS_COLD_ACCOUNT_ACCESS if is_cold_access else GAS_WARM_ACCESS - ) - total_gas_cost = access_gas_cost + copy_gas_cost + extend_memory.cost - - if is_cold_access: + if address in evm.accessed_addresses: + access_gas_cost = GasCosts.WARM_ACCESS + else: evm.accessed_addresses.add(address) + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS + + total_gas_cost = access_gas_cost + copy_gas_cost + extend_memory.cost charge_gas(evm, total_gas_cost) @@ -424,7 +418,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -450,11 +444,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -482,12 +481,11 @@ def extcodehash(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - is_cold_access = address not in evm.accessed_addresses - access_gas_cost = ( - GAS_COLD_ACCOUNT_ACCESS if is_cold_access else GAS_WARM_ACCESS - ) - if is_cold_access: + if address in evm.accessed_addresses: + access_gas_cost = GasCosts.WARM_ACCESS + else: evm.accessed_addresses.add(address) + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -520,7 +518,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -548,7 +546,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -571,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -598,7 +596,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/amsterdam/vm/instructions/keccak.py b/src/ethereum/forks/amsterdam/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/keccak.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/amsterdam/vm/instructions/log.py b/src/ethereum/forks/amsterdam/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/log.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/memory.py b/src/ethereum/forks/amsterdam/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/memory.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/amsterdam/vm/instructions/stack.py b/src/ethereum/forks/amsterdam/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/stack.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/amsterdam/vm/instructions/storage.py b/src/ethereum/forks/amsterdam/vm/instructions/storage.py index 176b0d9a1c8..56e1ed28d06 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/storage.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, check_gas, ) @@ -51,10 +46,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION tx_state = evm.message.tx_env.state @@ -84,7 +79,7 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # check we have at least the stipend gas - check_gas(evm, GAS_CALL_STIPEND + Uint(1)) + check_gas(evm, GasCosts.CALL_STIPEND + Uint(1)) tx_state = evm.message.tx_env.state original_value = get_storage_original( @@ -96,37 +91,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -151,7 +150,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -181,7 +180,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) set_transient_storage( evm.message.tx_env.state, evm.message.current_target, diff --git a/src/ethereum/forks/amsterdam/vm/instructions/system.py b/src/ethereum/forks/amsterdam/vm/instructions/system.py index 1660394e56d..42a4643f9c0 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/system.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/system.py @@ -43,15 +43,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -174,7 +166,9 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -224,8 +218,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -269,7 +263,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -387,11 +381,11 @@ def call(evm: Evm) -> None: is_cold_access = to not in evm.accessed_addresses if is_cold_access: - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS else: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE # check static gas before state access check_gas( @@ -404,7 +398,7 @@ def call(evm: Evm) -> None: if is_cold_access: evm.accessed_addresses.add(to) - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(tx_state, to): create_gas_cost = Uint(0) @@ -494,11 +488,11 @@ def callcode(evm: Evm) -> None: is_cold_access = code_address not in evm.accessed_addresses if is_cold_access: - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS else: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE # check static gas before state access check_gas( @@ -584,11 +578,11 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE is_cold_access = beneficiary not in evm.accessed_addresses if is_cold_access: - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS # check access gas cost before state access check_gas(evm, gas_cost) @@ -602,7 +596,7 @@ def selfdestruct(evm: Evm) -> None: not is_account_alive(tx_state, beneficiary) and get_account(tx_state, evm.message.current_target).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) @@ -656,9 +650,9 @@ def delegatecall(evm: Evm) -> None: is_cold_access = code_address not in evm.accessed_addresses if is_cold_access: - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS else: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS # check static gas before state access check_gas(evm, access_gas_cost + extend_memory.cost) @@ -746,9 +740,9 @@ def staticcall(evm: Evm) -> None: is_cold_access = to not in evm.accessed_addresses if is_cold_access: - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS else: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS # check static gas before state access check_gas(evm, access_gas_cost + extend_memory.cost) diff --git a/src/ethereum/forks/amsterdam/vm/interpreter.py b/src/ethereum/forks/amsterdam/vm/interpreter.py index c22f9eef143..80b30bd7ab2 100644 --- a/src/ethereum/forks/amsterdam/vm/interpreter.py +++ b/src/ethereum/forks/amsterdam/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -201,7 +201,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..fa0d3ec4c2d 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..a5b2be04018 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/arrow_glacier/fork.py b/src/ethereum/forks/arrow_glacier/fork.py index f833fe71c5f..1ca5a51b6ac 100644 --- a/src/ethereum/forks/arrow_glacier/fork.py +++ b/src/ethereum/forks/arrow_glacier/fork.py @@ -61,13 +61,12 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 10700000 @@ -849,12 +848,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -872,12 +871,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/arrow_glacier/transactions.py b/src/ethereum/forks/arrow_glacier/transactions.py index ca951f085c2..0e40010c617 100644 --- a/src/ethereum/forks/arrow_glacier/transactions.py +++ b/src/ethereum/forks/arrow_glacier/transactions.py @@ -23,37 +23,6 @@ from .exceptions import TransactionTypeError from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -370,7 +339,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -378,27 +347,29 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) access_list_cost = Uint(0) if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/arrow_glacier/vm/gas.py b/src/ethereum/forks/arrow_glacier/vm/gas.py index 7ac4146d8cf..c33cf7c0487 100644 --- a/src/ethereum/forks/arrow_glacier/vm/gas.py +++ b/src/ethereum/forks/arrow_glacier/vm/gas.py @@ -22,46 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -82,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -135,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -190,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py b/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py b/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/block.py b/src/ethereum/forks/arrow_glacier/vm/instructions/block.py index bbf01739ff2..e3400f9461a 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/block.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py b/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py b/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py b/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py index fe1b70c1269..851ab39b142 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,10 +67,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -103,7 +97,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -126,7 +120,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -149,7 +143,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -173,7 +167,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -198,7 +192,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -227,11 +221,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -256,7 +253,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -285,11 +282,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -314,7 +314,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -338,10 +338,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -374,16 +374,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -413,7 +413,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -439,11 +439,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -472,10 +477,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -507,7 +512,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -535,7 +540,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py b/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/log.py b/src/ethereum/forks/arrow_glacier/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py b/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py b/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py b/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py index d99ad70f93b..287544f353b 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py @@ -17,12 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,10 +39,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -73,7 +68,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,37 +81,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/system.py b/src/ethereum/forks/arrow_glacier/vm/instructions/system.py index b48d2498ac3..0282da0d90e 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/system.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -157,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -202,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -242,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -353,17 +345,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -433,12 +425,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -491,10 +483,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -503,7 +495,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -570,13 +562,17 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + access_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -629,10 +625,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/arrow_glacier/vm/interpreter.py b/src/ethereum/forks/arrow_glacier/vm/interpreter.py index 20d8c31f1e3..f2262c47175 100644 --- a/src/ethereum/forks/arrow_glacier/vm/interpreter.py +++ b/src/ethereum/forks/arrow_glacier/vm/interpreter.py @@ -45,7 +45,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -179,7 +179,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..9d8c71b806d 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,10 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas( + evm, + GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds, + ) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/berlin/fork.py b/src/ethereum/forks/berlin/fork.py index 54bc85a6aa6..72d37ec2bae 100644 --- a/src/ethereum/forks/berlin/fork.py +++ b/src/ethereum/forks/berlin/fork.py @@ -56,11 +56,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 9000000 @@ -734,14 +733,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -757,12 +756,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/berlin/transactions.py b/src/ethereum/forks/berlin/transactions.py index 10a9e22a2c0..2721c25520c 100644 --- a/src/ethereum/forks/berlin/transactions.py +++ b/src/ethereum/forks/berlin/transactions.py @@ -23,37 +23,6 @@ from .exceptions import TransactionTypeError from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -287,7 +256,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -295,27 +264,29 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) access_list_cost = Uint(0) if isinstance(tx, AccessListTransaction): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/berlin/vm/gas.py b/src/ethereum/forks/berlin/vm/gas.py index 80441f0e4fd..1ffb7025f2a 100644 --- a/src/ethereum/forks/berlin/vm/gas.py +++ b/src/ethereum/forks/berlin/vm/gas.py @@ -22,47 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -83,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -136,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -191,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/berlin/vm/instructions/arithmetic.py b/src/ethereum/forks/berlin/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/berlin/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/berlin/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/berlin/vm/instructions/bitwise.py b/src/ethereum/forks/berlin/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/berlin/vm/instructions/bitwise.py +++ b/src/ethereum/forks/berlin/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/berlin/vm/instructions/block.py b/src/ethereum/forks/berlin/vm/instructions/block.py index bbf01739ff2..e3400f9461a 100644 --- a/src/ethereum/forks/berlin/vm/instructions/block.py +++ b/src/ethereum/forks/berlin/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/berlin/vm/instructions/comparison.py b/src/ethereum/forks/berlin/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/berlin/vm/instructions/comparison.py +++ b/src/ethereum/forks/berlin/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/berlin/vm/instructions/control_flow.py b/src/ethereum/forks/berlin/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/berlin/vm/instructions/control_flow.py +++ b/src/ethereum/forks/berlin/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/berlin/vm/instructions/environment.py b/src/ethereum/forks/berlin/vm/instructions/environment.py index 63733aca3d5..9e7b817ace6 100644 --- a/src/ethereum/forks/berlin/vm/instructions/environment.py +++ b/src/ethereum/forks/berlin/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,10 +67,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -103,7 +97,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -126,7 +120,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -149,7 +143,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -173,7 +167,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -198,7 +192,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -227,11 +221,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -256,7 +253,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -285,11 +282,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -314,7 +314,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -338,10 +338,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -374,16 +374,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -413,7 +413,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -439,11 +439,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -472,10 +477,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -507,7 +512,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. diff --git a/src/ethereum/forks/berlin/vm/instructions/keccak.py b/src/ethereum/forks/berlin/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/berlin/vm/instructions/keccak.py +++ b/src/ethereum/forks/berlin/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/berlin/vm/instructions/log.py b/src/ethereum/forks/berlin/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/berlin/vm/instructions/log.py +++ b/src/ethereum/forks/berlin/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/berlin/vm/instructions/memory.py b/src/ethereum/forks/berlin/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/berlin/vm/instructions/memory.py +++ b/src/ethereum/forks/berlin/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/berlin/vm/instructions/stack.py b/src/ethereum/forks/berlin/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/berlin/vm/instructions/stack.py +++ b/src/ethereum/forks/berlin/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/berlin/vm/instructions/storage.py b/src/ethereum/forks/berlin/vm/instructions/storage.py index d99ad70f93b..287544f353b 100644 --- a/src/ethereum/forks/berlin/vm/instructions/storage.py +++ b/src/ethereum/forks/berlin/vm/instructions/storage.py @@ -17,12 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,10 +39,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -73,7 +68,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,37 +81,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/berlin/vm/instructions/system.py b/src/ethereum/forks/berlin/vm/instructions/system.py index 4320315d945..4c0e63d6dbe 100644 --- a/src/ethereum/forks/berlin/vm/instructions/system.py +++ b/src/ethereum/forks/berlin/vm/instructions/system.py @@ -40,16 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -158,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -203,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -243,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -354,17 +345,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -434,12 +425,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -492,10 +483,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -504,7 +495,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -515,7 +506,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -582,10 +573,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost @@ -641,10 +632,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/berlin/vm/interpreter.py b/src/ethereum/forks/berlin/vm/interpreter.py index 6edd4cae8ca..1f482d07cea 100644 --- a/src/ethereum/forks/berlin/vm/interpreter.py +++ b/src/ethereum/forks/berlin/vm/interpreter.py @@ -45,7 +45,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -178,7 +178,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo1/fork.py b/src/ethereum/forks/bpo1/fork.py index 7e6b5ee46de..19ce50f243d 100644 --- a/src/ethereum/forks/bpo1/fork.py +++ b/src/ethereum/forks/bpo1/fork.py @@ -81,8 +81,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -92,15 +91,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( @@ -1030,14 +1027,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1053,12 +1050,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/bpo1/transactions.py b/src/ethereum/forks/bpo1/transactions.py index c8f1826324e..486b21f99b0 100644 --- a/src/ethereum/forks/bpo1/transactions.py +++ b/src/ethereum/forks/bpo1/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -601,7 +564,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -612,8 +575,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -621,31 +583,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/bpo1/vm/eoa_delegation.py b/src/ethereum/forks/bpo1/vm/eoa_delegation.py index fce580bee4a..3fd42910817 100644 --- a/src/ethereum/forks/bpo1/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo1/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -147,10 +146,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/bpo1/vm/gas.py b/src/ethereum/forks/bpo1/vm/gas.py index 51b439cd0a0..232bbdd4f23 100644 --- a/src/ethereum/forks/bpo1/vm/gas.py +++ b/src/ethereum/forks/bpo1/vm/gas.py @@ -24,65 +24,169 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(10) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(15) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(8346193) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(10) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(15) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(8346193) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -103,8 +207,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -156,7 +260,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -211,7 +315,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -283,7 +387,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -314,21 +418,23 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -347,7 +453,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -368,9 +474,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo1/vm/instructions/bitwise.py b/src/ethereum/forks/bpo1/vm/instructions/bitwise.py index cc6fa2fbb23..7674d3c720f 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo1/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +265,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo1/vm/instructions/block.py b/src/ethereum/forks/bpo1/vm/instructions/block.py index 75810aacd39..7e32893722b 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/block.py +++ b/src/ethereum/forks/bpo1/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo1/vm/instructions/comparison.py b/src/ethereum/forks/bpo1/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo1/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo1/vm/instructions/control_flow.py b/src/ethereum/forks/bpo1/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo1/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/bpo1/vm/instructions/environment.py b/src/ethereum/forks/bpo1/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo1/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/bpo1/vm/instructions/keccak.py b/src/ethereum/forks/bpo1/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo1/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo1/vm/instructions/log.py b/src/ethereum/forks/bpo1/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/log.py +++ b/src/ethereum/forks/bpo1/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo1/vm/instructions/memory.py b/src/ethereum/forks/bpo1/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo1/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo1/vm/instructions/stack.py b/src/ethereum/forks/bpo1/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo1/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo1/vm/instructions/storage.py b/src/ethereum/forks/bpo1/vm/instructions/storage.py index fd5bf4572ff..5aa3cc6746f 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo1/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -50,10 +45,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +74,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +87,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo1/vm/instructions/system.py b/src/ethereum/forks/bpo1/vm/instructions/system.py index 29c3fe9e6e2..1fe8daf44d5 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/system.py +++ b/src/ethereum/forks/bpo1/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,10 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, + GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +211,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +256,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +369,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +383,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +458,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +471,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -531,10 +526,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -543,7 +538,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +599,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -673,10 +668,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/bpo1/vm/interpreter.py b/src/ethereum/forks/bpo1/vm/interpreter.py index 9c05883b7dc..b79580a6429 100644 --- a/src/ethereum/forks/bpo1/vm/interpreter.py +++ b/src/ethereum/forks/bpo1/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..d1f63224a0c 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..2fd32313f89 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo2/fork.py b/src/ethereum/forks/bpo2/fork.py index 7e6b5ee46de..19ce50f243d 100644 --- a/src/ethereum/forks/bpo2/fork.py +++ b/src/ethereum/forks/bpo2/fork.py @@ -81,8 +81,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -92,15 +91,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( @@ -1030,14 +1027,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1053,12 +1050,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/bpo2/transactions.py b/src/ethereum/forks/bpo2/transactions.py index c8f1826324e..486b21f99b0 100644 --- a/src/ethereum/forks/bpo2/transactions.py +++ b/src/ethereum/forks/bpo2/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -601,7 +564,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -612,8 +575,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -621,31 +583,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/bpo2/vm/eoa_delegation.py b/src/ethereum/forks/bpo2/vm/eoa_delegation.py index fce580bee4a..3fd42910817 100644 --- a/src/ethereum/forks/bpo2/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo2/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -147,10 +146,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/bpo2/vm/gas.py b/src/ethereum/forks/bpo2/vm/gas.py index 5c30cd6a340..50edd7d5d7a 100644 --- a/src/ethereum/forks/bpo2/vm/gas.py +++ b/src/ethereum/forks/bpo2/vm/gas.py @@ -24,65 +24,169 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(14) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(21) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(14) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(21) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -103,8 +207,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -156,7 +260,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -211,7 +315,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -283,7 +387,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -314,21 +418,23 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -347,7 +453,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -368,9 +474,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo2/vm/instructions/bitwise.py b/src/ethereum/forks/bpo2/vm/instructions/bitwise.py index cc6fa2fbb23..8b41a55d2b2 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo2/vm/instructions/bitwise.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -34,7 +34,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +59,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +84,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +108,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +134,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +169,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +199,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +229,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +262,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo2/vm/instructions/block.py b/src/ethereum/forks/bpo2/vm/instructions/block.py index 9923433c7b6..76ab809b06b 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/block.py +++ b/src/ethereum/forks/bpo2/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo2/vm/instructions/comparison.py b/src/ethereum/forks/bpo2/vm/instructions/comparison.py index a6a3d99bc86..ee5c881ef0d 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo2/vm/instructions/comparison.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -34,7 +34,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +60,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +87,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +113,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +140,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +166,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo2/vm/instructions/control_flow.py b/src/ethereum/forks/bpo2/vm/instructions/control_flow.py index b3b1f2316a7..d74e7b90340 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo2/vm/instructions/control_flow.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import GasCosts, charge_gas from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +57,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +84,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +113,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +137,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +162,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/bpo2/vm/instructions/environment.py b/src/ethereum/forks/bpo2/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo2/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/bpo2/vm/instructions/keccak.py b/src/ethereum/forks/bpo2/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo2/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo2/vm/instructions/log.py b/src/ethereum/forks/bpo2/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/log.py +++ b/src/ethereum/forks/bpo2/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo2/vm/instructions/memory.py b/src/ethereum/forks/bpo2/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo2/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo2/vm/instructions/stack.py b/src/ethereum/forks/bpo2/vm/instructions/stack.py index 0007a28acd4..d7b3df986b0 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo2/vm/instructions/stack.py @@ -17,7 +17,7 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..memory import buffer_read @@ -35,7 +35,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +63,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo2/vm/instructions/storage.py b/src/ethereum/forks/bpo2/vm/instructions/storage.py index fd5bf4572ff..dbbd8db40ca 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo2/vm/instructions/storage.py @@ -22,15 +22,7 @@ ) from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +84,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +145,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +172,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo2/vm/instructions/system.py b/src/ethereum/forks/bpo2/vm/instructions/system.py index 29c3fe9e6e2..2d99ac93e61 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/system.py +++ b/src/ethereum/forks/bpo2/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,9 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +210,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +255,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +368,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +382,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +457,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +470,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -531,10 +525,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -543,7 +537,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +598,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -673,10 +667,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/bpo2/vm/interpreter.py b/src/ethereum/forks/bpo2/vm/interpreter.py index a7b27243123..31e07e2d968 100644 --- a/src/ethereum/forks/bpo2/vm/interpreter.py +++ b/src/ethereum/forks/bpo2/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..f77ff60a32c 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -20,12 +20,7 @@ ) from ....vm import Evm -from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, - charge_gas, -) +from ....vm.gas import GasCosts, charge_gas from ....vm.memory import buffer_read from ...exceptions import InvalidParameter from . import ( @@ -60,7 +55,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +96,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +135,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..b49ec065e7c 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -20,12 +20,7 @@ ) from ....vm import Evm -from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, - charge_gas, -) +from ....vm.gas import GasCosts, charge_gas from ....vm.memory import buffer_read from ...exceptions import InvalidParameter from . import ( @@ -61,7 +56,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +97,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +136,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py index 133a4832bf8..2b4929fb8d2 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py @@ -16,11 +16,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def identity(evm: Evm) -> None: @@ -39,8 +35,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..04d0e2ff594 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py @@ -19,11 +19,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def ripemd160(evm: Evm) -> None: @@ -42,8 +38,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py index 04dfef6730d..f5346f1529c 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py @@ -18,11 +18,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def sha256(evm: Evm) -> None: @@ -41,8 +37,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo3/fork.py b/src/ethereum/forks/bpo3/fork.py index 7e6b5ee46de..19ce50f243d 100644 --- a/src/ethereum/forks/bpo3/fork.py +++ b/src/ethereum/forks/bpo3/fork.py @@ -81,8 +81,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -92,15 +91,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( @@ -1030,14 +1027,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1053,12 +1050,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/bpo3/transactions.py b/src/ethereum/forks/bpo3/transactions.py index c8f1826324e..486b21f99b0 100644 --- a/src/ethereum/forks/bpo3/transactions.py +++ b/src/ethereum/forks/bpo3/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -601,7 +564,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -612,8 +575,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -621,31 +583,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/bpo3/vm/eoa_delegation.py b/src/ethereum/forks/bpo3/vm/eoa_delegation.py index fce580bee4a..3fd42910817 100644 --- a/src/ethereum/forks/bpo3/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo3/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -147,10 +146,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/bpo3/vm/gas.py b/src/ethereum/forks/bpo3/vm/gas.py index 5c30cd6a340..50edd7d5d7a 100644 --- a/src/ethereum/forks/bpo3/vm/gas.py +++ b/src/ethereum/forks/bpo3/vm/gas.py @@ -24,65 +24,169 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(14) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(21) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(14) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(21) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -103,8 +207,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -156,7 +260,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -211,7 +315,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -283,7 +387,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -314,21 +418,23 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -347,7 +453,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -368,9 +474,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo3/vm/instructions/bitwise.py b/src/ethereum/forks/bpo3/vm/instructions/bitwise.py index cc6fa2fbb23..8b41a55d2b2 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo3/vm/instructions/bitwise.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -34,7 +34,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +59,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +84,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +108,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +134,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +169,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +199,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +229,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +262,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo3/vm/instructions/block.py b/src/ethereum/forks/bpo3/vm/instructions/block.py index 10fcbdbdb57..54183f4773e 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/block.py +++ b/src/ethereum/forks/bpo3/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo3/vm/instructions/comparison.py b/src/ethereum/forks/bpo3/vm/instructions/comparison.py index a6a3d99bc86..ee5c881ef0d 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo3/vm/instructions/comparison.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -34,7 +34,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +60,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +87,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +113,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +140,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +166,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo3/vm/instructions/control_flow.py b/src/ethereum/forks/bpo3/vm/instructions/control_flow.py index b3b1f2316a7..d74e7b90340 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo3/vm/instructions/control_flow.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import GasCosts, charge_gas from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +57,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +84,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +113,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +137,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +162,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/bpo3/vm/instructions/environment.py b/src/ethereum/forks/bpo3/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo3/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/bpo3/vm/instructions/keccak.py b/src/ethereum/forks/bpo3/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo3/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo3/vm/instructions/log.py b/src/ethereum/forks/bpo3/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/log.py +++ b/src/ethereum/forks/bpo3/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo3/vm/instructions/memory.py b/src/ethereum/forks/bpo3/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo3/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo3/vm/instructions/stack.py b/src/ethereum/forks/bpo3/vm/instructions/stack.py index 0007a28acd4..d7b3df986b0 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo3/vm/instructions/stack.py @@ -17,7 +17,7 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..memory import buffer_read @@ -35,7 +35,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +63,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo3/vm/instructions/storage.py b/src/ethereum/forks/bpo3/vm/instructions/storage.py index fd5bf4572ff..dbbd8db40ca 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo3/vm/instructions/storage.py @@ -22,15 +22,7 @@ ) from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +84,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +145,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +172,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo3/vm/instructions/system.py b/src/ethereum/forks/bpo3/vm/instructions/system.py index 29c3fe9e6e2..2d99ac93e61 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/system.py +++ b/src/ethereum/forks/bpo3/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,9 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +210,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +255,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +368,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +382,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +457,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +470,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -531,10 +525,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -543,7 +537,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +598,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -673,10 +667,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/bpo3/vm/interpreter.py b/src/ethereum/forks/bpo3/vm/interpreter.py index 4111d5b4c78..d3c301fc708 100644 --- a/src/ethereum/forks/bpo3/vm/interpreter.py +++ b/src/ethereum/forks/bpo3/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..fa0d3ec4c2d 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..a5b2be04018 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo4/fork.py b/src/ethereum/forks/bpo4/fork.py index 7e6b5ee46de..19ce50f243d 100644 --- a/src/ethereum/forks/bpo4/fork.py +++ b/src/ethereum/forks/bpo4/fork.py @@ -81,8 +81,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -92,15 +91,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( @@ -1030,14 +1027,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1053,12 +1050,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/bpo4/transactions.py b/src/ethereum/forks/bpo4/transactions.py index c8f1826324e..486b21f99b0 100644 --- a/src/ethereum/forks/bpo4/transactions.py +++ b/src/ethereum/forks/bpo4/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -601,7 +564,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -612,8 +575,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -621,31 +583,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/bpo4/vm/eoa_delegation.py b/src/ethereum/forks/bpo4/vm/eoa_delegation.py index fce580bee4a..3fd42910817 100644 --- a/src/ethereum/forks/bpo4/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo4/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -147,10 +146,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/bpo4/vm/gas.py b/src/ethereum/forks/bpo4/vm/gas.py index 5c30cd6a340..50edd7d5d7a 100644 --- a/src/ethereum/forks/bpo4/vm/gas.py +++ b/src/ethereum/forks/bpo4/vm/gas.py @@ -24,65 +24,169 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(14) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(21) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(14) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(21) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -103,8 +207,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -156,7 +260,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -211,7 +315,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -283,7 +387,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -314,21 +418,23 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -347,7 +453,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -368,9 +474,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo4/vm/instructions/bitwise.py b/src/ethereum/forks/bpo4/vm/instructions/bitwise.py index cc6fa2fbb23..7674d3c720f 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo4/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +265,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo4/vm/instructions/block.py b/src/ethereum/forks/bpo4/vm/instructions/block.py index 52145aa9f82..e53d2a57a35 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/block.py +++ b/src/ethereum/forks/bpo4/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo4/vm/instructions/comparison.py b/src/ethereum/forks/bpo4/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo4/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo4/vm/instructions/control_flow.py b/src/ethereum/forks/bpo4/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo4/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/bpo4/vm/instructions/environment.py b/src/ethereum/forks/bpo4/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo4/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/bpo4/vm/instructions/keccak.py b/src/ethereum/forks/bpo4/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo4/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo4/vm/instructions/log.py b/src/ethereum/forks/bpo4/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/log.py +++ b/src/ethereum/forks/bpo4/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo4/vm/instructions/memory.py b/src/ethereum/forks/bpo4/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo4/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo4/vm/instructions/stack.py b/src/ethereum/forks/bpo4/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo4/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo4/vm/instructions/storage.py b/src/ethereum/forks/bpo4/vm/instructions/storage.py index fd5bf4572ff..5aa3cc6746f 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo4/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -50,10 +45,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +74,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +87,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo4/vm/instructions/system.py b/src/ethereum/forks/bpo4/vm/instructions/system.py index 29c3fe9e6e2..1fe8daf44d5 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/system.py +++ b/src/ethereum/forks/bpo4/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,10 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, + GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +211,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +256,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +369,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +383,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +458,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +471,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -531,10 +526,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -543,7 +538,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +599,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -673,10 +668,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/bpo4/vm/interpreter.py b/src/ethereum/forks/bpo4/vm/interpreter.py index 7e789cf4b69..de598138081 100644 --- a/src/ethereum/forks/bpo4/vm/interpreter.py +++ b/src/ethereum/forks/bpo4/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..fa0d3ec4c2d 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..a5b2be04018 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo5/fork.py b/src/ethereum/forks/bpo5/fork.py index 7e6b5ee46de..19ce50f243d 100644 --- a/src/ethereum/forks/bpo5/fork.py +++ b/src/ethereum/forks/bpo5/fork.py @@ -81,8 +81,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -92,15 +91,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( @@ -1030,14 +1027,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1053,12 +1050,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/bpo5/transactions.py b/src/ethereum/forks/bpo5/transactions.py index c8f1826324e..486b21f99b0 100644 --- a/src/ethereum/forks/bpo5/transactions.py +++ b/src/ethereum/forks/bpo5/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -601,7 +564,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -612,8 +575,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -621,31 +583,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/bpo5/vm/eoa_delegation.py b/src/ethereum/forks/bpo5/vm/eoa_delegation.py index fce580bee4a..3fd42910817 100644 --- a/src/ethereum/forks/bpo5/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo5/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -147,10 +146,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/bpo5/vm/gas.py b/src/ethereum/forks/bpo5/vm/gas.py index 5c30cd6a340..50edd7d5d7a 100644 --- a/src/ethereum/forks/bpo5/vm/gas.py +++ b/src/ethereum/forks/bpo5/vm/gas.py @@ -24,65 +24,169 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(14) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(21) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(14) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(21) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -103,8 +207,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -156,7 +260,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -211,7 +315,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -283,7 +387,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -314,21 +418,23 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -347,7 +453,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -368,9 +474,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo5/vm/instructions/bitwise.py b/src/ethereum/forks/bpo5/vm/instructions/bitwise.py index cc6fa2fbb23..7674d3c720f 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo5/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +265,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo5/vm/instructions/block.py b/src/ethereum/forks/bpo5/vm/instructions/block.py index 84930244d4c..faa2e0fa040 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/block.py +++ b/src/ethereum/forks/bpo5/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo5/vm/instructions/comparison.py b/src/ethereum/forks/bpo5/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo5/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo5/vm/instructions/control_flow.py b/src/ethereum/forks/bpo5/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo5/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/bpo5/vm/instructions/environment.py b/src/ethereum/forks/bpo5/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo5/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/bpo5/vm/instructions/keccak.py b/src/ethereum/forks/bpo5/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo5/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo5/vm/instructions/log.py b/src/ethereum/forks/bpo5/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/log.py +++ b/src/ethereum/forks/bpo5/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo5/vm/instructions/memory.py b/src/ethereum/forks/bpo5/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo5/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo5/vm/instructions/stack.py b/src/ethereum/forks/bpo5/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo5/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo5/vm/instructions/storage.py b/src/ethereum/forks/bpo5/vm/instructions/storage.py index fd5bf4572ff..5aa3cc6746f 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo5/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -50,10 +45,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +74,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +87,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo5/vm/instructions/system.py b/src/ethereum/forks/bpo5/vm/instructions/system.py index 29c3fe9e6e2..1fe8daf44d5 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/system.py +++ b/src/ethereum/forks/bpo5/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,10 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, + GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +211,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +256,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +369,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +383,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +458,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +471,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -531,10 +526,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -543,7 +538,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +599,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -673,10 +668,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/bpo5/vm/interpreter.py b/src/ethereum/forks/bpo5/vm/interpreter.py index d0eda4ef22d..138131315c5 100644 --- a/src/ethereum/forks/bpo5/vm/interpreter.py +++ b/src/ethereum/forks/bpo5/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..fa0d3ec4c2d 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..a5b2be04018 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/byzantium/fork.py b/src/ethereum/forks/byzantium/fork.py index 3cbf03500b3..848a1edf547 100644 --- a/src/ethereum/forks/byzantium/fork.py +++ b/src/ethereum/forks/byzantium/fork.py @@ -51,11 +51,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(3 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 3000000 @@ -711,12 +710,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -734,12 +733,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/byzantium/transactions.py b/src/ethereum/forks/byzantium/transactions.py index 278238f8d5a..e8cde82b198 100644 --- a/src/ethereum/forks/byzantium/transactions.py +++ b/src/ethereum/forks/byzantium/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/byzantium/vm/gas.py b/src/ethereum/forks/byzantium/vm/gas.py index c4aa9846029..6121e3bbce0 100644 --- a/src/ethereum/forks/byzantium/vm/gas.py +++ b/src/ethereum/forks/byzantium/vm/gas.py @@ -22,46 +22,136 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(200) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(700) -GAS_BALANCE = Uint(400) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(700) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(200) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECADD = Uint(500) + PRECOMPILE_ECMUL = Uint(40000) + PRECOMPILE_ECPAIRING_BASE = Uint(100000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(80000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_EXTERNAL_BASE = Uint(700) + OPCODE_BALANCE = Uint(400) + OPCODE_CALL_BASE = Uint(700) @dataclass @@ -82,8 +172,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -135,7 +225,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -190,7 +280,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py b/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/byzantium/vm/instructions/bitwise.py b/src/ethereum/forks/byzantium/vm/instructions/bitwise.py index 2a506f55751..62da98041ad 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/bitwise.py +++ b/src/ethereum/forks/byzantium/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/byzantium/vm/instructions/block.py b/src/ethereum/forks/byzantium/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/block.py +++ b/src/ethereum/forks/byzantium/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/byzantium/vm/instructions/comparison.py b/src/ethereum/forks/byzantium/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/comparison.py +++ b/src/ethereum/forks/byzantium/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/byzantium/vm/instructions/control_flow.py b/src/ethereum/forks/byzantium/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/control_flow.py +++ b/src/ethereum/forks/byzantium/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/byzantium/vm/instructions/environment.py b/src/ethereum/forks/byzantium/vm/instructions/environment.py index 0fa98ce55a5..c459b2aebec 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/environment.py +++ b/src/ethereum/forks/byzantium/vm/instructions/environment.py @@ -21,12 +21,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_COPY, - GAS_EXTERNAL, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -47,7 +42,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -70,7 +65,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -97,7 +92,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -120,7 +115,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -143,7 +138,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -167,7 +162,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -192,7 +187,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -221,11 +216,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -250,7 +248,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -279,11 +277,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -308,7 +309,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -331,7 +332,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -362,11 +363,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -394,7 +398,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -420,11 +424,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/byzantium/vm/instructions/keccak.py b/src/ethereum/forks/byzantium/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/keccak.py +++ b/src/ethereum/forks/byzantium/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/byzantium/vm/instructions/log.py b/src/ethereum/forks/byzantium/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/log.py +++ b/src/ethereum/forks/byzantium/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/byzantium/vm/instructions/memory.py b/src/ethereum/forks/byzantium/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/memory.py +++ b/src/ethereum/forks/byzantium/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/byzantium/vm/instructions/stack.py b/src/ethereum/forks/byzantium/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/stack.py +++ b/src/ethereum/forks/byzantium/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/byzantium/vm/instructions/storage.py b/src/ethereum/forks/byzantium/vm/instructions/storage.py index e1c4e4e0958..0e5aae6031d 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/storage.py +++ b/src/ethereum/forks/byzantium/vm/instructions/storage.py @@ -17,10 +17,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -41,7 +38,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -72,12 +69,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/byzantium/vm/instructions/system.py b/src/ethereum/forks/byzantium/vm/instructions/system.py index 9a4a7ce52ae..01e4048cc67 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/system.py +++ b/src/ethereum/forks/byzantium/vm/instructions/system.py @@ -35,14 +35,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL, - GAS_CALL_VALUE, - GAS_CREATE, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -76,7 +69,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) create_message_gas = max_message_call_gas(Uint(evm.gas_left)) evm.gas_left -= create_message_gas @@ -170,7 +163,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -280,16 +273,16 @@ def call(evm: Evm) -> None: code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + create_gas_cost + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + create_gas_cost + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) if evm.message.is_static and value != U256(0): @@ -351,13 +344,13 @@ def callcode(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -404,7 +397,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( not is_account_alive(evm.message.block_env.state, beneficiary) and get_account( @@ -412,7 +405,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -423,7 +416,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -488,7 +481,11 @@ def delegatecall(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, GAS_CALL + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -547,7 +544,7 @@ def staticcall(evm: Evm) -> None: gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) diff --git a/src/ethereum/forks/byzantium/vm/interpreter.py b/src/ethereum/forks/byzantium/vm/interpreter.py index 2cb1ccc3335..a5a72762dbd 100644 --- a/src/ethereum/forks/byzantium/vm/interpreter.py +++ b/src/ethereum/forks/byzantium/vm/interpreter.py @@ -44,7 +44,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -174,7 +174,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py index d579abb2b8a..09bed4a0282 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(500)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(40000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(80000 * (len(data) // 192) + 100000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py index 133a4832bf8..2b4929fb8d2 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py @@ -16,11 +16,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def identity(evm: Evm) -> None: @@ -39,8 +35,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..04d0e2ff594 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py @@ -19,11 +19,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def ripemd160(evm: Evm) -> None: @@ -42,8 +38,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py index 04dfef6730d..f5346f1529c 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py @@ -18,11 +18,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def sha256(evm: Evm) -> None: @@ -41,8 +37,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index 1c1dbab2865..ac5373fac95 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -70,6 +70,7 @@ from .utils.message import prepare_message from .vm import Message from .vm.gas import ( + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -79,8 +80,6 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( @@ -852,12 +851,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -875,12 +874,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/cancun/transactions.py b/src/ethereum/forks/cancun/transactions.py index c94f3df0647..b8f431f64e0 100644 --- a/src/ethereum/forks/cancun/transactions.py +++ b/src/ethereum/forks/cancun/transactions.py @@ -24,37 +24,6 @@ from .exceptions import InitCodeTooLargeError, TransactionTypeError from .fork_types import VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -480,7 +449,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -488,17 +457,17 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) @@ -507,12 +476,12 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: tx, (AccessListTransaction, FeeMarketTransaction, BlobTransaction) ): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/cancun/vm/gas.py b/src/ethereum/forks/cancun/vm/gas.py index 0523287c6cf..c3a65792ec2 100644 --- a/src/ethereum/forks/cancun/vm/gas.py +++ b/src/ethereum/forks/cancun/vm/gas.py @@ -24,54 +24,155 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_TARGET_GAS_PER_BLOCK = U64(393216) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(3338477) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_TARGET_GAS_PER_BLOCK = U64(393216) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(3338477) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -92,8 +193,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -145,7 +246,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -200,7 +301,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -272,7 +373,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -301,10 +402,10 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: blob_gas_used = parent_header.blob_gas_used parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -323,7 +424,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -344,9 +445,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/cancun/vm/instructions/arithmetic.py b/src/ethereum/forks/cancun/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/cancun/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/cancun/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/cancun/vm/instructions/bitwise.py b/src/ethereum/forks/cancun/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/cancun/vm/instructions/bitwise.py +++ b/src/ethereum/forks/cancun/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/cancun/vm/instructions/block.py b/src/ethereum/forks/cancun/vm/instructions/block.py index 4f971a9dbf4..82378940859 100644 --- a/src/ethereum/forks/cancun/vm/instructions/block.py +++ b/src/ethereum/forks/cancun/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/cancun/vm/instructions/comparison.py b/src/ethereum/forks/cancun/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/cancun/vm/instructions/comparison.py +++ b/src/ethereum/forks/cancun/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/cancun/vm/instructions/control_flow.py b/src/ethereum/forks/cancun/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/cancun/vm/instructions/control_flow.py +++ b/src/ethereum/forks/cancun/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/cancun/vm/instructions/environment.py b/src/ethereum/forks/cancun/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/cancun/vm/instructions/environment.py +++ b/src/ethereum/forks/cancun/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/cancun/vm/instructions/keccak.py b/src/ethereum/forks/cancun/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/cancun/vm/instructions/keccak.py +++ b/src/ethereum/forks/cancun/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/cancun/vm/instructions/log.py b/src/ethereum/forks/cancun/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/cancun/vm/instructions/log.py +++ b/src/ethereum/forks/cancun/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/cancun/vm/instructions/memory.py b/src/ethereum/forks/cancun/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/cancun/vm/instructions/memory.py +++ b/src/ethereum/forks/cancun/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/cancun/vm/instructions/stack.py b/src/ethereum/forks/cancun/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/cancun/vm/instructions/stack.py +++ b/src/ethereum/forks/cancun/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/cancun/vm/instructions/storage.py b/src/ethereum/forks/cancun/vm/instructions/storage.py index fd5bf4572ff..5aa3cc6746f 100644 --- a/src/ethereum/forks/cancun/vm/instructions/storage.py +++ b/src/ethereum/forks/cancun/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -50,10 +45,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +74,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +87,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/cancun/vm/instructions/system.py b/src/ethereum/forks/cancun/vm/instructions/system.py index db725606a08..0808eb1f7a7 100644 --- a/src/ethereum/forks/cancun/vm/instructions/system.py +++ b/src/ethereum/forks/cancun/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -165,7 +157,9 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -215,8 +209,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -260,7 +254,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -371,17 +365,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -451,12 +445,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -509,10 +503,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -521,7 +515,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -582,10 +576,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost @@ -641,10 +635,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/cancun/vm/interpreter.py b/src/ethereum/forks/cancun/vm/interpreter.py index 7f4bed0129c..05d14c7aebe 100644 --- a/src/ethereum/forks/cancun/vm/interpreter.py +++ b/src/ethereum/forks/cancun/vm/interpreter.py @@ -43,7 +43,7 @@ set_code, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -171,7 +171,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py index 133a4832bf8..2b4929fb8d2 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py @@ -16,11 +16,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def identity(evm: Evm) -> None: @@ -39,8 +35,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..04d0e2ff594 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py @@ -19,11 +19,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def ripemd160(evm: Evm) -> None: @@ -42,8 +38,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py index 04dfef6730d..f5346f1529c 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py @@ -18,11 +18,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def sha256(evm: Evm) -> None: @@ -41,8 +37,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/constantinople/fork.py b/src/ethereum/forks/constantinople/fork.py index 7ed470d41e3..a75b6656f14 100644 --- a/src/ethereum/forks/constantinople/fork.py +++ b/src/ethereum/forks/constantinople/fork.py @@ -51,11 +51,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 5000000 @@ -711,12 +710,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -734,12 +733,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/constantinople/transactions.py b/src/ethereum/forks/constantinople/transactions.py index 278238f8d5a..e8cde82b198 100644 --- a/src/ethereum/forks/constantinople/transactions.py +++ b/src/ethereum/forks/constantinople/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/constantinople/vm/gas.py b/src/ethereum/forks/constantinople/vm/gas.py index f59699f0347..85e4d3be422 100644 --- a/src/ethereum/forks/constantinople/vm/gas.py +++ b/src/ethereum/forks/constantinople/vm/gas.py @@ -22,47 +22,140 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(200) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(700) -GAS_BALANCE = Uint(400) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(700) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_CODE_HASH = Uint(400) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(200) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECADD = Uint(500) + PRECOMPILE_ECMUL = Uint(40000) + PRECOMPILE_ECPAIRING_BASE = Uint(100000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(80000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_EXTCODEHASH = Uint(400) + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_EXTERNAL_BASE = Uint(700) + OPCODE_BALANCE = Uint(400) + OPCODE_CALL_BASE = Uint(700) @dataclass @@ -83,8 +176,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -136,7 +229,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -191,7 +284,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py b/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/constantinople/vm/instructions/bitwise.py b/src/ethereum/forks/constantinople/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/bitwise.py +++ b/src/ethereum/forks/constantinople/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/constantinople/vm/instructions/block.py b/src/ethereum/forks/constantinople/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/block.py +++ b/src/ethereum/forks/constantinople/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/constantinople/vm/instructions/comparison.py b/src/ethereum/forks/constantinople/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/comparison.py +++ b/src/ethereum/forks/constantinople/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/constantinople/vm/instructions/control_flow.py b/src/ethereum/forks/constantinople/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/control_flow.py +++ b/src/ethereum/forks/constantinople/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/constantinople/vm/instructions/environment.py b/src/ethereum/forks/constantinople/vm/instructions/environment.py index d5572be1b4a..2761ffda5fe 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/environment.py +++ b/src/ethereum/forks/constantinople/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_CODE_HASH, - GAS_COPY, - GAS_EXTERNAL, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -72,7 +66,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -99,7 +93,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -122,7 +116,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -145,7 +139,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -169,7 +163,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -194,7 +188,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -223,11 +217,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -252,7 +249,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -281,11 +278,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -310,7 +310,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -333,7 +333,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -364,11 +364,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -396,7 +399,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -422,11 +425,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -454,7 +462,7 @@ def extcodehash(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_CODE_HASH) + charge_gas(evm, GasCosts.OPCODE_EXTCODEHASH) # OPERATION account = get_account(evm.message.block_env.state, address) diff --git a/src/ethereum/forks/constantinople/vm/instructions/keccak.py b/src/ethereum/forks/constantinople/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/keccak.py +++ b/src/ethereum/forks/constantinople/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/constantinople/vm/instructions/log.py b/src/ethereum/forks/constantinople/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/log.py +++ b/src/ethereum/forks/constantinople/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/constantinople/vm/instructions/memory.py b/src/ethereum/forks/constantinople/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/memory.py +++ b/src/ethereum/forks/constantinople/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/constantinople/vm/instructions/stack.py b/src/ethereum/forks/constantinople/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/stack.py +++ b/src/ethereum/forks/constantinople/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/constantinople/vm/instructions/storage.py b/src/ethereum/forks/constantinople/vm/instructions/storage.py index e1c4e4e0958..0e5aae6031d 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/storage.py +++ b/src/ethereum/forks/constantinople/vm/instructions/storage.py @@ -17,10 +17,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -41,7 +38,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -72,12 +69,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/constantinople/vm/instructions/system.py b/src/ethereum/forks/constantinople/vm/instructions/system.py index c251e65574d..bd66624215d 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/system.py +++ b/src/ethereum/forks/constantinople/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL, - GAS_CALL_VALUE, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -157,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -202,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -242,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -352,16 +344,16 @@ def call(evm: Evm) -> None: code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + create_gas_cost + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + create_gas_cost + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) if evm.message.is_static and value != U256(0): @@ -423,13 +415,13 @@ def callcode(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -476,7 +468,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( not is_account_alive(evm.message.block_env.state, beneficiary) and get_account( @@ -484,7 +476,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -495,7 +487,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -561,7 +553,11 @@ def delegatecall(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, GAS_CALL + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -620,7 +616,7 @@ def staticcall(evm: Evm) -> None: gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) diff --git a/src/ethereum/forks/constantinople/vm/interpreter.py b/src/ethereum/forks/constantinople/vm/interpreter.py index b26937492a9..ffd3e29a5b7 100644 --- a/src/ethereum/forks/constantinople/vm/interpreter.py +++ b/src/ethereum/forks/constantinople/vm/interpreter.py @@ -44,7 +44,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -174,7 +174,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py index d579abb2b8a..09bed4a0282 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(500)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(40000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(80000 * (len(data) // 192) + 100000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/dao_fork/fork.py b/src/ethereum/forks/dao_fork/fork.py index 9dc372bec66..8dae3e9f95a 100644 --- a/src/ethereum/forks/dao_fork/fork.py +++ b/src/ethereum/forks/dao_fork/fork.py @@ -53,11 +53,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(5 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) @@ -721,12 +720,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -744,12 +743,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/dao_fork/transactions.py b/src/ethereum/forks/dao_fork/transactions.py index 934540874ca..e17bafae49d 100644 --- a/src/ethereum/forks/dao_fork/transactions.py +++ b/src/ethereum/forks/dao_fork/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(tx: Transaction) -> Address: diff --git a/src/ethereum/forks/dao_fork/vm/gas.py b/src/ethereum/forks/dao_fork/vm/gas.py index fc01397ceb0..f3644b8bf6a 100644 --- a/src/ethereum/forks/dao_fork/vm/gas.py +++ b/src/ethereum/forks/dao_fork/vm/gas.py @@ -24,43 +24,127 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(50) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(10) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(20) -GAS_BALANCE = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(40) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -REFUND_SELF_DESTRUCT = Uint(24000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(50) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = Uint(24000) + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(10) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_EXTERNAL_BASE = Uint(20) + OPCODE_BALANCE = Uint(20) + OPCODE_CALL_BASE = Uint(40) @dataclass @@ -81,8 +165,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -134,7 +218,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -205,8 +289,12 @@ def calculate_message_call_gas( message_call_gas: `MessageCallGas` """ - create_gas_cost = Uint(0) if account_exists(state, to) else GAS_NEW_ACCOUNT - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE - cost = GAS_CALL + gas + create_gas_cost + transfer_gas_cost - stipend = gas if value == 0 else GAS_CALL_STIPEND + gas + create_gas_cost = ( + Uint(0) if account_exists(state, to) else GasCosts.NEW_ACCOUNT + ) + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE + cost = ( + GasCosts.OPCODE_CALL_BASE + gas + create_gas_cost + transfer_gas_cost + ) + stipend = gas if value == 0 else GasCosts.CALL_STIPEND + gas return MessageCallGas(cost, stipend) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py b/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py b/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py index 2a506f55751..62da98041ad 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/dao_fork/vm/instructions/block.py b/src/ethereum/forks/dao_fork/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/block.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/comparison.py b/src/ethereum/forks/dao_fork/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/comparison.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py b/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/dao_fork/vm/instructions/environment.py b/src/ethereum/forks/dao_fork/vm/instructions/environment.py index 83eb5528226..d930368fdd9 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/environment.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/environment.py @@ -20,11 +20,7 @@ from ...vm.memory import buffer_read, memory_write from .. import Evm from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_COPY, - GAS_EXTERNAL, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -45,7 +41,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -68,7 +64,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -95,7 +91,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -118,7 +114,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -141,7 +137,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -165,7 +161,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -190,7 +186,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -219,11 +215,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -248,7 +247,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -277,11 +276,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -306,7 +308,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -329,7 +331,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -360,11 +362,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/dao_fork/vm/instructions/keccak.py b/src/ethereum/forks/dao_fork/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/keccak.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/dao_fork/vm/instructions/log.py b/src/ethereum/forks/dao_fork/vm/instructions/log.py index 76c02e737a4..e3e3ebd7e76 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/log.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/log.py @@ -18,9 +18,7 @@ from ...blocks import Log from .. import Evm from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/memory.py b/src/ethereum/forks/dao_fork/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/memory.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/stack.py b/src/ethereum/forks/dao_fork/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/stack.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/dao_fork/vm/instructions/storage.py b/src/ethereum/forks/dao_fork/vm/instructions/storage.py index 154b4fd47bb..0b2a1cce8aa 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/storage.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/storage.py @@ -16,10 +16,7 @@ from ...state import get_storage, set_storage from .. import Evm from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -40,7 +37,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -71,12 +68,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/system.py b/src/ethereum/forks/dao_fork/vm/instructions/system.py index 75226650693..c40a241886a 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/system.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/system.py @@ -32,10 +32,7 @@ incorporate_child_on_success, ) from ..gas import ( - GAS_CALL, - GAS_CREATE, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -68,7 +65,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) create_message_gas = evm.gas_left evm.gas_left = Uint(0) @@ -157,7 +154,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -368,7 +365,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_ZERO + gas_cost = GasCosts.ZERO originator = evm.message.current_target @@ -379,7 +376,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += int(REFUND_SELF_DESTRUCT) + evm.refund_counter += int(GasCosts.REFUND_SELF_DESTRUCT) charge_gas(evm, gas_cost) @@ -438,7 +435,7 @@ def delegatecall(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - charge_gas(evm, GAS_CALL + gas + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CALL_BASE + gas + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/dao_fork/vm/interpreter.py b/src/ethereum/forks/dao_fork/vm/interpreter.py index 4d26439da49..40bdffcc071 100644 --- a/src/ethereum/forks/dao_fork/vm/interpreter.py +++ b/src/ethereum/forks/dao_fork/vm/interpreter.py @@ -42,7 +42,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -158,7 +158,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/frontier/fork.py b/src/ethereum/forks/frontier/fork.py index 5f062710138..70c52a0c056 100644 --- a/src/ethereum/forks/frontier/fork.py +++ b/src/ethereum/forks/frontier/fork.py @@ -49,11 +49,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(5 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) @@ -700,14 +699,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -723,12 +722,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/frontier/transactions.py b/src/ethereum/forks/frontier/transactions.py index 32be1dcdf0a..69b9ec52083 100644 --- a/src/ethereum/forks/frontier/transactions.py +++ b/src/ethereum/forks/frontier/transactions.py @@ -21,22 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - @slotted_freezable @dataclass @@ -138,20 +122,22 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) - return GAS_TX_BASE + data_cost + return GasCosts.TX_BASE + data_cost def recover_sender(tx: Transaction) -> Address: diff --git a/src/ethereum/forks/frontier/vm/gas.py b/src/ethereum/forks/frontier/vm/gas.py index fc01397ceb0..ec6e91a20ce 100644 --- a/src/ethereum/forks/frontier/vm/gas.py +++ b/src/ethereum/forks/frontier/vm/gas.py @@ -24,43 +24,125 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(50) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(10) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(20) -GAS_BALANCE = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(40) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -REFUND_SELF_DESTRUCT = Uint(24000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(50) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = Uint(24000) + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + + # Transactions + TX_BASE = Uint(21000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(10) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_EXTERNAL_BASE = Uint(20) + OPCODE_BALANCE = Uint(20) + OPCODE_CALL_BASE = Uint(40) @dataclass @@ -81,8 +163,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -134,7 +216,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -205,8 +287,12 @@ def calculate_message_call_gas( message_call_gas: `MessageCallGas` """ - create_gas_cost = Uint(0) if account_exists(state, to) else GAS_NEW_ACCOUNT - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE - cost = GAS_CALL + gas + create_gas_cost + transfer_gas_cost - stipend = gas if value == 0 else GAS_CALL_STIPEND + gas + create_gas_cost = ( + Uint(0) if account_exists(state, to) else GasCosts.NEW_ACCOUNT + ) + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE + cost = ( + GasCosts.OPCODE_CALL_BASE + gas + create_gas_cost + transfer_gas_cost + ) + stipend = gas if value == 0 else GasCosts.CALL_STIPEND + gas return MessageCallGas(cost, stipend) diff --git a/src/ethereum/forks/frontier/vm/instructions/arithmetic.py b/src/ethereum/forks/frontier/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/frontier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/frontier/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/frontier/vm/instructions/bitwise.py b/src/ethereum/forks/frontier/vm/instructions/bitwise.py index 2a506f55751..62da98041ad 100644 --- a/src/ethereum/forks/frontier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/frontier/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/frontier/vm/instructions/block.py b/src/ethereum/forks/frontier/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/frontier/vm/instructions/block.py +++ b/src/ethereum/forks/frontier/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/frontier/vm/instructions/comparison.py b/src/ethereum/forks/frontier/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/frontier/vm/instructions/comparison.py +++ b/src/ethereum/forks/frontier/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/frontier/vm/instructions/control_flow.py b/src/ethereum/forks/frontier/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/frontier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/frontier/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/frontier/vm/instructions/environment.py b/src/ethereum/forks/frontier/vm/instructions/environment.py index 83eb5528226..d930368fdd9 100644 --- a/src/ethereum/forks/frontier/vm/instructions/environment.py +++ b/src/ethereum/forks/frontier/vm/instructions/environment.py @@ -20,11 +20,7 @@ from ...vm.memory import buffer_read, memory_write from .. import Evm from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_COPY, - GAS_EXTERNAL, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -45,7 +41,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -68,7 +64,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -95,7 +91,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -118,7 +114,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -141,7 +137,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -165,7 +161,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -190,7 +186,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -219,11 +215,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -248,7 +247,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -277,11 +276,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -306,7 +308,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -329,7 +331,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -360,11 +362,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/frontier/vm/instructions/keccak.py b/src/ethereum/forks/frontier/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/frontier/vm/instructions/keccak.py +++ b/src/ethereum/forks/frontier/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/frontier/vm/instructions/log.py b/src/ethereum/forks/frontier/vm/instructions/log.py index 76c02e737a4..e3e3ebd7e76 100644 --- a/src/ethereum/forks/frontier/vm/instructions/log.py +++ b/src/ethereum/forks/frontier/vm/instructions/log.py @@ -18,9 +18,7 @@ from ...blocks import Log from .. import Evm from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/frontier/vm/instructions/memory.py b/src/ethereum/forks/frontier/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/frontier/vm/instructions/memory.py +++ b/src/ethereum/forks/frontier/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/frontier/vm/instructions/stack.py b/src/ethereum/forks/frontier/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/frontier/vm/instructions/stack.py +++ b/src/ethereum/forks/frontier/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/frontier/vm/instructions/storage.py b/src/ethereum/forks/frontier/vm/instructions/storage.py index 154b4fd47bb..0b2a1cce8aa 100644 --- a/src/ethereum/forks/frontier/vm/instructions/storage.py +++ b/src/ethereum/forks/frontier/vm/instructions/storage.py @@ -16,10 +16,7 @@ from ...state import get_storage, set_storage from .. import Evm from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -40,7 +37,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -71,12 +68,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/frontier/vm/instructions/system.py b/src/ethereum/forks/frontier/vm/instructions/system.py index 41c3b22d3e2..6426fbfa04c 100644 --- a/src/ethereum/forks/frontier/vm/instructions/system.py +++ b/src/ethereum/forks/frontier/vm/instructions/system.py @@ -32,9 +32,7 @@ incorporate_child_on_success, ) from ..gas import ( - GAS_CREATE, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -67,7 +65,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) create_message_gas = evm.gas_left evm.gas_left = Uint(0) @@ -155,7 +153,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -362,7 +360,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_ZERO + gas_cost = GasCosts.ZERO originator = evm.message.current_target @@ -373,7 +371,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += int(REFUND_SELF_DESTRUCT) + evm.refund_counter += int(GasCosts.REFUND_SELF_DESTRUCT) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/frontier/vm/interpreter.py b/src/ethereum/forks/frontier/vm/interpreter.py index 842207405fa..90e59a193f0 100644 --- a/src/ethereum/forks/frontier/vm/interpreter.py +++ b/src/ethereum/forks/frontier/vm/interpreter.py @@ -42,7 +42,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -158,7 +158,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/gray_glacier/fork.py b/src/ethereum/forks/gray_glacier/fork.py index 301fdb2cd05..a5e2080c744 100644 --- a/src/ethereum/forks/gray_glacier/fork.py +++ b/src/ethereum/forks/gray_glacier/fork.py @@ -62,13 +62,12 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 11400000 @@ -850,12 +849,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -873,12 +872,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/gray_glacier/transactions.py b/src/ethereum/forks/gray_glacier/transactions.py index ca951f085c2..0e40010c617 100644 --- a/src/ethereum/forks/gray_glacier/transactions.py +++ b/src/ethereum/forks/gray_glacier/transactions.py @@ -23,37 +23,6 @@ from .exceptions import TransactionTypeError from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -370,7 +339,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -378,27 +347,29 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) access_list_cost = Uint(0) if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/gray_glacier/vm/gas.py b/src/ethereum/forks/gray_glacier/vm/gas.py index 7ac4146d8cf..c33cf7c0487 100644 --- a/src/ethereum/forks/gray_glacier/vm/gas.py +++ b/src/ethereum/forks/gray_glacier/vm/gas.py @@ -22,46 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -82,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -135,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -190,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py b/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py b/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/block.py b/src/ethereum/forks/gray_glacier/vm/instructions/block.py index bbf01739ff2..e3400f9461a 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/block.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py b/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py b/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/environment.py b/src/ethereum/forks/gray_glacier/vm/instructions/environment.py index fe1b70c1269..851ab39b142 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,10 +67,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -103,7 +97,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -126,7 +120,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -149,7 +143,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -173,7 +167,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -198,7 +192,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -227,11 +221,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -256,7 +253,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -285,11 +282,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -314,7 +314,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -338,10 +338,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -374,16 +374,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -413,7 +413,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -439,11 +439,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -472,10 +477,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -507,7 +512,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -535,7 +540,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py b/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/log.py b/src/ethereum/forks/gray_glacier/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/memory.py b/src/ethereum/forks/gray_glacier/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/memory.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/stack.py b/src/ethereum/forks/gray_glacier/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/storage.py b/src/ethereum/forks/gray_glacier/vm/instructions/storage.py index d99ad70f93b..287544f353b 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/storage.py @@ -17,12 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,10 +39,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -73,7 +68,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,37 +81,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/system.py b/src/ethereum/forks/gray_glacier/vm/instructions/system.py index b48d2498ac3..55c72f0fa9a 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/system.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -157,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -202,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -242,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -353,17 +345,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -433,12 +425,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -491,10 +483,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -503,7 +495,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -570,10 +562,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost @@ -629,10 +621,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/gray_glacier/vm/interpreter.py b/src/ethereum/forks/gray_glacier/vm/interpreter.py index 1135be95939..434147299b0 100644 --- a/src/ethereum/forks/gray_glacier/vm/interpreter.py +++ b/src/ethereum/forks/gray_glacier/vm/interpreter.py @@ -45,7 +45,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -179,7 +179,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/homestead/fork.py b/src/ethereum/forks/homestead/fork.py index 162a6bd1b7a..78592e2d770 100644 --- a/src/ethereum/forks/homestead/fork.py +++ b/src/ethereum/forks/homestead/fork.py @@ -49,11 +49,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(5 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) @@ -700,12 +699,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -723,12 +722,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/homestead/transactions.py b/src/ethereum/forks/homestead/transactions.py index 934540874ca..e17bafae49d 100644 --- a/src/ethereum/forks/homestead/transactions.py +++ b/src/ethereum/forks/homestead/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(tx: Transaction) -> Address: diff --git a/src/ethereum/forks/homestead/vm/gas.py b/src/ethereum/forks/homestead/vm/gas.py index fc01397ceb0..f3644b8bf6a 100644 --- a/src/ethereum/forks/homestead/vm/gas.py +++ b/src/ethereum/forks/homestead/vm/gas.py @@ -24,43 +24,127 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(50) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(10) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(20) -GAS_BALANCE = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(40) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -REFUND_SELF_DESTRUCT = Uint(24000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(50) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = Uint(24000) + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(10) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_EXTERNAL_BASE = Uint(20) + OPCODE_BALANCE = Uint(20) + OPCODE_CALL_BASE = Uint(40) @dataclass @@ -81,8 +165,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -134,7 +218,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -205,8 +289,12 @@ def calculate_message_call_gas( message_call_gas: `MessageCallGas` """ - create_gas_cost = Uint(0) if account_exists(state, to) else GAS_NEW_ACCOUNT - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE - cost = GAS_CALL + gas + create_gas_cost + transfer_gas_cost - stipend = gas if value == 0 else GAS_CALL_STIPEND + gas + create_gas_cost = ( + Uint(0) if account_exists(state, to) else GasCosts.NEW_ACCOUNT + ) + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE + cost = ( + GasCosts.OPCODE_CALL_BASE + gas + create_gas_cost + transfer_gas_cost + ) + stipend = gas if value == 0 else GasCosts.CALL_STIPEND + gas return MessageCallGas(cost, stipend) diff --git a/src/ethereum/forks/homestead/vm/instructions/arithmetic.py b/src/ethereum/forks/homestead/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/homestead/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/homestead/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/homestead/vm/instructions/bitwise.py b/src/ethereum/forks/homestead/vm/instructions/bitwise.py index 2a506f55751..62da98041ad 100644 --- a/src/ethereum/forks/homestead/vm/instructions/bitwise.py +++ b/src/ethereum/forks/homestead/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/homestead/vm/instructions/block.py b/src/ethereum/forks/homestead/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/homestead/vm/instructions/block.py +++ b/src/ethereum/forks/homestead/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/homestead/vm/instructions/comparison.py b/src/ethereum/forks/homestead/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/homestead/vm/instructions/comparison.py +++ b/src/ethereum/forks/homestead/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/homestead/vm/instructions/control_flow.py b/src/ethereum/forks/homestead/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/homestead/vm/instructions/control_flow.py +++ b/src/ethereum/forks/homestead/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/homestead/vm/instructions/environment.py b/src/ethereum/forks/homestead/vm/instructions/environment.py index 83eb5528226..d930368fdd9 100644 --- a/src/ethereum/forks/homestead/vm/instructions/environment.py +++ b/src/ethereum/forks/homestead/vm/instructions/environment.py @@ -20,11 +20,7 @@ from ...vm.memory import buffer_read, memory_write from .. import Evm from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_COPY, - GAS_EXTERNAL, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -45,7 +41,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -68,7 +64,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -95,7 +91,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -118,7 +114,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -141,7 +137,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -165,7 +161,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -190,7 +186,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -219,11 +215,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -248,7 +247,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -277,11 +276,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -306,7 +308,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -329,7 +331,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -360,11 +362,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/homestead/vm/instructions/keccak.py b/src/ethereum/forks/homestead/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/homestead/vm/instructions/keccak.py +++ b/src/ethereum/forks/homestead/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/homestead/vm/instructions/log.py b/src/ethereum/forks/homestead/vm/instructions/log.py index 76c02e737a4..e3e3ebd7e76 100644 --- a/src/ethereum/forks/homestead/vm/instructions/log.py +++ b/src/ethereum/forks/homestead/vm/instructions/log.py @@ -18,9 +18,7 @@ from ...blocks import Log from .. import Evm from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/homestead/vm/instructions/memory.py b/src/ethereum/forks/homestead/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/homestead/vm/instructions/memory.py +++ b/src/ethereum/forks/homestead/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/homestead/vm/instructions/stack.py b/src/ethereum/forks/homestead/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/homestead/vm/instructions/stack.py +++ b/src/ethereum/forks/homestead/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/homestead/vm/instructions/storage.py b/src/ethereum/forks/homestead/vm/instructions/storage.py index 154b4fd47bb..0b2a1cce8aa 100644 --- a/src/ethereum/forks/homestead/vm/instructions/storage.py +++ b/src/ethereum/forks/homestead/vm/instructions/storage.py @@ -16,10 +16,7 @@ from ...state import get_storage, set_storage from .. import Evm from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -40,7 +37,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -71,12 +68,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/homestead/vm/instructions/system.py b/src/ethereum/forks/homestead/vm/instructions/system.py index 75226650693..c40a241886a 100644 --- a/src/ethereum/forks/homestead/vm/instructions/system.py +++ b/src/ethereum/forks/homestead/vm/instructions/system.py @@ -32,10 +32,7 @@ incorporate_child_on_success, ) from ..gas import ( - GAS_CALL, - GAS_CREATE, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -68,7 +65,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) create_message_gas = evm.gas_left evm.gas_left = Uint(0) @@ -157,7 +154,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -368,7 +365,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_ZERO + gas_cost = GasCosts.ZERO originator = evm.message.current_target @@ -379,7 +376,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += int(REFUND_SELF_DESTRUCT) + evm.refund_counter += int(GasCosts.REFUND_SELF_DESTRUCT) charge_gas(evm, gas_cost) @@ -438,7 +435,7 @@ def delegatecall(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - charge_gas(evm, GAS_CALL + gas + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CALL_BASE + gas + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/homestead/vm/interpreter.py b/src/ethereum/forks/homestead/vm/interpreter.py index 47530fcf783..7d12402e037 100644 --- a/src/ethereum/forks/homestead/vm/interpreter.py +++ b/src/ethereum/forks/homestead/vm/interpreter.py @@ -42,7 +42,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -158,7 +158,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/istanbul/fork.py b/src/ethereum/forks/istanbul/fork.py index 7ed470d41e3..7765455cdb8 100644 --- a/src/ethereum/forks/istanbul/fork.py +++ b/src/ethereum/forks/istanbul/fork.py @@ -51,11 +51,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 5000000 @@ -711,14 +710,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -734,12 +733,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/istanbul/transactions.py b/src/ethereum/forks/istanbul/transactions.py index a831530b311..e8cde82b198 100644 --- a/src/ethereum/forks/istanbul/transactions.py +++ b/src/ethereum/forks/istanbul/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/istanbul/vm/gas.py b/src/ethereum/forks/istanbul/vm/gas.py index 8425495cd13..ba89267f506 100644 --- a/src/ethereum/forks/istanbul/vm/gas.py +++ b/src/ethereum/forks/istanbul/vm/gas.py @@ -22,49 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(800) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(700) -GAS_BALANCE = Uint(700) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(700) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_CODE_HASH = Uint(700) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(800) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_EXTCODEHASH = Uint(700) + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_EXTERNAL_BASE = Uint(700) + OPCODE_BALANCE = Uint(700) + OPCODE_CALL_BASE = Uint(700) @dataclass @@ -85,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -138,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -193,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py b/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/istanbul/vm/instructions/bitwise.py b/src/ethereum/forks/istanbul/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/bitwise.py +++ b/src/ethereum/forks/istanbul/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/istanbul/vm/instructions/block.py b/src/ethereum/forks/istanbul/vm/instructions/block.py index bbf01739ff2..e3400f9461a 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/block.py +++ b/src/ethereum/forks/istanbul/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/istanbul/vm/instructions/comparison.py b/src/ethereum/forks/istanbul/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/comparison.py +++ b/src/ethereum/forks/istanbul/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/istanbul/vm/instructions/control_flow.py b/src/ethereum/forks/istanbul/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/control_flow.py +++ b/src/ethereum/forks/istanbul/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/istanbul/vm/instructions/environment.py b/src/ethereum/forks/istanbul/vm/instructions/environment.py index f0cc93e67d8..b3ac54a689a 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/environment.py +++ b/src/ethereum/forks/istanbul/vm/instructions/environment.py @@ -22,14 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_CODE_HASH, - GAS_COPY, - GAS_EXTERNAL, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -50,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,7 +66,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -100,7 +93,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -123,7 +116,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -146,7 +139,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -170,7 +163,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -195,7 +188,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -224,11 +217,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -253,7 +249,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -282,11 +278,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -311,7 +310,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -334,7 +333,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -365,11 +364,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -397,7 +399,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -423,11 +425,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -455,7 +462,7 @@ def extcodehash(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_CODE_HASH) + charge_gas(evm, GasCosts.OPCODE_EXTCODEHASH) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -485,7 +492,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. diff --git a/src/ethereum/forks/istanbul/vm/instructions/keccak.py b/src/ethereum/forks/istanbul/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/keccak.py +++ b/src/ethereum/forks/istanbul/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/istanbul/vm/instructions/log.py b/src/ethereum/forks/istanbul/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/log.py +++ b/src/ethereum/forks/istanbul/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/istanbul/vm/instructions/memory.py b/src/ethereum/forks/istanbul/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/memory.py +++ b/src/ethereum/forks/istanbul/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/istanbul/vm/instructions/stack.py b/src/ethereum/forks/istanbul/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/stack.py +++ b/src/ethereum/forks/istanbul/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/istanbul/vm/instructions/storage.py b/src/ethereum/forks/istanbul/vm/instructions/storage.py index 99beae61e52..c34e6f31912 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/storage.py +++ b/src/ethereum/forks/istanbul/vm/instructions/storage.py @@ -17,11 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -42,7 +38,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -68,7 +64,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -79,30 +75,34 @@ def sstore(evm: Evm) -> None: if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE else: - gas_cost = GAS_SLOAD + gas_cost = GasCosts.SLOAD # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_SLOAD) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.SLOAD + ) else: # Slot was originally non-empty and was UPDATED earlier - evm.refund_counter += int(GAS_COLD_STORAGE_WRITE - GAS_SLOAD) + evm.refund_counter += int( + GasCosts.COLD_STORAGE_WRITE - GasCosts.SLOAD + ) charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/istanbul/vm/instructions/system.py b/src/ethereum/forks/istanbul/vm/instructions/system.py index a0b00f24d1e..12f69d1131d 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/system.py +++ b/src/ethereum/forks/istanbul/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL, - GAS_CALL_VALUE, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -157,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -202,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -242,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -352,16 +344,16 @@ def call(evm: Evm) -> None: code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + create_gas_cost + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + create_gas_cost + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) if evm.message.is_static and value != U256(0): @@ -423,13 +415,13 @@ def callcode(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -476,7 +468,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( not is_account_alive(evm.message.block_env.state, beneficiary) and get_account( @@ -484,7 +476,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -495,7 +487,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -561,7 +553,11 @@ def delegatecall(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, GAS_CALL + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -620,7 +616,7 @@ def staticcall(evm: Evm) -> None: gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) diff --git a/src/ethereum/forks/istanbul/vm/interpreter.py b/src/ethereum/forks/istanbul/vm/interpreter.py index 7a92f7471f3..2e3e5d6af2d 100644 --- a/src/ethereum/forks/istanbul/vm/interpreter.py +++ b/src/ethereum/forks/istanbul/vm/interpreter.py @@ -45,7 +45,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -178,7 +178,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/london/fork.py b/src/ethereum/forks/london/fork.py index a095e5fb6b9..026a6824881 100644 --- a/src/ethereum/forks/london/fork.py +++ b/src/ethereum/forks/london/fork.py @@ -62,13 +62,12 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) INITIAL_BASE_FEE = Uint(1000000000) MAX_OMMER_DEPTH = Uint(6) @@ -858,12 +857,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -881,12 +880,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/london/transactions.py b/src/ethereum/forks/london/transactions.py index ca951f085c2..0e40010c617 100644 --- a/src/ethereum/forks/london/transactions.py +++ b/src/ethereum/forks/london/transactions.py @@ -23,37 +23,6 @@ from .exceptions import TransactionTypeError from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -370,7 +339,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -378,27 +347,29 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) access_list_cost = Uint(0) if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/london/vm/gas.py b/src/ethereum/forks/london/vm/gas.py index 7ac4146d8cf..c33cf7c0487 100644 --- a/src/ethereum/forks/london/vm/gas.py +++ b/src/ethereum/forks/london/vm/gas.py @@ -22,46 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -82,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -135,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -190,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/london/vm/instructions/arithmetic.py b/src/ethereum/forks/london/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/london/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/london/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/london/vm/instructions/bitwise.py b/src/ethereum/forks/london/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/london/vm/instructions/bitwise.py +++ b/src/ethereum/forks/london/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/london/vm/instructions/block.py b/src/ethereum/forks/london/vm/instructions/block.py index bbf01739ff2..e3400f9461a 100644 --- a/src/ethereum/forks/london/vm/instructions/block.py +++ b/src/ethereum/forks/london/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/london/vm/instructions/comparison.py b/src/ethereum/forks/london/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/london/vm/instructions/comparison.py +++ b/src/ethereum/forks/london/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/london/vm/instructions/control_flow.py b/src/ethereum/forks/london/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/london/vm/instructions/control_flow.py +++ b/src/ethereum/forks/london/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/london/vm/instructions/environment.py b/src/ethereum/forks/london/vm/instructions/environment.py index fe1b70c1269..851ab39b142 100644 --- a/src/ethereum/forks/london/vm/instructions/environment.py +++ b/src/ethereum/forks/london/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,10 +67,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -103,7 +97,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -126,7 +120,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -149,7 +143,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -173,7 +167,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -198,7 +192,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -227,11 +221,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -256,7 +253,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -285,11 +282,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -314,7 +314,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -338,10 +338,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -374,16 +374,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -413,7 +413,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -439,11 +439,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -472,10 +477,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -507,7 +512,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -535,7 +540,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) diff --git a/src/ethereum/forks/london/vm/instructions/keccak.py b/src/ethereum/forks/london/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/london/vm/instructions/keccak.py +++ b/src/ethereum/forks/london/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/london/vm/instructions/log.py b/src/ethereum/forks/london/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/london/vm/instructions/log.py +++ b/src/ethereum/forks/london/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/london/vm/instructions/memory.py b/src/ethereum/forks/london/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/london/vm/instructions/memory.py +++ b/src/ethereum/forks/london/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/london/vm/instructions/stack.py b/src/ethereum/forks/london/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/london/vm/instructions/stack.py +++ b/src/ethereum/forks/london/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/london/vm/instructions/storage.py b/src/ethereum/forks/london/vm/instructions/storage.py index d99ad70f93b..287544f353b 100644 --- a/src/ethereum/forks/london/vm/instructions/storage.py +++ b/src/ethereum/forks/london/vm/instructions/storage.py @@ -17,12 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,10 +39,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -73,7 +68,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,37 +81,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/london/vm/instructions/system.py b/src/ethereum/forks/london/vm/instructions/system.py index b48d2498ac3..55c72f0fa9a 100644 --- a/src/ethereum/forks/london/vm/instructions/system.py +++ b/src/ethereum/forks/london/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -157,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -202,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -242,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -353,17 +345,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -433,12 +425,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -491,10 +483,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -503,7 +495,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -570,10 +562,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost @@ -629,10 +621,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/london/vm/interpreter.py b/src/ethereum/forks/london/vm/interpreter.py index b49ca7be07f..eb067c2bb4d 100644 --- a/src/ethereum/forks/london/vm/interpreter.py +++ b/src/ethereum/forks/london/vm/interpreter.py @@ -45,7 +45,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -179,7 +179,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/london/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/london/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/identity.py b/src/ethereum/forks/london/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/muir_glacier/fork.py b/src/ethereum/forks/muir_glacier/fork.py index 22fbdd1d988..dc79ce95617 100644 --- a/src/ethereum/forks/muir_glacier/fork.py +++ b/src/ethereum/forks/muir_glacier/fork.py @@ -51,11 +51,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(2 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 9000000 @@ -713,14 +712,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -736,12 +735,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/muir_glacier/transactions.py b/src/ethereum/forks/muir_glacier/transactions.py index a831530b311..e8cde82b198 100644 --- a/src/ethereum/forks/muir_glacier/transactions.py +++ b/src/ethereum/forks/muir_glacier/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/muir_glacier/vm/gas.py b/src/ethereum/forks/muir_glacier/vm/gas.py index 8425495cd13..ba89267f506 100644 --- a/src/ethereum/forks/muir_glacier/vm/gas.py +++ b/src/ethereum/forks/muir_glacier/vm/gas.py @@ -22,49 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(800) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(700) -GAS_BALANCE = Uint(700) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(700) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_CODE_HASH = Uint(700) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(800) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_EXTCODEHASH = Uint(700) + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_EXTERNAL_BASE = Uint(700) + OPCODE_BALANCE = Uint(700) + OPCODE_CALL_BASE = Uint(700) @dataclass @@ -85,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -138,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -193,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py b/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py b/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/block.py b/src/ethereum/forks/muir_glacier/vm/instructions/block.py index bbf01739ff2..e3400f9461a 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/block.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py b/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py b/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/environment.py b/src/ethereum/forks/muir_glacier/vm/instructions/environment.py index f0cc93e67d8..b3ac54a689a 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/environment.py @@ -22,14 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_CODE_HASH, - GAS_COPY, - GAS_EXTERNAL, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -50,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,7 +66,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -100,7 +93,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -123,7 +116,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -146,7 +139,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -170,7 +163,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -195,7 +188,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -224,11 +217,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -253,7 +249,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -282,11 +278,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -311,7 +310,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -334,7 +333,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -365,11 +364,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -397,7 +399,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -423,11 +425,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -455,7 +462,7 @@ def extcodehash(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_CODE_HASH) + charge_gas(evm, GasCosts.OPCODE_EXTCODEHASH) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -485,7 +492,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py b/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/log.py b/src/ethereum/forks/muir_glacier/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/memory.py b/src/ethereum/forks/muir_glacier/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/memory.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/stack.py b/src/ethereum/forks/muir_glacier/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/storage.py b/src/ethereum/forks/muir_glacier/vm/instructions/storage.py index 99beae61e52..c34e6f31912 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/storage.py @@ -17,11 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -42,7 +38,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -68,7 +64,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -79,30 +75,34 @@ def sstore(evm: Evm) -> None: if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE else: - gas_cost = GAS_SLOAD + gas_cost = GasCosts.SLOAD # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_SLOAD) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.SLOAD + ) else: # Slot was originally non-empty and was UPDATED earlier - evm.refund_counter += int(GAS_COLD_STORAGE_WRITE - GAS_SLOAD) + evm.refund_counter += int( + GasCosts.COLD_STORAGE_WRITE - GasCosts.SLOAD + ) charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/system.py b/src/ethereum/forks/muir_glacier/vm/instructions/system.py index a0b00f24d1e..12f69d1131d 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/system.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL, - GAS_CALL_VALUE, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -157,7 +149,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -202,8 +194,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -242,7 +234,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -352,16 +344,16 @@ def call(evm: Evm) -> None: code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + create_gas_cost + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + create_gas_cost + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) if evm.message.is_static and value != U256(0): @@ -423,13 +415,13 @@ def callcode(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -476,7 +468,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( not is_account_alive(evm.message.block_env.state, beneficiary) and get_account( @@ -484,7 +476,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -495,7 +487,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -561,7 +553,11 @@ def delegatecall(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, GAS_CALL + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -620,7 +616,7 @@ def staticcall(evm: Evm) -> None: gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) diff --git a/src/ethereum/forks/muir_glacier/vm/interpreter.py b/src/ethereum/forks/muir_glacier/vm/interpreter.py index e4f53153ce9..66db7006918 100644 --- a/src/ethereum/forks/muir_glacier/vm/interpreter.py +++ b/src/ethereum/forks/muir_glacier/vm/interpreter.py @@ -45,7 +45,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -178,7 +178,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index 7e6b5ee46de..19ce50f243d 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -81,8 +81,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( - BLOB_SCHEDULE_MAX, - GAS_PER_BLOB, + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -92,15 +91,13 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = BLOB_SCHEDULE_MAX * GAS_PER_BLOB +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( @@ -1030,14 +1027,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1053,12 +1050,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/osaka/transactions.py b/src/ethereum/forks/osaka/transactions.py index c8f1826324e..486b21f99b0 100644 --- a/src/ethereum/forks/osaka/transactions.py +++ b/src/ethereum/forks/osaka/transactions.py @@ -28,43 +28,6 @@ ) from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - TX_MAX_GAS_LIMIT = Uint(16_777_216) @@ -601,7 +564,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -612,8 +575,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -621,31 +583,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/osaka/vm/eoa_delegation.py b/src/ethereum/forks/osaka/vm/eoa_delegation.py index ff4aca94087..474ca9ae033 100644 --- a/src/ethereum/forks/osaka/vm/eoa_delegation.py +++ b/src/ethereum/forks/osaka/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -148,10 +147,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -200,7 +199,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/osaka/vm/gas.py b/src/ethereum/forks/osaka/vm/gas.py index 99ccfb48145..e54f305e45c 100644 --- a/src/ethereum/forks/osaka/vm/gas.py +++ b/src/ethereum/forks/osaka/vm/gas.py @@ -24,65 +24,169 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_P256VERIFY = Uint(6900) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_SCHEDULE_TARGET = U64(6) -BLOB_TARGET_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET -BLOB_BASE_COST = Uint(2**13) -BLOB_SCHEDULE_MAX = U64(9) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_P256VERIFY = Uint(6900) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_SCHEDULE_TARGET = U64(6) + BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST = Uint(2**13) + BLOB_SCHEDULE_MAX = U64(9) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_CLZ = LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -103,8 +207,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -156,7 +260,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -211,7 +315,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -283,7 +387,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -314,21 +418,23 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: base_fee_per_gas = parent_header.base_fee_per_gas parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - target_blob_gas_price = Uint(GAS_PER_BLOB) + target_blob_gas_price = Uint(GasCosts.PER_BLOB) target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas) - base_blob_tx_price = BLOB_BASE_COST * base_fee_per_gas + base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas if base_blob_tx_price > target_blob_gas_price: - blob_schedule_delta = BLOB_SCHEDULE_MAX - BLOB_SCHEDULE_TARGET + blob_schedule_delta = ( + GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET + ) return ( excess_blob_gas - + blob_gas_used * blob_schedule_delta // BLOB_SCHEDULE_MAX + + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX ) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -347,7 +453,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -368,9 +474,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/osaka/vm/instructions/arithmetic.py b/src/ethereum/forks/osaka/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/osaka/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/osaka/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/osaka/vm/instructions/bitwise.py b/src/ethereum/forks/osaka/vm/instructions/bitwise.py index cc6fa2fbb23..7674d3c720f 100644 --- a/src/ethereum/forks/osaka/vm/instructions/bitwise.py +++ b/src/ethereum/forks/osaka/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +265,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/osaka/vm/instructions/block.py b/src/ethereum/forks/osaka/vm/instructions/block.py index 43be9e58e23..d0aa17fe959 100644 --- a/src/ethereum/forks/osaka/vm/instructions/block.py +++ b/src/ethereum/forks/osaka/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/osaka/vm/instructions/comparison.py b/src/ethereum/forks/osaka/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/osaka/vm/instructions/comparison.py +++ b/src/ethereum/forks/osaka/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/osaka/vm/instructions/control_flow.py b/src/ethereum/forks/osaka/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/osaka/vm/instructions/control_flow.py +++ b/src/ethereum/forks/osaka/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/osaka/vm/instructions/environment.py b/src/ethereum/forks/osaka/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/osaka/vm/instructions/environment.py +++ b/src/ethereum/forks/osaka/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/osaka/vm/instructions/keccak.py b/src/ethereum/forks/osaka/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/osaka/vm/instructions/keccak.py +++ b/src/ethereum/forks/osaka/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/osaka/vm/instructions/log.py b/src/ethereum/forks/osaka/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/osaka/vm/instructions/log.py +++ b/src/ethereum/forks/osaka/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/osaka/vm/instructions/memory.py b/src/ethereum/forks/osaka/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/osaka/vm/instructions/memory.py +++ b/src/ethereum/forks/osaka/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/osaka/vm/instructions/stack.py b/src/ethereum/forks/osaka/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/osaka/vm/instructions/stack.py +++ b/src/ethereum/forks/osaka/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/osaka/vm/instructions/storage.py b/src/ethereum/forks/osaka/vm/instructions/storage.py index fd5bf4572ff..a782cd0db25 100644 --- a/src/ethereum/forks/osaka/vm/instructions/storage.py +++ b/src/ethereum/forks/osaka/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -50,10 +45,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +74,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +87,36 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: - # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: - # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: - # Storage slot being restored to its original value if original_value == 0: - # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: - # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/osaka/vm/instructions/system.py b/src/ethereum/forks/osaka/vm/instructions/system.py index 29c3fe9e6e2..0708c9041e2 100644 --- a/src/ethereum/forks/osaka/vm/instructions/system.py +++ b/src/ethereum/forks/osaka/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,10 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, + GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +211,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +256,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +369,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +383,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +458,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +471,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -489,7 +484,8 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.block_env.state, + evm.message.current_target, ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -531,19 +527,20 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.block_env.state, + evm.message.current_target, ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +601,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -618,7 +615,11 @@ def delegatecall(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + access_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -673,10 +674,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/osaka/vm/interpreter.py b/src/ethereum/forks/osaka/vm/interpreter.py index bdbf6520cc7..b956f824d0e 100644 --- a/src/ethereum/forks/osaka/vm/interpreter.py +++ b/src/ethereum/forks/osaka/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..9d8c71b806d 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,10 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas( + evm, + GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds, + ) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..fa0d3ec4c2d 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..a5b2be04018 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/p256verify.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/p256verify.py index e35ea1bb4ec..29c2e91e0f0 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/p256verify.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/p256verify.py @@ -24,7 +24,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_P256VERIFY, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -41,7 +41,7 @@ def p256verify(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_P256VERIFY) + charge_gas(evm, GasCosts.PRECOMPILE_P256VERIFY) if len(data) != 160: return diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 601f7064cfb..18be9678a70 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -57,12 +57,11 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) @@ -617,12 +616,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -640,12 +639,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/paris/transactions.py b/src/ethereum/forks/paris/transactions.py index 3b2f8b4425f..7ee0abbf8ef 100644 --- a/src/ethereum/forks/paris/transactions.py +++ b/src/ethereum/forks/paris/transactions.py @@ -23,37 +23,6 @@ from .exceptions import TransactionTypeError -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -370,7 +339,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -378,27 +347,29 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) access_list_cost = Uint(0) if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/paris/vm/gas.py b/src/ethereum/forks/paris/vm/gas.py index 7ac4146d8cf..d4536445c43 100644 --- a/src/ethereum/forks/paris/vm/gas.py +++ b/src/ethereum/forks/paris/vm/gas.py @@ -22,46 +22,143 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -82,8 +179,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -135,7 +232,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -190,7 +287,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/paris/vm/instructions/arithmetic.py b/src/ethereum/forks/paris/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/paris/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/paris/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/paris/vm/instructions/bitwise.py b/src/ethereum/forks/paris/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/paris/vm/instructions/bitwise.py +++ b/src/ethereum/forks/paris/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/paris/vm/instructions/block.py b/src/ethereum/forks/paris/vm/instructions/block.py index 3aa1fb2f6b6..19216cef9d5 100644 --- a/src/ethereum/forks/paris/vm/instructions/block.py +++ b/src/ethereum/forks/paris/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/paris/vm/instructions/comparison.py b/src/ethereum/forks/paris/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/paris/vm/instructions/comparison.py +++ b/src/ethereum/forks/paris/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/paris/vm/instructions/control_flow.py b/src/ethereum/forks/paris/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/paris/vm/instructions/control_flow.py +++ b/src/ethereum/forks/paris/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/paris/vm/instructions/environment.py b/src/ethereum/forks/paris/vm/instructions/environment.py index ba2bb42a425..588022b5722 100644 --- a/src/ethereum/forks/paris/vm/instructions/environment.py +++ b/src/ethereum/forks/paris/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,10 +67,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -103,7 +97,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -126,7 +120,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -149,7 +143,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -173,7 +167,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -198,7 +192,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -227,11 +221,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -256,7 +253,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -285,11 +282,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -314,7 +314,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -338,10 +338,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -374,16 +374,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -413,7 +413,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -439,11 +439,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -472,10 +477,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -507,7 +512,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -535,7 +540,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) diff --git a/src/ethereum/forks/paris/vm/instructions/keccak.py b/src/ethereum/forks/paris/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/paris/vm/instructions/keccak.py +++ b/src/ethereum/forks/paris/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/paris/vm/instructions/log.py b/src/ethereum/forks/paris/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/paris/vm/instructions/log.py +++ b/src/ethereum/forks/paris/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/paris/vm/instructions/memory.py b/src/ethereum/forks/paris/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/paris/vm/instructions/memory.py +++ b/src/ethereum/forks/paris/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/paris/vm/instructions/stack.py b/src/ethereum/forks/paris/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/paris/vm/instructions/stack.py +++ b/src/ethereum/forks/paris/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/paris/vm/instructions/storage.py b/src/ethereum/forks/paris/vm/instructions/storage.py index d99ad70f93b..287544f353b 100644 --- a/src/ethereum/forks/paris/vm/instructions/storage.py +++ b/src/ethereum/forks/paris/vm/instructions/storage.py @@ -17,12 +17,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,10 +39,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -73,7 +68,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,37 +81,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/paris/vm/instructions/system.py b/src/ethereum/forks/paris/vm/instructions/system.py index 2e9a8766a1e..01791beb50f 100644 --- a/src/ethereum/forks/paris/vm/instructions/system.py +++ b/src/ethereum/forks/paris/vm/instructions/system.py @@ -39,15 +39,7 @@ ) from ..exceptions import Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -156,7 +148,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -201,8 +193,8 @@ def create2(evm: Evm) -> None: call_data_words = ceil32(Uint(memory_size)) // Uint(32) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost, ) @@ -241,7 +233,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -352,17 +344,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -432,12 +424,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -490,10 +482,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -502,7 +494,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -565,10 +557,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost @@ -624,10 +616,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/paris/vm/interpreter.py b/src/ethereum/forks/paris/vm/interpreter.py index 92af867690a..32cb2e3b4de 100644 --- a/src/ethereum/forks/paris/vm/interpreter.py +++ b/src/ethereum/forks/paris/vm/interpreter.py @@ -43,7 +43,7 @@ set_code, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -167,7 +167,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/paris/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/paris/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py b/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index b1189cfa75e..9a14a702850 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -80,6 +80,7 @@ from .vm import Message from .vm.eoa_delegation import is_valid_delegation from .vm.gas import ( + GasCosts, calculate_blob_gas_price, calculate_data_fee, calculate_excess_blob_gas, @@ -89,8 +90,6 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") BEACON_ROOTS_ADDRESS = hex_to_address( @@ -1013,14 +1012,14 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is - passed through as a parameter is greater than or equal to the *sum* of - the parent's gas and the adjustment delta then the limit for gas is too - high and fails this function's check. Similarly, if the limit is less - than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's - check fails because the gas limit doesn't allow for a sufficient or - reasonable amount of gas to be used on a block. + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed + through as a parameter is greater than or equal to the *sum* of the + parent's gas and the adjustment delta then the limit for gas is too high + and fails this function's check. Similarly, if the limit is less than or + equal to the *difference* of the parent's gas and the adjustment delta *or* + the predefined ``LIMIT_MINIMUM`` then this function's check fails because + the gas limit doesn't allow for a sufficient or reasonable amount of gas to + be used on a block. Parameters ---------- @@ -1036,12 +1035,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/prague/transactions.py b/src/ethereum/forks/prague/transactions.py index 485a2460ba4..48845de1aa6 100644 --- a/src/ethereum/forks/prague/transactions.py +++ b/src/ethereum/forks/prague/transactions.py @@ -24,43 +24,6 @@ from .exceptions import InitCodeTooLargeError, TransactionTypeError from .fork_types import Authorization, VersionedHash -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_TOKEN_FLOOR = Uint(10) -""" -Minimum gas cost per byte of calldata as per [EIP-7623]. Used to calculate -the minimum gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_DATA_TOKEN_STANDARD = Uint(4) -""" -Gas cost per byte of calldata as per [EIP-7623]. Used to calculate the -gas cost for transactions that include calldata. - -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -593,7 +556,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -604,8 +567,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: gas cost of the transaction and the minimum gas cost used by the transaction based on the calldata size. """ - from .vm.eoa_delegation import GAS_AUTH_PER_EMPTY_ACCOUNT - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros @@ -613,31 +575,33 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: tokens_in_calldata = num_zeros + num_non_zeros * Uint(4) # EIP-7623 floor price (note: no EVM costs) calldata_floor_gas_cost = ( - tokens_in_calldata * GAS_TX_DATA_TOKEN_FLOOR + GAS_TX_BASE + tokens_in_calldata * GasCosts.TX_DATA_TOKEN_FLOOR + GasCosts.TX_BASE ) - data_cost = tokens_in_calldata * GAS_TX_DATA_TOKEN_STANDARD + data_cost = tokens_in_calldata * GasCosts.TX_DATA_TOKEN_STANDARD if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if has_access_list(tx): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): - auth_cost += Uint(GAS_AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations)) + auth_cost += Uint( + GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) + ) return ( Uint( - GAS_TX_BASE + GasCosts.TX_BASE + data_cost + create_cost + access_list_cost diff --git a/src/ethereum/forks/prague/vm/eoa_delegation.py b/src/ethereum/forks/prague/vm/eoa_delegation.py index fce580bee4a..3fd42910817 100644 --- a/src/ethereum/forks/prague/vm/eoa_delegation.py +++ b/src/ethereum/forks/prague/vm/eoa_delegation.py @@ -22,14 +22,13 @@ set_code, ) from ..utils.hexadecimal import hex_to_address -from ..vm.gas import GAS_COLD_ACCOUNT_ACCESS, GAS_WARM_ACCESS +from ..vm.gas import GasCosts from . import Evm, Message SET_CODE_TX_MAGIC = b"\x05" EOA_DELEGATION_MARKER = b"\xef\x01\x00" EOA_DELEGATION_MARKER_LENGTH = len(EOA_DELEGATION_MARKER) EOA_DELEGATED_CODE_LENGTH = 23 -GAS_AUTH_PER_EMPTY_ACCOUNT = 25000 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12500 NULL_ADDRESS = hex_to_address("0x0000000000000000000000000000000000000000") @@ -147,10 +146,10 @@ def access_delegation( address = Address(code[EOA_DELEGATION_MARKER_LENGTH:]) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code = get_code(state, get_account(state, address).code_hash) return True, address, code, access_gas_cost @@ -199,7 +198,8 @@ def set_delegation(message: Message) -> U256: if account_exists(state, authority): refund_counter += U256( - GAS_AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT + GasCosts.AUTH_PER_EMPTY_ACCOUNT + - REFUND_AUTH_PER_EXISTING_ACCOUNT ) if auth.address == NULL_ADDRESS: diff --git a/src/ethereum/forks/prague/vm/gas.py b/src/ethereum/forks/prague/vm/gas.py index 121292173ef..94352384934 100644 --- a/src/ethereum/forks/prague/vm/gas.py +++ b/src/ethereum/forks/prague/vm/gas.py @@ -24,61 +24,164 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) -GAS_PRECOMPILE_POINT_EVALUATION = Uint(50000) - -GAS_PER_BLOB = U64(2**17) -BLOB_TARGET_GAS_PER_BLOCK = U64(786432) -BLOB_MIN_GASPRICE = Uint(1) -BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716) - -GAS_PRECOMPILE_BLS_G1ADD = Uint(375) -GAS_PRECOMPILE_BLS_G1MUL = Uint(12000) -GAS_PRECOMPILE_BLS_G1MAP = Uint(5500) -GAS_PRECOMPILE_BLS_G2ADD = Uint(600) -GAS_PRECOMPILE_BLS_G2MUL = Uint(22500) -GAS_PRECOMPILE_BLS_G2MAP = Uint(23800) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Authorization + AUTH_PER_EMPTY_ACCOUNT = 25000 + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_POINT_EVALUATION = Uint(50000) + PRECOMPILE_BLS_G1ADD = Uint(375) + PRECOMPILE_BLS_G1MUL = Uint(12000) + PRECOMPILE_BLS_G1MAP = Uint(5500) + PRECOMPILE_BLS_G2ADD = Uint(600) + PRECOMPILE_BLS_G2MUL = Uint(22500) + PRECOMPILE_BLS_G2MAP = Uint(23800) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Blobs + PER_BLOB = U64(2**17) + BLOB_TARGET_GAS_PER_BLOCK = U64(786432) + BLOB_MIN_GASPRICE = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_TOKEN_STANDARD = Uint(4) + TX_DATA_TOKEN_FLOOR = Uint(10) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_BLOBBASEFEE = BASE + OPCODE_BLOBHASH = Uint(3) + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MCOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -99,8 +202,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -152,7 +255,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -207,7 +310,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -279,7 +382,7 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) def calculate_excess_blob_gas(parent_header: Header) -> U64: @@ -308,10 +411,10 @@ def calculate_excess_blob_gas(parent_header: Header) -> U64: blob_gas_used = parent_header.blob_gas_used parent_blob_gas = excess_blob_gas + blob_gas_used - if parent_blob_gas < BLOB_TARGET_GAS_PER_BLOCK: + if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK: return U64(0) - return parent_blob_gas - BLOB_TARGET_GAS_PER_BLOCK + return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK def calculate_total_blob_gas(tx: Transaction) -> U64: @@ -330,7 +433,7 @@ def calculate_total_blob_gas(tx: Transaction) -> U64: """ if isinstance(tx, BlobTransaction): - return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes)) + return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes)) else: return U64(0) @@ -351,9 +454,9 @@ def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ return taylor_exponential( - BLOB_MIN_GASPRICE, + GasCosts.BLOB_MIN_GASPRICE, Uint(excess_blob_gas), - BLOB_BASE_FEE_UPDATE_FRACTION, + GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION, ) diff --git a/src/ethereum/forks/prague/vm/instructions/arithmetic.py b/src/ethereum/forks/prague/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/prague/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/prague/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/prague/vm/instructions/bitwise.py b/src/ethereum/forks/prague/vm/instructions/bitwise.py index 41dabe8185b..1de6c615931 100644 --- a/src/ethereum/forks/prague/vm/instructions/bitwise.py +++ b/src/ethereum/forks/prague/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +172,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +202,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +232,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/prague/vm/instructions/block.py b/src/ethereum/forks/prague/vm/instructions/block.py index b3bfb500a09..4c405ad5194 100644 --- a/src/ethereum/forks/prague/vm/instructions/block.py +++ b/src/ethereum/forks/prague/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/prague/vm/instructions/comparison.py b/src/ethereum/forks/prague/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/prague/vm/instructions/comparison.py +++ b/src/ethereum/forks/prague/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/prague/vm/instructions/control_flow.py b/src/ethereum/forks/prague/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/prague/vm/instructions/control_flow.py +++ b/src/ethereum/forks/prague/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/prague/vm/instructions/environment.py b/src/ethereum/forks/prague/vm/instructions/environment.py index 5848530a960..7fa57b90d8b 100644 --- a/src/ethereum/forks/prague/vm/instructions/environment.py +++ b/src/ethereum/forks/prague/vm/instructions/environment.py @@ -23,14 +23,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_BLOBHASH_OPCODE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_blob_gas_price, calculate_gas_extend_memory, charge_gas, @@ -52,7 +45,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -76,10 +69,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -106,7 +99,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -129,7 +122,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -152,7 +145,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -176,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -201,7 +194,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -230,11 +223,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -259,7 +255,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -288,11 +284,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -317,7 +316,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -341,10 +340,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -377,16 +376,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -416,7 +415,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -442,11 +441,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -475,10 +479,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -510,7 +514,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -538,7 +542,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) @@ -561,7 +565,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GasCosts.OPCODE_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): @@ -588,7 +592,7 @@ def blob_base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BLOBBASEFEE) # OPERATION blob_base_fee = calculate_blob_gas_price( diff --git a/src/ethereum/forks/prague/vm/instructions/keccak.py b/src/ethereum/forks/prague/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/prague/vm/instructions/keccak.py +++ b/src/ethereum/forks/prague/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/prague/vm/instructions/log.py b/src/ethereum/forks/prague/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/prague/vm/instructions/log.py +++ b/src/ethereum/forks/prague/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/prague/vm/instructions/memory.py b/src/ethereum/forks/prague/vm/instructions/memory.py index 6e111051ee3..bba3ddf19d5 100644 --- a/src/ethereum/forks/prague/vm/instructions/memory.py +++ b/src/ethereum/forks/prague/vm/instructions/memory.py @@ -18,9 +18,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_COPY, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +47,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +78,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +106,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -135,7 +133,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) @@ -161,12 +159,15 @@ def mcopy(evm: Evm) -> None: # GAS words = ceil32(Uint(length)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_MCOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/prague/vm/instructions/stack.py b/src/ethereum/forks/prague/vm/instructions/stack.py index 0007a28acd4..366cf79f5e4 100644 --- a/src/ethereum/forks/prague/vm/instructions/stack.py +++ b/src/ethereum/forks/prague/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +66,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/prague/vm/instructions/storage.py b/src/ethereum/forks/prague/vm/instructions/storage.py index fd5bf4572ff..5aa3cc6746f 100644 --- a/src/ethereum/forks/prague/vm/instructions/storage.py +++ b/src/ethereum/forks/prague/vm/instructions/storage.py @@ -23,12 +23,7 @@ from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -50,10 +45,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -79,7 +74,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,37 +87,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/prague/vm/instructions/system.py b/src/ethereum/forks/prague/vm/instructions/system.py index 29c3fe9e6e2..2d99ac93e61 100644 --- a/src/ethereum/forks/prague/vm/instructions/system.py +++ b/src/ethereum/forks/prague/vm/instructions/system.py @@ -40,15 +40,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -166,7 +158,9 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -216,8 +210,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -261,7 +255,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -374,10 +368,10 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( @@ -388,10 +382,10 @@ def call(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -463,10 +457,10 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -476,7 +470,7 @@ def callcode(evm: Evm) -> None: ) = access_delegation(evm, code_address) access_gas_cost += delegated_access_gas_cost - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -531,10 +525,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -543,7 +537,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -604,10 +598,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS ( disable_precompiles, @@ -673,10 +667,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to ( diff --git a/src/ethereum/forks/prague/vm/interpreter.py b/src/ethereum/forks/prague/vm/interpreter.py index 290f2831710..fd41c59a310 100644 --- a/src/ethereum/forks/prague/vm/interpreter.py +++ b/src/ethereum/forks/prague/vm/interpreter.py @@ -46,7 +46,7 @@ ) from ..vm import Message from ..vm.eoa_delegation import get_delegated_code_address, set_delegation -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -191,7 +191,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/prague/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index 9c03c820465..fa0d3ec4c2d 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G1ADD, - GAS_PRECOMPILE_BLS_G1MAP, - GAS_PRECOMPILE_BLS_G1MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -60,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -101,7 +99,7 @@ def bls12_g1_msm(evm: Evm) -> None: else: discount = Uint(G1_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -140,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index 7a80d78b10c..a5b2be04018 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -21,9 +21,7 @@ from ....vm import Evm from ....vm.gas import ( - GAS_PRECOMPILE_BLS_G2ADD, - GAS_PRECOMPILE_BLS_G2MAP, - GAS_PRECOMPILE_BLS_G2MUL, + GasCosts, charge_gas, ) from ....vm.memory import buffer_read @@ -61,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -102,7 +100,7 @@ def bls12_g2_msm(evm: Evm) -> None: else: discount = Uint(G2_MAX_DISCOUNT) - gas_cost = Uint(k) * GAS_PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER + gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER charge_gas(evm, gas_cost) # OPERATION @@ -141,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GAS_PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/prague/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py b/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/point_evaluation.py b/src/ethereum/forks/prague/vm/precompiled_contracts/point_evaluation.py index ce1d022d049..d2d105ba13b 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/point_evaluation.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/point_evaluation.py @@ -22,7 +22,7 @@ from ...vm import Evm from ...vm.exceptions import KZGProofError -from ...vm.gas import GAS_PRECOMPILE_POINT_EVALUATION, charge_gas +from ...vm.gas import GasCosts, charge_gas FIELD_ELEMENTS_PER_BLOB = 4096 BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # noqa: E501 @@ -51,7 +51,7 @@ def point_evaluation(evm: Evm) -> None: proof = Bytes48(data[144:192]) # GAS - charge_gas(evm, GAS_PRECOMPILE_POINT_EVALUATION) + charge_gas(evm, GasCosts.PRECOMPILE_POINT_EVALUATION) if kzg_commitment_to_versioned_hash(commitment) != versioned_hash: raise KZGProofError diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index ed186933edf..7604389956a 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -58,12 +58,11 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) @@ -652,12 +651,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -675,12 +674,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/shanghai/transactions.py b/src/ethereum/forks/shanghai/transactions.py index 871782b3a73..459c70cb23c 100644 --- a/src/ethereum/forks/shanghai/transactions.py +++ b/src/ethereum/forks/shanghai/transactions.py @@ -23,37 +23,6 @@ from .exceptions import InitCodeTooLargeError, TransactionTypeError -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(16) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - -GAS_TX_ACCESS_LIST_ADDRESS = Uint(2400) -""" -Gas cost for including an address in the access list of a transaction. -""" - -GAS_TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) -""" -Gas cost for including a storage key in the access list of a transaction. -""" - @slotted_freezable @dataclass @@ -380,7 +349,7 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) 4. Cost for access list entries (if applicable) @@ -388,29 +357,29 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ - from .vm.gas import init_code_cost + from .vm.gas import GasCosts, init_code_cost num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + init_code_cost(ulen(tx.data)) + create_cost = GasCosts.TX_CREATE + init_code_cost(ulen(tx.data)) else: create_cost = Uint(0) access_list_cost = Uint(0) if isinstance(tx, (AccessListTransaction, FeeMarketTransaction)): for access in tx.access_list: - access_list_cost += GAS_TX_ACCESS_LIST_ADDRESS + access_list_cost += GasCosts.TX_ACCESS_LIST_ADDRESS access_list_cost += ( - ulen(access.slots) * GAS_TX_ACCESS_LIST_STORAGE_KEY + ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) - return GAS_TX_BASE + data_cost + create_cost + access_list_cost + return GasCosts.TX_BASE + data_cost + create_cost + access_list_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/shanghai/vm/gas.py b/src/ethereum/forks/shanghai/vm/gas.py index 44d049d552f..ca3de745672 100644 --- a/src/ethereum/forks/shanghai/vm/gas.py +++ b/src/ethereum/forks/shanghai/vm/gas.py @@ -22,47 +22,145 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 4800 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) -GAS_RETURN_DATA_COPY = Uint(3) -GAS_FAST_STEP = Uint(5) -GAS_PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) -GAS_COLD_STORAGE_ACCESS = Uint(2100) -GAS_COLD_ACCOUNT_ACCESS = Uint(2600) -GAS_WARM_ACCESS = Uint(100) -GAS_CODE_INIT_PER_WORD = Uint(2) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + WARM_ACCESS = Uint(100) + COLD_ACCOUNT_ACCESS = Uint(2600) + COLD_STORAGE_ACCESS = Uint(2100) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_INIT_PER_WORD = Uint(2) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + FAST_STEP = Uint(5) + + # Refunds + REFUND_STORAGE_CLEAR = 4800 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) + PRECOMPILE_ECADD = Uint(150) + PRECOMPILE_ECMUL = Uint(6000) + PRECOMPILE_ECPAIRING_BASE = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(16) + TX_ACCESS_LIST_ADDRESS = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_SHL = VERY_LOW + OPCODE_SHR = VERY_LOW + OPCODE_SAR = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_PREVRANDAO = BASE + OPCODE_RETURNDATASIZE = BASE + OPCODE_CHAINID = BASE + OPCODE_BASEFEE = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_PUSH0 = BASE + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_RETURNDATACOPY_BASE = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) @dataclass @@ -83,8 +181,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -136,7 +234,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -191,7 +289,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) @@ -263,4 +361,4 @@ def init_code_cost(init_code_length: Uint) -> Uint: The gas to be charged for the init code. """ - return GAS_CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) + return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32) diff --git a/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py b/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py index b7b1a370ad4..c361db7373f 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py @@ -17,14 +17,7 @@ from ethereum.utils.numeric import get_sign from .. import Evm -from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, - charge_gas, -) +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -44,7 +37,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +64,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +91,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +118,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +151,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +184,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +214,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +245,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +276,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +311,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +341,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/shanghai/vm/instructions/bitwise.py b/src/ethereum/forks/shanghai/vm/instructions/bitwise.py index 41dabe8185b..99b62433076 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/bitwise.py +++ b/src/ethereum/forks/shanghai/vm/instructions/bitwise.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -34,7 +34,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +59,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +84,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +108,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +134,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +169,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +199,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +229,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/shanghai/vm/instructions/block.py b/src/ethereum/forks/shanghai/vm/instructions/block.py index de2569869bd..cfba646567f 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/block.py +++ b/src/ethereum/forks/shanghai/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PREVRANDAO) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CHAINID) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/shanghai/vm/instructions/comparison.py b/src/ethereum/forks/shanghai/vm/instructions/comparison.py index a6a3d99bc86..ee5c881ef0d 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/comparison.py +++ b/src/ethereum/forks/shanghai/vm/instructions/comparison.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -34,7 +34,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +60,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +87,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +113,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +140,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +166,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/shanghai/vm/instructions/control_flow.py b/src/ethereum/forks/shanghai/vm/instructions/control_flow.py index b3b1f2316a7..d74e7b90340 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/control_flow.py +++ b/src/ethereum/forks/shanghai/vm/instructions/control_flow.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import GasCosts, charge_gas from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +57,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +84,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +113,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +137,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +162,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/shanghai/vm/instructions/environment.py b/src/ethereum/forks/shanghai/vm/instructions/environment.py index ba2bb42a425..588022b5722 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/environment.py +++ b/src/ethereum/forks/shanghai/vm/instructions/environment.py @@ -22,13 +22,7 @@ from .. import Evm from ..exceptions import OutOfBoundsRead from ..gas import ( - GAS_BASE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_COPY, - GAS_FAST_STEP, - GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, - GAS_WARM_ACCESS, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +43,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -73,10 +67,10 @@ def balance(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_addresses.add(address) - charge_gas(evm, GAS_COLD_ACCOUNT_ACCESS) + charge_gas(evm, GasCosts.COLD_ACCOUNT_ACCESS) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -103,7 +97,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -126,7 +120,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -149,7 +143,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -173,7 +167,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -198,7 +192,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -227,11 +221,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -256,7 +253,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -285,11 +282,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -314,7 +314,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -338,10 +338,10 @@ def extcodesize(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -374,16 +374,16 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost + copy_gas_cost + extend_memory.cost) @@ -413,7 +413,7 @@ def returndatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_RETURNDATASIZE) # OPERATION push(evm.stack, U256(len(evm.return_data))) @@ -439,11 +439,16 @@ def returndatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_RETURN_DATA_COPY * words + copy_gas_cost = GasCosts.OPCODE_RETURNDATACOPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_RETURNDATACOPY_BASE + + copy_gas_cost + + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -472,10 +477,10 @@ def extcodehash(evm: Evm) -> None: # GAS if address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS charge_gas(evm, access_gas_cost) @@ -507,7 +512,7 @@ def self_balance(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_FAST_STEP) + charge_gas(evm, GasCosts.FAST_STEP) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -535,7 +540,7 @@ def base_fee(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_BASEFEE) # OPERATION push(evm.stack, U256(evm.message.block_env.base_fee_per_gas)) diff --git a/src/ethereum/forks/shanghai/vm/instructions/keccak.py b/src/ethereum/forks/shanghai/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/keccak.py +++ b/src/ethereum/forks/shanghai/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/shanghai/vm/instructions/log.py b/src/ethereum/forks/shanghai/vm/instructions/log.py index abc297df6fa..bd5e652db22 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/log.py +++ b/src/ethereum/forks/shanghai/vm/instructions/log.py @@ -19,9 +19,7 @@ from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +57,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/shanghai/vm/instructions/memory.py b/src/ethereum/forks/shanghai/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/memory.py +++ b/src/ethereum/forks/shanghai/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/shanghai/vm/instructions/stack.py b/src/ethereum/forks/shanghai/vm/instructions/stack.py index 0007a28acd4..d7b3df986b0 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/stack.py +++ b/src/ethereum/forks/shanghai/vm/instructions/stack.py @@ -17,7 +17,7 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import GasCosts, charge_gas from ..memory import buffer_read @@ -35,7 +35,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -63,9 +63,9 @@ def push_n(evm: Evm, num_bytes: int) -> None: # GAS if num_bytes == 0: - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PUSH0) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/shanghai/vm/instructions/storage.py b/src/ethereum/forks/shanghai/vm/instructions/storage.py index d99ad70f93b..0936a10b1e1 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/storage.py +++ b/src/ethereum/forks/shanghai/vm/instructions/storage.py @@ -16,15 +16,7 @@ from ...state import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_STORAGE_ACCESS, - GAS_COLD_STORAGE_WRITE, - GAS_STORAGE_SET, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, GasCosts.WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_STORAGE_ACCESS) + charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,37 +78,41 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_STORAGE_ACCESS + gas_cost += GasCosts.COLD_STORAGE_ACCESS if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += GasCosts.STORAGE_SET else: - gas_cost += GAS_COLD_STORAGE_WRITE - GAS_COLD_STORAGE_ACCESS + gas_cost += ( + GasCosts.COLD_STORAGE_WRITE - GasCosts.COLD_STORAGE_ACCESS + ) else: - gas_cost += GAS_WARM_ACCESS + gas_cost += GasCosts.WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= GasCosts.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + GasCosts.STORAGE_SET - GasCosts.WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_COLD_STORAGE_WRITE - - GAS_COLD_STORAGE_ACCESS - - GAS_WARM_ACCESS + GasCosts.COLD_STORAGE_WRITE + - GasCosts.COLD_STORAGE_ACCESS + - GasCosts.WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/shanghai/vm/instructions/system.py b/src/ethereum/forks/shanghai/vm/instructions/system.py index e5abcae2236..b3fc0cd3dbb 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/system.py +++ b/src/ethereum/forks/shanghai/vm/instructions/system.py @@ -39,15 +39,7 @@ ) from ..exceptions import OutOfGasError, Revert, WriteInStaticContext from ..gas import ( - GAS_CALL_VALUE, - GAS_COLD_ACCOUNT_ACCESS, - GAS_CREATE, - GAS_KECCAK256_PER_WORD, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_WARM_ACCESS, - GAS_ZERO, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -164,7 +156,9 @@ def create(evm: Evm) -> None: ) init_code_gas = init_code_cost(Uint(memory_size)) - charge_gas(evm, GAS_CREATE + extend_memory.cost + init_code_gas) + charge_gas( + evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost + init_code_gas + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -214,8 +208,8 @@ def create2(evm: Evm) -> None: init_code_gas = init_code_cost(Uint(memory_size)) charge_gas( evm, - GAS_CREATE - + GAS_KECCAK256_PER_WORD * call_data_words + GasCosts.OPCODE_CREATE_BASE + + GasCosts.OPCODE_KECCACK256_PER_WORD * call_data_words + extend_memory.cost + init_code_gas, ) @@ -259,7 +253,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -370,17 +364,17 @@ def call(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -450,12 +444,12 @@ def callcode(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, @@ -508,10 +502,10 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if beneficiary not in evm.accessed_addresses: evm.accessed_addresses.add(beneficiary) - gas_cost += GAS_COLD_ACCOUNT_ACCESS + gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( not is_account_alive(evm.message.block_env.state, beneficiary) @@ -520,7 +514,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT charge_gas(evm, gas_cost) if evm.message.is_static: @@ -583,10 +577,10 @@ def delegatecall(evm: Evm) -> None: ) if code_address in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(code_address) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS message_call_gas = calculate_message_call_gas( U256(0), gas, Uint(evm.gas_left), extend_memory.cost, access_gas_cost @@ -642,10 +636,10 @@ def staticcall(evm: Evm) -> None: ) if to in evm.accessed_addresses: - access_gas_cost = GAS_WARM_ACCESS + access_gas_cost = GasCosts.WARM_ACCESS else: evm.accessed_addresses.add(to) - access_gas_cost = GAS_COLD_ACCOUNT_ACCESS + access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS code_address = to diff --git a/src/ethereum/forks/shanghai/vm/interpreter.py b/src/ethereum/forks/shanghai/vm/interpreter.py index 6485ebe11f2..d4ec312b4fa 100644 --- a/src/ethereum/forks/shanghai/vm/interpreter.py +++ b/src/ethereum/forks/shanghai/vm/interpreter.py @@ -43,7 +43,7 @@ set_code, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -168,7 +168,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: if len(contract_code) > 0: diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py index 214725d8da0..09bed4a0282 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py @@ -31,7 +31,7 @@ from py_ecc.typing import Optimized_Point3D as Point3D from ...vm import Evm -from ...vm.gas import charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read from ..exceptions import InvalidParameter, OutOfGasError @@ -149,7 +149,7 @@ def alt_bn128_add(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(150)) + charge_gas(evm, GasCosts.PRECOMPILE_ECADD) # OPERATION try: @@ -177,7 +177,7 @@ def alt_bn128_mul(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(6000)) + charge_gas(evm, GasCosts.PRECOMPILE_ECMUL) # OPERATION try: @@ -205,7 +205,11 @@ def alt_bn128_pairing_check(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000)) + charge_gas( + evm, + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + + GasCosts.PRECOMPILE_ECPAIRING_BASE, + ) # OPERATION if len(data) % 192 != 0: diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/blake2f.py index c5eaff7d62a..ae53b1ab4b5 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/blake2f.py @@ -14,7 +14,7 @@ from ethereum.crypto.blake2 import Blake2b from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_BLAKE2F_PER_ROUND, charge_gas +from ...vm.gas import GasCosts, charge_gas from ..exceptions import InvalidParameter @@ -35,7 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas(evm, GAS_PRECOMPILE_BLAKE2F_PER_ROUND * rounds) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py index 133a4832bf8..2b4929fb8d2 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py @@ -16,11 +16,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def identity(evm: Evm) -> None: @@ -39,8 +35,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..04d0e2ff594 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py @@ -19,11 +19,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def ripemd160(evm: Evm) -> None: @@ -42,8 +38,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py index 04dfef6730d..f5346f1529c 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py @@ -18,11 +18,7 @@ from ethereum.utils.numeric import ceil32 from ...vm import Evm -from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, - charge_gas, -) +from ...vm.gas import GasCosts, charge_gas def sha256(evm: Evm) -> None: @@ -41,8 +37,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/spurious_dragon/fork.py b/src/ethereum/forks/spurious_dragon/fork.py index a115049d968..7c3101d25a3 100644 --- a/src/ethereum/forks/spurious_dragon/fork.py +++ b/src/ethereum/forks/spurious_dragon/fork.py @@ -51,11 +51,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(5 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) @@ -709,12 +708,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -732,12 +731,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/spurious_dragon/transactions.py b/src/ethereum/forks/spurious_dragon/transactions.py index 278238f8d5a..e8cde82b198 100644 --- a/src/ethereum/forks/spurious_dragon/transactions.py +++ b/src/ethereum/forks/spurious_dragon/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(chain_id: U64, tx: Transaction) -> Address: diff --git a/src/ethereum/forks/spurious_dragon/vm/gas.py b/src/ethereum/forks/spurious_dragon/vm/gas.py index 937e953a145..49c69c4653a 100644 --- a/src/ethereum/forks/spurious_dragon/vm/gas.py +++ b/src/ethereum/forks/spurious_dragon/vm/gas.py @@ -22,45 +22,129 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(200) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(50) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(700) -GAS_BALANCE = Uint(400) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(700) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(200) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(50) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_EXTERNAL_BASE = Uint(700) + OPCODE_BALANCE = Uint(400) + OPCODE_CALL_BASE = Uint(700) @dataclass @@ -81,8 +165,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -134,7 +218,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -189,7 +273,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py b/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py b/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py index 2a506f55751..62da98041ad 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/block.py b/src/ethereum/forks/spurious_dragon/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/block.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py b/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py b/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py b/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py index 83eb5528226..d930368fdd9 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py @@ -20,11 +20,7 @@ from ...vm.memory import buffer_read, memory_write from .. import Evm from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_COPY, - GAS_EXTERNAL, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -45,7 +41,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -68,7 +64,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -95,7 +91,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -118,7 +114,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -141,7 +137,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -165,7 +161,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -190,7 +186,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -219,11 +215,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -248,7 +247,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -277,11 +276,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -306,7 +308,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -329,7 +331,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -360,11 +362,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py b/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/log.py b/src/ethereum/forks/spurious_dragon/vm/instructions/log.py index 76c02e737a4..e3e3ebd7e76 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/log.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/log.py @@ -18,9 +18,7 @@ from ...blocks import Log from .. import Evm from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py b/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py b/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py b/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py index 154b4fd47bb..0b2a1cce8aa 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py @@ -16,10 +16,7 @@ from ...state import get_storage, set_storage from .. import Evm from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -40,7 +37,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -71,12 +68,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/system.py b/src/ethereum/forks/spurious_dragon/vm/instructions/system.py index e35d7a5a7c7..037a54da3f9 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/system.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/system.py @@ -34,14 +34,7 @@ incorporate_child_on_success, ) from ..gas import ( - GAS_CALL, - GAS_CALL_VALUE, - GAS_CREATE, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -75,7 +68,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) create_message_gas = max_message_call_gas(Uint(evm.gas_left)) evm.gas_left -= create_message_gas @@ -164,7 +157,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -268,16 +261,16 @@ def call(evm: Evm) -> None: code_address = to - create_gas_cost = GAS_NEW_ACCOUNT + create_gas_cost = GasCosts.NEW_ACCOUNT if value == 0 or is_account_alive(evm.message.block_env.state, to): create_gas_cost = Uint(0) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + create_gas_cost + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + create_gas_cost + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -337,13 +330,13 @@ def callcode(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -388,7 +381,7 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( not is_account_alive(evm.message.block_env.state, beneficiary) and get_account( @@ -396,7 +389,7 @@ def selfdestruct(evm: Evm) -> None: ).balance != 0 ): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -407,7 +400,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) @@ -470,7 +463,11 @@ def delegatecall(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, GAS_CALL + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) diff --git a/src/ethereum/forks/spurious_dragon/vm/interpreter.py b/src/ethereum/forks/spurious_dragon/vm/interpreter.py index e65ffc2020a..c970cbc1ee4 100644 --- a/src/ethereum/forks/spurious_dragon/vm/interpreter.py +++ b/src/ethereum/forks/spurious_dragon/vm/interpreter.py @@ -44,7 +44,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -173,7 +173,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/tangerine_whistle/fork.py b/src/ethereum/forks/tangerine_whistle/fork.py index 162a6bd1b7a..78592e2d770 100644 --- a/src/ethereum/forks/tangerine_whistle/fork.py +++ b/src/ethereum/forks/tangerine_whistle/fork.py @@ -49,11 +49,10 @@ ) from .trie import root, trie_set from .utils.message import prepare_message +from .vm.gas import GasCosts from .vm.interpreter import process_message_call BLOCK_REWARD = U256(5 * 10**18) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) @@ -700,12 +699,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -723,12 +722,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/tangerine_whistle/transactions.py b/src/ethereum/forks/tangerine_whistle/transactions.py index 934540874ca..e17bafae49d 100644 --- a/src/ethereum/forks/tangerine_whistle/transactions.py +++ b/src/ethereum/forks/tangerine_whistle/transactions.py @@ -21,27 +21,6 @@ from .fork_types import Address -GAS_TX_BASE = Uint(21000) -""" -Base cost of a transaction in gas units. This is the minimum amount of gas -required to execute a transaction. -""" - -GAS_TX_DATA_PER_NON_ZERO = Uint(68) -""" -Gas cost per non-zero byte in the transaction data. -""" - -GAS_TX_DATA_PER_ZERO = Uint(4) -""" -Gas cost per zero byte in the transaction data. -""" - -GAS_TX_CREATE = Uint(32000) -""" -Additional gas cost for creating a new contract. -""" - @slotted_freezable @dataclass @@ -143,26 +122,28 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint: for all operations to be implemented. The intrinsic cost includes: - 1. Base cost (`GAS_TX_BASE`) + 1. Base cost (`TX_BASE`) 2. Cost for data (zero and non-zero bytes) 3. Cost for contract creation (if applicable) This function takes a transaction as a parameter and returns the intrinsic gas cost of the transaction. """ + from .vm.gas import GasCosts + num_zeros = Uint(tx.data.count(0)) num_non_zeros = ulen(tx.data) - num_zeros data_cost = ( - num_zeros * GAS_TX_DATA_PER_ZERO - + num_non_zeros * GAS_TX_DATA_PER_NON_ZERO + num_zeros * GasCosts.TX_DATA_PER_ZERO + + num_non_zeros * GasCosts.TX_DATA_PER_NON_ZERO ) if tx.to == Bytes0(b""): - create_cost = GAS_TX_CREATE + create_cost = GasCosts.TX_CREATE else: create_cost = Uint(0) - return GAS_TX_BASE + data_cost + create_cost + return GasCosts.TX_BASE + data_cost + create_cost def recover_sender(tx: Transaction) -> Address: diff --git a/src/ethereum/forks/tangerine_whistle/vm/gas.py b/src/ethereum/forks/tangerine_whistle/vm/gas.py index 56a9451c117..1dff8b9c25a 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/gas.py +++ b/src/ethereum/forks/tangerine_whistle/vm/gas.py @@ -22,45 +22,129 @@ from . import Evm from .exceptions import OutOfGasError -GAS_JUMPDEST = Uint(1) -GAS_BASE = Uint(2) -GAS_VERY_LOW = Uint(3) -GAS_SLOAD = Uint(200) -GAS_STORAGE_SET = Uint(20000) -GAS_COLD_STORAGE_WRITE = Uint(5000) -REFUND_STORAGE_CLEAR = 15000 -GAS_LOW = Uint(5) -GAS_MID = Uint(8) -GAS_HIGH = Uint(10) -GAS_EXPONENTIATION = Uint(10) -GAS_EXPONENTIATION_PER_BYTE = Uint(10) -GAS_MEMORY = Uint(3) -GAS_KECCAK256 = Uint(30) -GAS_KECCAK256_PER_WORD = Uint(6) -GAS_COPY = Uint(3) -GAS_BLOCK_HASH = Uint(20) -GAS_EXTERNAL = Uint(700) -GAS_BALANCE = Uint(400) -GAS_LOG = Uint(375) -GAS_LOG_DATA_PER_BYTE = Uint(8) -GAS_LOG_TOPIC = Uint(375) -GAS_CREATE = Uint(32000) -GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) -GAS_ZERO = Uint(0) -GAS_CALL = Uint(700) -GAS_NEW_ACCOUNT = Uint(25000) -GAS_CALL_VALUE = Uint(9000) -GAS_CALL_STIPEND = Uint(2300) -GAS_SELF_DESTRUCT = Uint(5000) -GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) -REFUND_SELF_DESTRUCT = 24000 -GAS_PRECOMPILE_ECRECOVER = Uint(3000) -GAS_PRECOMPILE_SHA256_BASE = Uint(60) -GAS_PRECOMPILE_SHA256_PER_WORD = Uint(12) -GAS_PRECOMPILE_RIPEMD160_BASE = Uint(600) -GAS_PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) -GAS_PRECOMPILE_IDENTITY_BASE = Uint(15) -GAS_PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + +# These values may be patched at runtime by a future gas repricing utility +class GasCosts: + """ + Constant gas values for the EVM. + """ + + # Tiers + BASE = Uint(2) + VERY_LOW = Uint(3) + LOW = Uint(5) + MID = Uint(8) + HIGH = Uint(10) + + # Access + SLOAD = Uint(200) + + # Storage + STORAGE_SET = Uint(20000) + COLD_STORAGE_WRITE = Uint(5000) + + # Call + CALL_VALUE = Uint(9000) + CALL_STIPEND = Uint(2300) + NEW_ACCOUNT = Uint(25000) + + # Contract Creation + CODE_DEPOSIT_PER_BYTE = Uint(200) + + # Utility + ZERO = Uint(0) + MEMORY_PER_WORD = Uint(3) + + # Refunds + REFUND_STORAGE_CLEAR = 15000 + REFUND_SELF_DESTRUCT = 24000 + + # Precompiles + PRECOMPILE_ECRECOVER = Uint(3000) + PRECOMPILE_SHA256_BASE = Uint(60) + PRECOMPILE_SHA256_PER_WORD = Uint(12) + PRECOMPILE_RIPEMD160_BASE = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) + PRECOMPILE_IDENTITY_BASE = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + + # Transactions + TX_BASE = Uint(21000) + TX_CREATE = Uint(32000) + TX_DATA_PER_ZERO = Uint(4) + TX_DATA_PER_NON_ZERO = Uint(68) + + # Block + LIMIT_ADJUSTMENT_FACTOR = Uint(1024) + LIMIT_MINIMUM = Uint(5000) + + # Static Opcodes + OPCODE_ADD = VERY_LOW + OPCODE_SUB = VERY_LOW + OPCODE_MUL = LOW + OPCODE_DIV = LOW + OPCODE_SDIV = LOW + OPCODE_MOD = LOW + OPCODE_SMOD = LOW + OPCODE_ADDMOD = MID + OPCODE_MULMOD = MID + OPCODE_SIGNEXTEND = LOW + OPCODE_LT = VERY_LOW + OPCODE_GT = VERY_LOW + OPCODE_SLT = VERY_LOW + OPCODE_SGT = VERY_LOW + OPCODE_EQ = VERY_LOW + OPCODE_ISZERO = VERY_LOW + OPCODE_AND = VERY_LOW + OPCODE_OR = VERY_LOW + OPCODE_XOR = VERY_LOW + OPCODE_NOT = VERY_LOW + OPCODE_BYTE = VERY_LOW + OPCODE_JUMP = MID + OPCODE_JUMPI = HIGH + OPCODE_JUMPDEST = Uint(1) + OPCODE_CALLDATALOAD = VERY_LOW + OPCODE_BLOCKHASH = Uint(20) + OPCODE_COINBASE = BASE + OPCODE_POP = BASE + OPCODE_MSIZE = BASE + OPCODE_PC = BASE + OPCODE_GAS = BASE + OPCODE_ADDRESS = BASE + OPCODE_ORIGIN = BASE + OPCODE_CALLER = BASE + OPCODE_CALLVALUE = BASE + OPCODE_CALLDATASIZE = BASE + OPCODE_CODESIZE = BASE + OPCODE_GASPRICE = BASE + OPCODE_TIMESTAMP = BASE + OPCODE_NUMBER = BASE + OPCODE_GASLIMIT = BASE + OPCODE_DIFFICULTY = BASE + OPCODE_PUSH = VERY_LOW + OPCODE_DUP = VERY_LOW + OPCODE_SWAP = VERY_LOW + + # Dynamic Opcodes + OPCODE_CALLDATACOPY_BASE = VERY_LOW + OPCODE_CODECOPY_BASE = VERY_LOW + OPCODE_MLOAD_BASE = VERY_LOW + OPCODE_MSTORE_BASE = VERY_LOW + OPCODE_MSTORE8_BASE = VERY_LOW + OPCODE_COPY_PER_WORD = Uint(3) + OPCODE_CREATE_BASE = Uint(32000) + OPCODE_EXP_BASE = Uint(10) + OPCODE_EXP_PER_BYTE = Uint(10) + OPCODE_KECCAK256_BASE = Uint(30) + OPCODE_KECCACK256_PER_WORD = Uint(6) + OPCODE_LOG_BASE = Uint(375) + OPCODE_LOG_DATA_PER_BYTE = Uint(8) + OPCODE_LOG_TOPIC = Uint(375) + OPCODE_SELFDESTRUCT_BASE = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_EXTERNAL_BASE = Uint(700) + OPCODE_BALANCE = Uint(400) + OPCODE_CALL_BASE = Uint(700) @dataclass @@ -81,8 +165,8 @@ class ExtendMemory: @dataclass class MessageCallGas: """ - Define the gas cost and gas given to the sub-call for - executing the call opcodes. + Define the gas cost and gas given to the sub-call for executing the call + opcodes. `cost`: `ethereum.base_types.Uint` The gas required to execute the call opcode, excludes @@ -134,7 +218,7 @@ def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint: """ size_in_words = ceil32(size_in_bytes) // Uint(32) - linear_cost = size_in_words * GAS_MEMORY + linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD quadratic_cost = size_in_words ** Uint(2) // Uint(512) total_gas_cost = linear_cost + quadratic_cost try: @@ -189,7 +273,7 @@ def calculate_message_call_gas( gas_left: Uint, memory_cost: Uint, extra_gas: Uint, - call_stipend: Uint = GAS_CALL_STIPEND, + call_stipend: Uint = GasCosts.CALL_STIPEND, ) -> MessageCallGas: """ Calculates the MessageCallGas (cost and gas made available to the sub-call) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py index b7b1a370ad4..4c7423cba8e 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py @@ -18,11 +18,7 @@ from .. import Evm from ..gas import ( - GAS_EXPONENTIATION, - GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -44,7 +40,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +67,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +94,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +121,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +154,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +187,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +217,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +248,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +279,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_MULMOD) # OPERATION if z == 0: @@ -318,7 +314,9 @@ def exp(evm: Evm) -> None: exponent_bits = exponent.bit_length() exponent_bytes = (exponent_bits + Uint(7)) // Uint(8) charge_gas( - evm, GAS_EXPONENTIATION + GAS_EXPONENTIATION_PER_BYTE * exponent_bytes + evm, + GasCosts.OPCODE_EXP_BASE + + GasCosts.OPCODE_EXP_PER_BYTE * exponent_bytes, ) # OPERATION @@ -346,7 +344,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, GasCosts.OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py index 2a506f55751..62da98041ad 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +62,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +87,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +111,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +137,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py index 0edcbf000d1..fbca7daa37c 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py @@ -14,7 +14,7 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from ..gas import GasCosts, charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, GasCosts.OPCODE_BLOCKHASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_COINBASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_TIMESTAMP) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_NUMBER) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_DIFFICULTY) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASLIMIT) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py index a6a3d99bc86..22d3d8916b1 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py @@ -14,7 +14,10 @@ from ethereum_types.numeric import U256, Uint from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..stack import pop, push @@ -34,7 +37,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +63,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +90,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +116,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +143,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +169,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py index b3b1f2316a7..548a05d3163 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py @@ -13,7 +13,10 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm.gas import ( + GasCosts, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +60,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, GasCosts.OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +87,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, GasCosts.OPCODE_JUMPI) # OPERATION if conditional_value == 0: @@ -113,7 +116,7 @@ def pc(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_PC) # OPERATION push(evm.stack, U256(evm.pc)) @@ -137,7 +140,7 @@ def gas_left(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GAS) # OPERATION push(evm.stack, U256(evm.gas_left)) @@ -162,7 +165,7 @@ def jumpdest(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_JUMPDEST) + charge_gas(evm, GasCosts.OPCODE_JUMPDEST) # OPERATION pass diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py index 83eb5528226..d930368fdd9 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py @@ -20,11 +20,7 @@ from ...vm.memory import buffer_read, memory_write from .. import Evm from ..gas import ( - GAS_BALANCE, - GAS_BASE, - GAS_COPY, - GAS_EXTERNAL, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -45,7 +41,7 @@ def address(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ADDRESS) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.current_target)) @@ -68,7 +64,7 @@ def balance(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BALANCE) + charge_gas(evm, GasCosts.OPCODE_BALANCE) # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. @@ -95,7 +91,7 @@ def origin(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_ORIGIN) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.tx_env.origin)) @@ -118,7 +114,7 @@ def caller(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLER) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.caller)) @@ -141,7 +137,7 @@ def callvalue(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLVALUE) # OPERATION push(evm.stack, evm.message.value) @@ -165,7 +161,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -190,7 +186,7 @@ def calldatasize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CALLDATASIZE) # OPERATION push(evm.stack, U256(len(evm.message.data))) @@ -219,11 +215,14 @@ def calldatacopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CALLDATACOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -248,7 +247,7 @@ def codesize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_CODESIZE) # OPERATION push(evm.stack, U256(len(evm.code))) @@ -277,11 +276,14 @@ def codecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_CODECOPY_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -306,7 +308,7 @@ def gasprice(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_GASPRICE) # OPERATION push(evm.stack, U256(evm.message.tx_env.gas_price)) @@ -329,7 +331,7 @@ def extcodesize(evm: Evm) -> None: address = to_address_masked(pop(evm.stack)) # GAS - charge_gas(evm, GAS_EXTERNAL) + charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION account = get_account(evm.message.block_env.state, address) @@ -360,11 +362,14 @@ def extcodecopy(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - copy_gas_cost = GAS_COPY * words + copy_gas_cost = GasCosts.OPCODE_COPY_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_EXTERNAL + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_EXTERNAL_BASE + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py index 8661c5d62f5..c8099ee0ecc 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py @@ -18,8 +18,7 @@ from .. import Evm from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +45,14 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = GasCosts.OPCODE_KECCACK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas( + evm, + GasCosts.OPCODE_KECCAK256_BASE + word_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py index 76c02e737a4..e3e3ebd7e76 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py @@ -18,9 +18,7 @@ from ...blocks import Log from .. import Evm from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + GasCosts.OPCODE_LOG_BASE + + GasCosts.OPCODE_LOG_DATA_PER_BYTE * Uint(size) + + GasCosts.OPCODE_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py index 3a242ba2f7a..93861811559 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py @@ -16,8 +16,7 @@ from .. import Evm from ..gas import ( - GAS_BASE, - GAS_VERY_LOW, + GasCosts, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MSTORE8_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_MLOAD_BASE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -132,7 +131,7 @@ def msize(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_MSIZE) # OPERATION push(evm.stack, U256(len(evm.memory))) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py index 0fc0d3fe4b5..9104c1e9749 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py @@ -17,7 +17,10 @@ from .. import Evm, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GasCosts, + charge_gas, +) from ..memory import buffer_read @@ -35,7 +38,7 @@ def pop(evm: Evm) -> None: stack.pop(evm.stack) # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, GasCosts.OPCODE_POP) # OPERATION pass @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_PUSH) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_DUP) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, GasCosts.OPCODE_SWAP) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py index 154b4fd47bb..0b2a1cce8aa 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py @@ -16,10 +16,7 @@ from ...state import get_storage, set_storage from .. import Evm from ..gas import ( - GAS_COLD_STORAGE_WRITE, - GAS_SLOAD, - GAS_STORAGE_SET, - REFUND_STORAGE_CLEAR, + GasCosts, charge_gas, ) from ..stack import pop, push @@ -40,7 +37,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, GasCosts.SLOAD) # OPERATION value = get_storage( @@ -71,12 +68,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = GasCosts.STORAGE_SET else: - gas_cost = GAS_COLD_STORAGE_WRITE + gas_cost = GasCosts.COLD_STORAGE_WRITE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += GasCosts.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py index 50a359402b1..6ef0f1a0015 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py @@ -33,14 +33,7 @@ incorporate_child_on_success, ) from ..gas import ( - GAS_CALL, - GAS_CALL_VALUE, - GAS_CREATE, - GAS_NEW_ACCOUNT, - GAS_SELF_DESTRUCT, - GAS_SELF_DESTRUCT_NEW_ACCOUNT, - GAS_ZERO, - REFUND_SELF_DESTRUCT, + GasCosts, calculate_gas_extend_memory, calculate_message_call_gas, charge_gas, @@ -74,7 +67,7 @@ def create(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_CREATE + extend_memory.cost) + charge_gas(evm, GasCosts.OPCODE_CREATE_BASE + extend_memory.cost) create_message_gas = max_message_call_gas(Uint(evm.gas_left)) evm.gas_left -= create_message_gas @@ -163,7 +156,7 @@ def return_(evm: Evm) -> None: evm.memory, [(memory_start_position, memory_size)] ) - charge_gas(evm, GAS_ZERO + extend_memory.cost) + charge_gas(evm, GasCosts.ZERO + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -268,14 +261,14 @@ def call(evm: Evm) -> None: code_address = to _account_exists = account_exists(evm.message.block_env.state, to) - create_gas_cost = Uint(0) if _account_exists else GAS_NEW_ACCOUNT - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + create_gas_cost = Uint(0) if _account_exists else GasCosts.NEW_ACCOUNT + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + create_gas_cost + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + create_gas_cost + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -335,13 +328,13 @@ def callcode(evm: Evm) -> None: (memory_output_start_position, memory_output_size), ], ) - transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE + transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( value, gas, Uint(evm.gas_left), extend_memory.cost, - GAS_CALL + transfer_gas_cost, + GasCosts.OPCODE_CALL_BASE + transfer_gas_cost, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) @@ -386,9 +379,9 @@ def selfdestruct(evm: Evm) -> None: beneficiary = to_address_masked(pop(evm.stack)) # GAS - gas_cost = GAS_SELF_DESTRUCT + gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if not account_exists(evm.message.block_env.state, beneficiary): - gas_cost += GAS_SELF_DESTRUCT_NEW_ACCOUNT + gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -399,7 +392,7 @@ def selfdestruct(evm: Evm) -> None: parent_evm = parent_evm.message.parent_evm if originator not in refunded_accounts: - evm.refund_counter += REFUND_SELF_DESTRUCT + evm.refund_counter += GasCosts.REFUND_SELF_DESTRUCT charge_gas(evm, gas_cost) @@ -459,7 +452,11 @@ def delegatecall(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - U256(0), gas, Uint(evm.gas_left), extend_memory.cost, GAS_CALL + U256(0), + gas, + Uint(evm.gas_left), + extend_memory.cost, + GasCosts.OPCODE_CALL_BASE, ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) diff --git a/src/ethereum/forks/tangerine_whistle/vm/interpreter.py b/src/ethereum/forks/tangerine_whistle/vm/interpreter.py index e6e7c7729c4..a687e748de3 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/interpreter.py +++ b/src/ethereum/forks/tangerine_whistle/vm/interpreter.py @@ -42,7 +42,7 @@ touch_account, ) from ..vm import Message -from ..vm.gas import GAS_CODE_DEPOSIT_PER_BYTE, charge_gas +from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS from . import Evm from .exceptions import ( @@ -158,7 +158,7 @@ def process_create_message(message: Message) -> Evm: if not evm.error: contract_code = evm.output contract_code_gas = ( - Uint(len(contract_code)) * GAS_CODE_DEPOSIT_PER_BYTE + ulen(contract_code) * GasCosts.CODE_DEPOSIT_PER_BYTE ) try: charge_gas(evm, contract_code_gas) diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ecrecover.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ecrecover.py index b6d23a58a89..17a0174f6ed 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ecrecover.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ecrecover.py @@ -19,7 +19,7 @@ from ethereum.utils.byte import left_pad_zero_bytes from ...vm import Evm -from ...vm.gas import GAS_PRECOMPILE_ECRECOVER, charge_gas +from ...vm.gas import GasCosts, charge_gas from ...vm.memory import buffer_read @@ -37,7 +37,7 @@ def ecrecover(evm: Evm) -> None: data = evm.message.data # GAS - charge_gas(evm, GAS_PRECOMPILE_ECRECOVER) + charge_gas(evm, GasCosts.PRECOMPILE_ECRECOVER) # OPERATION message_hash_bytes = buffer_read(data, U256(0), U256(32)) diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py index 133a4832bf8..cdbd61f5b0d 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py @@ -17,8 +17,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_IDENTITY_BASE, - GAS_PRECOMPILE_IDENTITY_PER_WORD, + GasCosts, charge_gas, ) @@ -39,8 +38,8 @@ def identity(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_IDENTITY_BASE - + GAS_PRECOMPILE_IDENTITY_PER_WORD * word_count, + GasCosts.PRECOMPILE_IDENTITY_BASE + + GasCosts.PRECOMPILE_IDENTITY_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py index d4e28adf0ad..eafdf08c365 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py @@ -20,8 +20,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_RIPEMD160_BASE, - GAS_PRECOMPILE_RIPEMD160_PER_WORD, + GasCosts, charge_gas, ) @@ -42,8 +41,8 @@ def ripemd160(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_RIPEMD160_BASE - + GAS_PRECOMPILE_RIPEMD160_PER_WORD * word_count, + GasCosts.PRECOMPILE_RIPEMD160_BASE + + GasCosts.PRECOMPILE_RIPEMD160_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py index 04dfef6730d..0a9f67e8441 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py @@ -19,8 +19,7 @@ from ...vm import Evm from ...vm.gas import ( - GAS_PRECOMPILE_SHA256_BASE, - GAS_PRECOMPILE_SHA256_PER_WORD, + GasCosts, charge_gas, ) @@ -41,8 +40,8 @@ def sha256(evm: Evm) -> None: word_count = ceil32(Uint(len(data))) // Uint(32) charge_gas( evm, - GAS_PRECOMPILE_SHA256_BASE - + GAS_PRECOMPILE_SHA256_PER_WORD * word_count, + GasCosts.PRECOMPILE_SHA256_BASE + + GasCosts.PRECOMPILE_SHA256_PER_WORD * word_count, ) # OPERATION diff --git a/src/ethereum_spec_tools/new_fork/builder.py b/src/ethereum_spec_tools/new_fork/builder.py index 575aff4e187..14a4899db1f 100644 --- a/src/ethereum_spec_tools/new_fork/builder.py +++ b/src/ethereum_spec_tools/new_fork/builder.py @@ -489,16 +489,16 @@ def modify_target_blob_gas_per_block( """Append a `CodemodArgs` that sets `BLOB_TARGET_GAS_PER_BLOCK`.""" self.modifiers.append( SetConstant( - "vm.gas.BLOB_TARGET_GAS_PER_BLOCK", + "vm.gas.GasCosts.BLOB_TARGET_GAS_PER_BLOCK", repr(blob_target_gas_per_block), ) ) def modify_gas_per_blob(self, gas_per_blob: U64) -> None: - """Append a `CodemodArgs` that sets `GAS_PER_BLOB`.""" + """Append a `CodemodArgs` that sets `PER_BLOB`.""" self.modifiers.append( SetConstant( - "vm.gas.GAS_PER_BLOB", + "vm.gas.GasCosts.PER_BLOB", repr(gas_per_blob), ) ) @@ -507,7 +507,7 @@ def modify_min_blob_gasprice(self, blob_min_gasprice: Uint) -> None: """Append a `CodemodArgs` that sets `BLOB_MIN_GASPRICE`.""" self.modifiers.append( SetConstant( - "vm.gas.BLOB_MIN_GASPRICE", + "vm.gas.GasCosts.BLOB_MIN_GASPRICE", repr(blob_min_gasprice), ) ) @@ -518,7 +518,7 @@ def modify_blob_base_fee_update_fraction( """Append a `CodemodArgs` that sets `BLOB_BASE_FEE_UPDATE_FRACTION`.""" self.modifiers.append( SetConstant( - "vm.gas.BLOB_BASE_FEE_UPDATE_FRACTION", + "vm.gas.GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION", repr(blob_base_fee_update_fraction), ) ) @@ -538,7 +538,7 @@ def modify_blob_schedule_target(self, blob_schedule_target: U64) -> None: """Append a `CodemodArgs` that sets `BLOB_SCHEDULE_TARGET`.""" self.modifiers.append( SetConstant( - "vm.gas.BLOB_SCHEDULE_TARGET", + "vm.gas.GasCosts.BLOB_SCHEDULE_TARGET", repr(blob_schedule_target), ) ) @@ -547,7 +547,7 @@ def modify_blob_schedule_max(self, blob_schedule_max: U64) -> None: """Append a `CodemodArgs` that sets `BLOB_SCHEDULE_MAX`.""" self.modifiers.append( SetConstant( - "vm.gas.BLOB_SCHEDULE_MAX", + "vm.gas.GasCosts.BLOB_SCHEDULE_MAX", repr(blob_schedule_max), ) ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 87a8907b048..ba4fbd5f221 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -2670,7 +2670,7 @@ def test_bal_gas_limit_boundary( Test the BAL max items gas limit boundary for an empty block. The consensus rule requires - ``bal_items <= block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM``. + ``bal_items <= block_gas_limit // BLOCK_ACCESS_LIST_ITEM``. The boundary gas limit is derived from the fork's system-contract BAL footprint. At the boundary the check passes; one below it fails. """ @@ -2678,7 +2678,7 @@ def test_bal_gas_limit_boundary( # bal_items <= block_gas_limit // ITEM_COST min_gas_limit = ( fork.empty_block_bal_item_count() - * fork.gas_costs().GAS_BLOCK_ACCESS_LIST_ITEM + * fork.gas_costs().BLOCK_ACCESS_LIST_ITEM ) gas_limit = min_gas_limit + boundary_offset diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index 3daa969304a..67f5aeda8ff 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -125,16 +125,16 @@ def test_bal_sstore_and_oog( intrinsic_gas_cost = fork.transaction_intrinsic_cost_calculator()() - # Full cost: PUSHes + SSTORE (GAS_COLD_STORAGE_ACCESS + GAS_STORAGE_SET) + # Full cost: PUSHes + SSTORE (COLD_STORAGE_ACCESS + STORAGE_SET) full_cost = storage_contract_code.gas_cost(fork) # Push cost for stipend boundary calculations push_code = Op.PUSH1(0x42) + Op.PUSH1(0x01) push_cost = push_code.gas_cost(fork) - # GAS_CALL_STIPEND is a threshold check, not a gas cost + # CALL_STIPEND is a threshold check, not a gas cost # Keep from gas_costs - stipend = fork.gas_costs().GAS_CALL_STIPEND + stipend = fork.gas_costs().CALL_STIPEND if out_of_gas_at == OutOfGasAt.EIP_2200_STIPEND: # 2300 after PUSHes (fails stipend check: 2300 <= 2300) @@ -625,7 +625,7 @@ def test_bal_call_no_delegation_oog_after_target_access( - target is always empty - required for create cost - value=1 (greater than 0) - required for create cost - The create_cost (GAS_NEW_ACCOUNT = 25000) is charged only for value + The create_cost (NEW_ACCOUNT = 25000) is charged only for value transfers to empty accounts, creating the gap tested here. """ diff --git a/tests/benchmark/compute/instruction/test_system.py b/tests/benchmark/compute/instruction/test_system.py index 4f9161ae213..551a1e242d0 100644 --- a/tests/benchmark/compute/instruction/test_system.py +++ b/tests/benchmark/compute/instruction/test_system.py @@ -73,7 +73,7 @@ def loop(threshold: int) -> Bytecode: intrinsic_cost_calc = fork.transaction_intrinsic_cost_calculator() intrinsic_cost = intrinsic_cost_calc() - access_list_addr_cost = fork.gas_costs().GAS_TX_ACCESS_LIST_ADDRESS + access_list_addr_cost = fork.gas_costs().TX_ACCESS_LIST_ADDRESS txs = [] remaining_gas = gas_benchmark_value diff --git a/tests/benchmark/compute/precompile/test_alt_bn128.py b/tests/benchmark/compute/precompile/test_alt_bn128.py index d81e490e964..9dbb1f0096d 100644 --- a/tests/benchmark/compute/precompile/test_alt_bn128.py +++ b/tests/benchmark/compute/precompile/test_alt_bn128.py @@ -458,8 +458,8 @@ def test_bn128_pairings_amortized( size_per_pairing = 192 gsc = fork.gas_costs() - base_cost = gsc.GAS_PRECOMPILE_ECPAIRING_BASE - pairing_cost = gsc.GAS_PRECOMPILE_ECPAIRING_PER_POINT + base_cost = gsc.PRECOMPILE_ECPAIRING_BASE + pairing_cost = gsc.PRECOMPILE_ECPAIRING_PER_POINT intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() mem_exp_gas_calculator = fork.memory_expansion_gas_calculator() warm_account_access_cost = Op.STATICCALL( @@ -572,8 +572,8 @@ def test_ec_pairing( intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() mem_exp = fork.memory_expansion_gas_calculator() precompile_cost = ( - gsc.GAS_PRECOMPILE_ECPAIRING_BASE - + gsc.GAS_PRECOMPILE_ECPAIRING_PER_POINT * num_pairs + gsc.PRECOMPILE_ECPAIRING_BASE + + gsc.PRECOMPILE_ECPAIRING_PER_POINT * num_pairs ) # Each iteration: STATICCALL ecpairing at advancing calldata offset, @@ -612,7 +612,7 @@ def test_ec_pairing( per_variant_gas = ( iteration_cost + pair_size * 16 - + words_per_variant * (gsc.GAS_COPY + gsc.GAS_MEMORY) + + words_per_variant * (gsc.OPCODE_COPY_PER_WORD + gsc.MEMORY_PER_WORD) ) empty_intrinsic = intrinsic_gas_calculator( calldata=[], return_cost_deducted_prior_execution=True @@ -644,7 +644,7 @@ def test_ec_pairing( per_tx_gas - execution_intrinsic - setup_cost - - math.ceil(len(calldata) / 32) * gsc.GAS_COPY + - math.ceil(len(calldata) / 32) * gsc.OPCODE_COPY_PER_WORD - mem_exp(new_bytes=len(calldata) + 32) ) @@ -722,9 +722,9 @@ def test_alt_bn128_uncachable( intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() gsc = fork.gas_costs() precompile_cost = ( - gsc.GAS_PRECOMPILE_ECMUL + gsc.PRECOMPILE_ECMUL if precompile_address == 0x07 - else gsc.GAS_PRECOMPILE_ECADD + else gsc.PRECOMPILE_ECADD ) attack_block = Op.POP( Op.STATICCALL( diff --git a/tests/benchmark/compute/precompile/test_blake2f.py b/tests/benchmark/compute/precompile/test_blake2f.py index 25a9407633a..e9995aa0b2b 100644 --- a/tests/benchmark/compute/precompile/test_blake2f.py +++ b/tests/benchmark/compute/precompile/test_blake2f.py @@ -121,8 +121,8 @@ def test_blake2f_uncachable( # BLAKE2F costs num_rounds gas. gsc = fork.gas_costs() precompile_cost = ( - num_rounds * gsc.GAS_PRECOMPILE_BLAKE2F_PER_ROUND - ) + gsc.GAS_PRECOMPILE_BLAKE2F_BASE + num_rounds * gsc.PRECOMPILE_BLAKE2F_PER_ROUND + ) + gsc.PRECOMPILE_BLAKE2F_BASE attack_block = Op.POP( Op.STATICCALL( diff --git a/tests/benchmark/compute/precompile/test_bls12_381.py b/tests/benchmark/compute/precompile/test_bls12_381.py index 4636b6015ed..e994283e11e 100644 --- a/tests/benchmark/compute/precompile/test_bls12_381.py +++ b/tests/benchmark/compute/precompile/test_bls12_381.py @@ -531,8 +531,8 @@ def test_bls12_pairing_uncachable( attack_contract_address = pre.deploy_contract(code=code) precompile_cost = ( - gsc.GAS_PRECOMPILE_BLS_PAIRING_BASE - + gsc.GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR * num_pairs + gsc.PRECOMPILE_BLS_PAIRING_BASE + + gsc.PRECOMPILE_BLS_PAIRING_PER_PAIR * num_pairs ) iteration_cost = loop.gas_cost(fork) + precompile_cost @@ -545,8 +545,8 @@ def test_bls12_pairing_uncachable( tokens_per_variant = pair_size * 4 # worst case: all non-zero per_variant_gas = ( iteration_cost - + tokens_per_variant * gsc.GAS_TX_DATA_TOKEN_FLOOR - + words_per_variant * (gsc.GAS_COPY + gsc.GAS_MEMORY) + + tokens_per_variant * gsc.TX_DATA_TOKEN_FLOOR + + words_per_variant * (gsc.OPCODE_COPY_PER_WORD + gsc.MEMORY_PER_WORD) ) empty_intrinsic = intrinsic_gas_calculator( calldata=[], @@ -579,7 +579,7 @@ def test_bls12_pairing_uncachable( per_tx_gas - execution_intrinsic - setup_cost - - math.ceil(len(calldata) / 32) * gsc.GAS_COPY + - math.ceil(len(calldata) / 32) * gsc.OPCODE_COPY_PER_WORD - mem_exp(new_bytes=len(calldata) + 32) ) diff --git a/tests/benchmark/compute/precompile/test_identity.py b/tests/benchmark/compute/precompile/test_identity.py index af33feecf34..17eef9589ee 100644 --- a/tests/benchmark/compute/precompile/test_identity.py +++ b/tests/benchmark/compute/precompile/test_identity.py @@ -32,8 +32,8 @@ def test_identity( optimal_input_length = calculate_optimal_input_length( available_gas=gas_available, fork=fork, - static_cost=gas_costs.GAS_PRECOMPILE_IDENTITY_BASE, - per_word_dynamic_cost=gas_costs.GAS_PRECOMPILE_IDENTITY_PER_WORD, + static_cost=gas_costs.PRECOMPILE_IDENTITY_BASE, + per_word_dynamic_cost=gas_costs.PRECOMPILE_IDENTITY_PER_WORD, bytes_per_unit_of_work=1, ) @@ -86,9 +86,9 @@ def test_identity_uncachable( precompile_cost = ( # static cost - gsc.GAS_PRECOMPILE_IDENTITY_BASE + gsc.PRECOMPILE_IDENTITY_BASE # dynamic cost - + math.ceil(size / 32) * gsc.GAS_PRECOMPILE_IDENTITY_PER_WORD + + math.ceil(size / 32) * gsc.PRECOMPILE_IDENTITY_PER_WORD ) attack_block = Op.MSTORE( diff --git a/tests/benchmark/compute/precompile/test_p256verify.py b/tests/benchmark/compute/precompile/test_p256verify.py index bcbc27e6d01..d40d6af031a 100644 --- a/tests/benchmark/compute/precompile/test_p256verify.py +++ b/tests/benchmark/compute/precompile/test_p256verify.py @@ -130,7 +130,7 @@ def test_p256verify_uncachable( gsc = fork.gas_costs() intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() - precompile_cost = gsc.GAS_PRECOMPILE_P256VERIFY + precompile_cost = gsc.PRECOMPILE_P256VERIFY # h: data[0:32] 32 bytes # r: data[32:64] 32 bytes diff --git a/tests/benchmark/compute/precompile/test_point_evaluation.py b/tests/benchmark/compute/precompile/test_point_evaluation.py index 5f723243944..c4b76c07962 100644 --- a/tests/benchmark/compute/precompile/test_point_evaluation.py +++ b/tests/benchmark/compute/precompile/test_point_evaluation.py @@ -113,7 +113,7 @@ def test_point_evaluation_uncachable( gsc = fork.gas_costs() intrinsic_gas_calculator = fork.transaction_intrinsic_cost_calculator() mem_exp = fork.memory_expansion_gas_calculator() - precompile_cost = gsc.GAS_PRECOMPILE_POINT_EVALUATION + precompile_cost = gsc.PRECOMPILE_POINT_EVALUATION # Each iteration: STATICCALL point_evaluation at advancing calldata # offset, then advance offset at MEM[CALLDATASIZE]. @@ -148,8 +148,8 @@ def test_point_evaluation_uncachable( words_per_variant = math.ceil(INPUT_SIZE / 32) per_variant_gas = ( iteration_cost - + INPUT_SIZE * gsc.GAS_TX_DATA_TOKEN_FLOOR - + words_per_variant * (gsc.GAS_COPY + gsc.GAS_MEMORY) + + INPUT_SIZE * gsc.TX_DATA_TOKEN_FLOOR + + words_per_variant * (gsc.OPCODE_COPY_PER_WORD + gsc.MEMORY_PER_WORD) ) empty_intrinsic = intrinsic_gas_calculator( calldata=[], return_cost_deducted_prior_execution=True @@ -193,7 +193,7 @@ def test_point_evaluation_uncachable( per_tx_gas - execution_intrinsic - setup_cost - - math.ceil(len(calldata) / 32) * gsc.GAS_COPY + - math.ceil(len(calldata) / 32) * gsc.OPCODE_COPY_PER_WORD - mem_exp(new_bytes=len(calldata) + 32) ) diff --git a/tests/benchmark/compute/precompile/test_ripemd160.py b/tests/benchmark/compute/precompile/test_ripemd160.py index 81cee31d4f5..3b8e4969d6d 100644 --- a/tests/benchmark/compute/precompile/test_ripemd160.py +++ b/tests/benchmark/compute/precompile/test_ripemd160.py @@ -32,8 +32,8 @@ def test_ripemd160( optimal_input_length = calculate_optimal_input_length( available_gas=gas_available, fork=fork, - static_cost=gas_costs.GAS_PRECOMPILE_RIPEMD160_BASE, - per_word_dynamic_cost=gas_costs.GAS_PRECOMPILE_RIPEMD160_PER_WORD, + static_cost=gas_costs.PRECOMPILE_RIPEMD160_BASE, + per_word_dynamic_cost=gas_costs.PRECOMPILE_RIPEMD160_PER_WORD, bytes_per_unit_of_work=64, ) @@ -86,9 +86,9 @@ def test_ripemd160_uncachable( precompile_cost = ( # static cost - gsc.GAS_PRECOMPILE_RIPEMD160_BASE + gsc.PRECOMPILE_RIPEMD160_BASE # dynamic cost - + math.ceil(size / 32) * gsc.GAS_PRECOMPILE_RIPEMD160_PER_WORD + + math.ceil(size / 32) * gsc.PRECOMPILE_RIPEMD160_PER_WORD ) attack_block = Op.POP( diff --git a/tests/benchmark/compute/precompile/test_sha256.py b/tests/benchmark/compute/precompile/test_sha256.py index 43245a04e19..beee369d534 100644 --- a/tests/benchmark/compute/precompile/test_sha256.py +++ b/tests/benchmark/compute/precompile/test_sha256.py @@ -32,8 +32,8 @@ def test_sha256( optimal_input_length = calculate_optimal_input_length( available_gas=gas_available, fork=fork, - static_cost=gas_costs.GAS_PRECOMPILE_SHA256_BASE, - per_word_dynamic_cost=gas_costs.GAS_PRECOMPILE_SHA256_PER_WORD, + static_cost=gas_costs.PRECOMPILE_SHA256_BASE, + per_word_dynamic_cost=gas_costs.PRECOMPILE_SHA256_PER_WORD, bytes_per_unit_of_work=64, ) @@ -86,9 +86,9 @@ def test_sha256_uncachable( precompile_cost = ( # static cost - gsc.GAS_PRECOMPILE_SHA256_BASE + gsc.PRECOMPILE_SHA256_BASE # dynamic cost - + math.ceil(size / 32) * gsc.GAS_PRECOMPILE_SHA256_PER_WORD + + math.ceil(size / 32) * gsc.PRECOMPILE_SHA256_PER_WORD ) attack_block = Op.POP( Op.STATICCALL( diff --git a/tests/benchmark/compute/scenario/test_transaction_types.py b/tests/benchmark/compute/scenario/test_transaction_types.py index 8ee1ed6546b..b23d3180d22 100644 --- a/tests/benchmark/compute/scenario/test_transaction_types.py +++ b/tests/benchmark/compute/scenario/test_transaction_types.py @@ -268,13 +268,13 @@ def test_ether_transfers_to_precompile( @pytest.fixture def total_cost_floor_per_token(fork: Fork) -> int: """Total cost floor per token (EIP-7623).""" - return fork.gas_costs().GAS_TX_DATA_TOKEN_FLOOR + return fork.gas_costs().TX_DATA_TOKEN_FLOOR @pytest.fixture def total_cost_standard_per_token(fork: Fork) -> int: """Standard cost per token (EIP-7623).""" - return fork.gas_costs().GAS_TX_DATA_TOKEN_STANDARD + return fork.gas_costs().TX_DATA_TOKEN_STANDARD def calldata_generator( @@ -286,11 +286,11 @@ def calldata_generator( # Gas cost calculation based on EIP-7683: (https://eips.ethereum.org/EIPS/eip-7683) # # tx.gasUsed = 21000 + max( - # GAS_TX_DATA_TOKEN_STANDARD * tokens_in_calldata + # TX_DATA_TOKEN_STANDARD * tokens_in_calldata # + execution_gas_used # + isContractCreation * (32000 + # INITCODE_WORD_COST * words(calldata)), - # GAS_TX_DATA_TOKEN_FLOOR * tokens_in_calldata) + # TX_DATA_TOKEN_FLOOR * tokens_in_calldata) # # Simplified in this test case: # - No execution gas used (no opcodes are executed) @@ -298,10 +298,10 @@ def calldata_generator( # # Therefore: # max_token_cost = - # max(GAS_TX_DATA_TOKEN_STANDARD, GAS_TX_DATA_TOKEN_FLOOR) + # max(TX_DATA_TOKEN_STANDARD, TX_DATA_TOKEN_FLOOR) # tx.gasUsed = 21000 + tokens_in_calldata * max_token_cost # - # Since max(GAS_TX_DATA_TOKEN_STANDARD, GAS_TX_DATA_TOKEN_FLOOR) = 10: + # Since max(TX_DATA_TOKEN_STANDARD, TX_DATA_TOKEN_FLOOR) = 10: # tx.gasUsed = 21000 + tokens_in_calldata * 10 # # Token accounting: @@ -421,8 +421,8 @@ def test_block_full_access_list_and_data( # Access list gas costs from fork's gas_costs gas_costs = fork.gas_costs() - gas_per_address = gas_costs.GAS_TX_ACCESS_LIST_ADDRESS - gas_per_storage_key = gas_costs.GAS_TX_ACCESS_LIST_STORAGE_KEY + gas_per_address = gas_costs.TX_ACCESS_LIST_ADDRESS + gas_per_storage_key = gas_costs.TX_ACCESS_LIST_STORAGE_KEY # Calculate number of storage keys we can fit gas_after_address = gas_for_access_list - gas_per_address @@ -594,7 +594,7 @@ def test_auth_transaction( total_refund += min( tx_gas_used // 5, ( - gas_costs.GAS_AUTH_PER_EMPTY_ACCOUNT + gas_costs.AUTH_PER_EMPTY_ACCOUNT - gas_costs.REFUND_AUTH_PER_EXISTING_ACCOUNT ) * auths_in_this_tx, diff --git a/tests/benchmark/stateful/bloatnet/test_multi_opcode.py b/tests/benchmark/stateful/bloatnet/test_multi_opcode.py index 050f3107eb8..4e38786bb37 100755 --- a/tests/benchmark/stateful/bloatnet/test_multi_opcode.py +++ b/tests/benchmark/stateful/bloatnet/test_multi_opcode.py @@ -208,7 +208,7 @@ def test_bloatnet_balance_opcode( # test_bloatnet_call_value_existing: # Same factory pattern as test_bloatnet_balance_opcode, but performs # CALL with value=1 wei to each factory contract. The subcall fails -# (insufficient gas for 24KB bytecode), but GAS_CALL_VALUE (9000 gas) +# (insufficient gas for 24KB bytecode), but CALL_VALUE (9000 gas) # is still charged on top of the cold account access cost. # # test_bloatnet_call_value_new_account: @@ -232,7 +232,7 @@ def test_bloatnet_call_value_existing( Benchmark CALL with value transfer to cold existing factory contracts. Unlike the existing CALL test which uses gas=1 and value=0, this test - passes value=1 wei per call, adding GAS_CALL_VALUE (9000 gas) to each + passes value=1 wei per call, adding CALL_VALUE (9000 gas) to each cold account access. The subcall fails (insufficient gas for bytecode execution), so value is not actually transferred, but the gas penalty is still charged. @@ -332,8 +332,8 @@ def test_bloatnet_call_value_new_account( (via the 2300 gas stipend), transferring value and creating a new account in the trie. Each iteration costs ~36,600 gas: - GAS_COLD_ACCOUNT_ACCESS: 2,600 - - GAS_CALL_VALUE: 9,000 - - GAS_NEW_ACCOUNT: 25,000 + - CALL_VALUE: 9,000 + - NEW_ACCOUNT: 25,000 This stresses trie expansion through massive new account creation. """ diff --git a/tests/berlin/eip2929_gas_cost_increases/test_create.py b/tests/berlin/eip2929_gas_cost_increases/test_create.py index d6bbb4570d8..3e73407f5d9 100644 --- a/tests/berlin/eip2929_gas_cost_increases/test_create.py +++ b/tests/berlin/eip2929_gas_cost_increases/test_create.py @@ -57,8 +57,8 @@ def test_create_insufficient_balance( A creator contract with zero balance attempts to create with value=1. The create aborts, and a subsequent BALANCE check on the would-be - contract address verifies it remains cold (costs G_COLD_ACCOUNT_ACCESS - instead of G_WARM_STORAGE_READ). + contract address verifies it remains cold (costs COLD_ACCOUNT_ACCESS + instead of WARM_STORAGE_READ). """ initcode = Op.STOP diff --git a/tests/byzantium/eip196_ec_add_mul/conftest.py b/tests/byzantium/eip196_ec_add_mul/conftest.py index 6fc5cae214d..42e0d29776f 100644 --- a/tests/byzantium/eip196_ec_add_mul/conftest.py +++ b/tests/byzantium/eip196_ec_add_mul/conftest.py @@ -27,9 +27,9 @@ def precompile_gas(precompile_address: Address, fork: Fork) -> int: gas_costs = fork.gas_costs() match precompile_address: case Spec.ECADD: - return gas_costs.GAS_PRECOMPILE_ECADD + return gas_costs.PRECOMPILE_ECADD case Spec.ECMUL: - return gas_costs.GAS_PRECOMPILE_ECMUL + return gas_costs.PRECOMPILE_ECMUL case _: raise ValueError( f"Unexpected precompile address: {precompile_address}" diff --git a/tests/byzantium/eip196_ec_add_mul/test_gas.py b/tests/byzantium/eip196_ec_add_mul/test_gas.py index b5fa091eb5f..bcf5012bc25 100644 --- a/tests/byzantium/eip196_ec_add_mul/test_gas.py +++ b/tests/byzantium/eip196_ec_add_mul/test_gas.py @@ -116,10 +116,10 @@ def test_invalid_gas_consumption( address_warm=False ).gas_cost(fork) - # Pre-EIP-2929: fixed G_call = 700; Berlin+: warm access cost. + # Pre-EIP-2929: fixed call = 700; Berlin+: warm access cost. gas_costs = fork.gas_costs() if fork >= Berlin: - staticcall_base = gas_costs.GAS_WARM_ACCESS + staticcall_base = gas_costs.WARM_ACCESS else: staticcall_base = 700 diff --git a/tests/byzantium/eip197_ec_pairing/conftest.py b/tests/byzantium/eip197_ec_pairing/conftest.py index 01bc4552191..8f3164caadf 100644 --- a/tests/byzantium/eip197_ec_pairing/conftest.py +++ b/tests/byzantium/eip197_ec_pairing/conftest.py @@ -23,6 +23,6 @@ def precompile_gas(input_data: bytes, fork: Fork) -> int: gas_costs = fork.gas_costs() k = len(input_data) // 192 return ( - gas_costs.GAS_PRECOMPILE_ECPAIRING_BASE - + gas_costs.GAS_PRECOMPILE_ECPAIRING_PER_POINT * k + gas_costs.PRECOMPILE_ECPAIRING_BASE + + gas_costs.PRECOMPILE_ECPAIRING_PER_POINT * k ) diff --git a/tests/byzantium/eip197_ec_pairing/test_gas.py b/tests/byzantium/eip197_ec_pairing/test_gas.py index a38b8d58431..1a1108c37f0 100644 --- a/tests/byzantium/eip197_ec_pairing/test_gas.py +++ b/tests/byzantium/eip197_ec_pairing/test_gas.py @@ -106,10 +106,10 @@ def test_invalid_gas_consumption( address_warm=False ).gas_cost(fork) - # Pre-EIP-2929: fixed G_call = 700; Berlin+: warm access cost. + # Pre-EIP-2929: fixed call = 700; Berlin+: warm access cost. gas_costs = fork.gas_costs() if fork >= Berlin: - staticcall_base = gas_costs.GAS_WARM_ACCESS + staticcall_base = gas_costs.WARM_ACCESS else: staticcall_base = 700 diff --git a/tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py b/tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py index 5e8e2cf1b54..952b41069ea 100644 --- a/tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py +++ b/tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py @@ -113,7 +113,7 @@ def call_gas(fork: Fork) -> int: Defaults to the point evaluation precompile gas cost, but can be parametrized to test different amounts. """ - return fork.gas_costs().GAS_PRECOMPILE_POINT_EVALUATION + return fork.gas_costs().PRECOMPILE_POINT_EVALUATION precompile_caller_storage_keys = count() @@ -202,9 +202,7 @@ def tx( sender=sender, data=precompile_input, to=precompile_caller_address, - gas_limit=fork.transitions_to() - .gas_costs() - .GAS_PRECOMPILE_POINT_EVALUATION + gas_limit=fork.transitions_to().gas_costs().PRECOMPILE_POINT_EVALUATION * 100, ) @@ -589,7 +587,7 @@ def test_tx_entry_point( # Consumed gas will only be the precompile gas if the proof is correct and # the call gas is sufficient. # Otherwise, the call gas will be consumed in full. - precompile_gas = fork.gas_costs().GAS_PRECOMPILE_POINT_EVALUATION + precompile_gas = fork.gas_costs().PRECOMPILE_POINT_EVALUATION consumed_gas = ( precompile_gas if call_gas >= precompile_gas and proof_correct @@ -714,7 +712,7 @@ def test_precompile_during_fork( Test calling the Point Evaluation Precompile during the appropriate fork. """ precompile_gas = ( - fork.transitions_to().gas_costs().GAS_PRECOMPILE_POINT_EVALUATION + fork.transitions_to().gas_costs().PRECOMPILE_POINT_EVALUATION ) # Blocks before fork blocks = [ diff --git a/tests/cancun/eip4844_blobs/test_point_evaluation_precompile_gas.py b/tests/cancun/eip4844_blobs/test_point_evaluation_precompile_gas.py index 1f313594db4..231f084a7f9 100644 --- a/tests/cancun/eip4844_blobs/test_point_evaluation_precompile_gas.py +++ b/tests/cancun/eip4844_blobs/test_point_evaluation_precompile_gas.py @@ -66,7 +66,7 @@ def call_gas(fork: Fork) -> int: Defaults to the point evaluation precompile gas cost, but can be parametrized to test different amounts. """ - return fork.gas_costs().GAS_PRECOMPILE_POINT_EVALUATION + return fork.gas_costs().PRECOMPILE_POINT_EVALUATION def copy_opcode_cost(fork: Fork, length: int) -> int: @@ -157,7 +157,7 @@ def tx( data=precompile_input, to=precompile_caller_address, value=0, - gas_limit=fork.gas_costs().GAS_PRECOMPILE_POINT_EVALUATION * 20, + gas_limit=fork.gas_costs().PRECOMPILE_POINT_EVALUATION * 20, ) @@ -172,7 +172,7 @@ def post( Prepare expected post for each test, depending on the success or failure of the precompile call and the gas usage. """ - precompile_gas = fork.gas_costs().GAS_PRECOMPILE_POINT_EVALUATION + precompile_gas = fork.gas_costs().PRECOMPILE_POINT_EVALUATION if proof == "correct": expected_gas_usage = ( call_gas if call_gas < precompile_gas else precompile_gas diff --git a/tests/frontier/opcodes/test_call.py b/tests/frontier/opcodes/test_call.py index e8345e9d5bb..95ad749a868 100644 --- a/tests/frontier/opcodes/test_call.py +++ b/tests/frontier/opcodes/test_call.py @@ -33,7 +33,7 @@ def test_call_large_offset_mstore( mem_offset = 128 # arbitrary number - # Cost of pushing args onto the stack (each PUSH costs G_VERY_LOW) + # Cost of pushing args onto the stack (each PUSH costs VERY_LOW) call_push_cost = (Op.PUSH1(0) * len(Op.CALL.kwargs)).gas_cost(fork) mstore_push_cost = (Op.PUSH1(0) * len(Op.MSTORE.kwargs)).gas_cost(fork) @@ -101,7 +101,7 @@ def test_call_memory_expands_on_early_revert( # arbitrary number, greater than memory size to trigger an expansion ret_size = 128 - # Cost of pushing args onto the stack (each PUSH costs G_VERY_LOW) + # Cost of pushing args onto the stack (each PUSH costs VERY_LOW) call_push_cost = (Op.PUSH1(0) * len(Op.CALL.kwargs)).gas_cost(fork) mstore_push_cost = (Op.PUSH1(0) * len(Op.MSTORE.kwargs)).gas_cost(fork) @@ -137,7 +137,7 @@ def test_call_memory_expands_on_early_revert( # call cost: # address_access_cost+new_acc_cost+memory_expansion_cost+value-stipend - # G_CALL_STIPEND is a threshold check, not a gas cost — keep from gas_costs + # CALL_STIPEND is a threshold check, not a gas cost — keep from gas_costs gsc = fork.gas_costs() call_cost = ( Op.CALL( @@ -146,7 +146,7 @@ def test_call_memory_expands_on_early_revert( account_new=True, new_memory_size=ret_size, ).gas_cost(fork) - - gsc.GAS_CALL_STIPEND + - gsc.CALL_STIPEND ) # mstore cost: base cost. No memory expansion cost needed, it was expanded @@ -186,7 +186,7 @@ def test_call_large_args_offset_size_zero( very_large_offset = 2**100 - # Cost of pushing args onto the stack (each PUSH costs G_VERY_LOW) + # Cost of pushing args onto the stack (each PUSH costs VERY_LOW) push_cost = (Op.PUSH1(0) * len(call_opcode.kwargs)).gas_cost(fork) call_measure = CodeGasMeasure( diff --git a/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py b/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py index 0c76bd57947..198045b3e3d 100644 --- a/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py +++ b/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py @@ -94,17 +94,17 @@ def sufficient_gas( cost = 700 # Pre-Berlin call cost gas_costs = fork.gas_costs() if is_value_call: - cost += gas_costs.GAS_CALL_VALUE + cost += gas_costs.CALL_VALUE if callee_opcode == Op.CALL: - cost += gas_costs.GAS_NEW_ACCOUNT + cost += gas_costs.NEW_ACCOUNT elif fork == Homestead: cost = 40 # Homestead call cost cost += 1 # mandatory callee gas allowance gas_costs = fork.gas_costs() if is_value_call: - cost += gas_costs.GAS_CALL_VALUE + cost += gas_costs.CALL_VALUE if callee_opcode == Op.CALL: - cost += gas_costs.GAS_NEW_ACCOUNT + cost += gas_costs.NEW_ACCOUNT else: raise Exception("Only forks Homestead and >=Byzantium supported") diff --git a/tests/json_loader/test_tools_new_fork.py b/tests/json_loader/test_tools_new_fork.py index 6cc7b584959..9afb2383cbd 100644 --- a/tests/json_loader/test_tools_new_fork.py +++ b/tests/json_loader/test_tools_new_fork.py @@ -76,7 +76,7 @@ def test_end_to_end(template_fork: str) -> None: expected = [ "BLOB_TARGET_GAS_PER_BLOCK = U64(199)", - "GAS_PER_BLOB = U64(1)", + "PER_BLOB = U64(1)", "BLOB_MIN_GASPRICE = Uint(2)", "BLOB_BASE_FEE_UPDATE_FRACTION = Uint(750)", "BLOB_SCHEDULE_TARGET = U64(88)", diff --git a/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py b/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py index 8ef1d237eb1..62ec21497af 100644 --- a/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py +++ b/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py @@ -328,7 +328,7 @@ def test_maximum_gas_refund( def total_cost_floor_per_token(fork: Fork) -> int: """Total cost floor per token.""" gas_costs = fork.gas_costs() - return gas_costs.GAS_TX_DATA_TOKEN_FLOOR + return gas_costs.TX_DATA_TOKEN_FLOOR @pytest.mark.xdist_group(name="bigmem") @@ -678,7 +678,7 @@ def intrinsic_cost_for_auth_list_length(auth_count: int) -> int: # EIP-7702 authorization transaction cost: # 21000 + 16 * non-zero calldata bytes + 4 * zero calldata bytes + 1900 * # access list storage key count + 2400 * access list address count + access - # list data cost + GAS_AUTH_PER_EMPTY_ACCOUNT_COST * authorization list + # list data cost + AUTH_PER_EMPTY_ACCOUNT_COST * authorization list # length # # There is no calldata and no storage keys in this test case. diff --git a/tests/osaka/eip7951_p256verify_precompiles/conftest.py b/tests/osaka/eip7951_p256verify_precompiles/conftest.py index 2c313fda41b..af45811a5ba 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/conftest.py +++ b/tests/osaka/eip7951_p256verify_precompiles/conftest.py @@ -33,7 +33,7 @@ def vector_gas_value() -> int | None: @pytest.fixture def precompile_gas(vector_gas_value: int | None, fork: Fork) -> int: """Gas cost for the precompile.""" - gas = fork.gas_costs().GAS_PRECOMPILE_P256VERIFY + gas = fork.gas_costs().PRECOMPILE_P256VERIFY if vector_gas_value is not None: assert vector_gas_value == gas, ( f"Calculated gas {vector_gas_value} != Vector gas {gas}" diff --git a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py index b826fcd7389..183ba71686c 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py +++ b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py @@ -1101,7 +1101,7 @@ def test_precompile_will_return_success_with_tx_value( call_256verify_bytecode = ( Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE()) + Op.CALL( - gas=fork.gas_costs().GAS_PRECOMPILE_P256VERIFY, + gas=fork.gas_costs().PRECOMPILE_P256VERIFY, address=Spec.P256VERIFY, value=Op.CALLVALUE(), args_offset=0, @@ -1244,7 +1244,7 @@ def test_contract_creation_transaction( contract_bytecode = ( Op.CODECOPY(0, Op.SUB(Op.CODESIZE, len(input_data)), len(input_data)) + Op.CALL( - gas=fork.gas_costs().GAS_PRECOMPILE_P256VERIFY, + gas=fork.gas_costs().PRECOMPILE_P256VERIFY, address=Spec.P256VERIFY, value=0, args_offset=0, @@ -1311,7 +1311,7 @@ def test_contract_initcode( call_256verify_bytecode = ( Op.CODECOPY(0, Op.SUB(Op.CODESIZE, len(input_data)), len(input_data)) + Op.CALL( - gas=fork.gas_costs().GAS_PRECOMPILE_P256VERIFY, + gas=fork.gas_costs().PRECOMPILE_P256VERIFY, address=Spec.P256VERIFY, value=0, args_offset=0, 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 9bcca0ac450..1c8b5f141b8 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/test_p256verify_before_fork.py +++ b/tests/osaka/eip7951_p256verify_precompiles/test_p256verify_before_fork.py @@ -29,7 +29,7 @@ @pytest.fixture def precompile_gas(vector_gas_value: int | None, fork: TransitionFork) -> int: """Gas cost for the precompile.""" - gas = fork.transitions_to().gas_costs().GAS_PRECOMPILE_P256VERIFY + gas = fork.transitions_to().gas_costs().PRECOMPILE_P256VERIFY if vector_gas_value is not None: assert vector_gas_value == gas, ( f"Calculated gas {vector_gas_value} != Vector gas {gas}" diff --git a/tests/prague/eip2537_bls_12_381_precompiles/spec.py b/tests/prague/eip2537_bls_12_381_precompiles/spec.py index 053b4ad743e..a8bb7a3431c 100644 --- a/tests/prague/eip2537_bls_12_381_precompiles/spec.py +++ b/tests/prague/eip2537_bls_12_381_precompiles/spec.py @@ -299,8 +299,8 @@ def _pairing_gas_from_costs( def calc(input_length: int) -> int: k = input_length // Spec.LEN_PER_PAIR return ( - gas_costs.GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR * k - + gas_costs.GAS_PRECOMPILE_BLS_PAIRING_BASE + gas_costs.PRECOMPILE_BLS_PAIRING_PER_PAIR * k + + gas_costs.PRECOMPILE_BLS_PAIRING_BASE ) return calc @@ -311,19 +311,19 @@ def build_gas_calculation_function_map( ) -> Dict[int, Callable[[int], int]]: """Build a gas calculation function map from fork gas costs.""" return { - Spec.G1ADD: lambda _: gas_costs.GAS_PRECOMPILE_BLS_G1ADD, + Spec.G1ADD: lambda _: gas_costs.PRECOMPILE_BLS_G1ADD, Spec.G1MSM: msm_gas_func_gen( BLS12Group.G1, len(PointG1() + Scalar()), - gas_costs.GAS_PRECOMPILE_BLS_G1MUL, + gas_costs.PRECOMPILE_BLS_G1MUL, ), - Spec.G2ADD: lambda _: gas_costs.GAS_PRECOMPILE_BLS_G2ADD, + Spec.G2ADD: lambda _: gas_costs.PRECOMPILE_BLS_G2ADD, Spec.G2MSM: msm_gas_func_gen( BLS12Group.G2, len(PointG2() + Scalar()), - gas_costs.GAS_PRECOMPILE_BLS_G2MUL, + gas_costs.PRECOMPILE_BLS_G2MUL, ), Spec.PAIRING: _pairing_gas_from_costs(gas_costs), - Spec.MAP_FP_TO_G1: lambda _: gas_costs.GAS_PRECOMPILE_BLS_G1MAP, - Spec.MAP_FP2_TO_G2: lambda _: gas_costs.GAS_PRECOMPILE_BLS_G2MAP, + Spec.MAP_FP_TO_G1: lambda _: gas_costs.PRECOMPILE_BLS_G1MAP, + Spec.MAP_FP2_TO_G2: lambda _: gas_costs.PRECOMPILE_BLS_G2MAP, } diff --git a/tests/prague/eip7623_increase_calldata_cost/spec.py b/tests/prague/eip7623_increase_calldata_cost/spec.py index ebca1ee7041..6527e5c69c5 100644 --- a/tests/prague/eip7623_increase_calldata_cost/spec.py +++ b/tests/prague/eip7623_increase_calldata_cost/spec.py @@ -24,5 +24,5 @@ class Spec: https://eips.ethereum.org/EIPS/eip-7623. """ - GAS_TX_DATA_TOKEN_STANDARD = 4 - GAS_TX_DATA_TOKEN_FLOOR = 10 + TX_DATA_TOKEN_STANDARD = 4 + TX_DATA_TOKEN_FLOOR = 10 diff --git a/tests/prague/eip7702_set_code_tx/spec.py b/tests/prague/eip7702_set_code_tx/spec.py index 2be51b6c99c..8f1eaac1fab 100644 --- a/tests/prague/eip7702_set_code_tx/spec.py +++ b/tests/prague/eip7702_set_code_tx/spec.py @@ -28,7 +28,7 @@ class Spec: SET_CODE_TX_TYPE = 0x04 MAGIC = 0x05 REFUND_AUTH_PER_EXISTING_ACCOUNT = 12_500 - GAS_AUTH_PER_EMPTY_ACCOUNT = 25_000 + AUTH_PER_EMPTY_ACCOUNT = 25_000 DELEGATION_DESIGNATION = Bytes("ef0100") RESET_DELEGATION_ADDRESS = Address(0) diff --git a/tests/prague/eip7702_set_code_tx/test_gas.py b/tests/prague/eip7702_set_code_tx/test_gas.py index b2b8233d1b4..7aea82b335a 100644 --- a/tests/prague/eip7702_set_code_tx/test_gas.py +++ b/tests/prague/eip7702_set_code_tx/test_gas.py @@ -800,7 +800,7 @@ def gas_test_parameter_args( if execution_gas_allowance: # Leave some gas for the execution of the test code. max_gas -= 1_000_000 - many_authorizations_count = max_gas // Spec.GAS_AUTH_PER_EMPTY_ACCOUNT + many_authorizations_count = max_gas // Spec.AUTH_PER_EMPTY_ACCOUNT cases += [ pytest.param( { @@ -876,7 +876,7 @@ def test_gas_cost( seen_authority.add(authority) discount_gas = ( - Spec.GAS_AUTH_PER_EMPTY_ACCOUNT - Spec.REFUND_AUTH_PER_EXISTING_ACCOUNT + Spec.AUTH_PER_EMPTY_ACCOUNT - Spec.REFUND_AUTH_PER_EXISTING_ACCOUNT ) * discounted_authorizations # We calculate the exact gas required to execute the test code. We add 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 eeca854e337..fe48936c1d5 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 @@ -773,8 +773,9 @@ def test_set_code_to_contract_creator( ) @pytest.mark.with_all_call_opcodes @pytest.mark.filter_combinations( - lambda call_opcode, value, **_: "value" in call_opcode.kwargs - or value == 0, + lambda call_opcode, value, **_: ( + "value" in call_opcode.kwargs or value == 0 + ), reason="opcode does not support value argument", ) def test_set_code_to_self_caller( @@ -908,8 +909,9 @@ def test_set_code_max_depth_call_stack( [0, 1], ) @pytest.mark.filter_combinations( - lambda call_opcode, value, **_: "value" in call_opcode.kwargs - or value == 0, + lambda call_opcode, value, **_: ( + "value" in call_opcode.kwargs or value == 0 + ), reason="opcode does not support value argument", ) @pytest.mark.eels_base_coverage @@ -2916,8 +2918,7 @@ def test_set_code_to_precompile_not_enough_gas_for_precompile_execution( authorization_list_or_count=[auth], ) discount = min( - Spec.GAS_AUTH_PER_EMPTY_ACCOUNT - - Spec.REFUND_AUTH_PER_EXISTING_ACCOUNT, + Spec.AUTH_PER_EMPTY_ACCOUNT - Spec.REFUND_AUTH_PER_EXISTING_ACCOUNT, intrinsic_gas // 5, # max discount EIP-3529 ) @@ -3845,7 +3846,7 @@ def test_many_delegations( max_gas = env.gas_limit gas_for_delegations = max_gas - 21_000 - 20_000 - (3 * 2) - delegation_count = gas_for_delegations // Spec.GAS_AUTH_PER_EMPTY_ACCOUNT + delegation_count = gas_for_delegations // Spec.AUTH_PER_EMPTY_ACCOUNT success_slot = 1 entry_code = Op.SSTORE(success_slot, 1) + Op.STOP diff --git a/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py b/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py index 9bd855017f7..c81aff2a27b 100644 --- a/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py +++ b/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py @@ -1,7 +1,7 @@ """ Tests for EIP-150 SELFDESTRUCT operation gas costs. -EIP-150 introduced G_SELF_DESTRUCT for SELFDESTRUCT and precise gas +EIP-150 introduced a gas cost for the SELFDESTRUCT opcode and precise gas boundaries for state access during the operation. """ @@ -52,7 +52,7 @@ def calculate_selfdestruct_gas( originator_balance: int, ) -> int: """Calculate exact gas needed for SELFDESTRUCT.""" - # G_NEW_ACCOUNT: + # NEW_ACCOUNT: # - Pre-EIP-161 (TangerineWhistle): charged when beneficiary is dead # - Post-EIP-161 (>=SpuriousDragon): charged when beneficiary is dead # AND originator has balance > 0 @@ -351,13 +351,13 @@ def test_selfdestruct_to_account( code=Op.STOP, balance=beneficiary_initial_balance ) - # Determine if beneficiary is dead (for G_NEW_ACCOUNT calculation) + # Determine if beneficiary is dead (for NEW_ACCOUNT calculation) # Contract with code is NOT dead even with balance=0 beneficiary_dead = ( beneficiary_initial_balance == 0 and beneficiary == "eoa" ) - # Calculate exact gas for success (includes G_NEW_ACCOUNT if applicable) + # Calculate exact gas for success (includes NEW_ACCOUNT if applicable) inner_call_gas = calculate_selfdestruct_gas( fork, beneficiary_warm=warm, @@ -367,7 +367,7 @@ def test_selfdestruct_to_account( if not is_success: inner_call_gas -= 1 - # In BAL if: success OR G_NEW_ACCOUNT charged (OOG after access) + # In BAL if: success OR NEW_ACCOUNT charged (OOG after access) needs_new_account = False if beneficiary_dead: if fork >= SpuriousDragon: @@ -463,7 +463,7 @@ def test_selfdestruct_state_access_boundary( Test state access boundary for account beneficiaries. Consensus check: beneficiary must be accessed at base cost boundary, - before G_NEW_ACCOUNT is evaluated. + before NEW_ACCOUNT is evaluated. - exact_gas: beneficiary IS accessed (in BAL) - exact_gas_minus_1: beneficiary NOT accessed (not in BAL) @@ -478,14 +478,14 @@ def test_selfdestruct_state_access_boundary( code=Op.STOP, balance=beneficiary_initial_balance ) - # Determine if beneficiary is dead (for G_NEW_ACCOUNT calculation) + # Determine if beneficiary is dead (for NEW_ACCOUNT calculation) # Contract with code is NOT dead even with balance=0 beneficiary_dead = ( beneficiary_initial_balance == 0 and beneficiary == "eoa" ) # Calculate gas for state access boundary only (base + cold access) - # Does NOT include G_NEW_ACCOUNT + # Does NOT include NEW_ACCOUNT inner_call_gas = Op.SELFDESTRUCT( 0, # beneficiary address (generates a PUSH) address_warm=warm or fork < Berlin, @@ -497,7 +497,7 @@ def test_selfdestruct_state_access_boundary( # Determine if operation succeeds at this gas level # At state access boundary, we have enough gas for base + cold access - # Operation succeeds if NO G_NEW_ACCOUNT is needed: + # Operation succeeds if NO NEW_ACCOUNT is needed: # - Beneficiary is alive (has balance or has code) # - OR beneficiary is dead but originator_balance=0 (>=SpuriousDragon) needs_new_account = False @@ -507,7 +507,7 @@ def test_selfdestruct_state_access_boundary( else: needs_new_account = True - # At exact_gas: success if no G_NEW_ACCOUNT needed + # At exact_gas: success if no NEW_ACCOUNT needed # At exact_gas_minus_1: always OOG (before state access) operation_success = is_success and not needs_new_account @@ -602,7 +602,7 @@ def test_selfdestruct_to_precompile( # Precompiles are dead when they have no balance beneficiary_dead = beneficiary_initial_balance == 0 - # Calculate exact gas for success (includes G_NEW_ACCOUNT if applicable) + # Calculate exact gas for success (includes NEW_ACCOUNT if applicable) # Precompiles are always warm inner_call_gas = calculate_selfdestruct_gas( fork, @@ -613,7 +613,7 @@ def test_selfdestruct_to_precompile( if not is_success: inner_call_gas -= 1 - # In BAL if: success OR G_NEW_ACCOUNT charged (OOG after access) + # In BAL if: success OR NEW_ACCOUNT charged (OOG after access) needs_new_account = False if beneficiary_dead: if fork >= SpuriousDragon: @@ -700,7 +700,7 @@ def test_selfdestruct_to_precompile_state_access_boundary( Test state access boundary for precompile beneficiaries. Consensus check: precompile must be accessed at base cost boundary, - before G_NEW_ACCOUNT is evaluated. Precompiles are always warm. + before NEW_ACCOUNT is evaluated. Precompiles are always warm. - exact_gas: precompile IS accessed (in BAL) - exact_gas_minus_1: precompile NOT accessed (not in BAL) @@ -711,7 +711,7 @@ def test_selfdestruct_to_precompile_state_access_boundary( beneficiary_dead = beneficiary_initial_balance == 0 - # State access boundary: base cost only (no G_NEW_ACCOUNT) + # State access boundary: base cost only (no NEW_ACCOUNT) # Precompiles are always warm inner_call_gas = Op.SELFDESTRUCT( 0, address_warm=True, account_new=False @@ -720,7 +720,7 @@ def test_selfdestruct_to_precompile_state_access_boundary( if not is_success: inner_call_gas -= 1 - # Success at base cost if no G_NEW_ACCOUNT needed + # Success at base cost if no NEW_ACCOUNT needed needs_new_account = False if beneficiary_dead: if fork >= SpuriousDragon: @@ -802,7 +802,7 @@ def test_selfdestruct_to_system_contract( Test SELFDESTRUCT success boundary for system contract beneficiaries. System contracts are always warm (no cold access charge) and always have - code (so beneficiary is never dead, no G_NEW_ACCOUNT charge). + code (so beneficiary is never dead, no NEW_ACCOUNT charge). - exact_gas: succeeds, balance transferred - exact_gas_minus_1: OOG, operation fails @@ -952,7 +952,7 @@ def test_selfdestruct_to_self( Key characteristics: - Beneficiary is always warm (it's the executing contract) - Beneficiary is always alive (EIP-161 nonce=1) - - No G_NEW_ACCOUNT charge + - No NEW_ACCOUNT charge - No cold access charge (>=Berlin) - Balance is "transferred" to self (no net change until destruction) @@ -967,7 +967,7 @@ def test_selfdestruct_to_self( alice = pre.fund_eoa() victim_code = Op.SELFDESTRUCT(Op.ADDRESS) - # Gas: ADDRESS + SELFDESTRUCT (no cold access, no G_NEW_ACCOUNT) + # Gas: ADDRESS + SELFDESTRUCT (no cold access, no NEW_ACCOUNT) base_gas = Op.SELFDESTRUCT( Op.ADDRESS, address_warm=True, account_new=False ).gas_cost(fork) @@ -1135,7 +1135,7 @@ def test_initcode_selfdestruct_to_self( - During initcode, the contract has no code yet - Contract has nonce=1 (post-EIP-161) making it non-empty - Beneficiary is always warm (it's the executing contract) - - No G_NEW_ACCOUNT charge (contract has nonce > 0) + - No NEW_ACCOUNT charge (contract has nonce > 0) - No cold access charge (>=Berlin) Note: Gas boundary testing not possible for initcode since CREATE From e8e9c3813c2f35b9d45b05ee580cff0936a0123d Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Mon, 20 Apr 2026 19:55:34 -0400 Subject: [PATCH 033/186] feat(doc): add directory listings to py modules (#2658) --- pyproject.toml | 4 +++- src/ethereum_spec_tools/docc.py | 9 ++++++++- uv.lock | 10 +++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 82e40bc95b0..061bf8fd466 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -225,7 +225,7 @@ actionlint = [ "shellcheck-py>=0.10", ] doc = [ - "docc>=0.4.0,<0.5.0", + "docc>=0.5.0,<0.6.0", "fladrif>=0.2.0,<0.3.0", "mistletoe>=1.5.0,<2", ] @@ -302,6 +302,7 @@ omit = [ [tool.docc] context = [ + "docc.listing.context", "docc.references.context", "docc.search.context", "docc.html.context", @@ -322,6 +323,7 @@ build = [ "docc.resources.build", ] transform = [ + "docc.listing.transform", "docc.python.transform", "docc.verbatim.transform", "docc.mistletoe.transform", diff --git a/src/ethereum_spec_tools/docc.py b/src/ethereum_spec_tools/docc.py index 3cf4e47b95d..9b10cd90b51 100644 --- a/src/ethereum_spec_tools/docc.py +++ b/src/ethereum_spec_tools/docc.py @@ -45,7 +45,7 @@ from docc.discover import Discover, T from docc.document import BlankNode, Document, ListNode, Node, Visit, Visitor from docc.plugins import html, mistletoe, python, verbatim -from docc.plugins.listing import Listable +from docc.plugins.listing import Listable, ListingNode from docc.plugins.python import PythonBuilder from docc.plugins.references import Definition, Reference from docc.settings import PluginSettings @@ -667,6 +667,10 @@ def shallow_equals(self, lhs: Node, rhs: Node) -> bool: assert isinstance(rhs, ListNode) return True + elif isinstance(lhs, ListingNode): + assert isinstance(rhs, ListingNode) + return True + elif isinstance(lhs, verbatim.Transcribed): assert isinstance(rhs, verbatim.Transcribed) return True @@ -750,6 +754,9 @@ def shallow_hash(self, node: Node) -> int: elif isinstance(node, ListNode): return hash(type(ListNode)) + elif isinstance(node, ListingNode): + return hash(type(ListingNode)) + elif isinstance(node, verbatim.Transcribed): return hash(type(verbatim.Transcribed)) diff --git a/uv.lock b/uv.lock index fc1bf99a549..056dedb4e0a 100644 --- a/uv.lock +++ b/uv.lock @@ -737,7 +737,7 @@ wheels = [ [[package]] name = "docc" -version = "0.4.1" +version = "0.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-resources" }, @@ -749,9 +749,9 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/32/836130b1f381d7a268eeef4e980b27d73b6484ac1b8eaef418fc0acecd1c/docc-0.4.1.tar.gz", hash = "sha256:789d2c3fef02f52f485ba310e651b3390b94ea43b0b309c53513c85829348f35", size = 70249, upload-time = "2026-02-24T15:52:48.949Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/c0/16c29211d1681769235d1eae52646e4dd967cda77d9643935f1c30c6f0a1/docc-0.5.0.tar.gz", hash = "sha256:e49bd0fd9df6bbbd8857c9feea44dc29b3343ae8e044e8d5e0a23a4bd5c2ecb8", size = 71806, upload-time = "2026-04-15T19:01:16.554Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/ad/6ea54fee2ea762b257a654827cb74ae10b515cdddb732dace59cccd406aa/docc-0.4.1-py3-none-any.whl", hash = "sha256:6dd25f72a010332f535e008b1693e41ce83da0941f79eee7c1b402c880ca3c95", size = 97150, upload-time = "2026-02-24T15:52:47.718Z" }, + { url = "https://files.pythonhosted.org/packages/b1/85/2c3d246676f6cb8acb4a50c4cdf130137d7f089f7ffe220ff776b4e6960e/docc-0.5.0-py3-none-any.whl", hash = "sha256:90fcf22e49ada1aaf802ead8e209bcf03316806c6799f6a2606fb927afaf7f1b", size = 98611, upload-time = "2026-04-15T19:01:15.526Z" }, ] [[package]] @@ -965,7 +965,7 @@ dev = [ { name = "cairosvg", specifier = ">=2.7.0,<3" }, { name = "codespell", specifier = "==2.4.1" }, { name = "codespell", specifier = ">=2.4.1,<3" }, - { name = "docc", specifier = ">=0.4.0,<0.5.0" }, + { name = "docc", specifier = ">=0.5.0,<0.6.0" }, { name = "ethereum-execution", extras = ["optimized"] }, { name = "ethereum-execution-testing", editable = "packages/testing" }, { name = "filelock", specifier = ">=3.15.1,<4" }, @@ -1003,7 +1003,7 @@ dev = [ { name = "vulture", specifier = "==2.14.0" }, ] doc = [ - { name = "docc", specifier = ">=0.4.0,<0.5.0" }, + { name = "docc", specifier = ">=0.5.0,<0.6.0" }, { name = "fladrif", specifier = ">=0.2.0,<0.3.0" }, { name = "mistletoe", specifier = ">=1.5.0,<2" }, ] From 6f43bc6fb36852f48de008e8ddd7374ee3cfe86c Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Wed, 22 Apr 2026 04:23:42 -0400 Subject: [PATCH 034/186] Replace `Uint(len(...))` with `ulen(...)` (#2580) * chore(specs): replace `Uint(len(...))` with `ulen(...)` * chore(spec-tool): pevent `Uint(len(...))` with a lint --- .../forks/amsterdam/block_access_lists.py | 4 +- src/ethereum/forks/amsterdam/fork.py | 4 +- src/ethereum/forks/amsterdam/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/arrow_glacier/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/berlin/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../berlin/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/bpo1/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../bpo1/vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../bpo1/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/bpo2/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../bpo2/vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../bpo2/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/bpo3/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../bpo3/vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../bpo3/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/bpo4/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../bpo4/vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../bpo4/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/bpo5/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../bpo5/vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../bpo5/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/byzantium/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/cancun/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../cancun/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/constantinople/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/dao_fork/vm/gas.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/frontier/vm/gas.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/gray_glacier/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/homestead/vm/gas.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/istanbul/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/london/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../london/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/muir_glacier/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/osaka/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../osaka/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/paris/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../paris/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/prague/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../prague/vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/shanghai/vm/gas.py | 4 +- .../vm/precompiled_contracts/alt_bn128.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- src/ethereum/forks/spurious_dragon/vm/gas.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- .../forks/tangerine_whistle/vm/gas.py | 4 +- .../vm/precompiled_contracts/identity.py | 4 +- .../vm/precompiled_contracts/ripemd160.py | 4 +- .../vm/precompiled_contracts/sha256.py | 4 +- .../lint/lints/uint_len.py | 68 +++++++++++++++++++ vulture_whitelist.py | 4 ++ 119 files changed, 306 insertions(+), 234 deletions(-) create mode 100644 src/ethereum_spec_tools/lint/lints/uint_len.py diff --git a/src/ethereum/forks/amsterdam/block_access_lists.py b/src/ethereum/forks/amsterdam/block_access_lists.py index 96ab1fdb431..94aae6ded2e 100644 --- a/src/ethereum/forks/amsterdam/block_access_lists.py +++ b/src/ethereum/forks/amsterdam/block_access_lists.py @@ -18,7 +18,7 @@ from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes32 from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U32, U64, U256, Uint +from ethereum_types.numeric import U32, U64, U256, Uint, ulen from ethereum.crypto.hash import Hash32, keccak256 from ethereum.state import EMPTY_CODE_HASH, Account, Address, PreState @@ -760,7 +760,7 @@ def validate_block_access_list_gas_limit( unique_slots.add(slot) # Count each unique storage key as one item - bal_items += Uint(len(unique_slots)) + bal_items += ulen(unique_slots) if bal_items > block_gas_limit // GasCosts.BLOCK_ACCESS_LIST_ITEM: raise BlockAccessListGasLimitExceededError( diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index e673bc3d8fd..9d037d2aa1b 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -17,7 +17,7 @@ from ethereum_rlp import rlp from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.crypto.hash import Hash32, keccak256 from ethereum.exceptions import ( @@ -850,7 +850,7 @@ def apply_body( # EIP-7928: Post-execution operations use index N+1 block_env.block_access_list_builder.block_access_index = BlockAccessIndex( - Uint(len(transactions)) + Uint(1) + ulen(transactions) + Uint(1) ) process_withdrawals(block_env, block_output, withdrawals) diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index b5ef8974d3e..f831e7f4ce9 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.forks.bpo5.blocks import Header as PreviousHeader from ethereum.trace import GasAndRefund, evm_trace @@ -311,7 +311,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/arrow_glacier/vm/gas.py b/src/ethereum/forks/arrow_glacier/vm/gas.py index c33cf7c0487..fb6225cd856 100644 --- a/src/ethereum/forks/arrow_glacier/vm/gas.py +++ b/src/ethereum/forks/arrow_glacier/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/berlin/vm/gas.py b/src/ethereum/forks/berlin/vm/gas.py index 1ffb7025f2a..6ffec083550 100644 --- a/src/ethereum/forks/berlin/vm/gas.py +++ b/src/ethereum/forks/berlin/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/berlin/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/bpo1/vm/gas.py b/src/ethereum/forks/bpo1/vm/gas.py index 232bbdd4f23..51c35efee77 100644 --- a/src/ethereum/forks/bpo1/vm/gas.py +++ b/src/ethereum/forks/bpo1/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -290,7 +290,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/bpo2/vm/gas.py b/src/ethereum/forks/bpo2/vm/gas.py index 50edd7d5d7a..34ac7c66389 100644 --- a/src/ethereum/forks/bpo2/vm/gas.py +++ b/src/ethereum/forks/bpo2/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -290,7 +290,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py index 2b4929fb8d2..4b294aeefc2 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -32,7 +32,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py index 04d0e2ff594..bbdf365d0d9 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py index f5346f1529c..f0f48b54553 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -34,7 +34,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/bpo3/vm/gas.py b/src/ethereum/forks/bpo3/vm/gas.py index 50edd7d5d7a..34ac7c66389 100644 --- a/src/ethereum/forks/bpo3/vm/gas.py +++ b/src/ethereum/forks/bpo3/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -290,7 +290,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/bpo4/vm/gas.py b/src/ethereum/forks/bpo4/vm/gas.py index 50edd7d5d7a..34ac7c66389 100644 --- a/src/ethereum/forks/bpo4/vm/gas.py +++ b/src/ethereum/forks/bpo4/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -290,7 +290,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/bpo5/vm/gas.py b/src/ethereum/forks/bpo5/vm/gas.py index 50edd7d5d7a..34ac7c66389 100644 --- a/src/ethereum/forks/bpo5/vm/gas.py +++ b/src/ethereum/forks/bpo5/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -290,7 +290,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/byzantium/vm/gas.py b/src/ethereum/forks/byzantium/vm/gas.py index 6121e3bbce0..26cee8b14af 100644 --- a/src/ethereum/forks/byzantium/vm/gas.py +++ b/src/ethereum/forks/byzantium/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -255,7 +255,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py index 2b4929fb8d2..4b294aeefc2 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -32,7 +32,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py index 04d0e2ff594..bbdf365d0d9 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py index f5346f1529c..f0f48b54553 100644 --- a/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/byzantium/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -34,7 +34,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/cancun/vm/gas.py b/src/ethereum/forks/cancun/vm/gas.py index c3a65792ec2..90cda5fe5ad 100644 --- a/src/ethereum/forks/cancun/vm/gas.py +++ b/src/ethereum/forks/cancun/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -276,7 +276,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py index 2b4929fb8d2..4b294aeefc2 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -32,7 +32,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py index 04d0e2ff594..bbdf365d0d9 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py index f5346f1529c..f0f48b54553 100644 --- a/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/cancun/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -34,7 +34,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/constantinople/vm/gas.py b/src/ethereum/forks/constantinople/vm/gas.py index 85e4d3be422..37b2d29f865 100644 --- a/src/ethereum/forks/constantinople/vm/gas.py +++ b/src/ethereum/forks/constantinople/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -259,7 +259,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/constantinople/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/dao_fork/vm/gas.py b/src/ethereum/forks/dao_fork/vm/gas.py index f3644b8bf6a..7c36dfd1ca2 100644 --- a/src/ethereum/forks/dao_fork/vm/gas.py +++ b/src/ethereum/forks/dao_fork/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.state import Address from ethereum.trace import GasAndRefund, evm_trace @@ -248,7 +248,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/dao_fork/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/frontier/vm/gas.py b/src/ethereum/forks/frontier/vm/gas.py index ec6e91a20ce..a47c26419c1 100644 --- a/src/ethereum/forks/frontier/vm/gas.py +++ b/src/ethereum/forks/frontier/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.state import Address from ethereum.trace import GasAndRefund, evm_trace @@ -246,7 +246,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/frontier/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/gray_glacier/vm/gas.py b/src/ethereum/forks/gray_glacier/vm/gas.py index c33cf7c0487..fb6225cd856 100644 --- a/src/ethereum/forks/gray_glacier/vm/gas.py +++ b/src/ethereum/forks/gray_glacier/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/gray_glacier/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/homestead/vm/gas.py b/src/ethereum/forks/homestead/vm/gas.py index f3644b8bf6a..7c36dfd1ca2 100644 --- a/src/ethereum/forks/homestead/vm/gas.py +++ b/src/ethereum/forks/homestead/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.state import Address from ethereum.trace import GasAndRefund, evm_trace @@ -248,7 +248,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/homestead/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/istanbul/vm/gas.py b/src/ethereum/forks/istanbul/vm/gas.py index ba89267f506..43cad92d739 100644 --- a/src/ethereum/forks/istanbul/vm/gas.py +++ b/src/ethereum/forks/istanbul/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/istanbul/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/london/vm/gas.py b/src/ethereum/forks/london/vm/gas.py index c33cf7c0487..fb6225cd856 100644 --- a/src/ethereum/forks/london/vm/gas.py +++ b/src/ethereum/forks/london/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/identity.py b/src/ethereum/forks/london/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/london/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/muir_glacier/vm/gas.py b/src/ethereum/forks/muir_glacier/vm/gas.py index ba89267f506..43cad92d739 100644 --- a/src/ethereum/forks/muir_glacier/vm/gas.py +++ b/src/ethereum/forks/muir_glacier/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/muir_glacier/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/osaka/vm/gas.py b/src/ethereum/forks/osaka/vm/gas.py index e54f305e45c..db5a2a3d669 100644 --- a/src/ethereum/forks/osaka/vm/gas.py +++ b/src/ethereum/forks/osaka/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -290,7 +290,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/paris/vm/gas.py b/src/ethereum/forks/paris/vm/gas.py index d4536445c43..9dbf5fab377 100644 --- a/src/ethereum/forks/paris/vm/gas.py +++ b/src/ethereum/forks/paris/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -262,7 +262,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py b/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/paris/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/prague/vm/gas.py b/src/ethereum/forks/prague/vm/gas.py index 94352384934..226163494a3 100644 --- a/src/ethereum/forks/prague/vm/gas.py +++ b/src/ethereum/forks/prague/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U64, U256, Uint +from ethereum_types.numeric import U64, U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32, taylor_exponential @@ -285,7 +285,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py b/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/shanghai/vm/gas.py b/src/ethereum/forks/shanghai/vm/gas.py index ca3de745672..b0447492ef5 100644 --- a/src/ethereum/forks/shanghai/vm/gas.py +++ b/src/ethereum/forks/shanghai/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -264,7 +264,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py index 09bed4a0282..862506c54c3 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/alt_bn128.py @@ -12,7 +12,7 @@ """ from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from py_ecc.optimized_bn128.optimized_curve import ( FQ, FQ2, @@ -207,7 +207,7 @@ def alt_bn128_pairing_check(evm: Evm) -> None: # GAS charge_gas( evm, - GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * Uint(len(data) // 192) + GasCosts.PRECOMPILE_ECPAIRING_PER_POINT * (ulen(data) // Uint(192)) + GasCosts.PRECOMPILE_ECPAIRING_BASE, ) diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py index 2b4929fb8d2..4b294aeefc2 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -32,7 +32,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py index 04d0e2ff594..bbdf365d0d9 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py index f5346f1529c..f0f48b54553 100644 --- a/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/shanghai/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -34,7 +34,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/spurious_dragon/vm/gas.py b/src/ethereum/forks/spurious_dragon/vm/gas.py index 49c69c4653a..3f5f8d58b04 100644 --- a/src/ethereum/forks/spurious_dragon/vm/gas.py +++ b/src/ethereum/forks/spurious_dragon/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -248,7 +248,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/spurious_dragon/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum/forks/tangerine_whistle/vm/gas.py b/src/ethereum/forks/tangerine_whistle/vm/gas.py index 1dff8b9c25a..9cc32869503 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/gas.py +++ b/src/ethereum/forks/tangerine_whistle/vm/gas.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import List, Tuple -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U256, Uint, ulen from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 @@ -248,7 +248,7 @@ def calculate_gas_extend_memory( """ size_to_extend = Uint(0) to_be_paid = Uint(0) - current_size = Uint(len(memory)) + current_size = ulen(memory) for start_position, size in extensions: if size == 0: continue diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py index cdbd61f5b0d..b7631736074 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/identity.py @@ -11,7 +11,7 @@ Implementation of the `IDENTITY` precompiled contract. """ -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -35,7 +35,7 @@ def identity(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_IDENTITY_BASE diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py index eafdf08c365..c82c9bd534d 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/ripemd160.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.byte import left_pad_zero_bytes from ethereum.utils.numeric import ceil32 @@ -38,7 +38,7 @@ def ripemd160(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_RIPEMD160_BASE diff --git a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py index 0a9f67e8441..9d467d7e951 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py +++ b/src/ethereum/forks/tangerine_whistle/vm/precompiled_contracts/sha256.py @@ -13,7 +13,7 @@ import hashlib -from ethereum_types.numeric import Uint +from ethereum_types.numeric import Uint, ulen from ethereum.utils.numeric import ceil32 @@ -37,7 +37,7 @@ def sha256(evm: Evm) -> None: data = evm.message.data # GAS - word_count = ceil32(Uint(len(data))) // Uint(32) + word_count = ceil32(ulen(data)) // Uint(32) charge_gas( evm, GasCosts.PRECOMPILE_SHA256_BASE diff --git a/src/ethereum_spec_tools/lint/lints/uint_len.py b/src/ethereum_spec_tools/lint/lints/uint_len.py new file mode 100644 index 00000000000..91d61581559 --- /dev/null +++ b/src/ethereum_spec_tools/lint/lints/uint_len.py @@ -0,0 +1,68 @@ +""" +Uint(len(...)) Lint. + +Ensures that `Uint(len(...))` is replaced with `ulen(...)`. +""" + +import ast +from typing import List, Sequence + +from ethereum_spec_tools.forks import Hardfork +from ethereum_spec_tools.lint import Diagnostic, Lint, walk_sources + + +class UintLenHygiene(Lint): + """ + Ensure `ulen(...)` is used instead of `Uint(len(...))`. + """ + + def lint( + self, forks: List[Hardfork], position: int + ) -> Sequence[Diagnostic]: + """ + Walk the sources for each hardfork and emit Diagnostic messages. + """ + fork = forks[position] + diagnostics: List[Diagnostic] = [] + + for name, source in walk_sources(fork): + visitor = self._parse(source, _Visitor()) + for lineno in visitor.violations: + diagnostics.append( + Diagnostic( + message=( + f"`Uint(len(...))` at line {lineno} in" + f" `{name}` should be `ulen(...)`" + ) + ) + ) + + return diagnostics + + +class _Visitor(ast.NodeVisitor): + """ + Visit call nodes and detect `Uint(len(...))` patterns. + """ + + violations: List[int] + + def __init__(self) -> None: + self.violations = [] + + def visit_Call(self, node: ast.Call) -> None: + """ + Visit a Call node. + """ + if ( + isinstance(node.func, ast.Name) + and node.func.id == "Uint" + and len(node.args) == 1 + and not node.keywords + and isinstance(node.args[0], ast.Call) + and isinstance(node.args[0].func, ast.Name) + and node.args[0].func.id == "len" + ): + self.violations.append(node.lineno) + + self.generic_visit(node) diff --git a/vulture_whitelist.py b/vulture_whitelist.py index 075f200f8c1..5a44d33da7c 100644 --- a/vulture_whitelist.py +++ b/vulture_whitelist.py @@ -28,6 +28,7 @@ GlacierForksHygiene, ) from ethereum_spec_tools.lint.lints.import_hygiene import ImportHygiene +from ethereum_spec_tools.lint.lints.uint_len import UintLenHygiene from ethereum_spec_tools.new_fork.codemod.comment import CommentReplaceCommand from ethereum_spec_tools.new_fork.codemod.constant import SetConstantCommand from ethereum_spec_tools.new_fork.codemod.string_replace import ( @@ -112,6 +113,9 @@ Trace.opName FinalTrace.gasUsed +# src/ethereum_spec_tools/lint/lints/uint_len.py +UintLenHygiene + # src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py GlacierForksHygiene GlacierForksHygiene.visit_AnnAssign From 739ecad65686e5bb5f82f1355524fa297914f991 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Wed, 22 Apr 2026 13:35:52 +0100 Subject: [PATCH 035/186] feat(doc): re-write readme/top-level docs and add specs section to html docs (#2677) * docs(specs): add Specs section with overview Introduce a top-level `Specs` section in the mkdocs navigation and a new `docs/specs/index.md` page that explains what EELS is, the coordination problem it solves, why Python was chosen, the Correct/Complete/Accessible principles, and the fork-as-a-copy (WET) model. This is the anchor page for further specs-side documentation (writing specs, adding a new EIP, spec releases, protocol history); those pages land in follow-up commits. * docs(specs): move protocol history table from README to Specs section The full mainnet hardfork table, the "clarifications without a protocol release" table, and the Paris/Shanghai activation note now live on a dedicated `docs/specs/protocol_history.md` page linked from the Specs overview and the mkdocs navigation. `README.md` keeps a one-line pointer to the new page. Fork-manifest links switch from repo-relative paths (`/src/ethereum/...`) to absolute GitHub URLs on `forks/amsterdam` so they resolve correctly from the rendered docs site. * docs(specs): move EIP_AUTHORS_MANUAL.md to docs/specs/adding_a_new_eip.md Pure rename so `git log --follow` (and `mkdocs-git-authors-plugin` by extension) continues to trace the file's history back to the original author, Guruprasad Kamath. Content modernization for the post-Weld world lands in the follow-up commit. * docs(specs): modernize adding_a_new_eip for the unified repo Post-Weld rewrite of the EIP author's manual. The cross-repo references to `execution-spec-tests` are replaced with pointers to in-tree tests under `./tests/`; the step-by-step workflow points at the in-tree `ethereum_spec_tools` utilities. The YouTube opcode tutorial link is preserved. The rename from `EIP_AUTHORS_MANUAL.md` to `docs/specs/adding_a_new_eip.md` was done as a pure `git mv` in the previous commit so `git log --follow` (and therefore the `mkdocs-git-authors-plugin`) continues to attribute the earlier content to its original author. Co-authored-by: Guruprasad Kamath * docs(specs): add writing_specs page from CONTRIBUTING technicals Extracts the style, comments, docstrings, constants, and cross-fork sections from `CONTRIBUTING.md` into a dedicated `docs/specs/writing_specs.md` page, alongside documentation for the `ethereum_spec_tools` CLI utilities (New Fork Tool, Sync Tool, Patch Tool, Lint Tool) and the `--evm-trace` debugging flag. The EIP-attributed-comment pitfall is preserved as a collapsible detail block so it remains readable without dominating the page. `CONTRIBUTING.md` is untouched in this commit; the slimming down to who/how/what happens in a follow-up. The `adding_a_new_eip` page gets its `Writing Specs` link back in this commit now that the target exists. * docs(contributing): slim CONTRIBUTING.md to who/how/what `CONTRIBUTING.md` now focuses on who the project welcomes contributions from, how to raise issues/PRs, and the three guiding principles (Correct, Complete, Accessible). The remaining sections point at the authoritative docs: - Environment setup, `uv`/`just`/shell completions, Python version, and the full recipe list go to `docs/getting_started/installation.md`. - Naming/comments/docstrings/constants/cross-fork discipline, and the `ethereum_spec_tools` CLI utilities go to `docs/specs/writing_specs.md`. - The `--evm-trace` debugging tip lives in `docs/specs/writing_specs.md`. - The `MYPY_CACHE_DIR` worktree tip is already covered in the installation docs. `copy_repo_docs_to_mkdocs.py` learns two new link rewrites so the repo-relative `docs/...` paths in `CONTRIBUTING.md` work both when viewed on GitHub and when the file is copied to `docs/getting_started/contributing.md` for the rendered site. * docs(specs): split RELEASING into contributor and maintainer pages The old `RELEASING.md` mixed two audiences: contributors (who want to understand the version-number scheme when reading `pyproject.toml` or proposing a release) and maintainers (who cut the tag, publish to PyPI, and file the GitHub release). Split along that seam: - `docs/specs/spec_releases.md` covers the versioning scheme (format, examples, and the current-to-next lookup table), sitting alongside the other specs-side documentation. - `docs/dev/releasing.md` is the maintainer runbook (updating the version in source, tagging, GitHub release, PyPI publish). Each page links to the other so a reader landing on either one can find the half they need. * docs(readme): rewrite README around the docs site and a Quick Start Post-Weld `README.md` becomes the GitHub-landing hook: a short description, pointers to the rendered documentation site, the `docc`-rendered pyspec, the protocol history page, a single-tab Quick Start cribbed from `docs/getting_started/installation.md`, and the license. The README now treats `docs/getting_started/installation.md` as the source of truth for environment setup: the Python-version line reflects the 3.11 to 3.14 range (recommending 3.12) rather than the stale "Python 3.11+"; the "Building Specification Documentation" and "Browsing Updated Documentation" sections collapse into a single `mkdocs serve` / `just docs-spec` note; and the "work-in-progress" placeholder heading is gone. * docs(specs): rename top-level section header to "Specifications" Use the full word "Specifications" in the navigation sidebar and the section index H1. The folder name under `docs/specs/` and the URL path are unchanged. * docs(specs): reframe coordination section around client diversity The opening section now leads with "Client Diversity requires Coordination" and frames client diversity as a positive property (resilience, no privileged implementation, permissionless participation) rather than opening on the coordination *problem*. Coordination follows as the natural consequence of that diversity: a multi-client network needs a precise shared description of behaviour, and EELS is it. Links the ethereum.org client-diversity page for readers who want the full argument. The Python-versus-prose point is kept but slimmed of incidental color ("implementation differences in early EIPs are part of the lore") that didn't add to the reframed narrative. * docs(specs): unwrap hard-wrapped paragraphs in docs/specs/ Consecutive prose lines and list-item continuations are collapsed onto a single line per paragraph / list item. Fenced code blocks, tables, HTML blocks, headings, admonition markers, blockquotes, and link reference definitions are preserved verbatim. Matches the single-line-per-paragraph style already applied to the opening paragraph of `docs/specs/index.md`, and makes the files easier to diff on prose edits. * docs(contributing): unwrap hard-wrapped paragraphs in CONTRIBUTING.md Matches the single-line-per-paragraph style now used across `docs/specs/*.md`, for cleaner future prose diffs. The blockquote content under the `[!IMPORTANT]` alert is also collapsed to a single line after the marker. * docs(contributing): point Getting Set Up at the README Quick Start `CONTRIBUTING.md` no longer embeds its own abbreviated install commands; it points at the [Quick Start](README.md#quick-start) for the short version and at the Installation guide for full setup. Avoids a third copy of the install commands drifting out of sync. `copy_repo_docs_to_mkdocs.py` rewrites `README.md#quick-start` to `installation.md#quick-start` when copying `CONTRIBUTING.md` into the mkdocs site, since the rendered site has no `README.md`. * docs(readme): unwrap paragraphs and use `just` recipes for docs builds Paragraphs are collapsed to a single line each, matching the style now used across `docs/specs/*.md` and `CONTRIBUTING.md` for cleaner future prose diffs. `mkdocs serve` is replaced with `just docs-serve-fast` so the README drives users through the repo's task runner rather than a raw `uv run` invocation; the `just docs-spec` call gets its own code block for symmetry. Both fences use the `console` language now that they are pure shell commands. * chore(docs): improve readme * chore(docs): 3.12 as default; 3.13 doesn't have coincurve wheels * chore(docs): improve contributing * chore(docs): update production client list in readme --------- Co-authored-by: Guruprasad Kamath --- CONTRIBUTING.md | 314 ++------------------ EIP_AUTHORS_MANUAL.md | 69 ----- README.md | 163 ++++------ docs/dev/releasing.md | 82 +++++ docs/getting_started/installation.md | 2 +- docs/navigation.md | 6 + docs/scripts/copy_repo_docs_to_mkdocs.py | 13 + docs/specs/adding_a_new_eip.md | 62 ++++ docs/specs/index.md | 60 ++++ docs/specs/protocol_history.md | 67 +++++ RELEASING.md => docs/specs/spec_releases.md | 120 +------- docs/specs/writing_specs.md | 214 ++++++++++++- 12 files changed, 605 insertions(+), 567 deletions(-) delete mode 100644 EIP_AUTHORS_MANUAL.md create mode 100644 docs/dev/releasing.md create mode 100644 docs/specs/adding_a_new_eip.md create mode 100644 docs/specs/index.md create mode 100644 docs/specs/protocol_history.md rename RELEASING.md => docs/specs/spec_releases.md (58%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0846469c60f..13dd3058c30 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,312 +1,46 @@ # Contribution Guidelines -Help is always welcome and there are plenty of options to contribute to the Ethereum Execution Layer Specifications (EELS). +Help is always welcome. The Ethereum Execution Layer Specifications (EELS) are a community effort and we appreciate support in the following areas: -In particular, we appreciate support in the following areas: - -- Reporting issues -- Fixing and responding to [issues](https://github.com/ethereum/execution-specs/issues), especially those tagged as [E-easy](https://github.com/ethereum/execution-specs/labels/E-easy) which are meant as introductory issues for external contributors. +- Reporting issues. +- Fixing and responding to [issues](https://github.com/ethereum/execution-specs/issues), especially those tagged [E-easy](https://github.com/ethereum/execution-specs/labels/E-easy), which are intended as introductory issues for external contributors. - Improving the documentation. > [!IMPORTANT] -> Generally, we do not assign issues to external contributors. If you want to work on an issue, you are very welcome to go ahead and make a pull request. We would, however, be happy to answer questions you may have before you start implementing. - -For details about EELS usage and building, please refer to the [README](https://github.com/ethereum/execution-specs/blob/master/README.md#usage) - -## Contribution Guidelines - -This specification aims to be: - -1. **Correct** - Describe the _intended_ behavior of the Ethereum blockchain, and any deviation from that is a bug. -2. **Complete** - Capture the entirety of _consensus critical_ parts of Ethereum. -3. **Accessible** - Prioritize readability, clarity, and plain language over performance and brevity. - -### Style - -#### Spelling and Naming - -- Attempt to use descriptive English words (or _very common_ abbreviations) in documentation and identifiers. -- Avoid using EIP numbers in identifiers, and prefer descriptive text instead (eg. `FeeMarketTransaction` instead of `Eip1559Transaction`). -- If necessary, there is a custom dictionary `whitelist.txt`. -- Avoid uninformative prefixes in identifiers (like `get_` or `compute_`). They don't add useful meaning and take up valuable real estate. - -#### Comments - -- Don't repeat what is obvious from the code. --
- (expand) Consider how future changes will interleave with yours, especially when creating semantic blocks. - -
Consider: - - - - - - - - - - - - - - - -
Fork TFork T+1
- - - - ```python - # EIP-1234: The dingus is the rate of fleep - dingus = a + b - dingus += c ^ d - dingus /= fleep(e) - ``` - - - - ```python - # EIP-1234: The dingus is the rate of fleep - dingus = a + b - - # EIP-4567: Frobulate the dingus - dingus = frobulate(dingus) - - dingus += c ^ d # <- - dingus /= fleep(e) # <- - ``` - -
- - The marked lines (`<-`) are now incorrectly attributed to EIP-4567 in Fork+1. Instead, omit the EIP identifier in the comments, and describe the changes introduced by the EIP in the function's docstrings. The rendered diffs will make it pretty obvious what's changed. -
- -#### Docstrings - -- Write in complete sentences, providing necessary background and context for the associated code. -- Function and method docstrings must use the imperative mood in the summary line. - - **Good:** Build the house using the provided lumber. - - **Bad:** Builds the house using the provided lumber. -- Always start with a single-line summary. When more detail is needed, use a multi-line docstring with a blank line after the summary line. - - **One-line summary:** - - ```python - """Return the pathname of the KOS root directory.""" - ``` - - - **Multi-line:** - - ```python - """ - Add a bloom entry to the bloom filter. - - The number of hash functions used is 3. They are calculated by - taking the least significant 11 bits from the first 3 16-bit - words of the `keccak_256()` hash of `bloom_entry`. - """ - ``` - -- Format using markdown. -- Links to relevant standards and EIPs may be specified using reference-style links. - - ```python - """ - Minimum gas cost per byte of calldata as per [EIP-7976]. - - [EIP-7976]: https://eips.ethereum.org/EIPS/eip-7976 - """ - ``` - -- Avoid beginning docstrings with an article ("the"/"a") or a pronoun ("it", "they", etc.). -- Don't include the function's signature. - -##### Constants - -- Do not include constant values in docstrings, neither as literals nor as expressions. It's too easy to change a constant's value and forget to update its docstring. -- Construct the constant's value from other constants or meaningful expressions in order to provide meaningful context. - - **Great:** `TARGET_BLOB_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET` - - Composed from named constants; the reader immediately understands what the value represents. - - **Acceptable:** `TX_MAX_GAS = Uint(2 ** 24)` - - More readable than a raw number, but still a literal expression that doesn't convey _why_ this value was chosen. - - **Bad:** `TX_MAX_GAS = Uint(16_777_216)` - - A magic number with no context. - -### Changes across various Forks - -Many contributions require changes across multiple forks, organized under `src/ethereum/forks/*`. When making such changes, please ensure that differences between the forks are minimal and consist only of necessary differences. This will help with getting cleaner [diff outputs](https://ethereum.github.io/execution-specs/diffs/index.html). - -When creating pull requests affecting multiple forks, we recommended submitting your PR in two steps: - -1. Apply the changes on a single fork, open a _draft_ pull request, and get feedback; then -2. Apply the changes across the other forks, push them, and mark the pull request as ready for review. - -This saves you having to apply code review feedback repeatedly for each fork. - -### Development - -Running the tests necessary to merge into the repository requires: - -- [`uv`](https://docs.astral.sh/uv/) package manager, -- [`just`](https://just.systems/) command runner (install via your package manager, [`uv tool install just-bin`](https://pypi.org/project/just-bin/), or [pre-built binaries](https://just.systems/man/en/pre-built-binaries.html)), -- Python 3.11.x, -- [PyPy](https://www.pypy.org/) [7.3.19](https://downloads.python.org/pypy/) or later. -- `geth` installed and present in `$PATH`. - -`execution-specs` depends on a submodule that contains common tests that are run across all clients, so we need to clone the repo with the --recursive flag. Example: - -```bash -git clone --recursive https://github.com/ethereum/execution-specs.git -``` - -Or, if you've already cloned the repository, you can fetch the submodules with: - -```bash -git submodule update --init --recursive -``` - -The static checks can be run with: - -```bash -just static -``` - -Individual checks and auto-fix are also available as recipes: - -```bash -just fix # Auto-fix formatting and lint issues. -just lint # Lint with ruff. -just format-check # Check formatting with ruff. -just typecheck # Run type checking with mypy. -just spellcheck # Check spelling with codespell. -``` - -Run `just` to see all available recipes. Recipes that accept arguments can be passed extra flags, for example: - -```bash -just typecheck --warn-unreachable -``` - -> [!TIP] -> If you use multiple git worktrees, set `MYPY_CACHE_DIR` to share a single -> mypy cache across all of them and avoid cold-start delays: -> -> ```bash -> export MYPY_CACHE_DIR=~/path/to/execution-specs/.mypy_cache -> ``` - -### Shell Auto-Completion - -`just` provides tab-completion for recipe names and arguments. To enable it for your shell: - -**Bash** — add to `~/.bashrc`: - -```bash -eval "$(just --completions bash)" -``` - -**Zsh** — add to `~/.zshrc`: - -```bash -eval "$(just --completions zsh)" -``` - -**Fish** — run once (fish auto-loads completions from this directory): - -```bash -just --completions fish > ~/.config/fish/completions/just.fish -``` - -After restarting your shell (or sourcing the config), `just ` will complete recipe names. - -A trace of the EVM execution for any test case can be obtained by providing the `--evm-trace` argument to pytest. -Note: Make sure to run the EVM trace on a small number of tests at a time. The log might otherwise get very big. -Below is an example. - -```bash -uv run pytest \ - 'tests/json_loader/test_state_tests.py::test_state_tests_frontier[stAttackTest - ContractCreationSpam - 0]' \ - --evm_trace -``` - -## CLI Utilities `ethereum_spec_tools` - -The EELS repository has various CLI utilities that can help in the development process. - -### New Fork Tool - -This tool can be used to create the base code for a new fork by using the existing code from a given fork. - -The command takes 4 arguments, 2 of which are optional - -- from_fork: The fork name from which the code is to be duplicated. Eg. - "Tangerine Whistle" -- to_fork: The fork name of the new fork Eg - "Spurious Dragon" -- from_test (Optional): Name of the from fork within the test fixtures in case it is different from fork name. Eg. - "EIP150" -- to_test (Optional): Name of the to fork within the test fixtures in case it is different from fork name Eg - "EIP158" - -As an example, if one wants to create baseline code for the `Spurious Dragon` fork from the `Tangerine Whistle` one - -```bash -uv run ethereum-spec-new-fork --from_fork="Tangerine Whistle" --to_fork="Spurious Dragon" --from_test=EIP150 --to_test=EIP158 -``` - -The following will have to however, be updated manually - -1. The fork number and `MAINNET_FORK_BLOCK` in `__init__.py`. If you are proposing a new EIP, please set `MAINNET_FORK_BLOCK` to `None`. -2. Any absolute package imports from other forks eg. in `trie.py` -3. Package names under `setup.cfg` -4. Add the new fork to the `monkey_patch()` function in `src/ethereum_optimized/__init__.py` -5. Adjust the underline in `fork/__init__.py` +> Generally, we do not assign issues to external contributors. If you want to work on an issue, you are welcome to go ahead and make a pull request. We are happy to answer questions before you start implementing. -### Sync Tool +## Contributions we don't accept -The sync tool allows one to use an RPC provider to fetch and validate blocks against EELS. -The state can also be stored in a local DB after validation. Since syncing directly with the specs can be -very slow, one can also leverage the optimized module. This contains alternative implementations of routines -in EELS that have been optimized for speed rather than clarity/readability. +Pull requests should have reasonable substance and context. In particular, we do not accept: -The tool can be called using the `ethereum-spec-sync` command which takes the following arguments +- Contributions that only fix spelling or grammatical errors in documentation, code, or elsewhere. +- Drive-by or vibe-coded contributions without proper engagement or context. -- rpc-url: Endpoint providing the Ethereum RPC API. Defaults to `http://localhost:8545/` -- unoptimized: Don't use the optimized state/ethash (this can be extremely slow) -- persist: Store the state in a db in this file -- geth: Use geth specific RPC endpoints while fetching blocks -- reset: Delete the db and start from scratch -- gas-per-commit: Commit to db each time this much gas is consumed. Defaults to 1_000_000_000 -- initial-state: Start from the state in this db, rather than genesis -- stop-at: After syncing this block, exit successfully +## Code of Conduct -- The following options are not supported WITH `--unoptimized` -> `--persist`, `--initial-state`, `--reset` -- The following options are not supported WITHOUT `--persist` -> `--initial_state`, `--reset` +All contributors are expected to be excellent to each other; other behavior is not tolerated. To report a concern, contact one of the [STEEL team members](https://steel.ethereum.foundation/team/). -### Patch Tool +## Principles -This tool can be used to apply the unstaged changes in `SOURCE_FORK` to each of the `TARGET_FORKS`. If some -of the change didn't apply, '.rej' files listing the unapplied changes will be left in the `TARGET_FORK`. +The specification aims to be: -The tool takes the following command line arguments +1. **Correct.** Describe the *intended* behavior of the Ethereum blockchain. Any deviation from that is a bug. +2. **Complete.** Capture the entirety of *consensus-critical* parts of Ethereum. +3. **Accessible.** Prioritize readability, clarity, and plain language over performance and brevity. -- The fork name where the changes have been made. Eg:- `frontier` (only a single fork name) -- The fork names where the changes have to be applied. Eg:- `homestead` (multiple values can be provided separated by space) -- optimized: Patch the optimized code instead -- tests: Patch the tests instead +## Getting set up -As an example, if one wants to apply changes made in `Frontier` fork to `Homestead` and `Tangerine Whistle` +Environment setup (cloning the repository, installing `uv` and `just`, Python requirements) is documented in the [Installation guide](docs/getting_started/installation.md). -```bash -uv run python src/ethereum_spec_tools/patch_tool.py frontier homestead tangerine_whistle -``` +Before opening a PR, run the checks relevant to your change; see [Verifying Changes](docs/getting_started/verifying_changes.md). -### Lint Tool +## Changes that affect multiple forks -This tool checks for style and formatting issues specific to EELS and emits diagnostics -when issues are found +When creating pull requests that touch several forks under `src/ethereum/forks/`, we recommend a two-step workflow: -The tool currently performs the following checks +1. Apply the changes on a single fork, open a *draft* PR, and get feedback. +2. Apply the changes across the other forks, push them, and mark the PR as ready for review. -- The order of the identifiers between each hardfork is consistent. -- Import statements follow the relevant import rules in modules. +This saves you from applying code review feedback repeatedly for each fork. -The command to run the tool is `just lint-spec` (or `uv run ethereum-spec-lint`). +See [Writing Specs](docs/specs/writing_specs.md) for the technical style rules (naming, comments, docstrings, constants, cross-fork discipline) and for the `ethereum_spec_tools` CLI utilities that help with these workflows. diff --git a/EIP_AUTHORS_MANUAL.md b/EIP_AUTHORS_MANUAL.md deleted file mode 100644 index f7ec268c7cd..00000000000 --- a/EIP_AUTHORS_MANUAL.md +++ /dev/null @@ -1,69 +0,0 @@ -# EIP Author's Manual - -## Introduction - -This document outlines the process of specifying and testing EIPs for the Ethereum execution layer. It is intended for EIP authors, researchers and implementers. An EIP will typically go through the following stages: - -| Stage | Activities | Outputs | -| ------------------ | ----------- | ------- | -| _Pre‑Draft_ | Prospective EIP author conceives of an idea for an improvement to Ethereum, and discusses with the community. |
  • Vague Consensus on [Ethereum Magicians][0]
| -| **Draft** |

EIP author writes a technical human-language document describing the improvement, initially in broad strokes and becoming more specific over time.

Concurrently, they develop a Python reference implementation to make the EIP executable and identify any immediate/obvious implementation issues. For example, the EIP may not be compatible with some detail of the current Ethereum Virtual Machine.

Finally for this stage, the author begins to write test schemes for the EIP. Having the reference implementation should help identify the various logical flows to test and thus feed into more robust testing. Once the test schemes are written, the reference implementation can then be used to fill the tests and generate the test vectors.

|
  • Complete (but not final) document in [EIPs Repository][1]
  • Reference Implementation in [EELS][2]
  • Initial Tests in [EEST][3]
| -| **Review** |

The broader Ethereum community discusses and provides input on the proposal.

Although the feedback from the community can be sought at all lifecycle stages, having a reference implementation and tests act as a good bridge between research and client implementation. It also helps core developers (who have limited time and resources) to understand the EIP better and provide more informed feedback.

|
  • Complete & final document in the [EIPs Repository][1]
  • Comprehensive tests in [EEST][3]
| -| **Last Call** | Usually after being nominated for inclusion in a fork, the EIP author signals that the proposal is effectively done and begins the last period for comments/discussion. |
  • Complete reference implementation in [EELS][2]
  • Complete tests in [EEST][3]
  • Immutable proposal in [EIPs Repository][1]
| -| **Final** | The proposal is now immutable (cannot be changed) and exists for reference. |
  • Mainnet client implementations
| - -[0]: https://ethereum-magicians.org/ -[1]: https://github.com/ethereum/EIPs/ -[2]: https://github.com/ethereum/execution-specs -[3]: https://github.com/ethereum/execution-spec-tests - -This document will focus on stages 3 and 4 of the above lifecycle. - -## Executable Specifications - -This repository contains the executable specifications for the Ethereum execution layer. - -### Folder Structure - -#### Forks live on mainnet - -The folder `src/ethereum` contains the specifications for the different execution layer forks. Each fork has its own folder. For example, the folder `src/ethereum/frontier` contains the specifications for the Frontier hardfork. The `state_transition` function which is available in the `src/ethereum//fork.py` is the transition function for each fork. - -#### Fork under development - -At any given time, there is a single fork under development. Any new EIP has to be implemented in the folder that is meant for that fork (`src/ethereum/` folder). - -For example, at the time of writing, the Prague Fork is still under development and the previous fork is Cancun, which is live on Mainnet. So the prague folder under `src/ethereum` is essentially just the Cancun fork with the values of variables updated to reflect Prague and its under-development status. This folder (`src/ethereum/prague`) serves as the baseline for further development and all new EIPs are to be implemented in this folder. - -### Branch Structure - -#### Forks live on mainnet - -The final stable specification for all forks that are currently live on mainnet are in the `mainnet` branch. - -#### Fork under development - -At any given time, there can only be one fork under active development. The branch structure for the fork under development is as follows: - -- `forks/`: The main branch for the fork under development. For example, `forks/prague` is the branch for the Prague fork. This branch will be merged into `mainnet` after the fork has gone live on mainnet. -- `eips//`: Branches for each EIP within the fork under development. For example, `eips/prague/eip-7702` is the branch for EIP-7702 for the Prague fork. This branch will be merged into `forks/prague` after the EIP has been confirmed for release in the fork. - -## Writing New EIPS - -Implementing a new EIP in the `execution-specs` repository involves the following steps: - -1. **Create a new branch**: Create a new branch for the EIP under the appropriate fork. For example, if you are implementing an EIP for the Prague fork, create a new branch under `eips//eip-`. -2. **Implement the EIP**: Implement the EIP in the `src/ethereum/` folder. -3. **Basic sanity checks**: Run `just static` to run basic formatting and linting checks. -4. **Raise a PR**: Raise a PR against the appropriate branch. For example, if you are implementing an EIP for the Prague fork, raise a PR against the `forks/prague` branch. - -An EIP can only be CFI'd (Considered For Inclusion) if it has a reference `execution-specs` implementation. The EIP author is responsible for maintaining their EIP up-to-date with the latest changes. For example, if an author had written their EIP for Cancun under `eips/cancun/eip-x`, but for some reason it didn't make it into Cancun, they would need to rebase their EIP to reflect the changes in Prague under `eips/prague/eip-x`. - -Please refer the following tutorial for writing new EIP. It takes you through a sample EIP for adding a new opcode to the specs. -[Tutorial](https://www.youtube.com/watch?v=QIcw_DGSy3s&t) - -## Writing Tests with `execution-spec-tests` - -In addition to having a reference implementation, it is also very useful for the community and core development if the EIP author concieves and writes test vectors for the EIP. There is a very user friendly framework for writing ethereum tests in the `execution-spec-tests` repository. Please refer to the following guide for writing tests to your EIP. - -[Writing Tests with `execution-spec-tests`](https://eest.ethereum.org/v2.0.0/getting_started/quick_start/) diff --git a/README.md b/README.md index 0eaee1ebe26..16903060dff 100644 --- a/README.md +++ b/README.md @@ -1,110 +1,77 @@ -# Ethereum Execution Client Specifications +# Ethereum Execution Layer Specifications -[![GitPOAP Badge](https://public-api.gitpoap.io/v1/repo/ethereum/execution-specs/badge)](https://www.gitpoap.io/gh/ethereum/execution-specs) -[![codecov](https://codecov.io/gh/ethereum/execution-specs/graph/badge.svg?token=0LQZO56RTM)](https://codecov.io/gh/ethereum/execution-specs) +[![latest version](https://img.shields.io/github/v/release/ethereum/execution-specs)](https://github.com/ethereum/execution-specs/releases/latest) +[![PyPI version](https://img.shields.io/pypi/v/ethereum-execution)](https://pypi.org/project/ethereum-execution/) +[![License](https://img.shields.io/github/license/ethereum/execution-specs)](https://github.com/ethereum/execution-specs/blob/main/LICENSE) [![Python Specification](https://github.com/ethereum/execution-specs/actions/workflows/test.yaml/badge.svg)](https://github.com/ethereum/execution-specs/actions/workflows/test.yaml) +[![codecov](https://codecov.io/gh/ethereum/execution-specs/graph/badge.svg?token=0LQZO56RTM)](https://codecov.io/gh/ethereum/execution-specs) +![Python Versions](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue) +[![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) +[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) +[![GitPOAP Badge](https://public-api.gitpoap.io/v1/repo/ethereum/execution-specs/badge)](https://www.gitpoap.io/gh/ethereum/execution-specs) -## Description - -This repository contains the specifications related to the Ethereum execution client, specifically the [pyspec](/src/ethereum/__init__.py) and specifications for [network upgrades](/src/ethereum/__init__.py). The [JSON-RPC API specification](https://github.com/ethereum/execution-apis) can be found in a separate repository. - -### Ethereum Protocol Releases - -| Version and Code Name | Block No. | Released | Incl EIPs | Fork Specifications | Blog | -|-----------------------|-----------|----------|-----------|-------|-------| -| Osaka | 23935694 | 2025-12-03 | [EIP-7594]
[EIP-7642]
[EIP-7823]
[EIP-7825]
[EIP-7883]
[EIP-7892]
[EIP-7910]
[EIP-7917]
[EIP-7918]
[EIP-7934]
[EIP-7935]
[EIP-7939]
[EIP-7951] | [Hardfork Meta EIP-7607](https://eips.ethereum.org/EIPS/eip-7607)
[Fork Manifest](/src/ethereum/forks/osaka/__init__.py) | [Blog](https://blog.ethereum.org/2025/11/06/fusaka-mainnet-announcement) | -| Prague | 22431084 | 2025-05-07 | [EIP-2537]
[EIP-2935]
[EIP-6110]
[EIP-7002]
[EIP-7251]
[EIP-7549]
[EIP-7623]
[EIP-7685]
[EIP-7691]
[EIP-7702] | [Hardfork Meta EIP-7600](https://eips.ethereum.org/EIPS/eip-7600)
[Fork Manifest](/src/ethereum/forks/prague/__init__.py)| [Blog](https://blog.ethereum.org/2025/04/23/pectra-mainnet) | -| Cancun | 19426587 | 2024-03-13
(1710338135) | [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)
[EIP-4788](https://eips.ethereum.org/EIPS/eip-4788)
[EIP-4844](https://eips.ethereum.org/EIPS/eip-4844)
[EIP-5656](https://eips.ethereum.org/EIPS/eip-5656)
[EIP-6780](https://eips.ethereum.org/EIPS/eip-6780)
[EIP-7044](https://eips.ethereum.org/EIPS/eip-7044)
[EIP-7045](https://eips.ethereum.org/EIPS/eip-7045)
[EIP-7514](https://eips.ethereum.org/EIPS/eip-7514)
[EIP-7516](https://eips.ethereum.org/EIPS/eip-7516)| [Hardfork Meta EIP-7569](https://eips.ethereum.org/EIPS/eip-7569)
[Fork Manifest](/src/ethereum/forks/cancun/__init__.py) | [Blog](https://blog.ethereum.org/2024/02/27/dencun-mainnet-announcement) | -| Shanghai | 17034870 | 2023-04-12
(1681338455) | [EIP-3651](https://eips.ethereum.org/EIPS/eip-3651)
[EIP-3855](https://eips.ethereum.org/EIPS/eip-3855)
[EIP-3860](https://eips.ethereum.org/EIPS/eip-3860)
[EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](/src/ethereum/forks/shanghai/__init__.py) | [Blog](https://blog.ethereum.org/2023/03/28/shapella-mainnet-announcement) | -| Paris | 15537394 | 2022-09-15 | [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675)
[EIP-4399](https://eips.ethereum.org/EIPS/eip-4399) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](/src/ethereum/forks/paris/__init__.py) | [Blog](https://blog.ethereum.org/2022/08/24/mainnet-merge-announcement) | -| Gray Glacier | 15050000 | 2022-06-30 | [EIP-5133](https://eips.ethereum.org/EIPS/eip-5133) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](/src/ethereum/forks/gray_glacier/__init__.py) | [Blog](https://blog.ethereum.org/2022/06/16/gray-glacier-announcement/) | -| Arrow Glacier | 13773000 | 2021-12-09 | [EIP-4345](https://eips.ethereum.org/EIPS/eip-4345) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](/src/ethereum/forks/arrow_glacier/__init__.py) | [Blog](https://blog.ethereum.org/2021/11/10/arrow-glacier-announcement/) | -| London | 12965000 | 2021-08-05 | [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
[EIP-3198](https://eips.ethereum.org/EIPS/eip-3198)
[EIP-3529](https://eips.ethereum.org/EIPS/eip-3529)
[EIP-3541](https://eips.ethereum.org/EIPS/eip-3541)
[EIP-3554](https://eips.ethereum.org/EIPS/eip-3554)| [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](/src/ethereum/forks/london/__init__.py) | [Blog](https://blog.ethereum.org/2021/07/15/london-mainnet-announcement/) | -| Berlin | 12244000 | 2021-04-15 | [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565)
[EIP-2929](https://eips.ethereum.org/EIPS/eip-2929)
[EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
[EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) | ~[Hardfork Meta EIP-2070](https://eips.ethereum.org/EIPS/eip-2070)~
[(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](/src/ethereum/forks/berlin/__init__.py) | [Blog](https://blog.ethereum.org/2021/03/08/ethereum-berlin-upgrade-announcement/) | -| Muir Glacier | 9200000 | 2020-01-02 | [EIP-2384](https://eips.ethereum.org/EIPS/eip-2384) | [Hardfork Meta EIP-2387](https://eips.ethereum.org/EIPS/eip-2387)
[Fork Manifest](/src/ethereum/forks/muir_glacier/__init__.py) | [Blog](https://blog.ethereum.org/2019/12/23/ethereum-muir-glacier-upgrade-announcement/) | -| Istanbul | 9069000 | 2019-12-07 | [EIP-152](https://eips.ethereum.org/EIPS/eip-152)
[EIP-1108](https://eips.ethereum.org/EIPS/eip-1108)
[EIP-1344](https://eips.ethereum.org/EIPS/eip-1344)
[EIP-1884](https://eips.ethereum.org/EIPS/eip-1884)
[EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)
[EIP-2200](https://eips.ethereum.org/EIPS/eip-2200) | [Hardfork Meta EIP-1679](https://eips.ethereum.org/EIPS/eip-1679)
[Fork Manifest](/src/ethereum/forks/istanbul/__init__.py) | [Blog](https://blog.ethereum.org/2019/11/20/ethereum-istanbul-upgrade-announcement/) | -| Petersburg | 7280000 | 2019-02-28 | [EIP-145](https://eips.ethereum.org/EIPS/eip-145)
[EIP-1014](https://eips.ethereum.org/EIPS/eip-1014)
[EIP-1052](https://eips.ethereum.org/EIPS/eip-1052)
[EIP-1234](https://eips.ethereum.org/EIPS/eip-1234) | [Hardfork Meta EIP-1716](https://eips.ethereum.org/EIPS/eip-1716) | [Blog](https://blog.ethereum.org/2019/02/22/ethereum-constantinople-st-petersburg-upgrade-announcement/) | -| Constantinople | 7280000 | 2019-02-28 | [EIP-145](https://eips.ethereum.org/EIPS/eip-145)
[EIP-1014](https://eips.ethereum.org/EIPS/eip-1014)
[EIP-1052](https://eips.ethereum.org/EIPS/eip-1052)
[EIP-1234](https://eips.ethereum.org/EIPS/eip-1234)
[EIP-1283](https://eips.ethereum.org/EIPS/eip-1283) | [Hardfork Meta EIP-1013](https://eips.ethereum.org/EIPS/eip-1013)
[Fork Manifest](/src/ethereum/forks/constantinople/__init__.py) | [Blog](https://blog.ethereum.org/2019/02/22/ethereum-constantinople-st-petersburg-upgrade-announcement/) | -| Byzantium | 4370000 | 2017-10-16 | [EIP-100](https://eips.ethereum.org/EIPS/eip-100)
[EIP-140](https://eips.ethereum.org/EIPS/eip-140)
[EIP-196](https://eips.ethereum.org/EIPS/eip-196)
[EIP-197](https://eips.ethereum.org/EIPS/eip-197)
[EIP-198](https://eips.ethereum.org/EIPS/eip-198)
[EIP-211](https://eips.ethereum.org/EIPS/eip-211)
[EIP-214](https://eips.ethereum.org/EIPS/eip-214)
[EIP-649](https://eips.ethereum.org/EIPS/eip-649)
[EIP-658](https://eips.ethereum.org/EIPS/eip-658) | [Hardfork Meta EIP-609](https://eips.ethereum.org/EIPS/eip-609)
[Fork Manifest](/src/ethereum/forks/byzantium/__init__.py) | [Blog](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/) | -| Spurious Dragon | 2675000 | 2016-11-22 | [EIP-155](https://eips.ethereum.org/EIPS/eip-155)
[EIP-160](https://eips.ethereum.org/EIPS/eip-160)
[EIP-161](https://eips.ethereum.org/EIPS/eip-161)
[EIP-170](https://eips.ethereum.org/EIPS/eip-170) | [Hardfork Meta EIP-607](https://eips.ethereum.org/EIPS/eip-607)
[Fork Manifest](/src/ethereum/forks/spurious_dragon/__init__.py) | [Blog](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) | -| Tangerine Whistle | 2463000 | 2016-10-18 | [EIP-150](https://eips.ethereum.org/EIPS/eip-150) | [Hardfork Meta EIP-608](https://eips.ethereum.org/EIPS/eip-608)
[Fork Manifest](/src/ethereum/forks/tangerine_whistle/__init__.py) | [Blog](https://blog.ethereum.org/2016/10/13/announcement-imminent-hard-fork-eip150-gas-cost-changes/) | -| DAO Fork | 1920000 | 2016-07-20 | | [Hardfork Meta EIP-779](https://eips.ethereum.org/EIPS/eip-779)
[Fork Manifest](/src/ethereum/forks/dao_fork/__init__.py) | [Blog](https://blog.ethereum.org/2016/07/15/to-fork-or-not-to-fork/) | -| DAO Wars | aborted | aborted | | | [Blog](https://blog.ethereum.org/2016/06/24/dao-wars-youre-voice-soft-fork-dilemma/) | -| Homestead | 1150000 | 2016-03-14 | [EIP-2](https://eips.ethereum.org/EIPS/eip-2)
[EIP-7](https://eips.ethereum.org/EIPS/eip-7)
[EIP-8](https://eips.ethereum.org/EIPS/eip-8) | [Hardfork Meta EIP-606](https://eips.ethereum.org/EIPS/eip-606)
[Fork Manifest](/src/ethereum/forks/homestead/__init__.py) | [Blog](https://blog.ethereum.org/2016/02/29/homestead-release/) | -| Frontier Thawing | 200000 | 2015-09-07 | | | [Blog](https://blog.ethereum.org/2015/08/04/the-thawing-frontier/) | -| Frontier | 1 | 2015-07-30 | | [Fork Manifest](/src/ethereum/forks/frontier/__init__.py) | [Blog](https://blog.ethereum.org/2015/07/22/frontier-is-coming-what-to-expect-and-how-to-prepare/) | - -*Note:* Starting with Paris, updates are no longer rolled out based on block numbers. Paris was enabled once proof-of-work Total Difficulty reached 58750000000000000000000. As of Shanghai (at 1681338455), upgrade activation is based on timestamps. - -[EIP-2537]: https://eips.ethereum.org/EIPS/eip-2537 -[EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 -[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 -[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 -[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 -[EIP-7549]: https://eips.ethereum.org/EIPS/eip-7549 -[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 -[EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 -[EIP-7691]: https://eips.ethereum.org/EIPS/eip-7691 -[EIP-7702]: https://eips.ethereum.org/EIPS/eip-7702 -[EIP-7594]: https://eips.ethereum.org/EIPS/eip-7594 -[EIP-7642]: https://eips.ethereum.org/EIPS/eip-7642 -[EIP-7823]: https://eips.ethereum.org/EIPS/eip-7823 -[EIP-7825]: https://eips.ethereum.org/EIPS/eip-7825 -[EIP-7883]: https://eips.ethereum.org/EIPS/eip-7883 -[EIP-7892]: https://eips.ethereum.org/EIPS/eip-7892 -[EIP-7910]: https://eips.ethereum.org/EIPS/eip-7910 -[EIP-7917]: https://eips.ethereum.org/EIPS/eip-7917 -[EIP-7918]: https://eips.ethereum.org/EIPS/eip-7918 -[EIP-7934]: https://eips.ethereum.org/EIPS/eip-7934 -[EIP-7935]: https://eips.ethereum.org/EIPS/eip-7935 -[EIP-7939]: https://eips.ethereum.org/EIPS/eip-7939 -[EIP-7951]: https://eips.ethereum.org/EIPS/eip-7951 - -Some clarifications were enabled without protocol releases: - -| EIP | Block No. | -|-----|-----------| -| [EIP-2681](https://eips.ethereum.org/EIPS/eip-2681) | 0 | -| [EIP-3607](https://eips.ethereum.org/EIPS/eip-3607) | 0 | -| [EIP-7523](https://eips.ethereum.org/EIPS/eip-7523) | 15537394 | -| [EIP-7610](https://eips.ethereum.org/EIPS/eip-7610) | 0 | - -## Execution Specification (work-in-progress) - -The execution specification is a python implementation of Ethereum that prioritizes readability and simplicity. It will be accompanied by both narrative and API level documentation of the various components written in markdown and rendered using docc... - -* [Rendered specification](https://ethereum.github.io/execution-specs/) - -## Usage - -The Ethereum specification is maintained as a Python library, for better integration with tooling and testing. - -Requires: - -* Python 3.11+, -* [`uv`](https://docs.astral.sh/uv/) package manager, -* [`just`](https://just.systems/) command runner (install via your package manager, [`uv tool install just-bin`](https://pypi.org/project/just-bin/), or [pre-built binaries](https://just.systems/man/en/pre-built-binaries.html)). - -### Building Specification Documentation - -Building the spec documentation: - -```bash -just docs-spec -``` +The Ethereum Execution Layer Specifications (EELS) are an executable Python reference implementation of Ethereum's execution layer, along with the test cases that verify it. It provides a shared, runnable description of consensus-critical behaviour, and the accompanying tests generate fixtures that can be used to validate execution client implementations. -The path to the generated HTML will be printed to the console. +## Quick Start -### Browsing Updated Documentation +execution-specs uses [`uv`](https://docs.astral.sh/uv/) to manage the Python environment and dependencies, and [`just`](https://just.systems/) as a task runner for common commands (linting, building docs, generating fixtures). The commands below install both and set up the repo from scratch. -To view the updated local documentation, run: +Requires a Unix-like shell. All platforms: -```bash -uv run mkdocs serve +```console +git clone https://github.com/ethereum/execution-specs +cd execution-specs +curl -LsSf https://astral.sh/uv/install.sh | sh +uv python install 3.12 +uv python pin 3.12 +uv sync +uv tool install --exclude-newer "10 days" rust-just +just shell-completions ``` -then connect to `localhost:8000` in a browser +Python 3.11–3.14 are supported; 3.12 tends to be the smoothest for local setup (pre-built wheels are available across the dependency set). For alternative `just` installation paths, macOS-specific installation notes, and troubleshooting, see [Installation](docs/getting_started/installation.md). + +## Documentation + +- **Repo documentation (default branch/fork)**: +- **Protocol history**: [docs/specs/protocol_history.md](docs/specs/protocol_history.md) +- **Versioning scheme**: [docs/specs/spec_releases.md](docs/specs/spec_releases.md) (PEP 440 compatible; hardfork encoded in the minor version, `rcN` marks devnets). + +## Contributing + +Earnest contributions are welcome; drive-by contributions are not. See [CONTRIBUTING.md](CONTRIBUTING.md) for how to raise issues and pull requests. Further reading: + +- [Code Standards](docs/getting_started/code_standards.md): Python coding preferences enforced in CI. +- [Verifying Changes](docs/getting_started/verifying_changes.md): Which local checks to run before opening a PR. +- [Writing Specs](docs/specs/writing_specs.md): Style rules and `ethereum_spec_tools` utilities for changes under `src/ethereum/`. +- [Writing Tests](docs/writing_tests/index.md): For guidance on adding consensus tests under `./tests/`. + +This repository is maintained by the [STEEL Team](https://steel.ethereum.foundation/) at the Ethereum Foundation. + +## Community and Support + +Discussion around the initial specification of protocol changes happens on [Ethereum Magicians](https://ethereum-magicians.org/), in pull requests on [ethereum/EIPs](https://github.com/ethereum/EIPs), on the [Ethereum R&D Discord](https://discord.com/invite/qGpsxSA) (one of the channels in the *Execution R&D* category; for testing use `#el-testing`), and in the AllCoreDevs calls. + +For tracking the status of upcoming Ethereum upgrades, see [Forkcast](https://forkcast.org/): EIP inclusion, client implementation progress, and ACD call summaries. + +For other help, see the [Documentation](#documentation) section above, or reach out to one of the [STEEL team members](https://steel.ethereum.foundation/team/) in the Ethereum R&D Discord. + +### Related projects + +- [ethereum/EIPs](https://github.com/ethereum/EIPs): The prose EIP documents that EELS implements. +- [ethereum/execution-apis](https://github.com/ethereum/execution-apis): The JSON-RPC API specification, which lives in a separate repository. +- [ethereum/consensus-specs](https://github.com/ethereum/consensus-specs): The consensus-layer counterpart to this repository. + +Production execution clients that implement the spec include [besu](https://github.com/besu-eth/besu), [erigon](https://github.com/erigontech/erigon), [ethrex](https://github.com/lambdaclass/ethrex), [geth](https://github.com/ethereum/go-ethereum), [nethermind](https://github.com/NethermindEth/nethermind), and [reth](https://github.com/paradigmxyz/reth). + +## Responsible Disclosure of Vulnerabilities + +> [!CAUTION] +> Care is required when filing issues or PRs for functionality that is live on Ethereum mainnet. Please report vulnerabilities and verify bounty eligibility via the [bug bounty program](https://bounty.ethereum.org); see [SECURITY.md](SECURITY.md) for details. +> +> - **Please do not create a PR with a vulnerability visible.** +> - **Please do not file a public ticket mentioning the vulnerability.** ## License -The Ethereum Execution Layer Specification code is licensed under the [Creative Commons Zero v1.0 Universal](LICENSE.md). +The Ethereum Execution Layer Specification is licensed under the [Creative Commons Zero v1.0 Universal](LICENSE.md). diff --git a/docs/dev/releasing.md b/docs/dev/releasing.md new file mode 100644 index 00000000000..137cf9dc702 --- /dev/null +++ b/docs/dev/releasing.md @@ -0,0 +1,82 @@ +# Releasing + +This is the maintainer runbook for cutting an EELS release. For the +contributor-facing explanation of the versioning scheme, see +[Spec Releases](../specs/spec_releases.md). + +## Overview + +1. Choose a version number (see + [Spec Releases](../specs/spec_releases.md)). +2. Update the version in source code. +3. Create a pull request. +4. Wait for it to get merged. +5. Create a tag. +6. Create a GitHub release. +7. Publish to PyPI. + +## Updating the version in source code + +The version number is set in `src/ethereum/__init__.py`. Change it +there. For example: + +```patch +diff --git a/src/ethereum/__init__.py b/src/ethereum/__init__.py +index 252f2f317..8cdd89a55 100644 +--- a/src/ethereum/__init__.py ++++ b/src/ethereum/__init__.py +@@ -18,7 +18,7 @@ possible, to aid in defining the behavior of Ethereum clients. + """ + import sys + +-__version__ = "1.15.0" ++__version__ = "1.16.0rc1" + + # + # Ensure we can reach 1024 frames of recursion +``` + +## Creating the pull request + +The usual: `git checkout -b release-vX.Y.Z`, `git commit -a`, and +`git push`. + +## Creating the tag + +> [!WARNING] +> Do not create the tag from the `HEAD` branch of the pull request. +> +> GitHub can rewrite commits when merging pull requests, and tagging the +> original commit will make the git history messier than necessary. + +The tag name should be the letter `v` followed by the version number +(e.g. `1.15.0rc5.post3` becomes `v1.15.0rc5.post3`). + +To create and push the tag: + +```bash +git checkout master # Replace `master` with the pull request's base branch. +git pull +git tag -a -s v1.15.0 # Replace `v1.15.0` with the tag name from earlier. +git push origin v1.15.0 # Replace the tag name here too. +``` + +> [!IMPORTANT] +> If `git tag` complains about a missing GPG/PGP key, follow +> [this guide][keygen] to generate one. It's best to add the key to +> your GitHub account as well. + +[keygen]: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key + +## Creating the GitHub release + +Go to the [release page][release], choose the newly created tag, and +generate release notes. + +[release]: https://github.com/ethereum/execution-specs/releases/new + +## Publishing to PyPI + +See the [Python Packaging User Guide][ppug]. + +[ppug]: https://packaging.python.org/en/latest/tutorials/packaging-projects/#generating-distribution-archives diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index 10524ae291d..b97e4e8d4d2 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -52,7 +52,7 @@ When installed via `curl`, `uv` can also download Python for your platform if a ## Installing Python and Python Dependencies -Clone @ethereum/execution-specs and install the project dependencies. We recommend using Python 3.12 for the simplest local development setup. +Clone @ethereum/execution-specs and install the project dependencies. Python 3.11–3.14 are supported; Python 3.12 tends to be the smoothest for local setup because pre-built wheels are available across the dependency set. The following commands use `uv` to install Python 3.12 and pin it for all commands run within the execution-specs directory: diff --git a/docs/navigation.md b/docs/navigation.md index 4ef0205eff7..3415721cc1a 100644 --- a/docs/navigation.md +++ b/docs/navigation.md @@ -10,6 +10,11 @@ * [Security Policy](getting_started/security.md) * [Installation Troubleshooting](getting_started/installation_troubleshooting.md) * [Getting Help](getting_started/getting_help.md) + * [Specifications](specs/index.md) + * [Writing Specs](specs/writing_specs.md) + * [Adding a New EIP](specs/adding_a_new_eip.md) + * [Spec Releases](specs/spec_releases.md) + * [Protocol History](specs/protocol_history.md) * [Consensus Tests](consensus_tests/index.md) * [Writing Tests](writing_tests/index.md) * [Adding a New Test](writing_tests/adding_a_new_test.md) @@ -75,6 +80,7 @@ * [Logging](dev/logging.md) * [Running Github Actions Locally](dev/test_actions_locally.md) * [Dependencies and Packaging](dev/deps_and_packaging.md) + * [Releasing](dev/releasing.md) * [Library Reference](library/index.md) * [EEST CLI Tools](library/cli/index.md) * [eest](library/cli/eest.md) diff --git a/docs/scripts/copy_repo_docs_to_mkdocs.py b/docs/scripts/copy_repo_docs_to_mkdocs.py index 6f011490f2f..023c7253802 100644 --- a/docs/scripts/copy_repo_docs_to_mkdocs.py +++ b/docs/scripts/copy_repo_docs_to_mkdocs.py @@ -46,6 +46,19 @@ def copy_markdown_file(source_path, destination_path, fix_links=True): line, ) + # Fix repo-relative docs/ links to work from + # docs/getting_started/.md + line = re.sub( + r"\]\(docs/getting_started/", + r"](", + line, + ) + line = re.sub( + r"\]\(docs/([^)]+)\)", + r"](../\1)", + line, + ) + destination.write(line) except Exception as e: raise Exception( diff --git a/docs/specs/adding_a_new_eip.md b/docs/specs/adding_a_new_eip.md new file mode 100644 index 00000000000..0ff60347416 --- /dev/null +++ b/docs/specs/adding_a_new_eip.md @@ -0,0 +1,62 @@ +# Adding a New EIP + +This page outlines the process of specifying and testing EIPs for the Ethereum execution layer. It is intended for EIP authors, researchers, and implementers. + +An EIP will typically go through the following stages: + +| Stage | Activities | Outputs | +| ------------------ | ----------- | ------- | +| *Pre-Draft* | Prospective EIP author conceives of an idea for an improvement to Ethereum, and discusses with the community. |
  • Vague Consensus on [Ethereum Magicians][0]
| +| **Draft** |

EIP author writes a technical human-language document describing the improvement, initially in broad strokes and becoming more specific over time.

Concurrently, they develop a Python reference implementation to make the EIP executable and identify any immediate/obvious implementation issues. For example, the EIP may not be compatible with some detail of the current Ethereum Virtual Machine.

Finally for this stage, the author begins to write test schemes for the EIP. Having the reference implementation should help identify the various logical flows to test and thus feed into more robust testing. Once the test schemes are written, the reference implementation can then be used to fill the tests and generate the test vectors.

|
  • Complete (but not final) document in [EIPs Repository][1]
  • Reference implementation in EELS (this repository)
  • Initial tests under `./tests/` (this repository)
| +| **Review** |

The broader Ethereum community discusses and provides input on the proposal.

Although the feedback from the community can be sought at all lifecycle stages, having a reference implementation and tests act as a good bridge between research and client implementation. It also helps core developers (who have limited time and resources) to understand the EIP better and provide more informed feedback.

|
  • Complete & final document in the [EIPs Repository][1]
  • Comprehensive tests under `./tests/`
| +| **Last Call** | Usually after being nominated for inclusion in a fork, the EIP author signals that the proposal is effectively done and begins the last period for comments/discussion. |
  • Complete reference implementation in EELS
  • Complete tests under `./tests/`
  • Immutable proposal in [EIPs Repository][1]
| +| **Final** | The proposal is now immutable (cannot be changed) and exists for reference. |
  • Mainnet client implementations
| + +[0]: https://ethereum-magicians.org/ +[1]: https://github.com/ethereum/EIPs/ + +The rest of this page focuses on the **Draft** and **Review** stages, where EIP authors interact most directly with EELS and the test suite. + +## Executable specifications + +This repository contains the executable specifications for the Ethereum execution layer under `src/ethereum/`. + +### Forks live on mainnet + +The folder `src/ethereum/forks/` contains the specifications for the different execution layer forks. Each fork has its own folder. For example, `src/ethereum/forks/frontier/` contains the specifications for the Frontier hardfork. The `state_transition` function in `src/ethereum/forks//fork.py` is the transition function for each fork. + +### Fork under development + +At any given time, there is a single fork under development. Any new EIP is implemented in the folder for that fork (`src/ethereum/forks//`). + +For example, if Amsterdam is under development and Prague is live on mainnet, the `src/ethereum/forks/amsterdam/` folder starts as a copy of Prague with values updated to reflect Amsterdam and its under-development status. This folder serves as the baseline for further development and all new EIPs are implemented in it. + +## Branch structure + +### Forks live on mainnet + +The final stable specification for all forks that are currently live on mainnet are on the `mainnet` branch. + +### Fork under development + +At any given time there is exactly one fork under active development. The branch structure for the fork under development is: + +- `forks/`: The main branch for the fork under development. For example, `forks/amsterdam` is the branch for the Amsterdam fork. This branch will be merged into `mainnet` after the fork has gone live. +- `eips//`: Branches for each EIP within the fork under development. For example, `eips/amsterdam/eip-7928` is the branch for EIP-7928 for the Amsterdam fork. This branch will be merged into `forks/amsterdam` after the EIP has been confirmed for release in the fork. + +## Writing a new EIP + +Implementing a new EIP in this repository involves the following steps: + +1. **Create a new branch.** Create a branch for the EIP under the appropriate fork. For example, if you are implementing an EIP for the Amsterdam fork, create a branch `eips/amsterdam/eip-`. +2. **Implement the EIP.** Implement the EIP in the `src/ethereum/forks//` folder. See [Writing Specs](writing_specs.md) for style rules and the `ethereum_spec_tools` CLI utilities (the *New Fork Tool* in particular). +3. **Basic sanity checks.** Run `just static` to run formatting, linting, and spec-specific lints. +4. **Raise a PR.** Raise a PR against the appropriate fork branch. For example, if you are implementing an EIP for Amsterdam, raise a PR against `forks/amsterdam`. + +An EIP can only be CFI'd (Considered For Inclusion) if it has a reference EELS implementation. The EIP author is responsible for keeping their EIP up to date with the latest changes. For example, if an author had written their EIP for Prague under `eips/prague/eip-x`, but for some reason it didn't make it into Prague, they would need to rebase their EIP to reflect the changes in Amsterdam under `eips/amsterdam/eip-x`. + +A sample tutorial that walks through adding a new opcode to the specification is available on YouTube: [EELS tutorial](https://www.youtube.com/watch?v=QIcw_DGSy3s). + +## Writing tests for an EIP + +In addition to a reference implementation, it is very useful for the community and for core development if the EIP author conceives and writes test vectors for the EIP. Tests live in this repository under `./tests/` and use a user-friendly Python test-writing framework. See [Writing Tests](../writing_tests/index.md) for a guide. diff --git a/docs/specs/index.md b/docs/specs/index.md new file mode 100644 index 00000000000..bbe3555553c --- /dev/null +++ b/docs/specs/index.md @@ -0,0 +1,60 @@ +# Specifications + +The Ethereum Execution Layer Specifications (EELS) are an executable Python reference implementation of Ethereum's execution layer. They serve as a source of truth for client developers, EIP authors, researchers, and anyone else trying to understand how an Ethereum execution node actually processes a block. + +Unlike a traditional prose specification, EELS is expressed as Python code. It can be executed, it can be imported, it can be tested, and it can be stepped through in a debugger. When the protocol changes, the change lands in EELS first and can be studied by client teams. + +## Client Diversity requires Coordination + +Ethereum runs on at least half a dozen independent execution clients (Geth, Nethermind, Besu, Erigon, Reth, ...). This diversity is a [feature, not an accident](https://ethereum.org/developers/docs/nodes-and-clients/client-diversity/): a flaw in any one client is contained, no single team holds the keys to the network, and permissionless participation is preserved. The price of that resilience is coordination: every client must agree, byte for byte, on every state transition, or the chain splits. + +For most of Ethereum's history the only "specification" was the Yellow Paper, a LaTeX document of dense mathematical notation, supplemented by individual EIPs and by the behavior of the reference clients themselves. Human language is ambiguous, and even mathematical notation leaves room for interpretation. + +Python offers a different contract. A Python function does not leave room for interpretation: either it returns the same value for the same input or it does not. By writing the specification as a program, every edge case is forced into the open, and every client team has a concrete reference to compare against. + +## Why Python + +Python is not the fastest language: EELS trades performance for readability, because the spec's job is to be understood, not to run fast. Production clients in Go, Rust, and C++ handle the performance; the spec's job is to describe what those clients are supposed to do. + +Python was chosen because: + +- It reads close to pseudocode, so readers who are not Python programmers can still follow it. +- It has a mature testing ecosystem (`pytest`, `hypothesis`, ...), which lets the spec be validated the same way any other library is validated. +- It is widely known among protocol researchers, making it approachable for new EIP authors. + +EELS is a "spiritual successor to the Yellow Paper" that trades dense notation for code a reader can step through. + +## Design principles + +EELS aims to be: + +1. **Correct.** The spec describes the *intended* behaviour of Ethereum. Any deviation is a bug. +2. **Complete.** Every consensus-critical behaviour is captured. If it affects state, it belongs in EELS. +3. **Accessible.** Readability, clarity, and plain language win over cleverness, performance, and brevity. + +The third principle is where EELS departs most sharply from production code. In a production client you minimise duplication (DRY, "don't repeat yourself"), because duplicated logic is expensive to maintain. In EELS you deliberately repeat yourself ("write everything twice", WET), because duplication is easier to read than a network of abstractions. A reader should be able to open a single fork's `state_transition` and follow it top to bottom without jumping files. + +## The fork-as-a-copy model + +Each hardfork under `src/ethereum/forks/` is a **complete copy** of the previous fork's code, edited in place. There is no shared base class, no feature-flag plumbing, no framework. When a reader wants to know what changed between, say, Cancun and Prague, they read the diff between `src/ethereum/forks/cancun/` and `src/ethereum/forks/prague/`. + +This has two concrete benefits: + +- Every fork is self-contained. Paris is Paris, forever; nothing a future fork does can change it. +- Changes are reviewable as diffs. The cost of an EIP, in terms of spec surface area, is immediately visible. + +The trade-off is that a bug fix that applies to every fork must be applied to every fork, by hand or with the patch tool. That cost is paid deliberately. + +## Where to go from here + +- [Writing Specs](writing_specs.md): style rules, cross-fork discipline, and the `ethereum_spec_tools` CLI utilities. +- [Adding a New EIP](adding_a_new_eip.md): the EIP lifecycle from pre-draft to final, and how to land a new EIP in EELS. +- [Spec Releases](spec_releases.md): how EELS versions relate to Ethereum hardforks and devnets. +- [Protocol History](protocol_history.md): the full table of mainnet hardforks, their included EIPs, and their fork manifests. +- [Rendered specification](https://ethereum.github.io/execution-specs/): the `docc`-rendered narrative view of the Python spec, with side-by-side diffs between forks. + +!!! bug "Reporting a vulnerability" + Care is required when filing issues or PRs for functionality that is live on Ethereum mainnet. Please report vulnerabilities and verify bounty eligibility via the [bug bounty program](https://bounty.ethereum.org). + + - **Please do not create a PR with a vulnerability visible.** + - **Please do not file a public ticket mentioning the vulnerability.** diff --git a/docs/specs/protocol_history.md b/docs/specs/protocol_history.md new file mode 100644 index 00000000000..f77b3a3bd98 --- /dev/null +++ b/docs/specs/protocol_history.md @@ -0,0 +1,67 @@ +# Protocol History + +The table below lists every mainnet Ethereum hardfork, its activation point, the EIPs it introduced, a link to its fork manifest in EELS, and the Ethereum Foundation announcement blog post. + +## Mainnet hardforks + +| Version and Code Name | Block No. | Released | Incl EIPs | Fork Specifications | Blog | +|-----------------------|-----------|----------|-----------|-------|-------| +| Osaka | 23935694 | 2025-12-03 | [EIP-7594]
[EIP-7642]
[EIP-7823]
[EIP-7825]
[EIP-7883]
[EIP-7892]
[EIP-7910]
[EIP-7917]
[EIP-7918]
[EIP-7934]
[EIP-7935]
[EIP-7939]
[EIP-7951] | [Hardfork Meta EIP-7607](https://eips.ethereum.org/EIPS/eip-7607)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/osaka/__init__.py) | [Blog](https://blog.ethereum.org/2025/11/06/fusaka-mainnet-announcement) | +| Prague | 22431084 | 2025-05-07 | [EIP-2537]
[EIP-2935]
[EIP-6110]
[EIP-7002]
[EIP-7251]
[EIP-7549]
[EIP-7623]
[EIP-7685]
[EIP-7691]
[EIP-7702] | [Hardfork Meta EIP-7600](https://eips.ethereum.org/EIPS/eip-7600)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/prague/__init__.py) | [Blog](https://blog.ethereum.org/2025/04/23/pectra-mainnet) | +| Cancun | 19426587 | 2024-03-13
(1710338135) | [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)
[EIP-4788](https://eips.ethereum.org/EIPS/eip-4788)
[EIP-4844](https://eips.ethereum.org/EIPS/eip-4844)
[EIP-5656](https://eips.ethereum.org/EIPS/eip-5656)
[EIP-6780](https://eips.ethereum.org/EIPS/eip-6780)
[EIP-7044](https://eips.ethereum.org/EIPS/eip-7044)
[EIP-7045](https://eips.ethereum.org/EIPS/eip-7045)
[EIP-7514](https://eips.ethereum.org/EIPS/eip-7514)
[EIP-7516](https://eips.ethereum.org/EIPS/eip-7516)| [Hardfork Meta EIP-7569](https://eips.ethereum.org/EIPS/eip-7569)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/cancun/__init__.py) | [Blog](https://blog.ethereum.org/2024/02/27/dencun-mainnet-announcement) | +| Shanghai | 17034870 | 2023-04-12
(1681338455) | [EIP-3651](https://eips.ethereum.org/EIPS/eip-3651)
[EIP-3855](https://eips.ethereum.org/EIPS/eip-3855)
[EIP-3860](https://eips.ethereum.org/EIPS/eip-3860)
[EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/shanghai/__init__.py) | [Blog](https://blog.ethereum.org/2023/03/28/shapella-mainnet-announcement) | +| Paris | 15537394 | 2022-09-15 | [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675)
[EIP-4399](https://eips.ethereum.org/EIPS/eip-4399) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/paris/__init__.py) | [Blog](https://blog.ethereum.org/2022/08/24/mainnet-merge-announcement) | +| Gray Glacier | 15050000 | 2022-06-30 | [EIP-5133](https://eips.ethereum.org/EIPS/eip-5133) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/gray_glacier/__init__.py) | [Blog](https://blog.ethereum.org/2022/06/16/gray-glacier-announcement/) | +| Arrow Glacier | 13773000 | 2021-12-09 | [EIP-4345](https://eips.ethereum.org/EIPS/eip-4345) | [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/arrow_glacier/__init__.py) | [Blog](https://blog.ethereum.org/2021/11/10/arrow-glacier-announcement/) | +| London | 12965000 | 2021-08-05 | [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
[EIP-3198](https://eips.ethereum.org/EIPS/eip-3198)
[EIP-3529](https://eips.ethereum.org/EIPS/eip-3529)
[EIP-3541](https://eips.ethereum.org/EIPS/eip-3541)
[EIP-3554](https://eips.ethereum.org/EIPS/eip-3554)| [(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/london/__init__.py) | [Blog](https://blog.ethereum.org/2021/07/15/london-mainnet-announcement/) | +| Berlin | 12244000 | 2021-04-15 | [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565)
[EIP-2929](https://eips.ethereum.org/EIPS/eip-2929)
[EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
[EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) | ~[Hardfork Meta EIP-2070](https://eips.ethereum.org/EIPS/eip-2070)~
[(Backfill) Meta EIP-7568](https://eips.ethereum.org/EIPS/eip-7568)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/berlin/__init__.py) | [Blog](https://blog.ethereum.org/2021/03/08/ethereum-berlin-upgrade-announcement/) | +| Muir Glacier | 9200000 | 2020-01-02 | [EIP-2384](https://eips.ethereum.org/EIPS/eip-2384) | [Hardfork Meta EIP-2387](https://eips.ethereum.org/EIPS/eip-2387)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/muir_glacier/__init__.py) | [Blog](https://blog.ethereum.org/2019/12/23/ethereum-muir-glacier-upgrade-announcement/) | +| Istanbul | 9069000 | 2019-12-07 | [EIP-152](https://eips.ethereum.org/EIPS/eip-152)
[EIP-1108](https://eips.ethereum.org/EIPS/eip-1108)
[EIP-1344](https://eips.ethereum.org/EIPS/eip-1344)
[EIP-1884](https://eips.ethereum.org/EIPS/eip-1884)
[EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)
[EIP-2200](https://eips.ethereum.org/EIPS/eip-2200) | [Hardfork Meta EIP-1679](https://eips.ethereum.org/EIPS/eip-1679)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/istanbul/__init__.py) | [Blog](https://blog.ethereum.org/2019/11/20/ethereum-istanbul-upgrade-announcement/) | +| Petersburg | 7280000 | 2019-02-28 | [EIP-145](https://eips.ethereum.org/EIPS/eip-145)
[EIP-1014](https://eips.ethereum.org/EIPS/eip-1014)
[EIP-1052](https://eips.ethereum.org/EIPS/eip-1052)
[EIP-1234](https://eips.ethereum.org/EIPS/eip-1234) | [Hardfork Meta EIP-1716](https://eips.ethereum.org/EIPS/eip-1716) | [Blog](https://blog.ethereum.org/2019/02/22/ethereum-constantinople-st-petersburg-upgrade-announcement/) | +| Constantinople | 7280000 | 2019-02-28 | [EIP-145](https://eips.ethereum.org/EIPS/eip-145)
[EIP-1014](https://eips.ethereum.org/EIPS/eip-1014)
[EIP-1052](https://eips.ethereum.org/EIPS/eip-1052)
[EIP-1234](https://eips.ethereum.org/EIPS/eip-1234)
[EIP-1283](https://eips.ethereum.org/EIPS/eip-1283) | [Hardfork Meta EIP-1013](https://eips.ethereum.org/EIPS/eip-1013)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/constantinople/__init__.py) | [Blog](https://blog.ethereum.org/2019/02/22/ethereum-constantinople-st-petersburg-upgrade-announcement/) | +| Byzantium | 4370000 | 2017-10-16 | [EIP-100](https://eips.ethereum.org/EIPS/eip-100)
[EIP-140](https://eips.ethereum.org/EIPS/eip-140)
[EIP-196](https://eips.ethereum.org/EIPS/eip-196)
[EIP-197](https://eips.ethereum.org/EIPS/eip-197)
[EIP-198](https://eips.ethereum.org/EIPS/eip-198)
[EIP-211](https://eips.ethereum.org/EIPS/eip-211)
[EIP-214](https://eips.ethereum.org/EIPS/eip-214)
[EIP-649](https://eips.ethereum.org/EIPS/eip-649)
[EIP-658](https://eips.ethereum.org/EIPS/eip-658) | [Hardfork Meta EIP-609](https://eips.ethereum.org/EIPS/eip-609)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/byzantium/__init__.py) | [Blog](https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/) | +| Spurious Dragon | 2675000 | 2016-11-22 | [EIP-155](https://eips.ethereum.org/EIPS/eip-155)
[EIP-160](https://eips.ethereum.org/EIPS/eip-160)
[EIP-161](https://eips.ethereum.org/EIPS/eip-161)
[EIP-170](https://eips.ethereum.org/EIPS/eip-170) | [Hardfork Meta EIP-607](https://eips.ethereum.org/EIPS/eip-607)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/spurious_dragon/__init__.py) | [Blog](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) | +| Tangerine Whistle | 2463000 | 2016-10-18 | [EIP-150](https://eips.ethereum.org/EIPS/eip-150) | [Hardfork Meta EIP-608](https://eips.ethereum.org/EIPS/eip-608)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/tangerine_whistle/__init__.py) | [Blog](https://blog.ethereum.org/2016/10/13/announcement-imminent-hard-fork-eip150-gas-cost-changes/) | +| DAO Fork | 1920000 | 2016-07-20 | | [Hardfork Meta EIP-779](https://eips.ethereum.org/EIPS/eip-779)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/dao_fork/__init__.py) | [Blog](https://blog.ethereum.org/2016/07/15/to-fork-or-not-to-fork/) | +| DAO Wars | aborted | aborted | | | [Blog](https://blog.ethereum.org/2016/06/24/dao-wars-youre-voice-soft-fork-dilemma/) | +| Homestead | 1150000 | 2016-03-14 | [EIP-2](https://eips.ethereum.org/EIPS/eip-2)
[EIP-7](https://eips.ethereum.org/EIPS/eip-7)
[EIP-8](https://eips.ethereum.org/EIPS/eip-8) | [Hardfork Meta EIP-606](https://eips.ethereum.org/EIPS/eip-606)
[Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/homestead/__init__.py) | [Blog](https://blog.ethereum.org/2016/02/29/homestead-release/) | +| Frontier Thawing | 200000 | 2015-09-07 | | | [Blog](https://blog.ethereum.org/2015/08/04/the-thawing-frontier/) | +| Frontier | 1 | 2015-07-30 | | [Fork Manifest](https://github.com/ethereum/execution-specs/blob/forks/amsterdam/src/ethereum/forks/frontier/__init__.py) | [Blog](https://blog.ethereum.org/2015/07/22/frontier-is-coming-what-to-expect-and-how-to-prepare/) | + +!!! note "Activation mechanism" + Starting with Paris, updates are no longer rolled out based on block numbers. Paris was enabled once proof-of-work Total Difficulty reached `58750000000000000000000`. As of Shanghai (at `1681338455`), upgrade activation is based on timestamps. + +[EIP-2537]: https://eips.ethereum.org/EIPS/eip-2537 +[EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935 +[EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110 +[EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002 +[EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251 +[EIP-7549]: https://eips.ethereum.org/EIPS/eip-7549 +[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623 +[EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 +[EIP-7691]: https://eips.ethereum.org/EIPS/eip-7691 +[EIP-7702]: https://eips.ethereum.org/EIPS/eip-7702 +[EIP-7594]: https://eips.ethereum.org/EIPS/eip-7594 +[EIP-7642]: https://eips.ethereum.org/EIPS/eip-7642 +[EIP-7823]: https://eips.ethereum.org/EIPS/eip-7823 +[EIP-7825]: https://eips.ethereum.org/EIPS/eip-7825 +[EIP-7883]: https://eips.ethereum.org/EIPS/eip-7883 +[EIP-7892]: https://eips.ethereum.org/EIPS/eip-7892 +[EIP-7910]: https://eips.ethereum.org/EIPS/eip-7910 +[EIP-7917]: https://eips.ethereum.org/EIPS/eip-7917 +[EIP-7918]: https://eips.ethereum.org/EIPS/eip-7918 +[EIP-7934]: https://eips.ethereum.org/EIPS/eip-7934 +[EIP-7935]: https://eips.ethereum.org/EIPS/eip-7935 +[EIP-7939]: https://eips.ethereum.org/EIPS/eip-7939 +[EIP-7951]: https://eips.ethereum.org/EIPS/eip-7951 + +## Clarifications without a protocol release + +Some clarifications were enabled without protocol releases: + +| EIP | Block No. | +|-----|-----------| +| [EIP-2681](https://eips.ethereum.org/EIPS/eip-2681) | 0 | +| [EIP-3607](https://eips.ethereum.org/EIPS/eip-3607) | 0 | +| [EIP-7523](https://eips.ethereum.org/EIPS/eip-7523) | 15537394 | +| [EIP-7610](https://eips.ethereum.org/EIPS/eip-7610) | 0 | diff --git a/RELEASING.md b/docs/specs/spec_releases.md similarity index 58% rename from RELEASING.md rename to docs/specs/spec_releases.md index 42ed198ea2d..ce88729f4cd 100644 --- a/RELEASING.md +++ b/docs/specs/spec_releases.md @@ -1,17 +1,17 @@ -# Execution Specification Releases +# Spec Releases -## About Versions +EELS is published as a versioned Python package. This page explains how the version number is structured and how it relates to Ethereum hardforks and devnets. For the maintainer runbook (tagging, publishing to PyPI), see [Releasing](../dev/releasing.md). -EELS' versioning scheme is intended to be compatible with Python's -[Version Specifiers], and is not compatible with [SemVer] (although it does -borrow some of SemVer's concepts.) +## About versions + +EELS' versioning scheme is intended to be compatible with Python's [Version Specifiers], and is *not* compatible with [SemVer] (although it borrows some of SemVer's concepts). [Version Specifiers]: https://packaging.python.org/en/latest/specifications/version-specifiers/ [SemVer]: https://semver.org/ ### Format -The general format of EELS version numbers is as follows: +The general format of EELS version numbers is: ```text COMPAT "." HARDFORK ( "." PATCH | ".0rc" DEVNET [ ".post" PATCH ] ) [ ".dev" DEV ] @@ -19,7 +19,7 @@ COMPAT "." HARDFORK ( "." PATCH | ".0rc" DEVNET [ ".post" PATCH ] ) [ ".dev" DEV Where: -- `COMPAT` is incremented when a release contains a backwards-incompatible change to an EELS' interface (Python API, command line tools, etc.) +- `COMPAT` is incremented when a release contains a backwards-incompatible change to an EELS interface (Python API, command-line tools, etc.). - `HARDFORK` is the number of hardforks included in the release after Frontier. - `DEVNET`, if present, is incremented when a release targets a new devnet. - `DEV`, if present, indicates a pre-release preview and is incremented for each pre-release before the final release. @@ -27,7 +27,7 @@ Where: ### Examples -The following table is a hypothetical complete example of all of the releases between `1.15.0rc1.dev1` and `2.16.0`, in order from oldest at the top to the newest at the bottom. +The following table is a hypothetical complete example of all of the releases between `1.15.0rc1.dev1` and `2.16.0`, oldest at the top: | Fork | Description | Version Number | | ------ | ------------------ | ----------------- | @@ -55,23 +55,9 @@ The following table is a hypothetical complete example of all of the releases be | | | | | prague | finalize mainnet | `2.16.0` | -## Creating a Release - -### Overview - -1. Choose a version number. -1. Update version in source code. -1. Create a pull request. -1. Wait for it to get merged. -1. Create a tag. -1. Create GitHub release. -1. Publish to PyPI. +## Choosing a version number -### Choosing a Version Number - -To choose the next version number, find the format matching the current version -number in the table below, then choose the new version according to the reason -for the new release. +When proposing a new release, find the format matching the current version number in the table below, then choose the new version according to the reason for the new release: | Current Version | Action | New Version | | ------------------------- | -------------------- | ---------------------- | @@ -105,87 +91,7 @@ for the new release. | | Devnet Release | `1.3.0rc5.post7` | | | Another Preview | `1.3.0rc5.post7.dev10` | -> [!NOTE] -> Append `.dev1` to any new version number to make it a pre-release, unless it -> already contained a `.devN` suffix. If it did, increment `N` to make another -> pre-release instead. - -### Updating Version in Source Code - -The version number is set in `src/ethereum/__init__.py`. Change it there. For -example: - -```patch -diff --git a/src/ethereum/__init__.py b/src/ethereum/__init__.py -index 252f2f317..8cdd89a55 100644 ---- a/src/ethereum/__init__.py -+++ b/src/ethereum/__init__.py -@@ -18,7 +18,7 @@ possible, to aid in defining the behavior of Ethereum clients. - """ - import sys - --__version__ = "1.15.0" -+__version__ = "1.16.0rc1" - - # - # Ensure we can reach 1024 frames of recursion -``` - -### Creating the Pull Request - -The usual. `git checkout -b release-vX.Y.Z`, `git commit -a`, and `git push`. - -### Waiting - -```text - ______________________________________ -/ Just because the message may never be \\ -| received does not mean it is not worth | -\\ sending. / - -------------------------------------- - \ ^__^ - \ (oo)\_______ - (__)\ )\/\\ - ||----w | - || || -``` - -### Creating the Tag - -> [!WARNING] -> Do not create the tag from the `HEAD` branch of the pull request. -> -> GitHub can rewrite commits when merging pull requests, and tagging the -> original commit will make the git history messier than necessary. - -The tag name should be the letter `v` followed by the version number (eg. -`1.15.0rc5.post3` becomes `v1.15.0rc5.post3`.) - -To create and push the tag: - -```bash -git checkout master # Replace `master` with the pull request's base branch. -git pull -git tag -a -s v1.15.0 # Replace `v1.15.0` with the tag name from earlier. -git push origin v1.15.0 # Replace the tag name here too. -``` - -> [!IMPORTANT] -> If `git tag` complains about a missing GPG/PGP key, follow -> [this guide][keygen] to generate one. It's best to add the key to your GitHub -> account as well. - -[keygen]: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key - -### Creating the GitHub Release - -Go to the [release page][release], choose the newly created tag, and generate some release -notes. - -[release]: https://github.com/ethereum/execution-specs/releases/new - -### Publishing to PyPI - -See the [Python Packaging User Guide][ppug] +!!! note + Append `.dev1` to any new version number to make it a pre-release, unless it already contained a `.devN` suffix. If it did, increment `N` to make another pre-release instead. -[ppug]: https://packaging.python.org/en/latest/tutorials/packaging-projects/#generating-distribution-archives +The version number is stored in `src/ethereum/__init__.py`. diff --git a/docs/specs/writing_specs.md b/docs/specs/writing_specs.md index bf1a7b46a03..462dbcd5189 100644 --- a/docs/specs/writing_specs.md +++ b/docs/specs/writing_specs.md @@ -1,4 +1,214 @@ # Writing Specs -!!! note "Coming soon" - This section is under construction. In the meantime, see the [EIP Authors Manual](https://github.com/ethereum/execution-specs/blob/a48e0b381d5225a6c3de2d06cd9ee7ae0b6ca9bb/EIP_AUTHORS_MANUAL.md) for guidance on adding a new EIP to the reference specifications. +This page collects the style rules, cross-fork discipline, and CLI utilities you need when writing or modifying code under `src/ethereum/`. + +The overarching goal is readability: anyone reading a fork from top to bottom should be able to follow what Ethereum does for a given block, without jumping between files or untangling abstractions. EELS deliberately prefers repeated code (WET: "write everything twice") over clever reuse (DRY), because duplication is easier to read than a network of abstractions. + +## Style + +### Spelling and naming + +- Prefer descriptive English words (or *very common* abbreviations) in documentation and identifiers. +- Avoid EIP numbers in identifiers; prefer descriptive text (e.g. `FeeMarketTransaction` over `Eip1559Transaction`). +- Avoid uninformative prefixes in identifiers (like `get_` or `compute_`). They don't add useful meaning and take up valuable real estate. +- If a term is specific to the domain, there is a custom spell-check dictionary at `whitelist.txt`. + +### Comments + +- Don't repeat what is obvious from the code. +- Don't attribute semantic blocks to a specific EIP in a leading comment, because future EIPs can land between your first and last lines and silently inherit the attribution. Instead, describe the change in the function's docstring. + +
+(expand) Why EIP-attributed comments rot. + +
Consider: + + + + + + + + + + + + + + + +
Fork TFork T+1
+ + + +```python +# EIP-1234: The dingus is the rate of fleep +dingus = a + b +dingus += c ^ d +dingus /= fleep(e) +``` + + + +```python +# EIP-1234: The dingus is the rate of fleep +dingus = a + b + +# EIP-4567: Frobulate the dingus +dingus = frobulate(dingus) + +dingus += c ^ d # <- +dingus /= fleep(e) # <- +``` + +
+ +The marked lines (`<-`) are now incorrectly attributed to EIP-4567 in Fork+1. Instead, omit the EIP identifier in comments and describe changes introduced by the EIP in the function's docstring. The rendered diffs will make it pretty obvious what's changed. + +
+ +### Docstrings + +- Write in complete sentences, providing necessary background and context for the associated code. +- Function and method docstrings must use the imperative mood in the summary line. + - **Good:** Build the house using the provided lumber. + - **Bad:** Builds the house using the provided lumber. +- Always start with a single-line summary. When more detail is needed, use a multi-line docstring with a blank line after the summary line. + - **One-line summary:** + + ```python + """Return the pathname of the KOS root directory.""" + ``` + + - **Multi-line:** + + ```python + """ + Add a bloom entry to the bloom filter. + + The number of hash functions used is 3. They are calculated by + taking the least significant 11 bits from the first 3 16-bit + words of the `keccak_256()` hash of `bloom_entry`. + """ + ``` + +- Format using markdown. +- Links to relevant standards and EIPs may be specified using reference-style links. + + ```python + """ + Minimum gas cost per byte of calldata as per [EIP-7976]. + + [EIP-7976]: https://eips.ethereum.org/EIPS/eip-7976 + """ + ``` + +- Avoid beginning docstrings with an article ("the"/"a") or a pronoun ("it", "they", etc.). +- Don't include the function's signature. + +### Constants + +- Do not include constant values in docstrings, neither as literals nor as expressions. It's too easy to change a constant's value and forget to update its docstring. +- Construct the constant's value from other constants or meaningful expressions in order to provide meaningful context. + - **Great:** `TARGET_BLOB_GAS_PER_BLOCK = GAS_PER_BLOB * BLOB_SCHEDULE_TARGET` + - Composed from named constants; the reader immediately understands what the value represents. + - **Acceptable:** `TX_MAX_GAS = Uint(2 ** 24)` + - More readable than a raw number, but still a literal expression that doesn't convey *why* this value was chosen. + - **Bad:** `TX_MAX_GAS = Uint(16_777_216)` + - A magic number with no context. + +## Changes across multiple forks + +Many contributions require changes across multiple forks, organized under `src/ethereum/forks/`. When making such changes, ensure that differences between the forks are minimal and consist only of necessary differences. This produces cleaner [diff outputs](https://ethereum.github.io/execution-specs/diffs/index.html). + +When creating pull requests affecting multiple forks, we recommend submitting your PR in two steps: + +1. Apply the changes on a single fork, open a *draft* pull request, and get feedback. +2. Apply the changes across the other forks, push them, and mark the pull request as ready for review. + +This saves you having to apply code review feedback repeatedly for each fork. + +## CLI utilities: `ethereum_spec_tools` + +The repository ships with CLI utilities that help during spec development. + +### New Fork Tool + +This tool creates the base code for a new fork by copying the existing code from a given fork. + +The command takes 4 arguments (2 optional): + +- `from_fork`: The fork name from which the code is to be duplicated. Example: `"Tangerine Whistle"`. +- `to_fork`: The fork name of the new fork. Example: `"Spurious Dragon"`. +- `from_test` (optional): Name of the from-fork within the test fixtures in case it is different from fork name. Example: `"EIP150"`. +- `to_test` (optional): Name of the to-fork within the test fixtures in case it is different from the fork name. Example: `"EIP158"`. + +For example, to create baseline code for `Spurious Dragon` from `Tangerine Whistle`: + +```bash +uv run ethereum-spec-new-fork --from_fork="Tangerine Whistle" --to_fork="Spurious Dragon" --from_test=EIP150 --to_test=EIP158 +``` + +The following must be updated manually afterwards: + +1. The fork number and `MAINNET_FORK_BLOCK` in `__init__.py`. If you are proposing a new EIP, set `MAINNET_FORK_BLOCK` to `None`. +2. Any absolute package imports from other forks, e.g. in `trie.py`. +3. Package names under `setup.cfg`. +4. Add the new fork to the `monkey_patch()` function in `src/ethereum_optimized/__init__.py`. +5. Adjust the underline in `fork/__init__.py`. + +### Sync Tool + +The sync tool uses an RPC provider to fetch and validate blocks against EELS. The validated state can be stored in a local DB. Because syncing directly with the specs is very slow, the sync tool can also leverage the `ethereum_optimized` module, which contains alternative implementations of routines in EELS optimized for speed rather than clarity/readability. + +Invoke the tool with `ethereum-spec-sync`. Arguments: + +- `rpc-url`: Endpoint providing the Ethereum RPC API. Defaults to `http://localhost:8545/`. +- `unoptimized`: Don't use the optimized state/ethash (this can be extremely slow). +- `persist`: Store state in a database at this file path. +- `geth`: Use geth-specific RPC endpoints while fetching blocks. +- `reset`: Delete the database and start from scratch. +- `gas-per-commit`: Commit to database each time this much gas has been consumed. Defaults to `1_000_000_000`. +- `initial-state`: Start from the state in this database rather than genesis. +- `stop-at`: After syncing this block, exit successfully. + +Option compatibility: + +- The following options are *not* supported *with* `--unoptimized`: `--persist`, `--initial-state`, `--reset`. +- The following options are *not* supported *without* `--persist`: `--initial_state`, `--reset`. + +### Patch Tool + +This tool applies the unstaged changes in `SOURCE_FORK` to each of `TARGET_FORKS`. If some of the changes fail to apply, `.rej` files listing the unapplied hunks are left in the target fork. + +Positional and flag arguments: + +- Source fork (single value). For example: `frontier`. +- Target forks (one or more values). For example: `homestead`. +- `optimized`: Patch the optimized code instead. +- `tests`: Patch the tests instead. + +Example: apply changes made in `Frontier` to `Homestead` and `Tangerine Whistle`: + +```bash +uv run python src/ethereum_spec_tools/patch_tool.py frontier homestead tangerine_whistle +``` + +### Lint Tool + +The spec lint tool checks for style and formatting issues specific to EELS and emits diagnostics when issues are found. Currently it verifies: + +- The order of identifiers between each hardfork is consistent. +- Import statements follow the relevant import rules in modules. + +Run it with `just lint-spec` (or `uv run ethereum-spec-lint`). + +## Debugging with `--evm-trace` + +A trace of the EVM execution for any test case can be obtained by passing the `--evm-trace` argument to pytest. Run it on a small number of tests at a time; the log can otherwise grow very large. + +```bash +uv run pytest \ + 'tests/json_loader/test_state_tests.py::test_state_tests_frontier[stAttackTest - ContractCreationSpam - 0]' \ + --evm_trace +``` From 8a85b5458dabbf068f5155cee7a54782d5d1313e Mon Sep 17 00:00:00 2001 From: danceratopz Date: Wed, 22 Apr 2026 13:44:34 +0100 Subject: [PATCH 036/186] feat(test-fill): enable phase-1-only pre-alloc generation (#2720) * refactor(test-fill): allow phase-1-only pre-alloc generation Re-order `FillCommand.create_executions` so that the execution plan reflects the user's intent: - `--use-pre-alloc-groups` now takes priority. The flag means pre-alloc groups already exist on disk from a previous run, so even alongside `--generate-all-formats` the run is single-phase. - `--generate-pre-alloc-groups` without `--generate-all-formats` now runs phase 1 only; don't continue to phase 2. - `--generate-all-formats` continues to trigger the full two-phase run. Update `test_legacy_generate_pre_alloc_groups_still_works` to reflect the new phase-1-only behaviour and add a test covering the `--use-pre-alloc-groups` priority. * test(test-fill): cover contradictory `--use-pre-alloc-groups` flag pairs Add failing tests asserting that `FillCommand.create_executions` raises `click.UsageError` when `--use-pre-alloc-groups` is combined with: - `--generate-pre-alloc-groups`: the first asserts the groups already exist on disk, the second regenerates them: contradictory intents. - `--clean`: `--clean` wipes the output directory that holds the pre-alloc groups the user is asserting exist. Without a guard, `FillCommand.create_executions` silently returns a single-phase plan and `FillingSession._load_pre_alloc_groups_from_folder` then fails on a missing folder. Validation logic follows in the next commit. * fix(test-fill): reject contradictory `--use-pre-alloc-groups` flag pairs Add `_validate_flag_combinations` to `FillCommand.create_executions` so contradictory flag pairs fail fast with `click.UsageError` instead of silently falling through to a broken single-phase execution. Rejected combinations: - `--use-pre-alloc-groups` + `--generate-pre-alloc-groups`: the first asserts the groups already exist, the second regenerates them. - `--use-pre-alloc-groups` + `--clean`: `--clean` wipes the output directory that holds the pre-alloc groups. `--use-pre-alloc-groups` + `--generate-all-formats` remains valid and single-phase, per the intent stated in 116e5093e83. * refactor(tooling): restore `bench-gas` two-phase fill Swap `--generate-pre-alloc-groups` for `--generate-all-formats` in the `bench-gas` recipe. After 116e5093e83, `--generate-pre-alloc-groups` alone runs phase 1 only and produces no benchmark fixtures; the recipe needs the full two-phase run to generate the `BlockchainEngineXFixture` output it targets. Matches the flag used in `.github/configs/feature.yaml`. * doc(test-fill): refresh pre-alloc flag docs Update documentation to reflect the phase-1-only behaviour of `--generate-pre-alloc-groups` introduced in 116e5093e83: - Remove the "Alternative approach" note in `filling_tests_command_line.md` that recommended `--generate-pre-alloc-groups` as a single-command replacement for `--generate-all-formats`: it now produces no fixtures. - Reframe the `blockchain_test_engine_x.md` usage notes to describe the two-invocation workflow (`--generate-pre-alloc-groups` then `--use-pre-alloc-groups`) as the explicit alternative to the single-command `--generate-all-formats` path. --- Justfile | 2 +- .../filling_tests_command_line.md | 8 -- .../test_formats/blockchain_test_engine_x.md | 2 +- .../cli/pytest_commands/fill.py | 109 +++++++++++------- .../cli/tests/test_generate_all_formats.py | 76 ++++++++++-- 5 files changed, 136 insertions(+), 61 deletions(-) diff --git a/Justfile b/Justfile index e7aa4247c5e..a35d190600e 100644 --- a/Justfile +++ b/Justfile @@ -220,7 +220,7 @@ bench-gas *args: uv run fill \ --evm-bin="{{ evm_bin }}" \ --gas-benchmark-values 1 \ - --generate-pre-alloc-groups \ + --generate-all-formats \ --fork Osaka \ -m "not slow" \ -n auto --maxprocesses 10 --dist=loadgroup \ diff --git a/docs/filling_tests/filling_tests_command_line.md b/docs/filling_tests/filling_tests_command_line.md index b4aae3cc727..599c93dc1d0 100644 --- a/docs/filling_tests/filling_tests_command_line.md +++ b/docs/filling_tests/filling_tests_command_line.md @@ -107,14 +107,6 @@ This flag automatically performs a two-phase execution: uv run fill --generate-all-formats --output=fixtures.tar.gz tests/shanghai/ ``` -!!! note "Alternative approach" - You can still use the legacy approach, but this will only generate the `BlockchainEngineXFixture` format: - ```console - # Single command that automatically does 2-phase execution - # but only generates BlockchainEngineXFixture - uv run fill --generate-pre-alloc-groups tests/shanghai/ - ``` - ## Debugging the `t8n` Command The `--evm-dump-dir` flag can be used to dump the inputs and outputs of every call made to the `t8n` command for debugging purposes, see [Debugging Transition Tools](./debugging_t8n_tools.md). diff --git a/docs/running_tests/test_formats/blockchain_test_engine_x.md b/docs/running_tests/test_formats/blockchain_test_engine_x.md index c9dc90a4caf..5087655e3b2 100644 --- a/docs/running_tests/test_formats/blockchain_test_engine_x.md +++ b/docs/running_tests/test_formats/blockchain_test_engine_x.md @@ -139,7 +139,7 @@ Engine API payload structure identical to the one defined in [Blockchain Engine ## Usage Notes - This format is generated when using: - - `--generate-pre-alloc-groups` flag (automatically triggers 2-phase execution, generates only `BlockchainEngineXFixture`) + - `--generate-pre-alloc-groups` followed by `--use-pre-alloc-groups` (two invocations: phase 1 populates the `pre_alloc` folder, phase 2 generates only `BlockchainEngineXFixture`) - `--generate-all-formats` flag (automatically triggers 2-phase execution, generates all fixture formats) - The `pre_alloc` folder is essential and must be distributed with the test fixtures - Tests are grouped by identical (fork + environment + pre-allocation) combinations diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/fill.py b/packages/testing/src/execution_testing/cli/pytest_commands/fill.py index 842935b65b5..fbd513b823d 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/fill.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/fill.py @@ -33,33 +33,81 @@ def create_executions( self, pytest_args: List[str] ) -> List[PytestExecution]: """ - Create execution plan that supports two-phase pre-allocation group + Create execution plan supporting two-phase pre-allocation group generation. - Returns single execution for normal filling, or two-phase execution - when --generate-pre-alloc-groups or --generate-all-formats is - specified. + Returns: + - Phase-1-only execution when `--generate-pre-alloc-groups` is + set without `--generate-all-formats`. + - Single-phase execution when `--use-pre-alloc-groups` is set, + regardless of `--generate-all-formats` (pre-alloc groups + already exist on disk from a previous run). + - Two-phase execution when `--generate-all-formats` is set. + - Normal single-phase execution otherwise. + """ processed_args = self.process_arguments(pytest_args) processed_args = self._add_default_ignores(processed_args) + self._validate_flag_combinations(processed_args) - # Check if we need two-phase execution - if self._should_use_two_phase_execution(processed_args): - return self._create_two_phase_executions(processed_args) - elif "--use-pre-alloc-groups" in processed_args: - # Only phase 2: using existing pre-allocation groups + if "--use-pre-alloc-groups" in processed_args: + # Pre-alloc groups already exist: single-phase fill only. return self._create_single_phase_with_pre_alloc_groups( processed_args ) - else: - # Normal single-phase execution - return [ - PytestExecution( - config_file=self.config_path, - args=processed_args, - allowed_exit_codes=self.allowed_exit_codes, - ) - ] + + has_phase_1_flag = "--generate-pre-alloc-groups" in processed_args + has_phase_2_flag = "--generate-all-formats" in processed_args + + if has_phase_2_flag: + # --generate-all-formats always regenerates pre-alloc as phase 1. + return self._create_two_phase_executions(processed_args) + if has_phase_1_flag: + # Phase 1 only: generate pre-alloc groups without filling. + return [self._create_phase1_only_execution(processed_args)] + + # Normal single-phase execution. + return [ + PytestExecution( + config_file=self.config_path, + args=processed_args, + allowed_exit_codes=self.allowed_exit_codes, + ) + ] + + def _validate_flag_combinations(self, args: List[str]) -> None: + """ + Reject contradictory flag combinations up front so phase 2 never + runs against a missing pre-alloc folder. + """ + if "--use-pre-alloc-groups" not in args: + return + if "--generate-pre-alloc-groups" in args: + raise click.UsageError( + "--use-pre-alloc-groups and --generate-pre-alloc-groups " + "are mutually exclusive: the first asserts the groups " + "already exist on disk, the second regenerates them." + ) + if "--clean" in args: + raise click.UsageError( + "--use-pre-alloc-groups cannot be combined with --clean: " + "--clean wipes the output directory that holds the " + "pre-alloc groups." + ) + + def _create_phase1_only_execution( + self, args: List[str] + ) -> PytestExecution: + """Create a phase-1 execution that generates pre-allocation groups.""" + return PytestExecution( + config_file=self.config_path, + args=self._create_phase1_args(args), + description="generating pre-allocation groups", + allowed_exit_codes=[ + *self.allowed_exit_codes, + pytest.ExitCode.NO_TESTS_COLLECTED, + ], + ) def _create_two_phase_executions( self, args: List[str] @@ -68,25 +116,11 @@ def _create_two_phase_executions( Create two-phase execution: pre-allocation group generation + fixture filling. """ - # Phase 1: Pre-allocation group generation (clean and minimal output) - phase1_args = self._create_phase1_args(args) - - # Phase 2: Main fixture generation (full user options) - phase2_args = self._create_phase2_args(args) - return [ + self._create_phase1_only_execution(args), PytestExecution( config_file=self.config_path, - args=phase1_args, - description="generating pre-allocation groups", - allowed_exit_codes=[ - *self.allowed_exit_codes, - pytest.ExitCode.NO_TESTS_COLLECTED, - ], - ), - PytestExecution( - config_file=self.config_path, - args=phase2_args, + args=self._create_phase2_args(args), description="filling test fixtures", ), ] @@ -195,13 +229,6 @@ def _add_use_pre_alloc_groups_flag(self, args: List[str]) -> List[str]: """Add --use-pre-alloc-groups flag to argument list.""" return args + ["--use-pre-alloc-groups"] - def _should_use_two_phase_execution(self, args: List[str]) -> bool: - """Determine if two-phase execution is needed.""" - return ( - "--generate-pre-alloc-groups" in args - or "--generate-all-formats" in args - ) - def _is_watch_mode(self, args: List[str]) -> bool: """Check if any watch flag is present in arguments.""" return any(flag in args for flag in ["--watch", "--watcherfall"]) diff --git a/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py b/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py index e30e9f15ce9..3db22720ee9 100644 --- a/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py +++ b/packages/testing/src/execution_testing/cli/tests/test_generate_all_formats.py @@ -2,6 +2,9 @@ from unittest.mock import patch +import click +import pytest + from execution_testing.cli.pytest_commands.fill import ( FillCommand, ) @@ -76,26 +79,79 @@ def test_generate_all_formats_removes_clean_from_phase2() -> None: assert "--clean" not in phase2_args -def test_legacy_generate_pre_alloc_groups_still_works() -> None: - """Test that the legacy --generate-pre-alloc-groups flag still works.""" +def test_generate_pre_alloc_groups_alone_is_phase_1_only() -> None: + """ + Test that --generate-pre-alloc-groups without --generate-all-formats + runs phase 1 only, so CI can populate pre-alloc groups on a + dedicated runner without wasting time on phase 2. + """ command = FillCommand() with patch.object(command, "process_arguments", side_effect=lambda x: x): pytest_args = ["--generate-pre-alloc-groups", "tests/somedir/"] executions = command.create_executions(pytest_args) - assert len(executions) == 2 + assert len(executions) == 1 - # Phase 1: Should have --generate-pre-alloc-groups phase1_args = executions[0].args assert "--generate-pre-alloc-groups" in phase1_args + assert "--use-pre-alloc-groups" not in phase1_args + assert "--generate-all-formats" not in phase1_args - # Phase 2: Should have --use-pre-alloc-groups but NOT --generate-all- - # formats - phase2_args = executions[1].args - assert "--use-pre-alloc-groups" in phase2_args - assert "--generate-all-formats" not in phase2_args - assert "--generate-pre-alloc-groups" not in phase2_args + +def test_use_pre_alloc_groups_forces_single_phase() -> None: + """ + Test that --use-pre-alloc-groups always runs a single phase, even + alongside --generate-all-formats (pre-alloc groups already exist on + disk from a previous run). + """ + command = FillCommand() + + with patch.object(command, "process_arguments", side_effect=lambda x: x): + pytest_args = [ + "--use-pre-alloc-groups", + "--generate-all-formats", + "tests/somedir/", + ] + executions = command.create_executions(pytest_args) + + assert len(executions) == 1 + assert "--use-pre-alloc-groups" in executions[0].args + assert "--generate-all-formats" in executions[0].args + + +def test_use_and_generate_pre_alloc_groups_together_is_rejected() -> None: + """ + --use-pre-alloc-groups + --generate-pre-alloc-groups are contradictory: + the first asserts the groups exist, the second regenerates them. + """ + command = FillCommand() + + with patch.object(command, "process_arguments", side_effect=lambda x: x): + pytest_args = [ + "--use-pre-alloc-groups", + "--generate-pre-alloc-groups", + "tests/somedir/", + ] + with pytest.raises(click.UsageError, match="mutually exclusive"): + command.create_executions(pytest_args) + + +def test_use_pre_alloc_groups_with_clean_is_rejected() -> None: + """ + --use-pre-alloc-groups + --clean is contradictory: --clean wipes the + output directory that holds the pre-alloc groups. + """ + command = FillCommand() + + with patch.object(command, "process_arguments", side_effect=lambda x: x): + pytest_args = [ + "--use-pre-alloc-groups", + "--clean", + "tests/somedir/", + ] + with pytest.raises(click.UsageError, match="--clean"): + command.create_executions(pytest_args) def test_single_phase_without_flags() -> None: From 49b882e814a925380c8dd85822a715dd88203f13 Mon Sep 17 00:00:00 2001 From: felipe Date: Wed, 22 Apr 2026 06:48:22 -0600 Subject: [PATCH 037/186] chore(test-types): adds extra modifier validation; adds unit tests (#2710) * chore: adds extra modifier validation; adds unit tests * chore: add a blip about unit testing to the claude test-writing skill * feat: add test that showcases the issue that `found_index` can still be `True` from an earlier call * fix: fix state leak in modifiers; add tests to catch this --------- Co-authored-by: Felix H --- .claude/commands/write-test.md | 4 + .../test_types/block_access_list/modifiers.py | 55 ++++--- .../tests/test_block_access_list_modifiers.py | 151 ++++++++++++++++++ 3 files changed, 188 insertions(+), 22 deletions(-) diff --git a/.claude/commands/write-test.md b/.claude/commands/write-test.md index 018317a7446..cbc8db3b601 100644 --- a/.claude/commands/write-test.md +++ b/.claude/commands/write-test.md @@ -61,6 +61,10 @@ Conventions and patterns for writing consensus tests. Run this skill before writ - `@pytest.mark.parametrize("name", [pytest.param(val, id="label"), ...])` with descriptive `id=` strings - Stack parametrize decorators for multiple dimensions +## Unit Tests (execution_testing package) + +Plain pytest. Tests are co-located with each module under `packages/testing/src/execution_testing/` in a sibling `tests/` directory. When adding a guardrail or validation, verify the tests fail without the change and pass with it. + ## After Writing Tests After writing or modifying tests, ask the user: "Would you like me to load the `/fill-tests` skill to verify the new tests fill correctly? (This loads an additional skill into context.)" If they agree, run `/fill-tests`, fill the new tests, then inspect the generated fixture JSON to verify the fixture contents match what the test intends. diff --git a/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py b/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py index 121ad26d13c..00903266251 100644 --- a/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py +++ b/packages/testing/src/execution_testing/test_types/block_access_list/modifiers.py @@ -28,10 +28,9 @@ def _remove_field_from_accounts( ) -> Callable[[BlockAccessList], BlockAccessList]: """Abstracted helper to remove a field from specified accounts.""" len_addresses = len(addresses) - found_addresses = set() def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal found_addresses + found_addresses: set[Address] = set() new_root = [] for account_change in bal.root: if account_change.address in addresses: @@ -70,10 +69,10 @@ def _modify_field_value( Abstracted helper to modify a field value for a specific account and transaction. """ - found_address = False def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal found_address + found_address = False + found_index = False new_root = [] for account_change in bal.root: if account_change.address == address: @@ -84,8 +83,10 @@ def transform(bal: BlockAccessList) -> BlockAccessList: if changes: if nested and slot is not None: # nested structure (storage) + found_slot = False for storage_slot in changes: if storage_slot.slot == slot: + found_slot = True for j, change in enumerate( storage_slot.slot_changes ): @@ -93,6 +94,7 @@ def transform(bal: BlockAccessList) -> BlockAccessList: change.block_access_index == block_access_index ): + found_index = True kwargs = { "block_access_index": ( block_access_index @@ -104,10 +106,16 @@ def transform(bal: BlockAccessList) -> BlockAccessList: ) break break + if not found_slot: + raise ValueError( + f"Storage slot {slot} not found in " + f"storage_changes of account {address}" + ) else: # flat structure (nonce, balance, code) for i, change in enumerate(changes): if change.block_access_index == block_access_index: + found_index = True kwargs = { "block_access_index": block_access_index, value_field: new_value, @@ -120,10 +128,14 @@ def transform(bal: BlockAccessList) -> BlockAccessList: new_root.append(account_change) if not found_address: - # sanity check that we actually found the address raise ValueError( f"Address {address} not found in BAL to modify {field_name}" ) + if not found_index: + raise ValueError( + f"Block access index {block_access_index} not found in " + f"{field_name} of account {address}" + ) return BlockAccessList(root=new_root) @@ -247,13 +259,12 @@ def swap_bal_indices( idx1: int, idx2: int ) -> Callable[[BlockAccessList], BlockAccessList]: """Swap block access indices throughout the BAL, modifying ordering.""" - nonce_indices = {idx1: False, idx2: False} - balance_indices = nonce_indices.copy() - storage_indices = nonce_indices.copy() - code_indices = nonce_indices.copy() def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal nonce_indices, balance_indices, storage_indices, code_indices + nonce_indices = {idx1: False, idx2: False} + balance_indices = nonce_indices.copy() + storage_indices = nonce_indices.copy() + code_indices = nonce_indices.copy() new_root = [] for account_change in bal.root: new_account = account_change.model_copy(deep=True) @@ -385,10 +396,8 @@ def append_change( else: raise TypeError(f"Unsupported change type: {type(change)}") - found_address = False - def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal found_address + found_address = False new_root = [] for account_change in bal.root: if account_change.address == account: @@ -427,10 +436,9 @@ def append_storage( slot_changes - If change provided and slot new: creates new BalStorageSlot """ - found_address = False def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal found_address + found_address = False new_root = [] for account_change in bal.root: if account_change.address == address: @@ -477,10 +485,9 @@ def duplicate_account( address: Address, ) -> Callable[[BlockAccessList], BlockAccessList]: """Duplicate an account entry in the BAL.""" - address_present = False def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal address_present + address_present = False new_root = [] for account_change in bal.root: new_root.append(account_change) @@ -514,7 +521,6 @@ def _duplicate_in_field( When sub_field and sub_match_fn are provided, find the parent entry via match_fn then duplicate within sub_field using sub_match_fn. """ - found = False def _copy(entry: Any) -> Any: if hasattr(entry, "model_copy"): @@ -522,7 +528,7 @@ def _copy(entry: Any) -> Any: return ZeroPaddedHexNumber(entry) def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal found + found = False new_root = [] for account_change in bal.root: if account_change.address == address: @@ -663,10 +669,9 @@ def insert_storage_read( Useful for testing that a key must not appear in both storage_changes and storage_reads. """ - found_address = False def transform(bal: BlockAccessList) -> BlockAccessList: - nonlocal found_address + found_address = False new_root = [] for account_change in bal.root: if account_change.address == address: @@ -721,8 +726,14 @@ def reorder_accounts( """Reorder accounts according to the provided index list.""" def transform(bal: BlockAccessList) -> BlockAccessList: - if len(indices) != len(bal.root): + n = len(bal.root) + if len(indices) != n: raise ValueError("Index list length must match number of accounts") + if sorted(indices) != list(range(n)): + raise ValueError( + f"Indices must be a valid permutation of 0..{n - 1}, " + f"got {indices}" + ) new_root = [bal.root[i] for i in indices] return BlockAccessList(root=new_root) diff --git a/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_modifiers.py b/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_modifiers.py index 50ca7d9dc83..4ac837be51d 100644 --- a/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_modifiers.py +++ b/packages/testing/src/execution_testing/test_types/tests/test_block_access_list_modifiers.py @@ -1,5 +1,7 @@ """Unit tests for BAL modifier functions.""" +from typing import Callable + import pytest from execution_testing.base_types import Address @@ -13,6 +15,8 @@ BlockAccessList, ) from execution_testing.test_types.block_access_list.modifiers import ( + append_change, + append_storage, duplicate_account, duplicate_balance_change, duplicate_code_change, @@ -21,6 +25,13 @@ duplicate_storage_read, duplicate_storage_slot, insert_storage_read, + modify_balance, + modify_code, + modify_nonce, + modify_storage, + remove_nonces, + reorder_accounts, + swap_bal_indices, ) ALICE = Address(0xA) @@ -217,3 +228,143 @@ def test_insert_storage_read_missing_address_raises() -> None: bal = BlockAccessList([BalAccountChange(address=ALICE, nonce_changes=[])]) with pytest.raises(ValueError, match="not found"): insert_storage_read(CONTRACT, 1)(bal) + + +def test_modify_nonce_missing_index_raises( + sample_bal: BlockAccessList, +) -> None: + """Raise when the block_access_index is absent from nonce_changes.""" + with pytest.raises(ValueError, match="not found"): + modify_nonce(ALICE, 99, 42)(sample_bal) + + +def test_modify_balance_missing_index_raises( + sample_bal: BlockAccessList, +) -> None: + """Raise when the block_access_index is absent from balance_changes.""" + with pytest.raises(ValueError, match="not found"): + modify_balance(ALICE, 99, 9999)(sample_bal) + + +def test_modify_code_missing_index_raises(sample_bal: BlockAccessList) -> None: + """Raise when the block_access_index is absent from code_changes.""" + with pytest.raises(ValueError, match="not found"): + modify_code(ALICE, 99, b"\x00")(sample_bal) + + +def test_modify_storage_missing_index_raises( + sample_bal: BlockAccessList, +) -> None: + """Raise when block_access_index is absent within the storage slot.""" + with pytest.raises(ValueError, match="not found"): + modify_storage(CONTRACT, 99, 1, 0xFF)(sample_bal) + + +def test_modify_storage_missing_slot_raises( + sample_bal: BlockAccessList, +) -> None: + """Raise when the storage slot itself is absent.""" + with pytest.raises(ValueError, match="not found"): + modify_storage(CONTRACT, 1, 99, 0xFF)(sample_bal) + + +def test_modify_nonce_reused_callable_missing_index_still_raises() -> None: + """Raise even when the same modifier callable is reused across BALs.""" + modifier = modify_nonce(ALICE, 1, 42) + valid_bal = BlockAccessList( + [ + BalAccountChange( + address=ALICE, + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1), + ], + ) + ] + ) + missing_index_bal = BlockAccessList( + [ + BalAccountChange( + address=ALICE, + nonce_changes=[], + ) + ] + ) + + modifier(valid_bal) + + with pytest.raises(ValueError, match="not found"): + modifier(missing_index_bal) + + +def test_reorder_accounts_duplicate_index_raises( + sample_bal: BlockAccessList, +) -> None: + """Raise when indices contain duplicates (not a valid permutation).""" + with pytest.raises(ValueError, match="valid permutation"): + reorder_accounts([0, 0])(sample_bal) + + +def test_reorder_accounts_out_of_range_raises( + sample_bal: BlockAccessList, +) -> None: + """Raise when indices are not a valid permutation (skipped index).""" + with pytest.raises(ValueError, match="valid permutation"): + reorder_accounts([0, 2])(sample_bal) + + +_EMPTY_BAL = BlockAccessList([]) +_ALICE_ONLY_BAL = BlockAccessList( + [BalAccountChange(address=ALICE, nonce_changes=[])] +) + + +@pytest.mark.parametrize( + "modifier_factory, missing_bal", + [ + pytest.param( + lambda: remove_nonces(ALICE), _EMPTY_BAL, id="remove_nonces" + ), + pytest.param( + lambda: swap_bal_indices(1, 1), _EMPTY_BAL, id="swap_bal_indices" + ), + pytest.param( + lambda: append_change( + ALICE, BalNonceChange(block_access_index=2, post_nonce=5) + ), + _EMPTY_BAL, + id="append_change", + ), + pytest.param( + lambda: append_storage(CONTRACT, slot=7, read=True), + _EMPTY_BAL, + id="append_storage", + ), + pytest.param( + lambda: duplicate_account(ALICE), + _EMPTY_BAL, + id="duplicate_account", + ), + pytest.param( + lambda: duplicate_nonce_change(ALICE, 1), + _ALICE_ONLY_BAL, + id="duplicate_nonce_change", + ), + pytest.param( + lambda: insert_storage_read(CONTRACT, 99), + _EMPTY_BAL, + id="insert_storage_read", + ), + ], +) +def test_reused_callable_does_not_carry_found_state( + sample_bal: BlockAccessList, + modifier_factory: Callable[ + [], Callable[[BlockAccessList], BlockAccessList] + ], + missing_bal: BlockAccessList, +) -> None: + """A modifier's found-state must not persist across calls.""" + modifier = modifier_factory() + modifier(sample_bal) + with pytest.raises(ValueError, match="not found"): + modifier(missing_bal) From 610d5387ae39a9ffb2690f67841ddccef3c5736c Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Date: Wed, 22 Apr 2026 18:04:04 +0200 Subject: [PATCH 038/186] refactor(specs): make `State` fork agnostic (#2381) * refactor(spec): make Trie fork-agnostic for amsterdam Move all trie logic to a shared `src/ethereum/trie.py`, removing the fork-specific `src/ethereum/forks/amsterdam/trie.py`. Also move trie internal node types (LeafNode, ExtensionNode, BranchNode, InternalNode) from `ethereum.state` into `ethereum.trie`, and trim `ethereum.state` to just account types and the PreState protocol. - New `ethereum/trie.py`: Trie, trie_set/get/copy, root, patricialize, encode_node/account/internal_node, EMPTY_TRIE_ROOT, and node types - `ethereum/state.py`: remove trie node types; import InternalNode from ethereum.trie under TYPE_CHECKING to break the runtime cycle - `amsterdam/trie.py`: deleted; consumers updated to import directly from ethereum.trie - `fork_loader.py`: fall back to ethereum.trie when a fork has no fork-specific trie module * refactor(spec): make State fork-agnostic for amsterdam Move the `State` class and all state helper functions from `ethereum/forks/amsterdam/state.py` into the shared `ethereum/state.py`, making the state implementation fork-agnostic for amsterdam. To break the circular import that would arise between `state.py` and `trie.py`, introduce `ethereum/types.py` as a thin module holding the base account types (`Account`, `Address`, `Root`, `EMPTY_CODE_HASH`, `EMPTY_ACCOUNT`). `trie.py` now imports from `types.py`, allowing `state.py` to import from both `types.py` and `trie.py` without a cycle. `ethereum/state.py` re-exports the base types so that the ~260 existing `from ethereum.state import ...` call sites across all forks require no changes. `fork_loader.py` and `t8n_types.py` are updated to fall back to the shared `ethereum.state` module when the fork-specific `state` module no longer exists. * refactor(tests): fall back to ethereum.state in VmTestLoader Add `_state_module()` helper to `VmTestLoader` that tries the fork-specific state module first and falls back to the shared `ethereum.state` when the fork no longer ships its own `state.py` (e.g. after the fork-agnostic-state refactor). TODO: remove the fallback once the state module is ported over to the older forks. * fix(tests): fix other json_infra tests * fix(docs): fix docs references * refactor(spec): address review feedback on encode_node Add a note explaining why `EMPTY_TRIE_ROOT` uses `Hash32` rather than `Root` (circular import), unify the `storage_root` annotation on `encode_node` to use `Bytes | None` for consistency with the `node` parameter, and tighten `encode_node`'s `node` parameter to `Extended` (non-nullable) now that `_prepare_trie` narrows `value` away from `None` before calling in. --- src/ethereum/forks/amsterdam/blocks.py | 12 +- src/ethereum/forks/amsterdam/fork.py | 16 +- src/ethereum/forks/amsterdam/requests.py | 2 +- src/ethereum/forks/amsterdam/state.py | 222 --------------- src/ethereum/forks/amsterdam/vm/__init__.py | 2 +- .../trie.py => merkle_patricia_trie.py} | 130 ++++++--- src/ethereum/state.py | 257 ++++++++++++++---- .../evm_tools/loaders/fork_loader.py | 70 ++++- .../evm_tools/t8n/t8n_types.py | 2 +- tests/json_loader/helpers/load_vm_tests.py | 24 +- tests/json_loader/test_genesis.py | 42 ++- tests/json_loader/test_tools_new_fork.py | 14 +- 12 files changed, 434 insertions(+), 359 deletions(-) delete mode 100644 src/ethereum/forks/amsterdam/state.py rename src/ethereum/{forks/amsterdam/trie.py => merkle_patricia_trie.py} (84%) diff --git a/src/ethereum/forks/amsterdam/blocks.py b/src/ethereum/forks/amsterdam/blocks.py index 09a15657002..f67d52adfc2 100644 --- a/src/ethereum/forks/amsterdam/blocks.py +++ b/src/ethereum/forks/amsterdam/blocks.py @@ -112,8 +112,8 @@ class Header: Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [changes]: ref:ethereum.forks.amsterdam.state.State.compute_state_root_and_trie_changes - [Trie]: ref:ethereum.forks.amsterdam.trie.Trie + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ # noqa: E501 transactions_root: Root @@ -124,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.amsterdam.trie.root - [Trie]: ref:ethereum.forks.amsterdam.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -135,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.amsterdam.trie.root - [Trie]: ref:ethereum.forks.amsterdam.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index 9d037d2aa1b..0ff0bf663ed 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -29,7 +29,14 @@ NonceMismatchError, ) from ethereum.forks.bpo5.blocks import Header as PreviousHeader -from ethereum.state import EMPTY_CODE_HASH, Address, BlockDiff, PreState +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + BlockDiff, + State, + apply_changes_to_state, +) from . import vm from .block_access_lists import ( @@ -60,10 +67,6 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - apply_changes_to_state, -) from .state_tracker import ( BlockState, TransactionState, @@ -89,7 +92,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -263,7 +265,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: def execute_block( block: Block, - pre_state: PreState, + pre_state: State, chain_context: ChainContext, ) -> BlockDiff: """ diff --git a/src/ethereum/forks/amsterdam/requests.py b/src/ethereum/forks/amsterdam/requests.py index 317b5121b3f..675f8a888f9 100644 --- a/src/ethereum/forks/amsterdam/requests.py +++ b/src/ethereum/forks/amsterdam/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/amsterdam/state.py b/src/ethereum/forks/amsterdam/state.py deleted file mode 100644 index 0c01146588e..00000000000 --- a/src/ethereum/forks/amsterdam/state.py +++ /dev/null @@ -1,222 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Dict, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.numeric import U256 - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_CODE_HASH, - Account, - Address, - BlockDiff, - InternalNode, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - def get_account_optional(self, address: Address) -> Optional[Account]: - """ - Get the account at an address. - - Return ``None`` if there is no account at the address. - """ - return trie_get(self._main_trie, address) - - def get_storage(self, address: Address, key: Bytes32) -> U256: - """ - Get a storage value. - - Return ``U256(0)`` if the key has not been set. - """ - trie = self._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - def account_has_storage(self, address: Address) -> bool: - """ - Check whether an account has any storage. - - Only needed for EIP-7610. - """ - return address in self._storage_tries - - def compute_state_root_and_trie_changes( - self, - account_changes: Dict[Address, Optional[Account]], - storage_changes: Dict[Address, Dict[Bytes32, U256]], - ) -> Tuple[Root, List[InternalNode]]: - """ - Compute the state root after applying changes to the pre-state. - - Return the new state root together with the internal trie nodes - that were created or modified. - """ - main_trie = copy_trie(self._main_trie) - storage_tries = { - k: copy_trie(v) for k, v in self._storage_tries.items() - } - - for address, account in account_changes.items(): - trie_set(main_trie, address, account) - - for address, slots in storage_changes.items(): - trie = storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - storage_tries[address] = trie - for key, value in slots.items(): - trie_set(trie, key, value) - if trie._data == {}: - del storage_tries[address] - - def get_storage_root(addr: Address) -> Root: - if addr in storage_tries: - return root(storage_tries[addr]) - return EMPTY_TRIE_ROOT - - state_root_value = root(main_trie, get_storage_root=get_storage_root) - - return state_root_value, [] - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._code_store - - -def apply_changes_to_state(state: State, diff: BlockDiff) -> None: - """ - Apply block-level diff to the ``State`` for the next block. - - Parameters - ---------- - state : - The state to update. - diff : - Account, storage, and code changes to apply. - - """ - for address, account in diff.account_changes.items(): - trie_set(state._main_trie, address, account) - - for address, slots in diff.storage_changes.items(): - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - for key, value in slots.items(): - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - state._code_store.update(diff.code_changes) - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, - address: Address, - account: Optional[Account], -) -> None: - """ - Set an account in a ``State``. - - Setting to ``None`` deletes the account. - """ - trie_set(state._main_trie, address, account) - - -def set_storage( - state: State, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a storage value in a ``State``. - - Setting to ``U256(0)`` deletes the key. - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def state_root(state: State) -> Root: - """ - Compute the state root of the current state. - """ - root_value, _ = state.compute_state_root_and_trie_changes({}, {}) - return root_value diff --git a/src/ethereum/forks/amsterdam/vm/__init__.py b/src/ethereum/forks/amsterdam/vm/__init__.py index fb69a51234b..44135d5e72a 100644 --- a/src/ethereum/forks/amsterdam/vm/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/__init__.py @@ -20,6 +20,7 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..block_access_lists import BlockAccessList, BlockAccessListBuilder @@ -27,7 +28,6 @@ from ..fork_types import Authorization, VersionedHash from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") diff --git a/src/ethereum/forks/amsterdam/trie.py b/src/ethereum/merkle_patricia_trie.py similarity index 84% rename from src/ethereum/forks/amsterdam/trie.py rename to src/ethereum/merkle_patricia_trie.py index bf5ee0d6c43..b9ae0d9e9b8 100644 --- a/src/ethereum/forks/amsterdam/trie.py +++ b/src/ethereum/merkle_patricia_trie.py @@ -12,9 +12,12 @@ `.fork_types.Account` objects. """ +from __future__ import annotations + import copy from dataclasses import dataclass, field from typing import ( + TYPE_CHECKING, Callable, Dict, Generic, @@ -30,26 +33,15 @@ from ethereum_rlp import Extended, rlp from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint +from ethereum_types.frozen import slotted_freezable +from ethereum_types.numeric import Uint from typing_extensions import assert_type -from ethereum.crypto.hash import keccak256 -from ethereum.forks.bpo5 import trie as previous_trie -from ethereum.state import ( - Account, - Address, - BranchNode, - BranchSubnodes, - ExtensionNode, - InternalNode, - LeafNode, - Root, -) +from ethereum.crypto.hash import Hash32, keccak256 from ethereum.utils.hexadecimal import hex_to_bytes -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction +if TYPE_CHECKING: + from ethereum.state import Account, Address, Root # note: an empty trie (regardless of whether it is secured) has root: # @@ -64,25 +56,86 @@ # 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 # # which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( +# +# Note: `Hash32` is used here rather than `Root` because `Root` is defined in +# `ethereum.state`, which imports from this module — referring to it at module +# scope would create a circular import. +EMPTY_TRIE_ROOT = Hash32( hex_to_bytes( "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" ) ) -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal + +@slotted_freezable +@dataclass +class LeafNode: + """Leaf node in the Merkle Trie.""" + + rest_of_key: Bytes + value: Extended + + +@slotted_freezable +@dataclass +class ExtensionNode: + """Extension node in the Merkle Trie.""" + + key_segment: Bytes + subnode: Extended + + +BranchSubnodes = Tuple[ + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, + Extended, +] + + +@slotted_freezable +@dataclass +class BranchNode: + """Branch node in the Merkle Trie.""" + + subnodes: BranchSubnodes + value: Extended + + +InternalNode = LeafNode | ExtensionNode | BranchNode + + K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) +V = TypeVar("V", bound=Extended | None) + + +def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: + """ + Encode `Account` dataclass. + + Storage is not stored in the `Account` dataclass, so `Accounts` cannot be + encoded without providing a storage root. + """ + return rlp.encode( + ( + raw_account_data.nonce, + raw_account_data.balance, + storage_root, + raw_account_data.code_hash, + ) + ) def encode_internal_node(node: Optional[InternalNode]) -> Extended: @@ -130,21 +183,19 @@ def encode_internal_node(node: Optional[InternalNode]) -> Extended: return keccak256(encoded) -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: +def encode_node(node: Extended, storage_root: Bytes | None = None) -> Bytes: """ Encode a Node for storage in the Merkle Trie. """ + from ethereum.state import Account + if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) elif isinstance(node, Bytes): return node else: - return previous_trie.encode_node(node, storage_root) + return rlp.encode(node) @dataclass @@ -326,6 +377,8 @@ def _prepare_trie( Object with keys mapped to nibble-byte form. """ + from ethereum.state import Account, Address + mapped: MutableMapping[Bytes, Bytes] = {} for preimage, value in trie._data.items(): @@ -368,10 +421,12 @@ def root( Returns ------- - root : `.fork_types.Root` + root : `.state.Root` MPT root of the underlying key-value pairs. """ + from ethereum.state import Root + obj = _prepare_trie(trie, get_storage_root) root_node = encode_internal_node(patricialize(obj, Uint(0))) @@ -443,9 +498,6 @@ def patricialize( value = b"" for key in obj: if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError value = obj[key] else: branches[key[level]][key] = obj[key] diff --git a/src/ethereum/state.py b/src/ethereum/state.py index 48349700f2b..8f62b960d32 100644 --- a/src/ethereum/state.py +++ b/src/ethereum/state.py @@ -5,17 +5,31 @@ The `PreState` protocol specifies the operations that any pre-execution state provider must support, allowing multiple backing implementations (in-memory `dict`, on-disk database, witness, etc.). + +The `State` class is the in-memory implementation of `PreState`. It consists +of a main account trie and storage tries for each contract. + +There is a distinction between an account that does not exist and +`EMPTY_ACCOUNT`. """ -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import Dict, List, Optional, Protocol, Tuple -from ethereum_rlp import Extended from ethereum_types.bytes import Bytes, Bytes20, Bytes32 from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.merkle_patricia_trie import ( + EMPTY_TRIE_ROOT, + InternalNode, + Trie, + copy_trie, + root, + trie_get, + trie_set, +) Address = Bytes20 Root = Hash32 @@ -42,56 +56,6 @@ class Account: ) -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - @dataclass class BlockDiff: """ @@ -152,7 +116,7 @@ def compute_state_root_and_trie_changes( self, account_changes: Dict[Address, Optional[Account]], storage_changes: Dict[Address, Dict[Bytes32, U256]], - ) -> Tuple[Root, List[InternalNode]]: + ) -> Tuple[Root, List["InternalNode"]]: """ Compute the state root after applying changes to the pre-state. @@ -160,3 +124,190 @@ def compute_state_root_and_trie_changes( that were created or modified. """ ... + + +@dataclass +class State: + """ + Contains all information that is preserved between transactions. + """ + + _main_trie: Trie[Address, Optional[Account]] = field( + default_factory=lambda: Trie(secured=True, default=None) + ) + _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( + default_factory=dict + ) + _code_store: Dict[Hash32, Bytes] = field( + default_factory=dict, compare=False + ) + + def get_code(self, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Return ``b""`` for ``EMPTY_CODE_HASH``. + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + return self._code_store[code_hash] + + def get_account_optional(self, address: Address) -> Optional[Account]: + """ + Get the account at an address. + + Return ``None`` if there is no account at the address. + """ + return trie_get(self._main_trie, address) + + def get_storage(self, address: Address, key: Bytes32) -> U256: + """ + Get a storage value. + + Return ``U256(0)`` if the key has not been set. + """ + trie = self._storage_tries.get(address) + if trie is None: + return U256(0) + + value = trie_get(trie, key) + + assert isinstance(value, U256) + return value + + def account_has_storage(self, address: Address) -> bool: + """ + Check whether an account has any storage. + + Only needed for EIP-7610. + """ + return address in self._storage_tries + + def compute_state_root_and_trie_changes( + self, + account_changes: Dict[Address, Optional[Account]], + storage_changes: Dict[Address, Dict[Bytes32, U256]], + ) -> Tuple[Root, List["InternalNode"]]: + """ + Compute the state root after applying changes to the pre-state. + + Return the new state root together with the internal trie nodes + that were created or modified. + """ + main_trie = copy_trie(self._main_trie) + storage_tries = { + k: copy_trie(v) for k, v in self._storage_tries.items() + } + + for address, account in account_changes.items(): + trie_set(main_trie, address, account) + + for address, slots in storage_changes.items(): + trie = storage_tries.get(address) + if trie is None: + trie = Trie(secured=True, default=U256(0)) + storage_tries[address] = trie + for key, value in slots.items(): + trie_set(trie, key, value) + if trie._data == {}: + del storage_tries[address] + + def get_storage_root(addr: Address) -> Root: + if addr in storage_tries: + return root(storage_tries[addr]) + return EMPTY_TRIE_ROOT + + state_root_value = root(main_trie, get_storage_root=get_storage_root) + + return state_root_value, [] + + +def close_state(state: State) -> None: + """ + Free resources held by the state. Used by optimized implementations to + release file descriptors. + """ + del state._main_trie + del state._storage_tries + del state._code_store + + +def apply_changes_to_state(state: State, diff: BlockDiff) -> None: + """ + Apply block-level diff to the ``State`` for the next block. + + Parameters + ---------- + state : + The state to update. + diff : + Account, storage, and code changes to apply. + + """ + for address, account in diff.account_changes.items(): + trie_set(state._main_trie, address, account) + + for address, slots in diff.storage_changes.items(): + trie = state._storage_tries.get(address) + if trie is None: + trie = Trie(secured=True, default=U256(0)) + state._storage_tries[address] = trie + for key, value in slots.items(): + trie_set(trie, key, value) + if trie._data == {}: + del state._storage_tries[address] + + state._code_store.update(diff.code_changes) + + +def store_code(state: State, code: Bytes) -> Hash32: + """ + Store bytecode in ``State``. + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + state._code_store[code_hash] = code + return code_hash + + +def set_account( + state: State, + address: Address, + account: Optional[Account], +) -> None: + """ + Set an account in a ``State``. + + Setting to ``None`` deletes the account. + """ + trie_set(state._main_trie, address, account) + + +def set_storage( + state: State, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a storage value in a ``State``. + + Setting to ``U256(0)`` deletes the key. + """ + assert trie_get(state._main_trie, address) is not None + + trie = state._storage_tries.get(address) + if trie is None: + trie = Trie(secured=True, default=U256(0)) + state._storage_tries[address] = trie + trie_set(trie, key, value) + if trie._data == {}: + del state._storage_tries[address] + + +def state_root(state: State) -> Root: + """ + Compute the state root of the current state. + """ + root_value, _ = state.compute_state_root_and_trie_changes({}, {}) + return root_value diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py index 33e4e379a82..c88eec7d9bd 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py @@ -307,52 +307,102 @@ def has_block_state(self) -> bool: @property def State(self) -> Any: """State class of the fork.""" - return self._module("state").State + try: + return self._module("state").State + except ModuleNotFoundError: + from ethereum.state import State + + return State @property def set_account(self) -> Any: """set_account function of the fork.""" - return self._module("state").set_account + try: + return self._module("state").set_account + except ModuleNotFoundError: + from ethereum.state import set_account + + return set_account @property def store_code(self) -> Any: """store_code function of the fork.""" - return getattr(self._module("state"), "store_code", None) + try: + return getattr(self._module("state"), "store_code", None) + except ModuleNotFoundError: + from ethereum.state import store_code + + return store_code @property def set_storage(self) -> Any: """set_storage function of the fork.""" - return self._module("state").set_storage + try: + return self._module("state").set_storage + except ModuleNotFoundError: + from ethereum.state import set_storage + + return set_storage @property def state_root(self) -> Any: """state_root function of the fork.""" - return self._module("state").state_root + try: + return self._module("state").state_root + except ModuleNotFoundError: + from ethereum.state import state_root + + return state_root @property def close_state(self) -> Any: """close_state function of the fork.""" - return self._module("state").close_state + try: + return self._module("state").close_state + except ModuleNotFoundError: + from ethereum.state import close_state + + return close_state @property def create_ether(self) -> Any: """create_ether function of the fork.""" - return self._module("state").create_ether + try: + return self._module("state").create_ether + except ModuleNotFoundError: + import ethereum.state + + return getattr(ethereum.state, "create_ether", None) @property def root(self) -> Any: """Root function of the fork.""" - return self._module("trie").root + try: + return self._module("trie").root + except ModuleNotFoundError: + from ethereum.merkle_patricia_trie import root + + return root @property def copy_trie(self) -> Any: """copy_trie function of the fork.""" - return self._module("trie").copy_trie + try: + return self._module("trie").copy_trie + except ModuleNotFoundError: + from ethereum.merkle_patricia_trie import copy_trie + + return copy_trie @property def trie_get(self) -> Any: """trie_get function of the fork.""" - return self._module("trie").trie_get + try: + return self._module("trie").trie_get + except ModuleNotFoundError: + from ethereum.merkle_patricia_trie import trie_get + + return trie_get @property def hex_to_address(self) -> Any: diff --git a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py index ec78bd09719..e2e953bd195 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py @@ -315,10 +315,10 @@ def update(self, t8n: "T8N", block_env: Any, block_output: Any) -> None: if t8n.fork.has_block_state: # TODO: remove this once the state tracker is ported over # to the older forks - from ethereum.forks.amsterdam.state import apply_changes_to_state from ethereum.forks.amsterdam.state_tracker import ( extract_block_diff, ) + from ethereum.state import apply_changes_to_state block_diff = extract_block_diff(t8n._block_state) state_root_value, _ = ( diff --git a/tests/json_loader/helpers/load_vm_tests.py b/tests/json_loader/helpers/load_vm_tests.py index 2f00b1a78c5..b34a1dcc2f8 100644 --- a/tests/json_loader/helpers/load_vm_tests.py +++ b/tests/json_loader/helpers/load_vm_tests.py @@ -55,13 +55,13 @@ def __init__(self, network: str, fork_name: str): self.BlockChain = self.fork.BlockChain self.get_last_256_block_hashes = self.fork.get_last_256_block_hashes - self.state = self._module("state") - self.State = self.state.State - self.close_state = self.state.close_state - self.set_account = self.state.set_account - self.set_storage = self.state.set_storage - self.storage_root = self.state.storage_root - self.store_code = self.state.store_code + state_mod = self._state_module() + self.State = state_mod.State + self.close_state = state_mod.close_state + self.set_account = state_mod.set_account + self.set_storage = state_mod.set_storage + self.storage_root = state_mod.storage_root + self.store_code = state_mod.store_code self.fork_types = self._module("fork_types") self.Account = self.fork_types.Account @@ -86,6 +86,16 @@ def __init__(self, network: str, fork_name: str): def _module(self, name: str) -> Any: return import_module(f"ethereum.forks.{self.fork_name}.{name}") + def _state_module(self) -> Any: + # TODO: remove this fallback once the state module is ported over + # to the older forks + try: + return self._module("state") + except ModuleNotFoundError: + import ethereum.state + + return ethereum.state + def run_test_from_dict(self, json_data: Dict[str, Any]) -> None: """ Execute a test case from parsed JSON data and check its post state. diff --git a/tests/json_loader/test_genesis.py b/tests/json_loader/test_genesis.py index 431af272598..a29fded25d5 100644 --- a/tests/json_loader/test_genesis.py +++ b/tests/json_loader/test_genesis.py @@ -67,22 +67,50 @@ def fork_name(fork: Hardfork) -> str: @pytest.mark.parametrize("fork", Hardfork.discover(), ids=fork_name) def test_genesis(fork: Hardfork) -> None: """Tests genesis block creation for all hardforks.""" + # TODO: remove once the changes have been back-ported + from ethereum.merkle_patricia_trie import Trie + from ethereum.state import ( + Address, + State, + root, + set_account, + set_storage, + state_root, + store_code, + ) + + try: + _trie = fork.module("trie").Trie + _set_account = fork.module("state").set_account + _set_storage = fork.module("state").set_storage + _state_root = fork.module("state").state_root + _root = fork.module("trie").root + _store_code = fork.module("state").store_code + state = fork.module("state").State() + except ModuleNotFoundError: + _trie = Trie + _set_account = set_account + _set_storage = set_storage + _state_root = state_root + _root = root + _store_code = store_code + state = State() + description: GenesisFork = GenesisFork( Address=Address, Account=fork.module("fork_types").Account, - Trie=fork.module("trie").Trie, + Trie=_trie, Bloom=fork.module("fork_types").Bloom, Header=fork.module("blocks").Header, Block=fork.module("blocks").Block, - set_account=fork.module("state").set_account, - set_storage=fork.module("state").set_storage, - state_root=fork.module("state").state_root, - root=fork.module("trie").root, + set_account=_set_account, + set_storage=_set_storage, + state_root=_state_root, + root=_root, hex_to_address=fork.module("utils.hexadecimal").hex_to_address, - store_code=fork.module("state").store_code, + store_code=_store_code, ) - state = fork.module("state").State() chain = fork.module("fork").BlockChain([], state, U64(1)) add_genesis_block(description, chain, MAINNET_GENESIS_CONFIGURATION) diff --git a/tests/json_loader/test_tools_new_fork.py b/tests/json_loader/test_tools_new_fork.py index 9afb2383cbd..0f009afeac5 100644 --- a/tests/json_loader/test_tools_new_fork.py +++ b/tests/json_loader/test_tools_new_fork.py @@ -89,11 +89,15 @@ def test_end_to_end(template_fork: str) -> None: with (fork_dir / "fork.py").open("r") as f: assert "MAX_BLOB_GAS_PER_BLOCK = U64(99)" in f.read() - with (fork_dir / "trie.py").open("r") as f: - assert ( - "from ethereum.forks.paris import trie as previous_trie" - in f.read() - ) + # TODO: Remove this condition once trie.py is removed from all + # forks (i.e. fork-agnostic Trie is ported to pre-amsterdam forks). + template_has_trie = ( + Path("src/ethereum/forks") / template_fork / "trie.py" + ).exists() + if template_has_trie: + assert (fork_dir / "trie.py").exists() + else: + assert not (fork_dir / "trie.py").exists() def has_module_docstring(file_path: Path) -> bool: From d4c95a4f3a21d4feb2bda4b16264b65867a9dbdb Mon Sep 17 00:00:00 2001 From: Chen Can Date: Thu, 23 Apr 2026 01:56:08 +0800 Subject: [PATCH 039/186] fix(evm_tools): avoid cloning unchanged fork template in ForkCache (#2738) * fix(evm_tools): handle GasCosts defaults in template match * fix(evm_tools): avoid cloning identical fork overrides * simplify fork cache template stuff --------- Co-authored-by: Sam Wilson --- .../evm_tools/t8n/__init__.py | 129 +++++++-- tests/evm_tools/test_fork_cache.py | 268 ++++++++++++++++++ 2 files changed, 376 insertions(+), 21 deletions(-) create mode 100644 tests/evm_tools/test_fork_cache.py diff --git a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py index 396737c25e9..23781ad7b94 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py @@ -7,7 +7,8 @@ import json import os from contextlib import AbstractContextManager -from typing import Any, Final, TextIO, Tuple, Type, TypeVar +from dataclasses import astuple, dataclass +from typing import Any, Final, TextIO, Type, TypeVar from ethereum_rlp import rlp from ethereum_types.numeric import U64, U256, Uint @@ -40,6 +41,7 @@ from .t8n_types import Alloc, Result, Txs T = TypeVar("T") +ForkCriteriaArgument = ByBlockNumber | ByTimestamp | Unscheduled | None def t8n_arguments(subparsers: argparse._SubParsersAction) -> None: @@ -97,12 +99,95 @@ def t8n_arguments(subparsers: argparse._SubParsersAction) -> None: t8n_parser.add_argument("--state-test", action="store_true") +@dataclass(frozen=True) +class _ForkOverrides: + """Store temporary hardfork override values.""" + + fork_criteria: ForkCriteriaArgument = None + blob_target_gas_per_block: U64 | None = None + gas_per_blob: U64 | None = None + blob_min_gasprice: Uint | None = None + blob_base_fee_update_fraction: Uint | None = None + max_blob_gas_per_block: U64 | None = None + blob_schedule_target: U64 | None = None + blob_schedule_max: U64 | None = None + + def is_empty(self) -> bool: + """Return true when all override values are unset.""" + return all(value is None for value in astuple(self)) + + @staticmethod + def _matches_field(override: object | None, on: object, name: str) -> bool: + if override is None: + return True + + try: + default = getattr(on, name) + except AttributeError: + return False + + return override == default + + def matches_template( + self, + template: Hardfork, + ) -> bool: + """Return true when the requested overrides match the template.""" + if self.is_empty(): + return True + + if ( + self.fork_criteria is not None + and self.fork_criteria != template.criteria + ): + return False + + fork_mod = template.module("fork") + gas_costs = template.module("vm.gas").GasCosts + + checks = ( + ( + self.max_blob_gas_per_block, + fork_mod, + "MAX_BLOB_GAS_PER_BLOCK", + ), + ( + self.blob_target_gas_per_block, + gas_costs, + "BLOB_TARGET_GAS_PER_BLOCK", + ), + (self.gas_per_blob, gas_costs, "PER_BLOB"), + ( + self.blob_min_gasprice, + gas_costs, + "BLOB_MIN_GASPRICE", + ), + ( + self.blob_base_fee_update_fraction, + gas_costs, + "BLOB_BASE_FEE_UPDATE_FRACTION", + ), + ( + self.blob_schedule_target, + gas_costs, + "BLOB_SCHEDULE_TARGET", + ), + ( + self.blob_schedule_max, + gas_costs, + "BLOB_SCHEDULE_MAX", + ), + ) + + return all(self._matches_field(*x) for x in checks) + + class ForkCache(AbstractContextManager): """ Stores references to temporary hardforks and cleans them up when exited. """ - _cache: Final[dict[Tuple[object, ...], TemporaryHardfork]] + _cache: Final[dict[tuple[str, _ForkOverrides], TemporaryHardfork]] def __init__(self) -> None: self._cache = {} @@ -129,20 +214,20 @@ def get( Search the cache for a matching hardfork, or create one if it doesn't exist. """ - cache_key = ( - template.short_name, - fork_criteria, - blob_target_gas_per_block, - gas_per_blob, - blob_min_gasprice, - blob_base_fee_update_fraction, - max_blob_gas_per_block, - blob_schedule_target, - blob_schedule_max, + overrides = _ForkOverrides( + fork_criteria=fork_criteria, + blob_target_gas_per_block=blob_target_gas_per_block, + gas_per_blob=gas_per_blob, + blob_min_gasprice=blob_min_gasprice, + blob_base_fee_update_fraction=blob_base_fee_update_fraction, + max_blob_gas_per_block=max_blob_gas_per_block, + blob_schedule_target=blob_schedule_target, + blob_schedule_max=blob_schedule_max, ) - if all(x is None for x in cache_key[1:]): + if overrides.matches_template(template): return template + cache_key = (template.short_name, overrides) try: return self._cache[cache_key] except KeyError: @@ -150,14 +235,16 @@ def get( clone = Hardfork.clone( template=template, - fork_criteria=fork_criteria, - blob_target_gas_per_block=blob_target_gas_per_block, - gas_per_blob=gas_per_blob, - blob_min_gasprice=blob_min_gasprice, - blob_base_fee_update_fraction=blob_base_fee_update_fraction, - max_blob_gas_per_block=max_blob_gas_per_block, - blob_schedule_target=blob_schedule_target, - blob_schedule_max=blob_schedule_max, + fork_criteria=overrides.fork_criteria, + blob_target_gas_per_block=overrides.blob_target_gas_per_block, + gas_per_blob=overrides.gas_per_blob, + blob_min_gasprice=overrides.blob_min_gasprice, + blob_base_fee_update_fraction=( + overrides.blob_base_fee_update_fraction + ), + max_blob_gas_per_block=overrides.max_blob_gas_per_block, + blob_schedule_target=overrides.blob_schedule_target, + blob_schedule_max=overrides.blob_schedule_max, ) self._cache[cache_key] = clone return clone diff --git a/tests/evm_tools/test_fork_cache.py b/tests/evm_tools/test_fork_cache.py new file mode 100644 index 00000000000..b2b67f2bdf0 --- /dev/null +++ b/tests/evm_tools/test_fork_cache.py @@ -0,0 +1,268 @@ +"""Tests for temporary fork caching.""" + +import importlib +from typing import Any + +import pytest +from ethereum_types.numeric import U64, Uint +from typing_extensions import assert_never + +from ethereum.fork_criteria import ( + ByBlockNumber, + ByTimestamp, + Unscheduled, +) +from ethereum_spec_tools.evm_tools.t8n import ForkCache +from ethereum_spec_tools.forks import Hardfork + +pytestmark = pytest.mark.evm_tools + +OVERRIDE_FIELDS: tuple[str, ...] = ( + "blob_target_gas_per_block", + "gas_per_blob", + "blob_min_gasprice", + "blob_base_fee_update_fraction", + "max_blob_gas_per_block", + "blob_schedule_target", + "blob_schedule_max", +) + + +class DummyTemporaryFork: + """Stand-in for a cloned hardfork.""" + + def __exit__(self, *args: Any, **kwargs: Any) -> None: + """Support ForkCache cleanup.""" + + +def _template() -> Hardfork: + """Return the Amsterdam fork template.""" + return Hardfork(importlib.import_module("ethereum.forks.amsterdam")) + + +def _different_fork_criteria( + criteria: ByBlockNumber | ByTimestamp | Unscheduled, +) -> ByBlockNumber | ByTimestamp | Unscheduled: + """Return a fork criterion that differs from `criteria`.""" + if isinstance(criteria, ByBlockNumber): + return ByBlockNumber(int(criteria.block_number) + 1) + + if isinstance(criteria, ByTimestamp): + return ByTimestamp(int(criteria.timestamp) + 1) + + if isinstance(criteria, Unscheduled): + zero_order = Unscheduled(order_index=0) + if criteria == zero_order: + return Unscheduled(order_index=1) + return zero_order + + assert_never(criteria) + + +def _gas_default( + gas_mod: Any, + gas_costs_attr: str, +) -> U64 | Uint | None: + """Return a gas default from `GasCosts`.""" + gas_costs = getattr(gas_mod, "GasCosts", None) + if gas_costs is None: + return None + + value = getattr(gas_costs, gas_costs_attr, None) + if value is None: + return None + + assert isinstance(value, U64 | Uint) + return value + + +def _override_defaults(template: Hardfork) -> dict[str, U64 | Uint]: + """Return template defaults keyed by ForkCache override name.""" + gas_mod = template.module("vm.gas") + fork_mod = template.module("fork") + + defaults: dict[str, U64 | Uint | None] = { + "blob_target_gas_per_block": _gas_default( + gas_mod, + "BLOB_TARGET_GAS_PER_BLOCK", + ), + "gas_per_blob": _gas_default(gas_mod, "PER_BLOB"), + "blob_min_gasprice": _gas_default(gas_mod, "BLOB_MIN_GASPRICE"), + "blob_base_fee_update_fraction": _gas_default( + gas_mod, + "BLOB_BASE_FEE_UPDATE_FRACTION", + ), + "max_blob_gas_per_block": getattr( + fork_mod, + "MAX_BLOB_GAS_PER_BLOCK", + None, + ), + "blob_schedule_target": _gas_default(gas_mod, "BLOB_SCHEDULE_TARGET"), + "blob_schedule_max": _gas_default(gas_mod, "BLOB_SCHEDULE_MAX"), + } + + missing = sorted( + name for name in OVERRIDE_FIELDS if defaults.get(name) is None + ) + if missing: + raise AssertionError( + "missing template defaults for overrides: " + ", ".join(missing) + ) + + return {key: value for key, value in defaults.items() if value is not None} + + +def test_fork_cache_returns_template_without_overrides( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Return the template when no overrides are provided.""" + template = _template() + + def clone(*args: Any, **kwargs: Any) -> DummyTemporaryFork: + pytest.fail("Hardfork.clone() should not run without overrides") + + monkeypatch.setattr(Hardfork, "clone", clone) + + with ForkCache() as cache: + fork = cache.get(template) + + assert fork is template + + +def test_fork_cache_returns_template_for_identical_overrides( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Return the template when requested overrides match it exactly.""" + template = _template() + identical_overrides = _override_defaults(template) + identical_fork_criteria = template.criteria + assert isinstance( + identical_fork_criteria, + ByBlockNumber | ByTimestamp | Unscheduled, + ) + + def clone(*args: Any, **kwargs: Any) -> DummyTemporaryFork: + pytest.fail("Hardfork.clone() should not run for identical overrides") + + monkeypatch.setattr(Hardfork, "clone", clone) + + with ForkCache() as cache: + fork = cache.get( + template, + fork_criteria=identical_fork_criteria, + **identical_overrides, + ) + + assert fork is template + + +def test_fork_cache_clones_when_fork_criteria_changes_template( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Clone the template when the fork criteria changes.""" + template = _template() + cloned = DummyTemporaryFork() + seen: dict[str, Any] = {} + + def clone(*args: Any, **kwargs: Any) -> DummyTemporaryFork: + seen.update(kwargs) + return cloned + + monkeypatch.setattr(Hardfork, "clone", clone) + + template_criteria = template.criteria + assert isinstance( + template_criteria, + ByBlockNumber | ByTimestamp | Unscheduled, + ) + changed_fork_criteria = _different_fork_criteria(template_criteria) + + with ForkCache() as cache: + fork = cache.get(template, fork_criteria=changed_fork_criteria) + + assert fork is cloned + assert seen["template"] is template + assert seen["fork_criteria"] == changed_fork_criteria + + +@pytest.mark.parametrize("field", OVERRIDE_FIELDS) +def test_fork_cache_returns_template_for_each_identical_blob_override( + monkeypatch: pytest.MonkeyPatch, + field: str, +) -> None: + """Return the template when each blob-related override matches it.""" + template = _template() + value = _override_defaults(template)[field] + + def clone(*args: Any, **kwargs: Any) -> DummyTemporaryFork: + pytest.fail("Hardfork.clone() should not run for identical overrides") + + monkeypatch.setattr(Hardfork, "clone", clone) + + with ForkCache() as cache: + fork = cache.get(template, **{field: value}) + + assert fork is template + + +@pytest.mark.parametrize("field", OVERRIDE_FIELDS) +def test_fork_cache_clones_for_each_changed_blob_override( + monkeypatch: pytest.MonkeyPatch, + field: str, +) -> None: + """Clone the template when each blob-related override is changed.""" + template = _template() + default_value = _override_defaults(template)[field] + changed_value = type(default_value)(int(default_value) + 1) + cloned = DummyTemporaryFork() + seen: dict[str, Any] = {} + + def clone(*args: Any, **kwargs: Any) -> DummyTemporaryFork: + seen.update(kwargs) + return cloned + + monkeypatch.setattr(Hardfork, "clone", clone) + + with ForkCache() as cache: + fork = cache.get(template, **{field: changed_value}) + + assert fork is cloned + assert seen["template"] is template + assert seen[field] == changed_value + + +def test_fork_cache_reuses_cached_clone_for_identical_changed_request( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Reuse the same cached clone when override requests repeat.""" + template = _template() + default_blob_schedule_target = _override_defaults(template)[ + "blob_schedule_target" + ] + changed_blob_schedule_target = U64(int(default_blob_schedule_target) + 1) + cloned = DummyTemporaryFork() + clone_count = 0 + + def clone(*args: Any, **kwargs: Any) -> DummyTemporaryFork: + del args + del kwargs + nonlocal clone_count + clone_count += 1 + return cloned + + monkeypatch.setattr(Hardfork, "clone", clone) + + with ForkCache() as cache: + first = cache.get( + template, + blob_schedule_target=changed_blob_schedule_target, + ) + second = cache.get( + template, + blob_schedule_target=changed_blob_schedule_target, + ) + + assert first is cloned + assert second is cloned + assert first is second + assert clone_count == 1 From ca4c64ecc2e922ec4bc0e544f135c45d8d7dcc97 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 23:54:31 +0530 Subject: [PATCH 040/186] chore: fix lint issue --- .../execution_testing/client_clis/clis/ethrex.py | 16 ---------------- src/ethereum/forks/amsterdam/fork.py | 2 +- src/ethereum/forks/bpo1/fork.py | 2 +- src/ethereum/forks/bpo2/fork.py | 2 +- src/ethereum/forks/bpo3/fork.py | 2 +- src/ethereum/forks/bpo4/fork.py | 2 +- src/ethereum/forks/bpo5/fork.py | 2 +- src/ethereum/forks/osaka/fork.py | 2 +- src/ethereum/forks/paris/fork.py | 3 ++- src/ethereum/forks/shanghai/fork.py | 3 ++- 10 files changed, 11 insertions(+), 25 deletions(-) diff --git a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py index 0ccebcd4ed7..d85a1e7ce86 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py +++ b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py @@ -56,22 +56,6 @@ class EthrexExceptionMapper(ExceptionMapper): BlockException.INVALID_BASEFEE_PER_GAS: ( "Base fee per gas is incorrect" ), - BlockException.INVALID_BLOCK_ACCESS_LIST: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_HASH: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - "Block access list hash does not match the one in " - "the header after executing" - ), } mapping_regex = { TransactionException.PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS: ( diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index 8278c988fc7..b596de2d887 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -107,10 +107,10 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" GWEI_TO_WEI = U256(10**9) diff --git a/src/ethereum/forks/bpo1/fork.py b/src/ethereum/forks/bpo1/fork.py index 9cc2cbad691..da61fe8f1cf 100644 --- a/src/ethereum/forks/bpo1/fork.py +++ b/src/ethereum/forks/bpo1/fork.py @@ -93,10 +93,10 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/bpo2/fork.py b/src/ethereum/forks/bpo2/fork.py index 9cc2cbad691..da61fe8f1cf 100644 --- a/src/ethereum/forks/bpo2/fork.py +++ b/src/ethereum/forks/bpo2/fork.py @@ -93,10 +93,10 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/bpo3/fork.py b/src/ethereum/forks/bpo3/fork.py index 9cc2cbad691..da61fe8f1cf 100644 --- a/src/ethereum/forks/bpo3/fork.py +++ b/src/ethereum/forks/bpo3/fork.py @@ -93,10 +93,10 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/bpo4/fork.py b/src/ethereum/forks/bpo4/fork.py index 9cc2cbad691..da61fe8f1cf 100644 --- a/src/ethereum/forks/bpo4/fork.py +++ b/src/ethereum/forks/bpo4/fork.py @@ -93,10 +93,10 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/bpo5/fork.py b/src/ethereum/forks/bpo5/fork.py index 9cc2cbad691..da61fe8f1cf 100644 --- a/src/ethereum/forks/bpo5/fork.py +++ b/src/ethereum/forks/bpo5/fork.py @@ -93,10 +93,10 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index fc8ccee0302..acfb44b52c7 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -101,6 +101,7 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +SYSTEM_TRANSACTION_GAS = Uint(30000000) DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0xbabe2bed00000000000000000000000000000003" ) @@ -114,7 +115,6 @@ BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) -SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB VERSIONED_HASH_VERSION_KZG = b"\x01" BLOB_FEE_COLLECTOR = hex_to_address( diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index cf197e9da9b..0ce7cba6026 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -66,8 +66,9 @@ from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 2370d566470..c27755121c3 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -67,8 +67,9 @@ from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) From efb56361e10f0733c3365b69d081e6345e58b542 Mon Sep 17 00:00:00 2001 From: Iman Kalyan Chakraborty <120107300+ImanKalyanChakraborty@users.noreply.github.com> Date: Wed, 22 Apr 2026 23:58:54 +0530 Subject: [PATCH 041/186] fix: add missing raise for InvalidParameter in decode_g{1,2}_scalar_pair (#2742) --- .../amsterdam/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../forks/bpo1/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../forks/bpo2/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../forks/bpo3/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../forks/bpo4/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../forks/bpo5/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../osaka/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- .../prague/vm/precompiled_contracts/bls12_381/__init__.py | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/bpo1/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/__init__.py index c99e7573f48..7d622da39d1 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/__init__.py @@ -414,7 +414,7 @@ def decode_g1_scalar_pair( """ if len(data) != 160: - InvalidParameter("Input should be 160 bytes long") + raise InvalidParameter("Input should be 160 bytes long") point = bytes_to_g1(data[:128], subgroup_check=True) @@ -614,7 +614,7 @@ def decode_g2_scalar_pair( """ if len(data) != 288: - InvalidParameter("Input should be 288 bytes long") + raise InvalidParameter("Input should be 288 bytes long") point = bytes_to_g2(data[:256], subgroup_check=True) n = int.from_bytes(data[256 : 256 + 32], "big") From 8d8301cc534fb3d51054eb0535f848d96491d972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Fri, 24 Apr 2026 22:08:34 +0800 Subject: [PATCH 042/186] fix(test-benchmark): zero tx included in `ecpairing` benchmark (#2749) * chore: assert nonzero transaction length * fix: skip benchmark with insufficient gas limit * fix: handle gas limit issue for 24 pairs in BLS12 pairing benchmark Co-authored-by: Copilot --------- Co-authored-by: Copilot --- .../compute/precompile/test_alt_bn128.py | 4 +++- .../benchmark/compute/precompile/test_blake2f.py | 2 ++ .../compute/precompile/test_bls12_381.py | 15 ++++++++++++++- .../benchmark/compute/precompile/test_identity.py | 2 ++ .../compute/precompile/test_p256verify.py | 2 ++ .../compute/precompile/test_ripemd160.py | 2 ++ tests/benchmark/compute/precompile/test_sha256.py | 2 ++ 7 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/benchmark/compute/precompile/test_alt_bn128.py b/tests/benchmark/compute/precompile/test_alt_bn128.py index 9dbb1f0096d..dfb63a9aeab 100644 --- a/tests/benchmark/compute/precompile/test_alt_bn128.py +++ b/tests/benchmark/compute/precompile/test_alt_bn128.py @@ -648,7 +648,7 @@ def test_ec_pairing( - mem_exp(new_bytes=len(calldata) + 32) ) - if gas_for_loop < (per_tx_variants + 1) * iteration_cost: + if gas_for_loop < per_tx_variants * iteration_cost: break expected_opcode_count += per_tx_variants @@ -663,6 +663,8 @@ def test_ec_pairing( remaining_gas -= per_tx_gas seed_offset += per_tx_variants + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Precompile.BN128_PAIRING, skip_gas_used_validation=True, diff --git a/tests/benchmark/compute/precompile/test_blake2f.py b/tests/benchmark/compute/precompile/test_blake2f.py index e9995aa0b2b..7083d108e56 100644 --- a/tests/benchmark/compute/precompile/test_blake2f.py +++ b/tests/benchmark/compute/precompile/test_blake2f.py @@ -202,6 +202,8 @@ def test_blake2f_uncachable( ) remaining_gas -= per_tx_gas + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Op.STATICCALL, skip_gas_used_validation=True, diff --git a/tests/benchmark/compute/precompile/test_bls12_381.py b/tests/benchmark/compute/precompile/test_bls12_381.py index e994283e11e..40ccfc96415 100644 --- a/tests/benchmark/compute/precompile/test_bls12_381.py +++ b/tests/benchmark/compute/precompile/test_bls12_381.py @@ -478,6 +478,8 @@ def test_bls12_381_uncachable( remaining_gas -= per_tx_gas seed += 1 + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=target, skip_gas_used_validation=True, @@ -583,7 +585,7 @@ def test_bls12_pairing_uncachable( - mem_exp(new_bytes=len(calldata) + 32) ) - if gas_for_loop < (per_tx_variants + 1) * iteration_cost: + if gas_for_loop < per_tx_variants * iteration_cost: break expected_opcode_count += per_tx_variants @@ -598,6 +600,17 @@ def test_bls12_pairing_uncachable( remaining_gas -= per_tx_gas seed_offset += per_tx_variants + # TODO: 24 pairs exceeds the 1M block gas limit used in CI, + # which breaks the test run + if num_pairs == 24: + pytest.skip( + f"gas_benchmark_value={gas_benchmark_value} too small for " + f"num_pairs={num_pairs} " + f"(need ~{per_variant_gas + fixed_overhead} gas)" + ) + + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Precompile.BLS12_PAIRING, skip_gas_used_validation=True, diff --git a/tests/benchmark/compute/precompile/test_identity.py b/tests/benchmark/compute/precompile/test_identity.py index 17eef9589ee..e9e38dcea8c 100644 --- a/tests/benchmark/compute/precompile/test_identity.py +++ b/tests/benchmark/compute/precompile/test_identity.py @@ -154,6 +154,8 @@ def test_identity_uncachable( ) remaining_gas -= per_tx_gas + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Precompile.IDENTITY, skip_gas_used_validation=True, diff --git a/tests/benchmark/compute/precompile/test_p256verify.py b/tests/benchmark/compute/precompile/test_p256verify.py index d40d6af031a..45951cc0d6a 100644 --- a/tests/benchmark/compute/precompile/test_p256verify.py +++ b/tests/benchmark/compute/precompile/test_p256verify.py @@ -211,6 +211,8 @@ def test_p256verify_uncachable( remaining_gas -= per_tx_gas seed += 10000 + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Precompile.P256VERIFY, skip_gas_used_validation=True, diff --git a/tests/benchmark/compute/precompile/test_ripemd160.py b/tests/benchmark/compute/precompile/test_ripemd160.py index 3b8e4969d6d..219ec7876d3 100644 --- a/tests/benchmark/compute/precompile/test_ripemd160.py +++ b/tests/benchmark/compute/precompile/test_ripemd160.py @@ -153,6 +153,8 @@ def test_ripemd160_uncachable( ) remaining_gas -= per_tx_gas + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Precompile.RIPEMD160, skip_gas_used_validation=True, diff --git a/tests/benchmark/compute/precompile/test_sha256.py b/tests/benchmark/compute/precompile/test_sha256.py index beee369d534..6397ffbc8fd 100644 --- a/tests/benchmark/compute/precompile/test_sha256.py +++ b/tests/benchmark/compute/precompile/test_sha256.py @@ -151,6 +151,8 @@ def test_sha256_uncachable( ) remaining_gas -= per_tx_gas + assert len(txs) != 0, "No transactions were added to the test." + benchmark_test( target_opcode=Precompile.SHA256, skip_gas_used_validation=True, From 8db70f9324b17f5a98821c277059c8daef3a408b Mon Sep 17 00:00:00 2001 From: danceratopz Date: Sat, 25 Apr 2026 21:27:47 +0100 Subject: [PATCH 043/186] feat(ci,docs): build and publish a combined HTML and spec doc artifact (#2638) --- .github/configs/docs-branches.yaml | 18 + .github/workflows/docs-build.yaml | 356 ++++++++++++++++++ .github/workflows/test-docs.yaml | 57 --- README.md | 2 +- docs/dev/docs.md | 2 +- docs/hooks/reference_new_tab.py | 34 ++ docs/index.md | 4 +- docs/navigation.md | 1 + docs/specs/index.md | 2 +- docs/specs/reference/index.md | 11 + docs/specs/writing_specs.md | 2 +- docs/writing_tests/post_mortems.md | 2 +- mkdocs.yml | 8 +- .../src/execution_testing/config/docs.py | 8 +- 14 files changed, 437 insertions(+), 70 deletions(-) create mode 100644 .github/configs/docs-branches.yaml create mode 100644 .github/workflows/docs-build.yaml delete mode 100644 .github/workflows/test-docs.yaml create mode 100644 docs/hooks/reference_new_tab.py create mode 100644 docs/specs/reference/index.md diff --git a/.github/configs/docs-branches.yaml b/.github/configs/docs-branches.yaml new file mode 100644 index 00000000000..bcc44b6b1dd --- /dev/null +++ b/.github/configs/docs-branches.yaml @@ -0,0 +1,18 @@ +# Branches whose documentation is built and published to +# steel.ethereum.foundation/docs/execution-specs/ +# +# The `branches[]` list must stay in sync with steel-website's +# `docs-config.yml`; a branch that publishes here but isn't listed there +# is dispatched but dropped by the aggregator. +# +# Each entry defines: +# - path: The branch name (must match the Git branch exactly) +# - label: Human-readable label for the version switcher UI + +branches: + - path: "mainnet" + label: "Mainnet (BPO2)" + - path: "forks/amsterdam" + label: "Amsterdam" + - path: "devnets/bal/4" + label: "bal-devnet-4" diff --git a/.github/workflows/docs-build.yaml b/.github/workflows/docs-build.yaml new file mode 100644 index 00000000000..a9617549142 --- /dev/null +++ b/.github/workflows/docs-build.yaml @@ -0,0 +1,356 @@ +# Build Docs +# +# Dual-purpose workflow: +# - On PRs: Tests that MkDocs and spec docs build successfully +# - On push to allowlisted branches: Builds, uploads artifacts, and triggers +# the aggregator workflow in steel-website for deployment +# +# Site structure at steel.ethereum.foundation/docs/execution-specs/: +# /docs/execution-specs/ - Default branch docs (mirrored) +# /docs/execution-specs/specs/reference/ - Default branch spec reference (mirrored) +# /docs/execution-specs// - Branch-specific docs +# /docs/execution-specs//specs/reference - Branch-specific spec reference (docc output) + +name: Build Docs + +on: + push: + # Branches that auto-publish on push. Other allowlisted branches in + # .github/configs/docs-branches.yaml publish only via workflow_dispatch + # (use the `ref:` input to publish a tag/SHA). + branches: + - mainnet + - forks/amsterdam + paths: &docs_paths + - "src/ethereum/**" + - "src/ethereum_spec_tools/docc.py" + - "src/ethereum_spec_tools/forks.py" + - "static/**" + - "docs/**" + - "packages/testing/**" + - "*.md" + - "mkdocs.yml" + - "uv.lock" + - "pyproject.toml" + - ".github/workflows/docs-build.yaml" + - ".github/configs/docs-branches.yaml" + + pull_request: + paths: *docs_paths + + workflow_dispatch: + inputs: + branch: + description: "Branch to publish under. Must be in the allowlist (see .github/configs/docs-branches.yaml)." + required: true + type: string + default: forks/amsterdam + ref: + description: "Ref to build: branch name, tag (e.g. v1.2.3), or commit SHA. Empty = tip of the branch above." + required: false + type: string + default: "" + +concurrency: + group: docs-build-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + lint-md: + name: "Lint Markdown" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + # TODO: Still on node20 — update when upstream releases a node22+ version + - uses: DavidAnson/markdownlint-cli2-action@07035fd053f7be764496c0f8d8f9f41f98305101 # v22.0.0 + with: + globs: | + docs/**/*.md + *.md + + changelog: + name: "Validate Changelog Entries" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: ./.github/actions/setup-uv + - name: Run changelog validation + run: just changelog + + check-should-publish: + name: "Check Should Publish" + runs-on: ubuntu-latest + needs: [lint-md, changelog] + outputs: + should_publish: ${{ steps.check.outputs.should_publish }} + branch: ${{ steps.check.outputs.branch }} + branch_artifact_name: ${{ steps.check.outputs.branch_artifact_name }} + commit_sha: ${{ steps.check.outputs.commit_sha }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + sparse-checkout: .github/configs/docs-branches.yaml + sparse-checkout-cone-mode: false + + - name: Resolve publish configuration + id: check + env: + BRANCH_INPUT: ${{ github.event.inputs.branch || github.ref_name }} + REF_INPUT: ${{ github.event.inputs.ref }} + EVENT_NAME: ${{ github.event_name }} + GH_TOKEN: ${{ github.token }} + run: | + echo "branch=$BRANCH_INPUT" >> "$GITHUB_OUTPUT" + + # Create artifact-safe name (replace / with -) + BRANCH_ARTIFACT_NAME="${BRANCH_INPUT//\//-}" + echo "branch_artifact_name=$BRANCH_ARTIFACT_NAME" >> "$GITHUB_OUTPUT" + + # Extract branch paths from allowlist config + ALLOWLISTED_BRANCHES=$(yq '.branches[].path' .github/configs/docs-branches.yaml 2>/dev/null || echo "") + + if [ -z "$ALLOWLISTED_BRANCHES" ]; then + echo "ERROR: Could not read allowlist from .github/configs/docs-branches.yaml" + exit 1 + fi + + # Check if branch is in allowlist + if echo "$ALLOWLISTED_BRANCHES" | grep -qxF "$BRANCH_INPUT"; then + SHOULD_PUBLISH="true" + else + SHOULD_PUBLISH="false" + fi + echo "should_publish=$SHOULD_PUBLISH" >> "$GITHUB_OUTPUT" + + # Resolve the concrete SHA we will build, so metadata.json and the + # aggregator dispatch payload match what the build jobs check out. + # + # On push, GITHUB_SHA is the pushed commit; using it avoids a race + # where another push lands between the event and a `gh api` lookup. + # On workflow_dispatch, the user may specify any branch/tag/SHA via + # the `ref` input (empty falls back to the branch tip), and + # github.sha points at whatever ref the dispatch was launched from + # (often the default branch), so we resolve via the API. + if [ "$EVENT_NAME" != "pull_request" ] && [ "$SHOULD_PUBLISH" = "true" ]; then + if [ "$EVENT_NAME" = "push" ]; then + COMMIT_SHA="$GITHUB_SHA" + else + RESOLVE_REF="${REF_INPUT:-$BRANCH_INPUT}" + COMMIT_SHA=$(gh api "repos/${GITHUB_REPOSITORY}/commits/${RESOLVE_REF}" --jq .sha 2>/dev/null || true) + if [ -z "$COMMIT_SHA" ]; then + echo "ERROR: could not resolve commit SHA for ref '${RESOLVE_REF}'" + exit 1 + fi + fi + echo "commit_sha=$COMMIT_SHA" >> "$GITHUB_OUTPUT" + fi + + # Write job summary + { + echo "## Check Should Publish" + echo "" + echo "| Setting | Value |" + echo "|---------|-------|" + echo "| **Branch** | \`$BRANCH_INPUT\` |" + if [ -n "$REF_INPUT" ]; then + echo "| **Ref** | \`$REF_INPUT\` |" + fi + if [ -n "${COMMIT_SHA:-}" ]; then + echo "| **Resolved SHA** | \`${COMMIT_SHA:0:7}\` |" + fi + echo "| **Event** | \`$EVENT_NAME\` |" + echo "| **Allowlisted** | $SHOULD_PUBLISH |" + echo "" + + if [ "$EVENT_NAME" = "pull_request" ]; then + echo "-> **Build only** -- pull request; artifacts are not published." + elif [ "$SHOULD_PUBLISH" = "true" ]; then + echo "-> **Will publish** at " + echo "" + echo "_Note: the URL only resolves if \`${BRANCH_INPUT}\` is also configured in steel-website's \`BRANCH_CONFIG\` (\`deploy.yml\`). If not, the aggregator will receive the dispatch but drop the artifact._" + else + echo "-> **Skipping publish** -- branch is not in the allowlist (\`.github/configs/docs-branches.yaml\`)." + echo "" + echo "Allowlisted branches:" + echo "$ALLOWLISTED_BRANCHES" | while read -r b; do + echo "- \`$b\`" + done + fi + } >> "$GITHUB_STEP_SUMMARY" + + html-docs: + name: "Build HTML Docs" + runs-on: ubuntu-latest + needs: check-should-publish + # Always build for PRs (testing); only build for push if allowlisted + if: github.event_name == 'pull_request' || needs.check-should-publish.outputs.should_publish == 'true' + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event_name == 'workflow_dispatch' && needs.check-should-publish.outputs.commit_sha || '' }} + fetch-depth: 0 + submodules: recursive + + - uses: ./.github/actions/setup-uv + + - name: Build MkDocs documentation + env: + BRANCH: ${{ needs.check-should-publish.outputs.branch }} + SHOULD_PUBLISH: ${{ needs.check-should-publish.outputs.should_publish }} + run: | + if [ "$SHOULD_PUBLISH" = "true" ]; then + export SITE_URL="https://steel.ethereum.foundation/docs/execution-specs/${BRANCH}/" + else + export SITE_URL="https://example.com/docs/${BRANCH}/" + fi + + echo "Building MkDocs with SITE_URL=$SITE_URL" + just docs + + - name: Upload HTML docs artifact + if: needs.check-should-publish.outputs.should_publish == 'true' + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: docs-html-${{ needs.check-should-publish.outputs.branch_artifact_name }} + path: .just/docs/site/ + retention-days: 1 + if-no-files-found: error + + spec-docs: + name: "Build Spec Docs" + runs-on: ubuntu-latest + needs: check-should-publish + if: github.event_name == 'pull_request' || needs.check-should-publish.outputs.should_publish == 'true' + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event_name == 'workflow_dispatch' && needs.check-should-publish.outputs.commit_sha || '' }} + fetch-depth: 0 + submodules: recursive + + - uses: ./.github/actions/setup-uv + + - name: Build spec documentation + run: just docs-spec + env: + DOCC_SKIP_DIFFS: ${{ case(github.event_name == 'push' && github.ref_name == github.event.repository.default_branch, '', '1') }} + + - name: Upload spec docs artifact + if: needs.check-should-publish.outputs.should_publish == 'true' + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: docs-spec-${{ needs.check-should-publish.outputs.branch_artifact_name }} + path: .just/docs-spec/ + retention-days: 1 + if-no-files-found: error + + combine: + name: "Combine and Upload" + runs-on: ubuntu-latest + needs: [check-should-publish, html-docs, spec-docs] + if: needs.check-should-publish.outputs.should_publish == 'true' + + steps: + - name: Download HTML docs artifact + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: docs-html-${{ needs.check-should-publish.outputs.branch_artifact_name }} + path: html-docs/ + + - name: Download spec docs artifact + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: docs-spec-${{ needs.check-should-publish.outputs.branch_artifact_name }} + path: spec-docs/ + + - name: Stage combined artifact + env: + BRANCH: ${{ needs.check-should-publish.outputs.branch }} + COMMIT_SHA: ${{ needs.check-should-publish.outputs.commit_sha }} + run: | + mkdir -p "stage/${BRANCH}/specs/reference" + + # HTML docs at root of branch directory + rsync -a html-docs/ "stage/${BRANCH}/" + + # Spec reference (docc output) nested under specs/ to mirror nav hierarchy + rsync -a spec-docs/ "stage/${BRANCH}/specs/reference/" + + # Build metadata + cat > "stage/${BRANCH}/metadata.json" < +- **Repo documentation (default branch/fork)**: - **Protocol history**: [docs/specs/protocol_history.md](docs/specs/protocol_history.md) - **Versioning scheme**: [docs/specs/spec_releases.md](docs/specs/spec_releases.md) (PEP 440 compatible; hardfork encoded in the minor version, `rcN` marks devnets). diff --git a/docs/dev/docs.md b/docs/dev/docs.md index a60dc352985..96fe14f6044 100644 --- a/docs/dev/docs.md +++ b/docs/dev/docs.md @@ -1,6 +1,6 @@ # Documentation -The `execution-specs` documentation is generated via [`mkdocs`](https://www.mkdocs.org/) and (soon) hosted remotely on Github Pages at [steel.ethereum.foundation/docs/](https://steel.ethereum.foundation/docs/). +The `execution-specs` documentation is generated via [`mkdocs`](https://www.mkdocs.org/) and hosted at [steel.ethereum.foundation/docs/execution-specs/](https://steel.ethereum.foundation/docs/execution-specs/). ## Prerequisites diff --git a/docs/hooks/reference_new_tab.py b/docs/hooks/reference_new_tab.py new file mode 100644 index 00000000000..97937b0be4b --- /dev/null +++ b/docs/hooks/reference_new_tab.py @@ -0,0 +1,34 @@ +""" +Add `target="_blank"` to links pointing at the `docc`-rendered reference. + +Without this, Material's `navigation.instant` intercepts clicks and tries to +XHR-swap the target page into the current DOM, which fails silently because +`docc`'s HTML does not match Material's template markers: the URL and title +update but the body stays on the original page. `target="_blank"` makes +instant-nav opt out and forces a full-page load, matching the home page card +that already sets the attribute via `attr_list`. + +Matches every relative href form mkdocs emits for the reference page across +page depths (e.g., `reference/`, `../reference/`, `specs/reference/`, +`../../specs/reference/`). The trailing slash after `reference` prevents +matching unrelated paths like `reference_specification/`. +""" + +import re + +_A_TAG_REF = re.compile( + r']*?href="(?:\.\./)*(?:specs/)?reference/(?:index\.html)?"[^>]*?)>' +) + + +def _rewrite(match: "re.Match[str]") -> str: + attrs = match.group(1) + if "target=" in attrs: + return match.group(0) + return f'
' + + +def on_post_page(output: str, page, config) -> str: + """Rewrite anchor tags pointing at the reference to open in a new tab.""" + del page, config + return _A_TAG_REF.sub(_rewrite, output) diff --git a/docs/index.md b/docs/index.md index 277f0f58f94..c16b008cb7f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,7 +56,7 @@ EELS is a collaborative effort between Ethereum Improvement Proposals (EIP) auth Browse the rendered Python specifications for the current fork and EIP. - [:octicons-arrow-right-24: Specifications](spec/) + [:octicons-arrow-right-24: Reference ↗](specs/reference/index.md){target=_blank rel=noopener} - :material-format-list-checks: **Test Case Reference** @@ -64,7 +64,7 @@ EELS is a collaborative effort between Ethereum Improvement Proposals (EIP) auth Browse all test cases organized by fork and EIP. - [:octicons-arrow-right-24: Browse tests](tests/) + [:octicons-arrow-right-24: Browse tests](tests/index.md) diff --git a/docs/navigation.md b/docs/navigation.md index 3415721cc1a..e5344212474 100644 --- a/docs/navigation.md +++ b/docs/navigation.md @@ -11,6 +11,7 @@ * [Installation Troubleshooting](getting_started/installation_troubleshooting.md) * [Getting Help](getting_started/getting_help.md) * [Specifications](specs/index.md) + * [Reference ↗](specs/reference/index.md) * [Writing Specs](specs/writing_specs.md) * [Adding a New EIP](specs/adding_a_new_eip.md) * [Spec Releases](specs/spec_releases.md) diff --git a/docs/specs/index.md b/docs/specs/index.md index bbe3555553c..a7cdb96f34e 100644 --- a/docs/specs/index.md +++ b/docs/specs/index.md @@ -51,7 +51,7 @@ The trade-off is that a bug fix that applies to every fork must be applied to ev - [Adding a New EIP](adding_a_new_eip.md): the EIP lifecycle from pre-draft to final, and how to land a new EIP in EELS. - [Spec Releases](spec_releases.md): how EELS versions relate to Ethereum hardforks and devnets. - [Protocol History](protocol_history.md): the full table of mainnet hardforks, their included EIPs, and their fork manifests. -- [Rendered specification](https://ethereum.github.io/execution-specs/): the `docc`-rendered narrative view of the Python spec, with side-by-side diffs between forks. +- [Rendered specification](https://steel.ethereum.foundation/docs/execution-specs/specs/reference/): the `docc`-rendered narrative view of the Python spec, with side-by-side diffs between forks. !!! bug "Reporting a vulnerability" Care is required when filing issues or PRs for functionality that is live on Ethereum mainnet. Please report vulnerabilities and verify bounty eligibility via the [bug bounty program](https://bounty.ethereum.org). diff --git a/docs/specs/reference/index.md b/docs/specs/reference/index.md new file mode 100644 index 00000000000..73f068664f2 --- /dev/null +++ b/docs/specs/reference/index.md @@ -0,0 +1,11 @@ +# Reference + +The rendered Ethereum execution specification is generated by `docc` +from the Python source under `src/ethereum/`. + +At deploy time, this placeholder is replaced by the `docc` output. To +build the reference locally, run: + +```bash +just docs-spec +``` diff --git a/docs/specs/writing_specs.md b/docs/specs/writing_specs.md index 462dbcd5189..03f862251c6 100644 --- a/docs/specs/writing_specs.md +++ b/docs/specs/writing_specs.md @@ -119,7 +119,7 @@ The marked lines (`<-`) are now incorrectly attributed to EIP-4567 in Fork+1. In ## Changes across multiple forks -Many contributions require changes across multiple forks, organized under `src/ethereum/forks/`. When making such changes, ensure that differences between the forks are minimal and consist only of necessary differences. This produces cleaner [diff outputs](https://ethereum.github.io/execution-specs/diffs/index.html). +Many contributions require changes across multiple forks, organized under `src/ethereum/forks/`. When making such changes, ensure that differences between the forks are minimal and consist only of necessary differences. This produces cleaner [diff outputs](https://steel.ethereum.foundation/docs/execution-specs/specs/reference/diffs/index.html). When creating pull requests affecting multiple forks, we recommend submitting your PR in two steps: diff --git a/docs/writing_tests/post_mortems.md b/docs/writing_tests/post_mortems.md index b9f5dd0ec30..5c18ef41fd4 100644 --- a/docs/writing_tests/post_mortems.md +++ b/docs/writing_tests/post_mortems.md @@ -78,7 +78,7 @@ IDs of the tests added that now cover the missed scenario and link to the docume *Example:* -- [`tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm.py::test_invalid\[fork_Prague-state_test---bls_g1_truncated_input-\]`](../tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm/test_invalid/) +- [`tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm.py::test_invalid\[fork_Prague-state_test---bls_g1_truncated_input-\]`](../tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1msm/test_invalid.md) ### Framework/Documentation Changes diff --git a/mkdocs.yml b/mkdocs.yml index 9f5018c01b7..f5f9fa55257 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,9 +1,8 @@ -site_name: Ethereum Execution Layer Specifications +site_name: Ethereum Execution Specs site_description: The Ethereum Execution Layer Specifications and Tests -site_url: https://steel.ethereum.foundation/docs/ +site_url: !ENV [SITE_URL, "https://steel.ethereum.foundation/docs/execution-specs/"] repo_url: https://github.com/ethereum/execution-specs repo_name: execution-specs -edit_uri: edit/forks/amsterdam/docs/ copyright: "Copyright: 2026, Ethereum Community" plugins: @@ -32,6 +31,9 @@ plugins: - literate-nav: nav_file: navigation.md +hooks: + - docs/hooks/reference_new_tab.py + watch: - CONTRIBUTING.md - SECURITY.md diff --git a/packages/testing/src/execution_testing/config/docs.py b/packages/testing/src/execution_testing/config/docs.py index 291f6552311..21f21a1b5a8 100644 --- a/packages/testing/src/execution_testing/config/docs.py +++ b/packages/testing/src/execution_testing/config/docs.py @@ -17,8 +17,10 @@ class DocsConfig(BaseModel): GENERATE_UNTIL_FORK: str = "Amsterdam" """The fork until which documentation should be generated.""" - DOCS_BASE_URL: str = "https://steel.ethereum.foundation/docs" + DOCS_BASE_URL: str = ( + "https://steel.ethereum.foundation/docs/execution-specs" + ) - # Documentation URLs prefixed with `DOCS_URL__` to avoid conflicts - # with other URLs + # Documentation URLs prefixed with `DOCS_URL__` to avoid conflicts with + # other URLs DOCS_URL__WRITING_TESTS: str = f"{DOCS_BASE_URL}/writing_tests/" From 5a2cba1c787fe8ece487dfed7bca8e9a4dc95f2e Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Date: Sun, 26 Apr 2026 17:08:50 +0200 Subject: [PATCH 044/186] fix(justfile): make json-loader pytest step collect filled fixtures (#2754) --- Justfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Justfile b/Justfile index a35d190600e..2e53741f3d2 100644 --- a/Justfile +++ b/Justfile @@ -160,7 +160,7 @@ json-loader *args: --skip-index \ --clean \ --ignore=tests/ported_static \ - --output="{{ output_dir }}/json-loader/fixtures" \ + --output="tests/json_loader/fixtures" \ --cov-config=pyproject.toml \ --cov=ethereum \ --cov-fail-under=85 @@ -169,8 +169,7 @@ json-loader *args: -n auto --maxprocesses 6 --dist=loadfile \ --basetemp="{{ output_dir }}/json-loader/tmp" \ "$@" \ - tests/json_loader \ - "{{ output_dir }}/json-loader/fixtures" + tests/json_loader # --- Unit Tests --- From e7043cccec0466c011685b132e8853cdd7879ed3 Mon Sep 17 00:00:00 2001 From: Leo Lara Date: Sun, 26 Apr 2026 22:22:44 +0700 Subject: [PATCH 045/186] feat(scripts): use dynamic addresses in ported static tests (#2695) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert all ported static tests under `tests/ported_static/` from hard-coded addresses (literal `Address(0x…)` and `EOA(key=…)`) to dynamic allocation (`pre.fund_eoa()`, `pre.deploy_contract()` without `address=`). Tests now behave like hand-written EEST tests, where the framework picks addresses at fill time. 68 of 2151 tests become runnable under the `execute` plugin against live networks (no `pre_alloc_mutable` marker). Achieved without changing test semantics — verified by 39,002 / 39,002 trace comparisons equivalent under `exact-no-stack` against pre-conversion baseline traces. ### What changed **`scripts/filler_to_python/analyzer.py`** — bulk of the work. New analyzer logic: - Topological sort of contracts by bytecode address references; substitute known addresses with variable names (`addr_to_var`) in emitted Op expressions. - Resolve CREATE-derived addresses in post-state storage and account references via `compute_create_address(...)` (depth 2, nonce 0–15). - Coinbase pinning: any account whose address equals `env.current_coinbase` is kept hardcoded so the env's `fee_recipient` and the pre-state entry agree. - Sender pinning when post-state has unresolvable addresses or address-like storage values (>2³² ints) — keeps CREATE addresses derivable from sender consistent with baseline. - Short-PUSH detection: contracts referenced via `PUSH<20` (i.e. addresses with leading-zero bytes) are pinned to baseline addresses. - Same for EOAs (precompile-touch case): EOAs referenced via short PUSH or hint-overridden into the precompile range (``) are pinned literally at `0x01–0x10`. - Computed call targets (`address=Op.ADD/MLOAD/CALLDATALOAD/...`) and address arithmetic trigger a global hardcoded fallback. - `FORCE_HARDCODED_TESTS` allowlist (144 entries) for tests that fundamentally don't survive dynamic addresses (gas-precise tests, keccak-derived storage keys, cryptographic signatures in tx-data, CREATE2 collisions, structural pre-execution rejections). - `needs_mutable_pre` flag — emitted only when `assert_mutable()` would actually fire (sender or any account hardcoded, sender funded with non-default nonce, or any contract emitted with `nonce=0`). **`scripts/filler_to_python/ir.py`** — `use_dynamic` on `AccountIR`/`SenderIR`/`AccessListEntryIR`, `nonce` on `SenderIR`, `needs_mutable_pre` on `IntermediateTestModel`. **`scripts/filler_to_python/templates/state_test.py.j2`** — conditional rendering: `pre.fund_eoa(amount=...)` / `pre.deploy_contract(...)` for dynamic tests, `EOA(key=...)` / `pre[var] = Account(...)` / `pre.deploy_contract(..., address=Address(...))` for hardcoded ones. `@pytest.mark.pre_alloc_mutable` is only emitted when `needs_mutable_pre`. **`scripts/filler_to_python/render.py`** — `format_storage` handles string variable references; new context fields piped to the template. **`tests/ported_static/`** — all 2151 test files regenerated. 14 `@manually-enhanced` files preserved as-is via the existing skip mechanism. ### Verification | Check | Result | |---|---| | Regeneration | 2137 / 2151 OK + 14 skipped (manually-enhanced) | | `just static` | clean | | Full fill (CI mode) | 60,476 / 60,476 passed | | Full fill `--traces` | 60,476 / 60,476 passed (depends on PR #2709 in `forks/amsterdam`) | | `--verify-traces` `exact-no-stack` | **39,002 / 39,002 equivalent** | > **Note:** The trace report shows 78 additional "divergences" on 3 STRUCTURAL tests (CREATE-collision / EIP-3607). These are spurious and tracked in #2758 — an asymmetry between in-memory and disk-loaded traces in the verify-traces machinery (extends #2709). The tests themselves pass, fixtures are byte-identical to baseline, and the comparison artifact is independent of this PR. --- scripts/filler_to_python/analyzer.py | 807 +- scripts/filler_to_python/ir.py | 5 + scripts/filler_to_python/render.py | 7 +- .../templates/state_test.py.j2 | 28 +- scripts/verify_dynamic_addresses.sh | 34 + .../test_add_non_const.py | 6 +- .../test_addmod_non_const.py | 6 +- .../test_and_non_const.py | 6 +- .../test_balance_non_const.py | 6 +- .../test_byte_non_const.py | 6 +- .../test_call_non_const.py | 6 +- .../test_callcode_non_const.py | 6 +- .../test_calldatacopy_non_const.py | 6 +- .../test_calldataload_non_const.py | 2 +- .../test_codecopy_non_const.py | 6 +- .../test_create_non_const.py | 15 +- .../test_delegatecall_non_const.py | 6 +- .../test_div_non_const.py | 6 +- .../stArgsZeroOneBalance/test_eq_non_const.py | 6 +- .../test_exp_non_const.py | 6 +- .../test_extcodecopy_non_const.py | 6 +- .../test_extcodesize_non_const.py | 6 +- .../stArgsZeroOneBalance/test_gt_non_const.py | 6 +- .../test_iszero_non_const.py | 6 +- .../test_jump_non_const.py | 6 +- .../test_jumpi_non_const.py | 6 +- .../test_log0_non_const.py | 6 +- .../test_log1_non_const.py | 6 +- .../test_log2_non_const.py | 6 +- .../test_log3_non_const.py | 6 +- .../stArgsZeroOneBalance/test_lt_non_const.py | 6 +- .../test_mload_non_const.py | 6 +- .../test_mod_non_const.py | 6 +- .../test_mstore8_non_const.py | 6 +- .../test_mstore_non_const.py | 6 +- .../test_mul_non_const.py | 6 +- .../test_mulmod_non_const.py | 6 +- .../test_not_non_const.py | 2 +- .../stArgsZeroOneBalance/test_or_non_const.py | 6 +- .../test_return_non_const.py | 6 +- .../test_sdiv_non_const.py | 6 +- .../test_sgt_non_const.py | 6 +- .../test_sha3_non_const.py | 2 +- .../test_signext_non_const.py | 6 +- .../test_sload_non_const.py | 6 +- .../test_slt_non_const.py | 6 +- .../test_smod_non_const.py | 6 +- .../test_sstore_non_const.py | 6 +- .../test_sub_non_const.py | 6 +- .../test_suicide_non_const.py | 6 +- .../test_xor_non_const.py | 6 +- .../test_contract_creation_spam.py | 2 +- .../stAttackTest/test_crashing_transaction.py | 10 +- .../stBadOpcode/test_eip2315_not_removed.py | 7 +- .../stBadOpcode/test_invalid_addr.py | 6 +- .../stBadOpcode/test_measure_gas.py | 184 +- .../stBadOpcode/test_operation_diff_gas.py | 184 +- ...s_tue_07_58_41_minus_15153_minus_575192.py | 7 +- ...7_58_41_minus_15153_minus_575192_london.py | 7 +- ...copy_python_bug_tue_03_48_41_minus_1432.py | 11 +- .../stBugs/test_staticcall_createfails.py | 6 +- .../test_call_oog_additional_gas_costs1.py | 24 +- .../test_call_oog_additional_gas_costs2.py | 22 +- .../stCallCodes/test_callcall_00.py | 67 +- .../stCallCodes/test_callcall_00_ooge.py | 49 +- .../test_callcall_00_ooge_value_transfer.py | 49 +- .../test_callcall_00_suicide_end.py | 22 +- .../stCallCodes/test_callcallcall_000.py | 70 +- .../stCallCodes/test_callcallcall_000_ooge.py | 52 +- .../test_callcallcall_000_oogm_after.py | 48 +- .../test_callcallcall_000_oogm_before.py | 52 +- .../test_callcallcall_000_suicide_end.py | 22 +- .../test_callcallcall_000_suicide_middle.py | 22 +- .../test_callcallcall_abcb_recursive.py | 6 +- .../stCallCodes/test_callcallcallcode_001.py | 74 +- .../test_callcallcallcode_001_ooge.py | 56 +- .../test_callcallcallcode_001_oogm_after.py | 52 +- .../test_callcallcallcode_001_oogm_before.py | 56 +- .../test_callcallcallcode_001_suicide_end.py | 22 +- ...est_callcallcallcode_001_suicide_middle.py | 22 +- .../test_callcallcallcode_abcb_recursive.py | 6 +- .../stCallCodes/test_callcallcode_01.py | 67 +- .../stCallCodes/test_callcallcode_01_ooge.py | 49 +- .../test_callcallcode_01_suicide_end.py | 22 +- .../stCallCodes/test_callcallcodecall_010.py | 70 +- .../test_callcallcodecall_010_ooge.py | 52 +- .../test_callcallcodecall_010_oogm_after.py | 48 +- .../test_callcallcodecall_010_oogm_before.py | 52 +- .../test_callcallcodecall_010_suicide_end.py | 22 +- ...est_callcallcodecall_010_suicide_middle.py | 22 +- .../test_callcallcodecall_abcb_recursive.py | 6 +- .../test_callcallcodecallcode_011.py | 74 +- .../test_callcallcodecallcode_011_ooge.py | 56 +- ...est_callcallcodecallcode_011_oogm_after.py | 52 +- ...st_callcallcodecallcode_011_oogm_before.py | 56 +- ...st_callcallcodecallcode_011_suicide_end.py | 22 +- ...callcallcodecallcode_011_suicide_middle.py | 22 +- ...est_callcallcodecallcode_abcb_recursive.py | 6 +- .../stCallCodes/test_callcode_check_pc.py | 24 +- .../stCallCodes/test_callcode_dynamic_code.py | 38 +- .../test_callcode_dynamic_code2_self_call.py | 18 +- .../test_callcode_emptycontract.py | 7 +- ..._callcode_in_initcode_to_empty_contract.py | 2 +- ..._exis_contract_with_v_transfer_ne_money.py | 42 +- ...llcode_in_initcode_to_existing_contract.py | 42 +- ...o_existing_contract_with_value_transfer.py | 2 +- .../stCallCodes/test_callcodecall_10.py | 67 +- .../stCallCodes/test_callcodecall_10_ooge.py | 49 +- .../test_callcodecall_10_suicide_end.py | 22 +- .../stCallCodes/test_callcodecallcall_100.py | 74 +- .../test_callcodecallcall_100_ooge.py | 56 +- .../test_callcodecallcall_100_oogm_after.py | 52 +- .../test_callcodecallcall_100_oogm_before.py | 56 +- .../test_callcodecallcall_100_suicide_end.py | 22 +- ...est_callcodecallcall_100_suicide_middle.py | 22 +- .../test_callcodecallcall_abcb_recursive.py | 6 +- .../test_callcodecallcallcode_101.py | 70 +- .../test_callcodecallcallcode_101_ooge.py | 52 +- ...est_callcodecallcallcode_101_oogm_after.py | 48 +- ...st_callcodecallcallcode_101_oogm_before.py | 52 +- ...st_callcodecallcallcode_101_suicide_end.py | 22 +- ...callcodecallcallcode_101_suicide_middle.py | 22 +- ...est_callcodecallcallcode_abcb_recursive.py | 6 +- .../stCallCodes/test_callcodecallcode_11.py | 67 +- .../test_callcodecallcode_11_ooge.py | 49 +- .../test_callcodecallcode_11_suicide_end.py | 22 +- .../test_callcodecallcodecall_110.py | 74 +- .../test_callcodecallcodecall_110_ooge.py | 56 +- ...est_callcodecallcodecall_110_oogm_after.py | 52 +- ...st_callcodecallcodecall_110_oogm_before.py | 56 +- ...st_callcodecallcodecall_110_suicide_end.py | 22 +- ...callcodecallcodecall_110_suicide_middle.py | 22 +- ...est_callcodecallcodecall_abcb_recursive.py | 6 +- .../test_callcodecallcodecallcode_111.py | 70 +- .../test_callcodecallcodecallcode_111_ooge.py | 52 +- ...callcodecallcodecallcode_111_oogm_after.py | 48 +- ...allcodecallcodecallcode_111_oogm_before.py | 52 +- ...allcodecallcodecallcode_111_suicide_end.py | 22 +- ...codecallcodecallcode_111_suicide_middle.py | 22 +- ...callcodecallcodecallcode_abcb_recursive.py | 6 +- .../test_call1024_balance_too_low.py | 9 +- .../test_call1024_oog.py | 9 +- .../test_call_lose_gas_oog.py | 9 +- .../test_call_output1.py | 20 +- .../test_call_output2.py | 20 +- .../test_call_output3.py | 20 +- .../test_call_output3_fail.py | 20 +- .../test_call_output3partial.py | 20 +- .../test_call_output3partial_fail.py | 20 +- .../test_call_recursive_bomb_pre_call.py | 50 +- .../test_call_with_high_value.py | 24 +- .../test_call_with_high_value_and_gas_oog.py | 24 +- ...all_with_high_value_and_oo_gat_tx_level.py | 28 +- .../test_call_with_high_value_oo_gin_call.py | 28 +- .../test_callcode1024_balance_too_low.py | 9 +- .../test_callcode1024_oog.py | 9 +- .../test_callcode_lose_gas_oog.py | 9 +- .../test_callcode_output1.py | 20 +- .../test_callcode_output2.py | 20 +- .../test_callcode_output3.py | 20 +- .../test_callcode_output3_fail.py | 20 +- .../test_callcode_output3partial.py | 20 +- .../test_callcode_output3partial_fail.py | 20 +- .../test_callcode_with_high_value.py | 28 +- ...st_callcode_with_high_value_and_gas_oog.py | 28 +- ..._ask_more_gas_then_transaction_provided.py | 16 +- .../test_create_fail_balance_too_low.py | 2 +- ...t_create_init_fail_bad_jump_destination.py | 2 +- ..._create_init_fail_bad_jump_destination2.py | 2 +- .../test_create_init_fail_oo_gduring_init.py | 2 +- .../test_create_init_fail_oo_gduring_init2.py | 7 +- ...te_init_fail_stack_size_larger_than1024.py | 2 +- .../test_create_init_fail_stack_underflow.py | 2 +- ..._create_init_fail_undefined_instruction.py | 53 +- ...create_init_fail_undefined_instruction2.py | 2 +- .../test_create_init_oo_gfor_create.py | 7 +- .../test_create_js_example_contract.py | 15 +- .../test_create_js_no_collision.py | 16 +- .../test_create_name_registrator_per_txs.py | 8 +- ...name_registrator_per_txs_not_enough_gas.py | 8 +- ...e_registrator_pre_store1_not_enough_gas.py | 7 +- ...eate_name_registratorendowment_too_high.py | 7 +- .../test_callcallcallcode_001.py | 72 +- .../test_callcallcallcode_001_ooge.py | 58 +- .../test_callcallcallcode_001_oogm_after.py | 54 +- .../test_callcallcallcode_001_oogm_before.py | 58 +- .../test_callcallcallcode_001_suicide_end.py | 22 +- ...est_callcallcallcode_001_suicide_middle.py | 22 +- .../test_callcallcallcode_abcb_recursive.py | 6 +- .../test_callcallcode_01.py | 67 +- .../test_callcallcode_01_ooge.py | 49 +- .../test_callcallcode_01_suicide_end.py | 22 +- .../test_callcallcodecall_010.py | 74 +- .../test_callcallcodecall_010_ooge.py | 52 +- .../test_callcallcodecall_010_oogm_after.py | 48 +- .../test_callcallcodecall_010_oogm_before.py | 52 +- .../test_callcallcodecall_010_suicide_end.py | 22 +- ...est_callcallcodecall_010_suicide_middle.py | 22 +- .../test_callcallcodecall_abcb_recursive.py | 6 +- .../test_callcallcodecallcode_011.py | 74 +- .../test_callcallcodecallcode_011_ooge.py | 58 +- ...est_callcallcodecallcode_011_oogm_after.py | 54 +- ...st_callcallcodecallcode_011_oogm_before.py | 58 +- ...st_callcallcodecallcode_011_suicide_end.py | 22 +- ...callcallcodecallcode_011_suicide_middle.py | 22 +- ...est_callcallcodecallcode_abcb_recursive.py | 6 +- .../test_callcodecall_10.py | 65 +- .../test_callcodecall_10_ooge.py | 47 +- .../test_callcodecall_10_suicide_end.py | 22 +- .../test_callcodecallcall_100.py | 74 +- .../test_callcodecallcall_100_ooge.py | 58 +- .../test_callcodecallcall_100_oogm_after.py | 54 +- .../test_callcodecallcall_100_oogm_before.py | 58 +- .../test_callcodecallcall_100_suicide_end.py | 22 +- ...est_callcodecallcall_100_suicide_middle.py | 22 +- .../test_callcodecallcall_abcb_recursive.py | 6 +- .../test_callcodecallcallcode_101.py | 72 +- .../test_callcodecallcallcode_101_ooge.py | 52 +- ...est_callcodecallcallcode_101_oogm_after.py | 48 +- ...st_callcodecallcallcode_101_oogm_before.py | 52 +- ...st_callcodecallcallcode_101_suicide_end.py | 22 +- ...callcodecallcallcode_101_suicide_middle.py | 22 +- ...est_callcodecallcallcode_abcb_recursive.py | 6 +- .../test_callcodecallcode_11.py | 65 +- .../test_callcodecallcode_11_ooge.py | 47 +- .../test_callcodecallcode_11_suicide_end.py | 22 +- .../test_callcodecallcodecall_110.py | 78 +- .../test_callcodecallcodecall_110_ooge.py | 58 +- ...est_callcodecallcodecall_110_oogm_after.py | 54 +- ...st_callcodecallcodecall_110_oogm_before.py | 58 +- ...st_callcodecallcodecall_110_suicide_end.py | 22 +- ...callcodecallcodecall_110_suicide_middle.py | 22 +- ...est_callcodecallcodecall_abcb_recursive.py | 6 +- .../test_callcodecallcodecallcode_111.py | 68 +- .../test_callcodecallcodecallcode_111_ooge.py | 52 +- ...callcodecallcodecallcode_111_oogm_after.py | 48 +- ...allcodecallcodecallcode_111_oogm_before.py | 52 +- ...allcodecallcodecallcode_111_suicide_end.py | 22 +- ...codecallcodecallcode_111_suicide_middle.py | 22 +- ...callcodecallcodecallcode_abcb_recursive.py | 6 +- .../test_callcallcallcode_001.py | 72 +- .../test_callcallcallcode_001_ooge.py | 58 +- .../test_callcallcallcode_001_oogm_after.py | 54 +- .../test_callcallcallcode_001_oogm_before.py | 58 +- .../test_callcallcallcode_001_suicide_end.py | 22 +- ...est_callcallcallcode_001_suicide_middle.py | 22 +- .../test_callcallcallcode_abcb_recursive.py | 6 +- .../test_callcallcode_01.py | 67 +- .../test_callcallcode_01_ooge.py | 49 +- .../test_callcallcode_01_suicide_end.py | 22 +- .../test_callcallcodecall_010.py | 80 +- .../test_callcallcodecall_010_ooge.py | 52 +- .../test_callcallcodecall_010_oogm_after.py | 48 +- .../test_callcallcodecall_010_oogm_before.py | 52 +- .../test_callcallcodecall_010_suicide_end.py | 22 +- ...est_callcallcodecall_010_suicide_middle.py | 22 +- .../test_callcallcodecall_abcb_recursive.py | 6 +- .../test_callcallcodecallcode_011.py | 72 +- .../test_callcallcodecallcode_011_ooge.py | 58 +- ...est_callcallcodecallcode_011_oogm_after.py | 54 +- ...st_callcallcodecallcode_011_oogm_before.py | 58 +- ...st_callcallcodecallcode_011_suicide_end.py | 22 +- ...callcallcodecallcode_011_suicide_middle.py | 22 +- ...est_callcallcodecallcode_abcb_recursive.py | 6 +- .../test_callcodecall_10.py | 65 +- .../test_callcodecall_10_ooge.py | 47 +- .../test_callcodecall_10_suicide_end.py | 22 +- .../test_callcodecallcall_100.py | 80 +- .../test_callcodecallcall_100_ooge.py | 58 +- .../test_callcodecallcall_100_oogm_after.py | 54 +- .../test_callcodecallcall_100_oogm_before.py | 58 +- .../test_callcodecallcall_100_suicide_end.py | 22 +- ...est_callcodecallcall_100_suicide_middle.py | 22 +- .../test_callcodecallcall_abcb_recursive.py | 6 +- .../test_callcodecallcallcode_101.py | 78 +- .../test_callcodecallcallcode_101_ooge.py | 52 +- ...est_callcodecallcallcode_101_oogm_after.py | 48 +- ...st_callcodecallcallcode_101_oogm_before.py | 52 +- ...st_callcodecallcallcode_101_suicide_end.py | 22 +- ...callcodecallcallcode_101_suicide_middle.py | 22 +- ...est_callcodecallcallcode_abcb_recursive.py | 6 +- .../test_callcodecallcode_11.py | 65 +- .../test_callcodecallcode_11_ooge.py | 47 +- .../test_callcodecallcode_11_suicide_end.py | 22 +- .../test_callcodecallcodecall_110.py | 84 +- .../test_callcodecallcodecall_110_ooge.py | 58 +- ...est_callcodecallcodecall_110_oogm_after.py | 54 +- ...st_callcodecallcodecall_110_oogm_before.py | 58 +- ...st_callcodecallcodecall_110_suicide_end.py | 22 +- ...callcodecallcodecall_110_suicide_middle.py | 22 +- ...est_callcodecallcodecall_abcb_recursive.py | 6 +- .../test_callcodecallcodecallcode_111.py | 66 +- .../test_callcodecallcodecallcode_111_ooge.py | 52 +- ...callcodecallcodecallcode_111_oogm_after.py | 48 +- ...allcodecallcodecallcode_111_oogm_before.py | 52 +- ...allcodecallcodecallcode_111_suicide_end.py | 22 +- ...codecallcodecallcode_111_suicide_middle.py | 22 +- ...callcodecallcodecallcode_abcb_recursive.py | 6 +- ...opy_target_range_longer_than_code_tests.py | 30 +- .../test_ext_code_copy_tests_paris.py | 42 +- .../stCodeSizeLimit/test_codesize_init.py | 8 +- .../test_codesize_oog_invalid_size.py | 8 +- .../stCodeSizeLimit/test_codesize_valid.py | 8 +- .../test_create_code_size_limit.py | 9 +- ..._create2_successful_then_returndatasize.py | 10 +- ..._create2_successful_then_returndatasize.py | 4 +- .../stCreate2/test_create2_bounds.py | 9 +- .../stCreate2/test_create2_bounds2.py | 9 +- .../stCreate2/test_create2_bounds3.py | 9 +- ...cide_during_init_then_store_then_return.py | 30 +- ..._create2_oo_gafter_init_code_returndata.py | 7 +- ...create2_oo_gafter_init_code_returndata3.py | 26 +- ...te2_oo_gafter_init_code_returndata_size.py | 7 +- ...test_create2_oo_gafter_init_code_revert.py | 22 +- ...est_create2_oo_gafter_init_code_revert2.py | 22 +- .../test_create2_oog_from_call_refunds.py | 410 +- .../stCreate2/test_create2_smart_init_code.py | 2 +- .../stCreate2/test_create2call_precompiles.py | 6 +- .../test_create2check_fields_in_initcode.py | 200 +- ...atacopy_0_0_following_successful_create.py | 2 +- ...est_returndatacopy_after_failing_create.py | 7 +- .../test_returndatacopy_following_create.py | 2 +- ...turndatacopy_following_revert_in_create.py | 2 +- ...urndatacopy_following_successful_create.py | 7 +- ...urndatasize_following_successful_create.py | 7 +- .../test_revert_depth_create2_oog.py | 22 +- .../test_revert_depth_create2_oog_berlin.py | 22 +- ...t_revert_depth_create_address_collision.py | 20 +- ...t_depth_create_address_collision_berlin.py | 20 +- .../stCreate2/test_revert_opcode_create.py | 7 +- ...revert_opcode_in_create_returns_create2.py | 7 +- .../stCreateTest/test_code_in_constructor.py | 19 +- .../stCreateTest/test_create2_refund_ef.py | 2 +- .../test_create_address_warm_after_fail.py | 84 +- .../test_create_collision_results.py | 24 +- .../test_create_collision_to_empty2.py | 9 +- .../test_create_contract_return_big_offset.py | 8 +- ...test_create_contract_sstore_during_init.py | 8 +- ...e_contract_create_e_contract_in_init_tr.py | 7 +- ...tract_create_ne_contract_in_init_oog_tr.py | 17 +- ..._contract_create_ne_contract_in_init_tr.py | 13 +- ..._contract_then_call_to_non_existent_acc.py | 2 +- ...empty000_createin_init_code_transaction.py | 11 +- .../test_create_empty_contract.py | 9 +- ..._create_empty_contract_and_call_it_0wei.py | 8 +- ..._create_empty_contract_and_call_it_1wei.py | 8 +- ...test_create_empty_contract_with_balance.py | 9 +- ...test_create_empty_contract_with_storage.py | 2 +- ..._contract_with_storage_and_call_it_0wei.py | 8 +- ..._contract_with_storage_and_call_it_1wei.py | 8 +- .../stCreateTest/test_create_fail_result.py | 257 +- .../stCreateTest/test_create_large_result.py | 11 +- .../test_create_oo_gafter_init_code.py | 7 +- ...t_create_oo_gafter_init_code_returndata.py | 7 +- ..._create_oo_gafter_init_code_returndata3.py | 26 +- ...ate_oo_gafter_init_code_returndata_size.py | 7 +- .../test_create_oo_gafter_init_code_revert.py | 42 +- ...test_create_oo_gafter_init_code_revert2.py | 20 +- .../test_create_oo_gafter_max_codesize.py | 7 +- .../test_create_oog_from_call_refunds.py | 444 +- .../stCreateTest/test_create_results.py | 42 +- .../test_create_transaction_call_data.py | 7 +- .../test_create_transaction_high_nonce.py | 8 +- .../test_call1024_balance_too_low.py | 9 +- .../test_call1024_oog.py | 9 +- .../test_call_lose_gas_oog.py | 9 +- .../test_call_output1.py | 20 +- .../test_call_output2.py | 20 +- .../test_call_output3.py | 20 +- .../test_call_output3partial.py | 20 +- .../test_call_output3partial_fail.py | 20 +- .../test_call_recursive_bomb_pre_call.py | 6 +- .../test_call_with_high_value_and_gas_oog.py | 28 +- .../test_callcode_lose_gas_oog.py | 9 +- .../test_callcode_output3.py | 20 +- ...st_callcode_with_high_value_and_gas_oog.py | 28 +- ...est_deleagate_call_after_value_transfer.py | 36 +- .../test_delegatecall1024.py | 9 +- .../test_delegatecall1024_oog.py | 9 +- .../test_delegatecall_and_oo_gat_tx_level.py | 28 +- .../test_delegatecall_basic.py | 28 +- .../test_delegatecall_emptycontract.py | 7 +- ...egatecall_in_initcode_to_empty_contract.py | 7 +- ...tecall_in_initcode_to_existing_contract.py | 9 +- ...ll_in_initcode_to_existing_contract_oog.py | 2 +- .../test_delegatecall_oo_gin_call.py | 28 +- .../test_delegatecall_sender_check.py | 33 +- .../test_delegatecall_value_check.py | 24 +- .../test_delegatecode_dynamic_code.py | 7 +- ...st_delegatecode_dynamic_code2_self_call.py | 8 +- ...est_10_revert_undoes_store_after_return.py | 7 +- .../test_14_revert_after_nested_staticcall.py | 7 +- .../test_trans_storage_ok.py | 486 +- .../test_trans_storage_reset.py | 44 +- ...e_consume_more_gas_then_transaction_has.py | 24 +- ...more_gas_on_depth2_then_transaction_has.py | 37 +- .../test_call_goes_oog_on_second_level.py | 47 +- .../test_call_goes_oog_on_second_level2.py | 37 +- .../test_create_and_gas_inside_create.py | 9 +- .../test_delegate_call_on_eip.py | 22 +- ..._that_ask_fore_gas_then_trabsaction_has.py | 24 +- .../test_new_gas_price_for_codes.py | 27 +- .../test_suicide_to_existing_contract.py | 6 +- .../test_suicide_to_not_existing_contract.py | 28 +- .../test_transaction64_rule_d64e0.py | 22 +- .../test_transaction64_rule_d64m1.py | 22 +- .../test_transaction64_rule_d64p1.py | 22 +- ...t_transaction64_rule_integer_boundaries.py | 7 +- .../test_eip2929.py | 99 +- .../test_eip2929_minus_ff.py | 31 +- .../test_eip2929_oog.py | 116 +- .../test_gas_cost.py | 2 +- .../test_gas_cost_berlin.py | 6 +- .../test_gas_cost_exp.py | 7 +- .../test_gas_cost_jump.py | 15 +- .../test_gas_cost_mem_seg.py | 7 +- .../test_gas_cost_memory.py | 17 +- .../test_gas_cost_return.py | 9 +- .../test_raw_balance_gas.py | 11 +- .../test_raw_call_code_gas.py | 10 +- .../test_raw_call_code_gas_ask.py | 10 +- .../test_raw_call_code_gas_memory.py | 10 +- .../test_raw_call_code_gas_memory_ask.py | 10 +- .../test_raw_call_code_gas_value_transfer.py | 10 +- ...st_raw_call_code_gas_value_transfer_ask.py | 10 +- ...raw_call_code_gas_value_transfer_memory.py | 10 +- ...call_code_gas_value_transfer_memory_ask.py | 10 +- .../test_raw_call_gas.py | 10 +- .../test_raw_call_gas_ask.py | 10 +- .../test_raw_call_gas_value_transfer.py | 10 +- .../test_raw_call_gas_value_transfer_ask.py | 10 +- ...test_raw_call_gas_value_transfer_memory.py | 10 +- ..._raw_call_gas_value_transfer_memory_ask.py | 10 +- .../test_raw_call_memory_gas.py | 10 +- .../test_raw_call_memory_gas_ask.py | 10 +- ...test_raw_create_fail_gas_value_transfer.py | 7 +- ...est_raw_create_fail_gas_value_transfer2.py | 7 +- .../test_raw_create_gas.py | 7 +- .../test_raw_create_gas_memory.py | 7 +- .../test_raw_create_gas_value_transfer.py | 7 +- ...st_raw_create_gas_value_transfer_memory.py | 7 +- .../test_raw_delegate_call_gas.py | 10 +- .../test_raw_delegate_call_gas_ask.py | 10 +- .../test_raw_delegate_call_gas_memory.py | 10 +- .../test_raw_delegate_call_gas_memory_ask.py | 10 +- .../test_raw_ext_code_copy_gas.py | 15 +- .../test_raw_ext_code_copy_memory_gas.py | 13 +- .../test_raw_ext_code_size_gas.py | 12 +- .../stEIP1559/test_base_fee_diff_places.py | 368 +- .../test_base_fee_diff_places_osaka.py | 368 +- .../stEIP1559/test_gas_price_diff_places.py | 354 +- .../test_gas_price_diff_places_osaka.py | 354 +- .../stEIP1559/test_low_fee_cap.py | 8 +- .../stEIP1559/test_low_gas_limit.py | 7 +- .../stEIP1559/test_low_gas_price_old_types.py | 8 +- .../stEIP1559/test_out_of_funds.py | 8 +- .../stEIP1559/test_out_of_funds_old_types.py | 8 +- .../stEIP1559/test_sender_balance.py | 2 +- .../stEIP1559/test_tip_too_high.py | 8 +- .../test_transaction_intinsic_bug_paris.py | 9 +- .../stEIP1559/test_val_causes_oof.py | 8 +- .../test_call_one_v_call_suicide.py | 6 +- .../test_call_one_v_call_suicide2.py | 22 +- ...est_call_to_empty_then_call_error_paris.py | 27 +- .../test_call_zero_v_call_suicide.py | 6 +- .../stEIP158Specific/test_exp_empty.py | 7 +- .../test_extcodesize_to_epmty_paris.py | 17 +- .../test_vitalik_transaction_test_paris.py | 3 +- .../stEIP2930/test_address_opcodes.py | 30 +- .../stEIP2930/test_coinbase_t01.py | 13 +- .../stEIP2930/test_coinbase_t2.py | 13 +- .../stEIP2930/test_storage_costs.py | 52 +- .../stEIP2930/test_transaction_costs.py | 7 +- .../stEIP2930/test_varied_context.py | 730 +- .../test_coinbase_warm_account_call_gas.py | 4 +- ...est_coinbase_warm_account_call_gas_fail.py | 158 +- .../stEIP3855_push0/test_push0.py | 38 +- .../stEIP3855_push0/test_push0_gas.py | 7 +- .../test_create2_init_code_size_limit.py | 54 +- .../test_create_init_code_size_limit.py | 56 +- .../test_creation_tx_init_code_size_limit.py | 8 +- .../test_create_blobhash_tx.py | 9 +- .../test_empty_blobhash_list.py | 9 +- .../test_opcode_blobh_bounds.py | 4 +- .../test_opcode_blobhash_out_of_range.py | 4 +- .../test_wrong_blobhash_version.py | 9 +- .../stEIP5656_MCOPY/test_mcopy.py | 2 +- .../stEIP5656_MCOPY/test_mcopy_copy_cost.py | 8 +- .../test_mcopy_memory_expansion_cost.py | 8 +- tests/ported_static/stExample/test_add11.py | 2 +- .../ported_static/stExample/test_add11_yml.py | 2 +- .../stExample/test_basefee_example.py | 9 +- tests/ported_static/stExample/test_eip1559.py | 9 +- .../stExample/test_indexes_omit_example.py | 7 +- .../stExample/test_invalid_tr.py | 7 +- .../stExample/test_labels_example.py | 2 +- .../stExample/test_merge_test.py | 4 +- .../stExample/test_ranges_example.py | 2 +- .../stExample/test_yul_example.py | 7 +- ..._creation_oo_gdont_leave_empty_contract.py | 7 +- ...nt_leave_empty_contract_via_transaction.py | 14 +- .../test_create_contract_via_contract.py | 7 +- ...ate_contract_via_contract_oog_init_code.py | 13 +- ...eate_contract_via_transaction_cost53000.py | 8 +- ...ract_to_create_contract_and_call_it_oog.py | 10 +- ...all_contract_to_create_contract_no_cash.py | 7 +- ...st_call_contract_to_create_contract_oog.py | 6 +- ...ntract_to_create_contract_oog_bonus_gas.py | 10 +- ...t_which_would_create_contract_if_called.py | 15 +- ...hich_would_create_contract_in_init_code.py | 12 +- .../test_call_recursive_contract.py | 8 +- ...l_the_contract_to_create_empty_contract.py | 7 +- .../test_out_of_gas_contract_creation.py | 10 +- .../stInitCodeTest/test_return_test.py | 28 +- .../stInitCodeTest/test_return_test2.py | 32 +- ...test_stack_under_flow_contract_creation.py | 6 +- ...est_transaction_create_random_init_code.py | 6 +- ...est_transaction_create_stop_in_initcode.py | 8 +- ..._transaction_create_suicide_in_initcode.py | 6 +- .../stLogTests/test_log0_empty_mem.py | 24 +- .../test_log0_log_mem_start_too_high.py | 40 +- .../test_log0_log_memsize_too_high.py | 40 +- .../stLogTests/test_log0_log_memsize_zero.py | 34 +- .../stLogTests/test_log0_non_empty_mem.py | 34 +- .../test_log0_non_empty_mem_log_mem_size1.py | 34 +- ...empty_mem_log_mem_size1_log_mem_start31.py | 34 +- .../stLogTests/test_log1_caller.py | 28 +- .../stLogTests/test_log1_empty_mem.py | 24 +- .../test_log1_log_mem_start_too_high.py | 42 +- .../test_log1_log_memsize_too_high.py | 42 +- .../stLogTests/test_log1_log_memsize_zero.py | 34 +- .../stLogTests/test_log1_max_topic.py | 42 +- .../stLogTests/test_log1_non_empty_mem.py | 28 +- .../test_log1_non_empty_mem_log_mem_size1.py | 34 +- ...empty_mem_log_mem_size1_log_mem_start31.py | 34 +- .../stLogTests/test_log2_caller.py | 28 +- .../stLogTests/test_log2_empty_mem.py | 24 +- .../test_log2_log_mem_start_too_high.py | 44 +- .../test_log2_log_memsize_too_high.py | 44 +- .../stLogTests/test_log2_log_memsize_zero.py | 34 +- .../stLogTests/test_log2_max_topic.py | 44 +- .../stLogTests/test_log2_non_empty_mem.py | 34 +- .../test_log2_non_empty_mem_log_mem_size1.py | 34 +- ...empty_mem_log_mem_size1_log_mem_start31.py | 34 +- .../stLogTests/test_log3_caller.py | 32 +- .../stLogTests/test_log3_empty_mem.py | 30 +- .../test_log3_log_mem_start_too_high.py | 46 +- .../test_log3_log_memsize_too_high.py | 46 +- .../stLogTests/test_log3_log_memsize_zero.py | 34 +- .../stLogTests/test_log3_max_topic.py | 46 +- .../stLogTests/test_log3_non_empty_mem.py | 34 +- .../test_log3_non_empty_mem_log_mem_size1.py | 34 +- ...empty_mem_log_mem_size1_log_mem_start31.py | 34 +- .../ported_static/stLogTests/test_log3_pc.py | 32 +- .../stLogTests/test_log4_caller.py | 42 +- .../stLogTests/test_log4_empty_mem.py | 40 +- .../test_log4_log_mem_start_too_high.py | 46 +- .../test_log4_log_memsize_too_high.py | 46 +- .../stLogTests/test_log4_log_memsize_zero.py | 46 +- .../stLogTests/test_log4_max_topic.py | 46 +- .../stLogTests/test_log4_non_empty_mem.py | 46 +- .../test_log4_non_empty_mem_log_mem_size1.py | 46 +- ...empty_mem_log_mem_size1_log_mem_start31.py | 46 +- .../ported_static/stLogTests/test_log4_pc.py | 42 +- .../stLogTests/test_log_in_oog_call.py | 28 +- ...ransaction_has_with_mem_expanding_calls.py | 12 +- ...ransaction_has_with_mem_expanding_calls.py | 37 +- ..._second_level2_with_mem_expanding_calls.py | 13 +- ...n_second_level_with_mem_expanding_calls.py | 39 +- ..._inside_create_with_mem_expanding_calls.py | 9 +- ...te_call_on_eip_with_mem_expanding_calls.py | 22 +- ...ransaction_has_with_mem_expanding_calls.py | 24 +- ...rice_for_codes_with_mem_expanding_calls.py | 29 +- .../test_oo_gin_return.py | 6 +- .../stMemoryStressTest/test_call_bounds.py | 40 +- .../stMemoryStressTest/test_call_bounds2.py | 26 +- .../stMemoryStressTest/test_call_bounds2a.py | 26 +- .../stMemoryStressTest/test_call_bounds3.py | 38 +- .../test_callcode_bounds.py | 40 +- .../test_callcode_bounds2.py | 26 +- .../test_callcode_bounds3.py | 26 +- .../test_callcode_bounds4.py | 36 +- .../stMemoryStressTest/test_create_bounds.py | 9 +- .../stMemoryStressTest/test_create_bounds2.py | 9 +- .../stMemoryStressTest/test_create_bounds3.py | 9 +- .../test_delegatecall_bounds.py | 42 +- .../test_delegatecall_bounds2.py | 26 +- .../test_delegatecall_bounds3.py | 36 +- .../stMemoryStressTest/test_dup_bounds.py | 7 +- .../stMemoryStressTest/test_fill_stack.py | 7 +- .../stMemoryStressTest/test_jump_bounds.py | 7 +- .../stMemoryStressTest/test_jump_bounds2.py | 7 +- .../stMemoryStressTest/test_jumpi_bounds.py | 7 +- .../test_mload32bit_bound.py | 7 +- .../test_mload32bit_bound2.py | 7 +- .../test_mload32bit_bound_msize.py | 7 +- .../test_mload32bit_bound_return.py | 7 +- .../test_mload32bit_bound_return2.py | 7 +- .../stMemoryStressTest/test_mload_bounds.py | 7 +- .../stMemoryStressTest/test_mload_bounds2.py | 7 +- .../stMemoryStressTest/test_mload_bounds3.py | 7 +- .../stMemoryStressTest/test_mstore_bounds.py | 9 +- .../stMemoryStressTest/test_mstore_bounds2.py | 9 +- .../test_mstore_bounds2a.py | 9 +- .../stMemoryStressTest/test_pop_bounds.py | 7 +- .../stMemoryStressTest/test_return_bounds.py | 287 +- .../stMemoryStressTest/test_sload_bounds.py | 7 +- .../stMemoryStressTest/test_sstore_bounds.py | 2 +- .../test_static_call_bounds.py | 40 +- .../test_static_call_bounds2.py | 26 +- .../test_static_call_bounds2a.py | 26 +- .../test_static_call_bounds3.py | 38 +- .../ported_static/stMemoryTest/test_buffer.py | 31 +- .../stMemoryTest/test_buffer_src_offset.py | 11 +- .../test_call_data_copy_offset.py | 4 +- .../stMemoryTest/test_calldatacopy_dejavu.py | 7 +- .../stMemoryTest/test_calldatacopy_dejavu2.py | 2 +- .../stMemoryTest/test_code_copy_offset.py | 4 +- .../stMemoryTest/test_codecopy_dejavu.py | 7 +- .../stMemoryTest/test_codecopy_dejavu2.py | 7 +- .../stMemoryTest/test_extcodecopy_dejavu.py | 7 +- .../stMemoryTest/test_log1_dejavu.py | 7 +- .../stMemoryTest/test_log2_dejavu.py | 7 +- .../stMemoryTest/test_log3_dejavu.py | 7 +- .../stMemoryTest/test_log4_dejavu.py | 7 +- .../stMemoryTest/test_mem0b_single_byte.py | 7 +- .../stMemoryTest/test_mem31b_single_byte.py | 7 +- .../stMemoryTest/test_mem32b_single_byte.py | 7 +- .../stMemoryTest/test_mem32kb.py | 7 +- .../stMemoryTest/test_mem32kb_minus_1.py | 7 +- .../stMemoryTest/test_mem32kb_minus_31.py | 7 +- .../stMemoryTest/test_mem32kb_minus_32.py | 7 +- .../stMemoryTest/test_mem32kb_minus_33.py | 7 +- .../stMemoryTest/test_mem32kb_plus_1.py | 7 +- .../stMemoryTest/test_mem32kb_plus_31.py | 7 +- .../stMemoryTest/test_mem32kb_plus_32.py | 7 +- .../stMemoryTest/test_mem32kb_plus_33.py | 7 +- .../stMemoryTest/test_mem32kb_single_byte.py | 7 +- .../test_mem32kb_single_byte_minus_1.py | 7 +- .../test_mem32kb_single_byte_minus_31.py | 7 +- .../test_mem32kb_single_byte_minus_32.py | 7 +- .../test_mem32kb_single_byte_minus_33.py | 7 +- .../test_mem32kb_single_byte_plus_1.py | 7 +- .../test_mem32kb_single_byte_plus_31.py | 7 +- .../test_mem32kb_single_byte_plus_32.py | 7 +- .../test_mem32kb_single_byte_plus_33.py | 7 +- .../stMemoryTest/test_mem33b_single_byte.py | 7 +- .../stMemoryTest/test_mem64kb.py | 7 +- .../stMemoryTest/test_mem64kb_minus_1.py | 7 +- .../stMemoryTest/test_mem64kb_minus_31.py | 7 +- .../stMemoryTest/test_mem64kb_minus_32.py | 7 +- .../stMemoryTest/test_mem64kb_minus_33.py | 7 +- .../stMemoryTest/test_mem64kb_plus_1.py | 7 +- .../stMemoryTest/test_mem64kb_plus_31.py | 7 +- .../stMemoryTest/test_mem64kb_plus_32.py | 7 +- .../stMemoryTest/test_mem64kb_plus_33.py | 7 +- .../stMemoryTest/test_mem64kb_single_byte.py | 7 +- .../test_mem64kb_single_byte_minus_1.py | 7 +- .../test_mem64kb_single_byte_minus_31.py | 7 +- .../test_mem64kb_single_byte_minus_32.py | 7 +- .../test_mem64kb_single_byte_minus_33.py | 7 +- .../test_mem64kb_single_byte_plus_1.py | 7 +- .../test_mem64kb_single_byte_plus_31.py | 7 +- .../test_mem64kb_single_byte_plus_32.py | 7 +- .../test_mem64kb_single_byte_plus_33.py | 7 +- .../stMemoryTest/test_mem_copy_self.py | 2 +- .../stMemoryTest/test_mem_return.py | 7 +- .../stMemoryTest/test_mload16bit_bound.py | 7 +- .../stMemoryTest/test_mload8bit_bound.py | 7 +- .../stMemoryTest/test_mload_dejavu.py | 7 +- .../stMemoryTest/test_mstore_dejavu.py | 7 +- .../stMemoryTest/test_mstroe8_dejavu.py | 7 +- tests/ported_static/stMemoryTest/test_oog.py | 152 +- .../stMemoryTest/test_sha3_dejavu.py | 7 +- .../stMemoryTest/test_stack_limit_gas_1023.py | 7 +- .../stMemoryTest/test_stack_limit_gas_1024.py | 7 +- .../stMemoryTest/test_stack_limit_gas_1025.py | 7 +- .../test_stack_limit_push31_1023.py | 7 +- .../test_stack_limit_push31_1024.py | 7 +- .../test_stack_limit_push31_1025.py | 7 +- .../test_stack_limit_push32_1023.py | 7 +- .../test_stack_limit_push32_1024.py | 7 +- .../test_stack_limit_push32_1025.py | 7 +- ...test_non_zero_value_call_to_empty_paris.py | 12 +- ...zero_value_call_to_non_non_zero_balance.py | 12 +- ...ero_value_call_to_one_storage_key_paris.py | 2 +- ..._non_zero_value_callcode_to_empty_paris.py | 12 +- ..._value_callcode_to_non_non_zero_balance.py | 12 +- ...value_callcode_to_one_storage_key_paris.py | 2 +- ..._zero_value_delegatecall_to_empty_paris.py | 12 +- ...ue_delegatecall_to_non_non_zero_balance.py | 12 +- ...e_delegatecall_to_one_storage_key_paris.py | 2 +- ...t_non_zero_value_suicide_to_empty_paris.py | 2 +- ...o_value_suicide_to_non_non_zero_balance.py | 2 +- ..._value_suicide_to_one_storage_key_paris.py | 2 +- ...ansaction_cal_lwith_data_to_empty_paris.py | 10 +- ..._cal_lwith_data_to_non_non_zero_balance.py | 10 +- ...o_value_transaction_call_to_empty_paris.py | 10 +- ...ransaction_call_to_non_non_zero_balance.py | 10 +- .../stPreCompiledContracts/test_modexp.py | 2 +- .../test_modexp_tests.py | 7 +- .../test_precomps_eip2929_cancun.py | 48 +- .../stPreCompiledContracts/test_sec80.py | 7 +- .../test_call_ecrecover0.py | 12 +- .../test_call_ecrecover0_0input.py | 7 +- ...t_call_ecrecover0_complete_return_value.py | 11 +- .../test_call_ecrecover0_gas2999.py | 7 +- .../test_call_ecrecover0_gas3000.py | 12 +- .../test_call_ecrecover0_no_gas.py | 7 +- ...all_ecrecover0_overlapping_input_output.py | 12 +- .../test_call_ecrecover1.py | 7 +- .../test_call_ecrecover2.py | 7 +- .../test_call_ecrecover3.py | 2 +- .../test_call_ecrecover80.py | 7 +- .../test_call_ecrecover_check_length.py | 12 +- ...est_call_ecrecover_check_length_wrong_v.py | 2 +- .../test_call_ecrecover_h_prefixed0.py | 2 +- .../test_call_ecrecover_invalid_signature.py | 2 +- .../test_call_ecrecover_overflow.py | 2 +- .../test_call_ecrecover_r_prefixed0.py | 7 +- .../test_call_ecrecover_s_prefixed0.py | 2 +- .../test_call_ecrecover_unrecoverable_key.py | 2 +- .../test_call_ecrecover_v_prefixed0.py | 12 +- .../test_call_ripemd160_1.py | 2 +- .../test_call_ripemd160_2.py | 2 +- .../test_call_ripemd160_3.py | 2 +- .../test_call_ripemd160_3_postfixed0.py | 2 +- .../test_call_ripemd160_3_prefixed0.py | 2 +- .../test_call_ripemd160_4.py | 2 +- .../test_call_ripemd160_4_gas719.py | 2 +- .../test_call_ripemd160_5.py | 2 +- .../test_call_sha256_0.py | 2 +- .../test_call_sha256_1.py | 2 +- .../test_call_sha256_1_nonzero_value.py | 2 +- .../test_call_sha256_2.py | 2 +- .../test_call_sha256_3.py | 2 +- .../test_call_sha256_3_postfix0.py | 2 +- .../test_call_sha256_3_prefix0.py | 2 +- .../test_call_sha256_4.py | 2 +- .../test_call_sha256_4_gas99.py | 2 +- .../test_call_sha256_5.py | 2 +- .../test_callcode_ecrecover0.py | 12 +- .../test_callcode_ecrecover0_0input.py | 7 +- ...llcode_ecrecover0_complete_return_value.py | 11 +- .../test_callcode_ecrecover0_gas2999.py | 7 +- .../test_callcode_ecrecover0_gas3000.py | 12 +- .../test_callcode_ecrecover0_no_gas.py | 7 +- ...ode_ecrecover0_overlapping_input_output.py | 12 +- .../test_callcode_ecrecover1.py | 7 +- .../test_callcode_ecrecover2.py | 7 +- .../test_callcode_ecrecover3.py | 2 +- .../test_callcode_ecrecover80.py | 7 +- .../test_callcode_ecrecover_h_prefixed0.py | 2 +- .../test_callcode_ecrecover_r_prefixed0.py | 7 +- .../test_callcode_ecrecover_s_prefixed0.py | 2 +- .../test_callcode_ecrecover_v_prefixed0.py | 12 +- .../test_callcode_ecrecover_v_prefixedf0.py | 7 +- .../test_callcode_ripemd160_0.py | 7 +- .../test_callcode_ripemd160_1.py | 2 +- .../test_callcode_ripemd160_2.py | 2 +- .../test_callcode_ripemd160_3.py | 2 +- .../test_callcode_ripemd160_3_postfixed0.py | 2 +- .../test_callcode_ripemd160_3_prefixed0.py | 2 +- .../test_callcode_ripemd160_4.py | 2 +- .../test_callcode_ripemd160_4_gas719.py | 2 +- .../test_callcode_ripemd160_5.py | 2 +- .../test_callcode_sha256_0.py | 2 +- .../test_callcode_sha256_1.py | 2 +- .../test_callcode_sha256_1_nonzero_value.py | 2 +- .../test_callcode_sha256_2.py | 2 +- .../test_callcode_sha256_3.py | 2 +- .../test_callcode_sha256_3_postfix0.py | 2 +- .../test_callcode_sha256_3_prefix0.py | 2 +- .../test_callcode_sha256_4.py | 2 +- .../test_callcode_sha256_4_gas99.py | 2 +- .../test_callcode_sha256_5.py | 2 +- .../test_ecrecover_short_buff.py | 2 +- .../test_ecrecover_weird_v.py | 2 +- .../test_modexp_0_0_0_20500.py | 144 +- .../test_modexp_0_0_0_22000.py | 144 +- .../test_modexp_0_0_0_25000.py | 144 +- .../test_modexp_0_0_0_35000.py | 144 +- .../test_modexp_random_input.py | 8 +- .../test_call1_mb1024_calldepth.py | 9 +- .../test_call20_kbytes_contract50_1.py | 10 +- .../test_call20_kbytes_contract50_2.py | 10 +- .../test_call20_kbytes_contract50_3.py | 10 +- .../test_call50000.py | 12 +- .../test_call50000_ecrec.py | 7 +- .../test_call50000_identity.py | 7 +- .../test_call50000_identity2.py | 7 +- .../test_call50000_rip160.py | 7 +- .../test_callcode50000.py | 12 +- .../test_create1000.py | 63 +- .../test_create1000_byzantium.py | 12 +- .../test_create1000_shnghai.py | 52 +- ...atic_complexity_solidity_call_data_copy.py | 24 +- .../stRandom/test_random_statetest0.py | 7 +- .../stRandom/test_random_statetest1.py | 7 +- .../stRandom/test_random_statetest10.py | 7 +- .../stRandom/test_random_statetest100.py | 7 +- .../stRandom/test_random_statetest102.py | 34 +- .../stRandom/test_random_statetest103.py | 23 +- .../stRandom/test_random_statetest104.py | 2 +- .../stRandom/test_random_statetest105.py | 34 +- .../stRandom/test_random_statetest106.py | 2 +- .../stRandom/test_random_statetest107.py | 34 +- .../stRandom/test_random_statetest108.py | 7 +- .../stRandom/test_random_statetest11.py | 34 +- .../stRandom/test_random_statetest110.py | 2 +- .../stRandom/test_random_statetest111.py | 7 +- .../stRandom/test_random_statetest112.py | 2 +- .../stRandom/test_random_statetest114.py | 2 +- .../stRandom/test_random_statetest115.py | 34 +- .../stRandom/test_random_statetest116.py | 34 +- .../stRandom/test_random_statetest117.py | 32 +- .../stRandom/test_random_statetest118.py | 34 +- .../stRandom/test_random_statetest119.py | 2 +- .../stRandom/test_random_statetest12.py | 34 +- .../stRandom/test_random_statetest120.py | 2 +- .../stRandom/test_random_statetest121.py | 34 +- .../stRandom/test_random_statetest122.py | 34 +- .../stRandom/test_random_statetest124.py | 2 +- .../stRandom/test_random_statetest125.py | 7 +- .../stRandom/test_random_statetest126.py | 7 +- .../stRandom/test_random_statetest129.py | 34 +- .../stRandom/test_random_statetest13.py | 39 +- .../stRandom/test_random_statetest130.py | 34 +- .../stRandom/test_random_statetest131.py | 2 +- .../stRandom/test_random_statetest133.py | 23 +- .../stRandom/test_random_statetest134.py | 39 +- .../stRandom/test_random_statetest135.py | 39 +- .../stRandom/test_random_statetest137.py | 2 +- .../stRandom/test_random_statetest138.py | 2 +- .../stRandom/test_random_statetest139.py | 7 +- .../stRandom/test_random_statetest14.py | 2 +- .../stRandom/test_random_statetest142.py | 34 +- .../stRandom/test_random_statetest143.py | 9 +- .../stRandom/test_random_statetest144.py | 4 +- .../stRandom/test_random_statetest145.py | 44 +- .../stRandom/test_random_statetest146.py | 7 +- .../stRandom/test_random_statetest147.py | 2 +- .../stRandom/test_random_statetest148.py | 28 +- .../stRandom/test_random_statetest149.py | 39 +- .../stRandom/test_random_statetest15.py | 34 +- .../stRandom/test_random_statetest150.py | 38 +- .../stRandom/test_random_statetest151.py | 7 +- .../stRandom/test_random_statetest153.py | 7 +- .../stRandom/test_random_statetest154.py | 38 +- .../stRandom/test_random_statetest155.py | 34 +- .../stRandom/test_random_statetest156.py | 2 +- .../stRandom/test_random_statetest157.py | 7 +- .../stRandom/test_random_statetest158.py | 34 +- .../stRandom/test_random_statetest159.py | 34 +- .../stRandom/test_random_statetest16.py | 23 +- .../stRandom/test_random_statetest161.py | 2 +- .../stRandom/test_random_statetest162.py | 2 +- .../stRandom/test_random_statetest163.py | 7 +- .../stRandom/test_random_statetest164.py | 36 +- .../stRandom/test_random_statetest166.py | 2 +- .../stRandom/test_random_statetest167.py | 34 +- .../stRandom/test_random_statetest169.py | 34 +- .../stRandom/test_random_statetest17.py | 7 +- .../stRandom/test_random_statetest171.py | 39 +- .../stRandom/test_random_statetest172.py | 7 +- .../stRandom/test_random_statetest173.py | 20 +- .../stRandom/test_random_statetest174.py | 7 +- .../stRandom/test_random_statetest175.py | 2 +- .../stRandom/test_random_statetest176.py | 23 +- .../stRandom/test_random_statetest177.py | 7 +- .../stRandom/test_random_statetest178.py | 38 +- .../stRandom/test_random_statetest179.py | 34 +- .../stRandom/test_random_statetest18.py | 7 +- .../stRandom/test_random_statetest180.py | 34 +- .../stRandom/test_random_statetest183.py | 32 +- .../stRandom/test_random_statetest184.py | 4 +- .../stRandom/test_random_statetest185.py | 7 +- .../stRandom/test_random_statetest187.py | 2 +- .../stRandom/test_random_statetest188.py | 2 +- .../stRandom/test_random_statetest189.py | 7 +- .../stRandom/test_random_statetest19.py | 2 +- .../stRandom/test_random_statetest190.py | 39 +- .../stRandom/test_random_statetest191.py | 34 +- .../stRandom/test_random_statetest192.py | 2 +- .../stRandom/test_random_statetest194.py | 39 +- .../stRandom/test_random_statetest195.py | 2 +- .../stRandom/test_random_statetest196.py | 39 +- .../stRandom/test_random_statetest197.py | 7 +- .../stRandom/test_random_statetest198.py | 2 +- .../stRandom/test_random_statetest199.py | 7 +- .../stRandom/test_random_statetest2.py | 34 +- .../stRandom/test_random_statetest20.py | 7 +- .../stRandom/test_random_statetest200.py | 28 +- .../stRandom/test_random_statetest201.py | 2 +- .../stRandom/test_random_statetest202.py | 7 +- .../stRandom/test_random_statetest204.py | 34 +- .../stRandom/test_random_statetest205.py | 38 +- .../stRandom/test_random_statetest206.py | 34 +- .../stRandom/test_random_statetest207.py | 7 +- .../stRandom/test_random_statetest208.py | 2 +- .../stRandom/test_random_statetest209.py | 7 +- .../stRandom/test_random_statetest210.py | 2 +- .../stRandom/test_random_statetest211.py | 7 +- .../stRandom/test_random_statetest212.py | 34 +- .../stRandom/test_random_statetest214.py | 34 +- .../stRandom/test_random_statetest215.py | 30 +- .../stRandom/test_random_statetest216.py | 34 +- .../stRandom/test_random_statetest217.py | 7 +- .../stRandom/test_random_statetest219.py | 2 +- .../stRandom/test_random_statetest22.py | 2 +- .../stRandom/test_random_statetest220.py | 32 +- .../stRandom/test_random_statetest221.py | 34 +- .../stRandom/test_random_statetest222.py | 2 +- .../stRandom/test_random_statetest225.py | 2 +- .../stRandom/test_random_statetest226.py | 39 +- .../stRandom/test_random_statetest227.py | 32 +- .../stRandom/test_random_statetest228.py | 12 +- .../stRandom/test_random_statetest23.py | 34 +- .../stRandom/test_random_statetest230.py | 7 +- .../stRandom/test_random_statetest231.py | 34 +- .../stRandom/test_random_statetest232.py | 20 +- .../stRandom/test_random_statetest233.py | 7 +- .../stRandom/test_random_statetest236.py | 2 +- .../stRandom/test_random_statetest237.py | 36 +- .../stRandom/test_random_statetest238.py | 2 +- .../stRandom/test_random_statetest24.py | 7 +- .../stRandom/test_random_statetest242.py | 34 +- .../stRandom/test_random_statetest243.py | 2 +- .../stRandom/test_random_statetest244.py | 12 +- .../stRandom/test_random_statetest245.py | 34 +- .../stRandom/test_random_statetest246.py | 7 +- .../stRandom/test_random_statetest247.py | 2 +- .../stRandom/test_random_statetest248.py | 7 +- .../stRandom/test_random_statetest249.py | 7 +- .../stRandom/test_random_statetest25.py | 7 +- .../stRandom/test_random_statetest250.py | 39 +- .../stRandom/test_random_statetest251.py | 7 +- .../stRandom/test_random_statetest252.py | 7 +- .../stRandom/test_random_statetest254.py | 2 +- .../stRandom/test_random_statetest257.py | 7 +- .../stRandom/test_random_statetest259.py | 34 +- .../stRandom/test_random_statetest26.py | 7 +- .../stRandom/test_random_statetest260.py | 7 +- .../stRandom/test_random_statetest261.py | 23 +- .../stRandom/test_random_statetest263.py | 34 +- .../stRandom/test_random_statetest264.py | 39 +- .../stRandom/test_random_statetest265.py | 7 +- .../stRandom/test_random_statetest266.py | 7 +- .../stRandom/test_random_statetest267.py | 34 +- .../stRandom/test_random_statetest268.py | 34 +- .../stRandom/test_random_statetest269.py | 34 +- .../stRandom/test_random_statetest27.py | 34 +- .../stRandom/test_random_statetest270.py | 34 +- .../stRandom/test_random_statetest271.py | 23 +- .../stRandom/test_random_statetest273.py | 2 +- .../stRandom/test_random_statetest274.py | 39 +- .../stRandom/test_random_statetest275.py | 7 +- .../stRandom/test_random_statetest276.py | 2 +- .../stRandom/test_random_statetest278.py | 2 +- .../stRandom/test_random_statetest279.py | 44 +- .../stRandom/test_random_statetest28.py | 34 +- .../stRandom/test_random_statetest280.py | 2 +- .../stRandom/test_random_statetest281.py | 30 +- .../stRandom/test_random_statetest282.py | 34 +- .../stRandom/test_random_statetest283.py | 2 +- .../stRandom/test_random_statetest285.py | 7 +- .../stRandom/test_random_statetest286.py | 34 +- .../stRandom/test_random_statetest287.py | 34 +- .../stRandom/test_random_statetest288.py | 7 +- .../stRandom/test_random_statetest29.py | 2 +- .../stRandom/test_random_statetest290.py | 34 +- .../stRandom/test_random_statetest291.py | 2 +- .../stRandom/test_random_statetest292.py | 39 +- .../stRandom/test_random_statetest293.py | 2 +- .../stRandom/test_random_statetest294.py | 7 +- .../stRandom/test_random_statetest295.py | 23 +- .../stRandom/test_random_statetest296.py | 23 +- .../stRandom/test_random_statetest297.py | 34 +- .../stRandom/test_random_statetest298.py | 32 +- .../stRandom/test_random_statetest299.py | 2 +- .../stRandom/test_random_statetest3.py | 40 +- .../stRandom/test_random_statetest30.py | 7 +- .../stRandom/test_random_statetest300.py | 7 +- .../stRandom/test_random_statetest301.py | 2 +- .../stRandom/test_random_statetest302.py | 39 +- .../stRandom/test_random_statetest303.py | 23 +- .../stRandom/test_random_statetest304.py | 7 +- .../stRandom/test_random_statetest305.py | 34 +- .../stRandom/test_random_statetest306.py | 38 +- .../stRandom/test_random_statetest307.py | 49 +- .../stRandom/test_random_statetest308.py | 34 +- .../stRandom/test_random_statetest309.py | 7 +- .../stRandom/test_random_statetest31.py | 7 +- .../stRandom/test_random_statetest310.py | 2 +- .../stRandom/test_random_statetest311.py | 34 +- .../stRandom/test_random_statetest312.py | 23 +- .../stRandom/test_random_statetest313.py | 7 +- .../stRandom/test_random_statetest315.py | 34 +- .../stRandom/test_random_statetest316.py | 7 +- .../stRandom/test_random_statetest318.py | 34 +- .../stRandom/test_random_statetest320.py | 23 +- .../stRandom/test_random_statetest321.py | 7 +- .../stRandom/test_random_statetest322.py | 2 +- .../stRandom/test_random_statetest323.py | 23 +- .../stRandom/test_random_statetest325.py | 2 +- .../stRandom/test_random_statetest326.py | 7 +- .../stRandom/test_random_statetest327.py | 7 +- .../stRandom/test_random_statetest329.py | 34 +- .../stRandom/test_random_statetest33.py | 2 +- .../stRandom/test_random_statetest332.py | 2 +- .../stRandom/test_random_statetest333.py | 34 +- .../stRandom/test_random_statetest334.py | 2 +- .../stRandom/test_random_statetest335.py | 7 +- .../stRandom/test_random_statetest336.py | 7 +- .../stRandom/test_random_statetest337.py | 7 +- .../stRandom/test_random_statetest338.py | 34 +- .../stRandom/test_random_statetest339.py | 34 +- .../stRandom/test_random_statetest340.py | 39 +- .../stRandom/test_random_statetest341.py | 39 +- .../stRandom/test_random_statetest342.py | 2 +- .../stRandom/test_random_statetest343.py | 7 +- .../stRandom/test_random_statetest345.py | 7 +- .../stRandom/test_random_statetest346.py | 7 +- .../stRandom/test_random_statetest347.py | 9 +- .../stRandom/test_random_statetest348.py | 34 +- .../stRandom/test_random_statetest349.py | 2 +- .../stRandom/test_random_statetest350.py | 7 +- .../stRandom/test_random_statetest351.py | 2 +- .../stRandom/test_random_statetest352.py | 39 +- .../stRandom/test_random_statetest353.py | 23 +- .../stRandom/test_random_statetest354.py | 34 +- .../stRandom/test_random_statetest355.py | 23 +- .../stRandom/test_random_statetest356.py | 34 +- .../stRandom/test_random_statetest357.py | 7 +- .../stRandom/test_random_statetest358.py | 34 +- .../stRandom/test_random_statetest359.py | 7 +- .../stRandom/test_random_statetest36.py | 7 +- .../stRandom/test_random_statetest360.py | 34 +- .../stRandom/test_random_statetest361.py | 2 +- .../stRandom/test_random_statetest362.py | 34 +- .../stRandom/test_random_statetest363.py | 34 +- .../stRandom/test_random_statetest364.py | 34 +- .../stRandom/test_random_statetest365.py | 9 +- .../stRandom/test_random_statetest366.py | 34 +- .../stRandom/test_random_statetest367.py | 34 +- .../stRandom/test_random_statetest368.py | 23 +- .../stRandom/test_random_statetest369.py | 2 +- .../stRandom/test_random_statetest37.py | 2 +- .../stRandom/test_random_statetest370.py | 39 +- .../stRandom/test_random_statetest371.py | 2 +- .../stRandom/test_random_statetest372.py | 34 +- .../stRandom/test_random_statetest376.py | 2 +- .../stRandom/test_random_statetest378.py | 2 +- .../stRandom/test_random_statetest379.py | 7 +- .../stRandom/test_random_statetest380.py | 2 +- .../stRandom/test_random_statetest381.py | 34 +- .../stRandom/test_random_statetest382.py | 34 +- .../stRandom/test_random_statetest383.py | 20 +- .../stRandom/test_random_statetest384.py | 2 +- .../stRandom/test_random_statetest39.py | 2 +- .../stRandom/test_random_statetest4.py | 7 +- .../stRandom/test_random_statetest41.py | 34 +- .../stRandom/test_random_statetest42.py | 2 +- .../stRandom/test_random_statetest43.py | 44 +- .../stRandom/test_random_statetest45.py | 23 +- .../stRandom/test_random_statetest47.py | 34 +- .../stRandom/test_random_statetest48.py | 38 +- .../stRandom/test_random_statetest49.py | 46 +- .../stRandom/test_random_statetest5.py | 39 +- .../stRandom/test_random_statetest51.py | 7 +- .../stRandom/test_random_statetest52.py | 2 +- .../stRandom/test_random_statetest53.py | 39 +- .../stRandom/test_random_statetest54.py | 23 +- .../stRandom/test_random_statetest55.py | 23 +- .../stRandom/test_random_statetest57.py | 7 +- .../stRandom/test_random_statetest58.py | 2 +- .../stRandom/test_random_statetest59.py | 2 +- .../stRandom/test_random_statetest6.py | 34 +- .../stRandom/test_random_statetest60.py | 2 +- .../stRandom/test_random_statetest62.py | 34 +- .../stRandom/test_random_statetest63.py | 2 +- .../stRandom/test_random_statetest64.py | 34 +- .../stRandom/test_random_statetest66.py | 34 +- .../stRandom/test_random_statetest67.py | 2 +- .../stRandom/test_random_statetest69.py | 2 +- .../stRandom/test_random_statetest72.py | 39 +- .../stRandom/test_random_statetest73.py | 34 +- .../stRandom/test_random_statetest74.py | 34 +- .../stRandom/test_random_statetest75.py | 34 +- .../stRandom/test_random_statetest77.py | 2 +- .../stRandom/test_random_statetest78.py | 23 +- .../stRandom/test_random_statetest80.py | 34 +- .../stRandom/test_random_statetest81.py | 2 +- .../stRandom/test_random_statetest82.py | 7 +- .../stRandom/test_random_statetest83.py | 2 +- .../stRandom/test_random_statetest84.py | 7 +- .../stRandom/test_random_statetest85.py | 23 +- .../stRandom/test_random_statetest87.py | 2 +- .../stRandom/test_random_statetest88.py | 34 +- .../stRandom/test_random_statetest89.py | 2 +- .../stRandom/test_random_statetest9.py | 2 +- .../stRandom/test_random_statetest90.py | 34 +- .../stRandom/test_random_statetest92.py | 34 +- .../stRandom/test_random_statetest95.py | 2 +- .../stRandom/test_random_statetest96.py | 34 +- .../stRandom/test_random_statetest97.py | 39 +- .../stRandom/test_random_statetest98.py | 36 +- .../stRandom2/test_random_statetest.py | 34 +- .../stRandom2/test_random_statetest384.py | 2 +- .../stRandom2/test_random_statetest385.py | 32 +- .../stRandom2/test_random_statetest386.py | 7 +- .../stRandom2/test_random_statetest387.py | 7 +- .../stRandom2/test_random_statetest388.py | 34 +- .../stRandom2/test_random_statetest389.py | 39 +- .../stRandom2/test_random_statetest393.py | 23 +- .../stRandom2/test_random_statetest395.py | 2 +- .../stRandom2/test_random_statetest396.py | 23 +- .../stRandom2/test_random_statetest397.py | 7 +- .../stRandom2/test_random_statetest398.py | 34 +- .../stRandom2/test_random_statetest399.py | 2 +- .../stRandom2/test_random_statetest401.py | 34 +- .../stRandom2/test_random_statetest402.py | 2 +- .../stRandom2/test_random_statetest404.py | 7 +- .../stRandom2/test_random_statetest405.py | 2 +- .../stRandom2/test_random_statetest406.py | 34 +- .../stRandom2/test_random_statetest407.py | 34 +- .../stRandom2/test_random_statetest408.py | 34 +- .../stRandom2/test_random_statetest409.py | 34 +- .../stRandom2/test_random_statetest410.py | 39 +- .../stRandom2/test_random_statetest411.py | 2 +- .../stRandom2/test_random_statetest412.py | 34 +- .../stRandom2/test_random_statetest413.py | 2 +- .../stRandom2/test_random_statetest414.py | 7 +- .../stRandom2/test_random_statetest415.py | 23 +- .../stRandom2/test_random_statetest416.py | 42 +- .../stRandom2/test_random_statetest417.py | 7 +- .../stRandom2/test_random_statetest418.py | 39 +- .../stRandom2/test_random_statetest419.py | 2 +- .../stRandom2/test_random_statetest420.py | 23 +- .../stRandom2/test_random_statetest421.py | 2 +- .../stRandom2/test_random_statetest422.py | 39 +- .../stRandom2/test_random_statetest424.py | 34 +- .../stRandom2/test_random_statetest425.py | 2 +- .../stRandom2/test_random_statetest426.py | 34 +- .../stRandom2/test_random_statetest428.py | 7 +- .../stRandom2/test_random_statetest429.py | 34 +- .../stRandom2/test_random_statetest430.py | 34 +- .../stRandom2/test_random_statetest433.py | 23 +- .../stRandom2/test_random_statetest435.py | 2 +- .../stRandom2/test_random_statetest436.py | 34 +- .../stRandom2/test_random_statetest437.py | 34 +- .../stRandom2/test_random_statetest438.py | 7 +- .../stRandom2/test_random_statetest439.py | 34 +- .../stRandom2/test_random_statetest440.py | 32 +- .../stRandom2/test_random_statetest442.py | 4 +- .../stRandom2/test_random_statetest443.py | 39 +- .../stRandom2/test_random_statetest444.py | 7 +- .../stRandom2/test_random_statetest445.py | 23 +- .../stRandom2/test_random_statetest446.py | 2 +- .../stRandom2/test_random_statetest447.py | 34 +- .../stRandom2/test_random_statetest448.py | 39 +- .../stRandom2/test_random_statetest449.py | 39 +- .../stRandom2/test_random_statetest450.py | 39 +- .../stRandom2/test_random_statetest451.py | 34 +- .../stRandom2/test_random_statetest452.py | 34 +- .../stRandom2/test_random_statetest454.py | 39 +- .../stRandom2/test_random_statetest455.py | 34 +- .../stRandom2/test_random_statetest456.py | 7 +- .../stRandom2/test_random_statetest457.py | 2 +- .../stRandom2/test_random_statetest458.py | 38 +- .../stRandom2/test_random_statetest460.py | 2 +- .../stRandom2/test_random_statetest461.py | 7 +- .../stRandom2/test_random_statetest462.py | 30 +- .../stRandom2/test_random_statetest464.py | 2 +- .../stRandom2/test_random_statetest465.py | 39 +- .../stRandom2/test_random_statetest466.py | 7 +- .../stRandom2/test_random_statetest467.py | 38 +- .../stRandom2/test_random_statetest469.py | 7 +- .../stRandom2/test_random_statetest470.py | 2 +- .../stRandom2/test_random_statetest471.py | 2 +- .../stRandom2/test_random_statetest472.py | 39 +- .../stRandom2/test_random_statetest473.py | 39 +- .../stRandom2/test_random_statetest474.py | 2 +- .../stRandom2/test_random_statetest475.py | 41 +- .../stRandom2/test_random_statetest476.py | 7 +- .../stRandom2/test_random_statetest477.py | 34 +- .../stRandom2/test_random_statetest478.py | 7 +- .../stRandom2/test_random_statetest480.py | 2 +- .../stRandom2/test_random_statetest481.py | 7 +- .../stRandom2/test_random_statetest482.py | 34 +- .../stRandom2/test_random_statetest483.py | 39 +- .../stRandom2/test_random_statetest484.py | 23 +- .../stRandom2/test_random_statetest485.py | 7 +- .../stRandom2/test_random_statetest487.py | 2 +- .../stRandom2/test_random_statetest488.py | 34 +- .../stRandom2/test_random_statetest489.py | 34 +- .../stRandom2/test_random_statetest491.py | 2 +- .../stRandom2/test_random_statetest493.py | 34 +- .../stRandom2/test_random_statetest494.py | 7 +- .../stRandom2/test_random_statetest495.py | 20 +- .../stRandom2/test_random_statetest496.py | 7 +- .../stRandom2/test_random_statetest497.py | 7 +- .../stRandom2/test_random_statetest498.py | 34 +- .../stRandom2/test_random_statetest499.py | 7 +- .../stRandom2/test_random_statetest500.py | 34 +- .../stRandom2/test_random_statetest501.py | 2 +- .../stRandom2/test_random_statetest502.py | 34 +- .../stRandom2/test_random_statetest503.py | 2 +- .../stRandom2/test_random_statetest504.py | 23 +- .../stRandom2/test_random_statetest505.py | 2 +- .../stRandom2/test_random_statetest506.py | 34 +- .../stRandom2/test_random_statetest507.py | 34 +- .../stRandom2/test_random_statetest508.py | 2 +- .../stRandom2/test_random_statetest509.py | 7 +- .../stRandom2/test_random_statetest510.py | 34 +- .../stRandom2/test_random_statetest511.py | 34 +- .../stRandom2/test_random_statetest512.py | 34 +- .../stRandom2/test_random_statetest513.py | 7 +- .../stRandom2/test_random_statetest514.py | 2 +- .../stRandom2/test_random_statetest516.py | 2 +- .../stRandom2/test_random_statetest517.py | 2 +- .../stRandom2/test_random_statetest518.py | 34 +- .../stRandom2/test_random_statetest519.py | 20 +- .../stRandom2/test_random_statetest520.py | 2 +- .../stRandom2/test_random_statetest521.py | 34 +- .../stRandom2/test_random_statetest523.py | 7 +- .../stRandom2/test_random_statetest524.py | 7 +- .../stRandom2/test_random_statetest525.py | 7 +- .../stRandom2/test_random_statetest526.py | 30 +- .../stRandom2/test_random_statetest527.py | 39 +- .../stRandom2/test_random_statetest528.py | 7 +- .../stRandom2/test_random_statetest531.py | 7 +- .../stRandom2/test_random_statetest532.py | 2 +- .../stRandom2/test_random_statetest533.py | 39 +- .../stRandom2/test_random_statetest534.py | 34 +- .../stRandom2/test_random_statetest535.py | 34 +- .../stRandom2/test_random_statetest536.py | 7 +- .../stRandom2/test_random_statetest537.py | 2 +- .../stRandom2/test_random_statetest539.py | 2 +- .../stRandom2/test_random_statetest541.py | 7 +- .../stRandom2/test_random_statetest542.py | 34 +- .../stRandom2/test_random_statetest543.py | 7 +- .../stRandom2/test_random_statetest544.py | 2 +- .../stRandom2/test_random_statetest545.py | 2 +- .../stRandom2/test_random_statetest546.py | 34 +- .../stRandom2/test_random_statetest547.py | 7 +- .../stRandom2/test_random_statetest548.py | 2 +- .../stRandom2/test_random_statetest550.py | 2 +- .../stRandom2/test_random_statetest552.py | 2 +- .../stRandom2/test_random_statetest553.py | 34 +- .../stRandom2/test_random_statetest554.py | 38 +- .../stRandom2/test_random_statetest555.py | 34 +- .../stRandom2/test_random_statetest556.py | 2 +- .../stRandom2/test_random_statetest558.py | 7 +- .../stRandom2/test_random_statetest559.py | 2 +- .../stRandom2/test_random_statetest560.py | 7 +- .../stRandom2/test_random_statetest562.py | 7 +- .../stRandom2/test_random_statetest563.py | 23 +- .../stRandom2/test_random_statetest564.py | 34 +- .../stRandom2/test_random_statetest565.py | 2 +- .../stRandom2/test_random_statetest566.py | 39 +- .../stRandom2/test_random_statetest567.py | 7 +- .../stRandom2/test_random_statetest569.py | 23 +- .../stRandom2/test_random_statetest571.py | 39 +- .../stRandom2/test_random_statetest572.py | 39 +- .../stRandom2/test_random_statetest574.py | 2 +- .../stRandom2/test_random_statetest575.py | 39 +- .../stRandom2/test_random_statetest576.py | 23 +- .../stRandom2/test_random_statetest577.py | 7 +- .../stRandom2/test_random_statetest578.py | 2 +- .../stRandom2/test_random_statetest579.py | 7 +- .../stRandom2/test_random_statetest580.py | 2 +- .../stRandom2/test_random_statetest581.py | 2 +- .../stRandom2/test_random_statetest582.py | 39 +- .../stRandom2/test_random_statetest583.py | 39 +- .../stRandom2/test_random_statetest584.py | 34 +- .../stRandom2/test_random_statetest585.py | 34 +- .../stRandom2/test_random_statetest586.py | 7 +- .../stRandom2/test_random_statetest587.py | 34 +- .../stRandom2/test_random_statetest588.py | 7 +- .../stRandom2/test_random_statetest589.py | 39 +- .../stRandom2/test_random_statetest592.py | 34 +- .../stRandom2/test_random_statetest596.py | 2 +- .../stRandom2/test_random_statetest597.py | 23 +- .../stRandom2/test_random_statetest599.py | 34 +- .../stRandom2/test_random_statetest600.py | 2 +- .../stRandom2/test_random_statetest601.py | 7 +- .../stRandom2/test_random_statetest602.py | 34 +- .../stRandom2/test_random_statetest603.py | 34 +- .../stRandom2/test_random_statetest604.py | 7 +- .../stRandom2/test_random_statetest605.py | 34 +- .../stRandom2/test_random_statetest607.py | 34 +- .../stRandom2/test_random_statetest608.py | 2 +- .../stRandom2/test_random_statetest609.py | 7 +- .../stRandom2/test_random_statetest610.py | 34 +- .../stRandom2/test_random_statetest611.py | 7 +- .../stRandom2/test_random_statetest612.py | 2 +- .../stRandom2/test_random_statetest615.py | 2 +- .../stRandom2/test_random_statetest616.py | 2 +- .../stRandom2/test_random_statetest618.py | 39 +- .../stRandom2/test_random_statetest620.py | 2 +- .../stRandom2/test_random_statetest621.py | 28 +- .../stRandom2/test_random_statetest624.py | 7 +- .../stRandom2/test_random_statetest625.py | 7 +- .../stRandom2/test_random_statetest626.py | 39 +- .../stRandom2/test_random_statetest627.py | 7 +- .../stRandom2/test_random_statetest628.py | 9 +- .../stRandom2/test_random_statetest629.py | 34 +- .../stRandom2/test_random_statetest630.py | 2 +- .../stRandom2/test_random_statetest632.py | 7 +- .../stRandom2/test_random_statetest633.py | 34 +- .../stRandom2/test_random_statetest635.py | 2 +- .../stRandom2/test_random_statetest636.py | 34 +- .../stRandom2/test_random_statetest637.py | 2 +- .../stRandom2/test_random_statetest638.py | 2 +- .../stRandom2/test_random_statetest639.py | 38 +- .../stRandom2/test_random_statetest640.py | 7 +- .../stRandom2/test_random_statetest641.py | 34 +- .../stRandom2/test_random_statetest642.py | 2 +- .../stRandom2/test_random_statetest643.py | 7 +- .../stRandom2/test_random_statetest644.py | 8 +- .../stRandom2/test_random_statetest645.py | 4 +- .../stRandom2/test_random_statetest647.py | 8 +- .../stRandom2/test_random_statetest648.py | 8 +- .../stRandom2/test_random_statetest649.py | 7 +- .../stRandom2/test_random_statetest650.py | 7 +- .../test_recursive_create.py | 7 +- .../test_recursive_create_return_value.py | 7 +- .../stRefundTest/test_refund50_1.py | 7 +- .../stRefundTest/test_refund50_2.py | 7 +- .../stRefundTest/test_refund50percent_cap.py | 2 +- .../stRefundTest/test_refund600.py | 2 +- .../stRefundTest/test_refund_call_a.py | 26 +- ...st_refund_call_a_not_enough_gas_in_call.py | 26 +- .../stRefundTest/test_refund_call_a_oog.py | 26 +- .../test_refund_call_to_suicide_no_storage.py | 6 +- .../test_refund_call_to_suicide_storage.py | 6 +- .../test_refund_call_to_suicide_twice.py | 6 +- .../test_refund_change_non_zero_storage.py | 7 +- .../stRefundTest/test_refund_ff.py | 14 +- .../test_refund_get_ether_back.py | 7 +- .../stRefundTest/test_refund_max.py | 7 +- .../test_refund_multimple_suicide.py | 7 +- .../stRefundTest/test_refund_no_oog_1.py | 7 +- .../stRefundTest/test_refund_oog.py | 7 +- .../test_refund_single_suicide.py | 7 +- .../stRefundTest/test_refund_sstore.py | 7 +- .../test_refund_suicide50procent_cap.py | 6 +- .../test_refund_tx_to_suicide_oog.py | 7 +- ...ecrec_success_empty_then_returndatasize.py | 7 +- ...n_create_successful_then_returndatasize.py | 10 +- ...hen_call_value_fail_then_returndatasize.py | 12 +- ...n_create_successful_then_returndatasize.py | 10 +- .../test_clear_return_buffer.py | 12 +- ...st_create_callprecompile_returndatasize.py | 8 +- .../test_modexp_modsize0_returndatasize.py | 7 +- ...atacopy_0_0_following_successful_create.py | 7 +- ...t_returndatacopy_after_failing_callcode.py | 20 +- ...est_returndatacopy_after_failing_create.py | 7 +- ...turndatacopy_after_failing_delegatecall.py | 20 +- ...returndatacopy_after_failing_staticcall.py | 24 +- ...turndatacopy_after_revert_in_staticcall.py | 37 +- ...eturndatacopy_after_successful_callcode.py | 30 +- ...ndatacopy_after_successful_delegatecall.py | 34 +- ...urndatacopy_after_successful_staticcall.py | 37 +- .../test_returndatacopy_following_call.py | 4 +- .../test_returndatacopy_following_create.py | 8 +- ...t_returndatacopy_following_failing_call.py | 10 +- .../test_returndatacopy_following_revert.py | 4 +- ...turndatacopy_following_revert_in_create.py | 2 +- ...urndatacopy_following_successful_create.py | 7 +- ...turndatacopy_following_too_big_transfer.py | 10 +- .../test_returndatacopy_initial.py | 7 +- .../test_returndatacopy_initial_256.py | 7 +- .../test_returndatacopy_initial_big_sum.py | 7 +- .../test_returndatacopy_overrun.py | 10 +- ...t_returndatasize_after_failing_callcode.py | 27 +- ...turndatasize_after_failing_delegatecall.py | 27 +- ...returndatasize_after_failing_staticcall.py | 27 +- ...t_returndatasize_after_oog_after_deeper.py | 56 +- ...eturndatasize_after_successful_callcode.py | 34 +- ...ndatasize_after_successful_delegatecall.py | 28 +- ...urndatasize_after_successful_staticcall.py | 34 +- .../test_returndatasize_bug.py | 32 +- ...urndatasize_following_successful_create.py | 7 +- .../test_returndatasize_initial.py | 7 +- .../test_returndatasize_initial_zero_read.py | 7 +- .../test_revert_ret_data_size.py | 102 +- .../test_subcall_return_more_then_expected.py | 102 +- .../test_too_long_return_data_copy.py | 18 +- .../stRevertTest/test_cost_revert.py | 2 +- .../test_loop_calls_depth_then_revert.py | 6 +- .../test_loop_calls_depth_then_revert2.py | 6 +- .../test_loop_calls_depth_then_revert3.py | 13 +- .../test_loop_calls_then_revert.py | 24 +- ...t_loop_delegate_calls_depth_then_revert.py | 6 +- .../test_nashatyrev_suicide_revert.py | 7 +- ...python_revert_test_tue201814_minus_1430.py | 194 +- .../stRevertTest/test_revert_depth2.py | 68 +- ...t_revert_depth_create_address_collision.py | 20 +- .../test_revert_depth_create_oog.py | 28 +- .../stRevertTest/test_revert_in_call_code.py | 26 +- .../test_revert_in_delegate_call.py | 26 +- .../test_revert_in_static_call.py | 22 +- .../test_revert_on_empty_stack.py | 7 +- .../stRevertTest/test_revert_opcode.py | 7 +- .../stRevertTest/test_revert_opcode_calls.py | 72 +- .../stRevertTest/test_revert_opcode_create.py | 7 +- .../test_revert_opcode_direct_call.py | 28 +- ...pcode_in_calls_on_non_empty_return_data.py | 116 +- .../test_revert_opcode_in_create_returns.py | 7 +- .../test_revert_opcode_in_init.py | 8 +- .../test_revert_opcode_multiple_sub_calls.py | 88 +- ...t_revert_opcode_with_big_output_in_init.py | 8 +- ...evert_precompiled_touch_exact_oog_paris.py | 134 +- .../test_revert_precompiled_touch_nonce.py | 38 +- ...t_revert_precompiled_touch_noncestorage.py | 54 +- .../test_revert_precompiled_touch_paris.py | 34 +- ..._revert_precompiled_touch_storage_paris.py | 68 +- .../stRevertTest/test_revert_prefound_call.py | 12 +- .../test_revert_prefound_call_oog.py | 12 +- ...st_revert_prefound_empty_call_oog_paris.py | 12 +- .../test_revert_prefound_empty_call_paris.py | 12 +- .../test_revert_prefound_empty_oog_paris.py | 10 +- .../stRevertTest/test_revert_prefound_oog.py | 10 +- .../test_revert_sub_call_storage_oog.py | 7 +- .../test_revert_sub_call_storage_oog2.py | 7 +- .../stRevertTest/test_state_revert.py | 6 +- ...st_touch_to_empty_account_revert2_paris.py | 45 +- ...st_touch_to_empty_account_revert3_paris.py | 81 +- ...est_touch_to_empty_account_revert_paris.py | 29 +- ...tore_call_to_self_sub_refund_below_zero.py | 7 +- .../stSStoreTest/test_sstore_gas.py | 7 +- .../stSelfBalance/test_self_balance.py | 7 +- .../test_self_balance_call_types.py | 21 +- .../test_self_balance_equals_balance.py | 7 +- .../test_self_balance_gas_cost.py | 7 +- .../stSelfBalance/test_self_balance_update.py | 7 +- tests/ported_static/stShift/test_sar00.py | 7 +- tests/ported_static/stShift/test_sar01.py | 7 +- tests/ported_static/stShift/test_sar10.py | 7 +- tests/ported_static/stShift/test_sar11.py | 7 +- .../stShift/test_sar_0_256_minus_1.py | 2 +- .../stShift/test_sar_2_254_254.py | 7 +- .../ported_static/stShift/test_sar_2_255_1.py | 2 +- .../stShift/test_sar_2_255_255.py | 2 +- .../stShift/test_sar_2_255_256.py | 2 +- .../stShift/test_sar_2_255_257.py | 2 +- .../stShift/test_sar_2_255_minus_1_248.py | 7 +- .../stShift/test_sar_2_255_minus_1_254.py | 7 +- .../stShift/test_sar_2_255_minus_1_255.py | 7 +- .../stShift/test_sar_2_255_minus_1_256.py | 7 +- .../stShift/test_sar_2_256_minus_1_0.py | 7 +- .../stShift/test_sar_2_256_minus_1_1.py | 2 +- .../stShift/test_sar_2_256_minus_1_255.py | 2 +- .../stShift/test_sar_2_256_minus_1_256.py | 2 +- .../stShift/test_shift_signed_combinations.py | 2 +- tests/ported_static/stShift/test_shl01.py | 7 +- .../stShift/test_shl01_minus_0100.py | 7 +- .../stShift/test_shl01_minus_0101.py | 7 +- .../stShift/test_shl01_minus_ff.py | 2 +- tests/ported_static/stShift/test_shl10.py | 7 +- tests/ported_static/stShift/test_shl11.py | 7 +- .../stShift/test_shl_2_255_minus_1_1.py | 2 +- .../stShift/test_shl_minus_1_0.py | 2 +- .../stShift/test_shl_minus_1_1.py | 2 +- .../stShift/test_shl_minus_1_255.py | 2 +- .../stShift/test_shl_minus_1_256.py | 7 +- tests/ported_static/stShift/test_shr01.py | 7 +- tests/ported_static/stShift/test_shr10.py | 7 +- tests/ported_static/stShift/test_shr11.py | 7 +- .../ported_static/stShift/test_shr_2_255_1.py | 2 +- .../stShift/test_shr_2_255_255.py | 7 +- .../stShift/test_shr_2_255_256.py | 7 +- .../stShift/test_shr_2_255_257.py | 7 +- .../stShift/test_shr_minus_1_0.py | 2 +- .../stShift/test_shr_minus_1_1.py | 2 +- .../stShift/test_shr_minus_1_255.py | 7 +- .../stShift/test_shr_minus_1_256.py | 7 +- .../stSolidityTest/test_ambiguous_method.py | 7 +- .../stSolidityTest/test_by_zero.py | 8 +- .../stSolidityTest/test_call_infinite_loop.py | 7 +- .../test_call_low_level_creates_solidity.py | 16 +- .../test_call_recursive_methods.py | 7 +- .../test_contract_inheritance.py | 7 +- .../test_create_contract_from_method.py | 7 +- .../test_recursive_create_contracts.py | 11 +- ...sive_create_contracts_create4_contracts.py | 21 +- ...t_test_block_and_transaction_properties.py | 13 +- .../test_test_contract_interaction.py | 7 +- .../test_test_contract_suicide.py | 7 +- .../test_test_cryptographic_functions.py | 7 +- .../stSolidityTest/test_test_keywords.py | 7 +- .../stSolidityTest/test_test_overflow.py | 7 +- .../test_test_store_gas_prices.py | 7 +- .../test_test_structures_and_variabless.py | 10 +- .../stSpecialTest/test_block504980.py | 12280 ++++++++-------- .../stSpecialTest/test_deployment_error.py | 8 +- .../stSpecialTest/test_eoa_empty_paris.py | 12 +- .../test_failed_tx_xcf416c53_paris.py | 11 +- .../stSpecialTest/test_gas_price0.py | 7 +- .../stSpecialTest/test_jumpdest_attack.py | 7 +- .../test_jumpdest_attackwith_jump.py | 7 +- .../stSpecialTest/test_make_money.py | 26 +- .../test_overflow_gas_make_money.py | 8 +- .../stSpecialTest/test_push32without_byte.py | 7 +- .../test_selfdestruct_eip2929.py | 15 +- .../stSpecialTest/test_sha3_deja.py | 7 +- .../test_stack_depth_limit_sec.py | 8 +- .../stSpecialTest/test_tx_e1c174e2.py | 6 +- .../stStackTests/test_shallow_stack.py | 8 +- .../stStackTests/test_stack_overflow.py | 10 +- .../stStackTests/test_stack_overflow_dup.py | 10 +- .../stStackTests/test_stack_overflow_m1.py | 10 +- .../test_stack_overflow_m1_dup.py | 10 +- .../stStackTests/test_stack_overflow_swap.py | 10 +- .../stStackTests/test_stacksanity_swap.py | 10 +- .../stStackTests/test_underflow_test.py | 2 +- .../stStaticCall/test_static_ab_acalls0.py | 6 +- .../stStaticCall/test_static_ab_acalls1.py | 6 +- .../stStaticCall/test_static_ab_acalls2.py | 6 +- .../stStaticCall/test_static_ab_acalls3.py | 6 +- .../test_static_ab_acalls_suicide0.py | 6 +- .../test_static_ab_acalls_suicide1.py | 2 +- .../stStaticCall/test_static_call10.py | 9 +- .../test_static_call1024_balance_too_low.py | 9 +- .../test_static_call1024_balance_too_low2.py | 9 +- .../stStaticCall/test_static_call1024_oog.py | 9 +- .../test_static_call1024_pre_calls.py | 9 +- .../test_static_call1024_pre_calls2.py | 6 +- .../test_static_call1024_pre_calls3.py | 9 +- .../test_static_call1_mb1024_calldepth.py | 9 +- .../stStaticCall/test_static_call50000.py | 26 +- .../test_static_call50000_ecrec.py | 6 +- .../test_static_call50000_identity.py | 6 +- .../test_static_call50000_identity2.py | 6 +- .../test_static_call50000_rip160.py | 6 +- ...test_static_call50000bytes_contract50_1.py | 32 +- ...test_static_call50000bytes_contract50_2.py | 32 +- ...test_static_call50000bytes_contract50_3.py | 32 +- ...e_consume_more_gas_then_transaction_has.py | 34 +- ...more_gas_on_depth2_then_transaction_has.py | 82 +- .../stStaticCall/test_static_call_basic.py | 42 +- .../test_static_call_change_revert.py | 38 +- ...ract_to_create_contract_and_call_it_oog.py | 10 +- ...ic_call_contract_to_create_contract_oog.py | 11 +- ...ntract_to_create_contract_oog_bonus_gas.py | 10 +- ...t_which_would_create_contract_if_called.py | 13 +- .../stStaticCall/test_static_call_create.py | 22 +- .../stStaticCall/test_static_call_create2.py | 10 +- .../stStaticCall/test_static_call_create3.py | 9 +- .../test_static_call_ecrecover0.py | 12 +- .../test_static_call_ecrecover0_0input.py | 2 +- ...c_call_ecrecover0_complete_return_value.py | 11 +- .../test_static_call_ecrecover0_gas2999.py | 7 +- .../test_static_call_ecrecover0_gas3000.py | 12 +- .../test_static_call_ecrecover0_no_gas.py | 8 +- ...all_ecrecover0_overlapping_input_output.py | 12 +- .../test_static_call_ecrecover1.py | 7 +- .../test_static_call_ecrecover2.py | 7 +- .../test_static_call_ecrecover3.py | 2 +- .../test_static_call_ecrecover80.py | 7 +- ...test_static_call_ecrecover_check_length.py | 12 +- ...tic_call_ecrecover_check_length_wrong_v.py | 2 +- .../test_static_call_ecrecover_h_prefixed0.py | 2 +- .../test_static_call_ecrecover_r_prefixed0.py | 7 +- .../test_static_call_ecrecover_s_prefixed0.py | 2 +- .../test_static_call_ecrecover_v_prefixed0.py | 12 +- ...st_static_call_goes_oog_on_second_level.py | 45 +- ...t_static_call_goes_oog_on_second_level2.py | 46 +- .../test_static_call_identitiy_1.py | 7 +- ...st_static_call_identity_1_nonzero_value.py | 2 +- .../test_static_call_identity_2.py | 2 +- .../test_static_call_identity_3.py | 2 +- .../test_static_call_identity_4.py | 2 +- .../test_static_call_identity_4_gas17.py | 2 +- .../test_static_call_identity_4_gas18.py | 2 +- .../test_static_call_identity_5.py | 2 +- .../test_static_call_lose_gas_oog.py | 9 +- .../test_static_call_one_v_call_suicide.py | 6 +- ...t_static_call_oog_additional_gas_costs1.py | 7 +- ...ic_call_oog_additional_gas_costs2_paris.py | 12 +- .../stStaticCall/test_static_call_output1.py | 20 +- .../stStaticCall/test_static_call_output2.py | 20 +- .../stStaticCall/test_static_call_output3.py | 20 +- .../test_static_call_output3_fail.py | 20 +- .../test_static_call_output3partial.py | 20 +- .../test_static_call_output3partial_fail.py | 20 +- .../test_static_call_recursive_bomb0.py | 42 +- ...l_recursive_bomb0_oog_at_max_call_depth.py | 46 +- .../test_static_call_recursive_bomb1.py | 42 +- .../test_static_call_recursive_bomb2.py | 42 +- .../test_static_call_recursive_bomb3.py | 42 +- .../test_static_call_recursive_bomb_log.py | 46 +- .../test_static_call_recursive_bomb_log2.py | 44 +- ...est_static_call_recursive_bomb_pre_call.py | 6 +- ...st_static_call_recursive_bomb_pre_call2.py | 42 +- .../test_static_call_ripemd160_1.py | 2 +- .../test_static_call_ripemd160_2.py | 2 +- .../test_static_call_ripemd160_3.py | 2 +- ...test_static_call_ripemd160_3_postfixed0.py | 2 +- .../test_static_call_ripemd160_3_prefixed0.py | 2 +- .../test_static_call_ripemd160_4.py | 2 +- .../test_static_call_ripemd160_4_gas719.py | 2 +- .../test_static_call_ripemd160_5.py | 2 +- .../stStaticCall/test_static_call_sha256_1.py | 2 +- ...test_static_call_sha256_1_nonzero_value.py | 2 +- .../stStaticCall/test_static_call_sha256_2.py | 2 +- .../stStaticCall/test_static_call_sha256_3.py | 2 +- .../test_static_call_sha256_3_postfix0.py | 2 +- .../test_static_call_sha256_3_prefix0.py | 2 +- .../stStaticCall/test_static_call_sha256_4.py | 2 +- .../test_static_call_sha256_4_gas99.py | 2 +- .../stStaticCall/test_static_call_sha256_5.py | 2 +- ..._static_call_to_call_code_op_code_check.py | 2 +- .../test_static_call_to_call_op_code_check.py | 2 +- ...t_static_call_to_del_call_op_code_check.py | 2 +- .../test_static_call_to_name_registrator0.py | 40 +- .../test_static_call_to_return1.py | 26 +- ...est_static_call_to_static_op_code_check.py | 2 +- .../test_static_call_value_inherit.py | 28 +- ...est_static_call_value_inherit_from_call.py | 31 +- .../test_static_call_with_high_value.py | 26 +- ...static_call_with_high_value_and_gas_oog.py | 36 +- ...all_with_high_value_and_oo_gat_tx_level.py | 26 +- ...static_call_with_high_value_oo_gin_call.py | 26 +- .../test_static_call_zero_v_call_suicide.py | 6 +- .../stStaticCall/test_static_callcall_00.py | 116 +- .../test_static_callcall_00_ooge.py | 104 +- .../test_static_callcall_00_ooge_1.py | 102 +- .../test_static_callcall_00_ooge_2.py | 102 +- .../test_static_callcall_00_suicide_end.py | 22 +- .../test_static_callcallcall_000.py | 130 +- .../test_static_callcallcall_000_ooge.py | 130 +- ...test_static_callcallcall_000_oogm_after.py | 62 +- ...est_static_callcallcall_000_oogm_after2.py | 62 +- ...est_static_callcallcall_000_oogm_before.py | 78 +- ...est_static_callcallcall_000_suicide_end.py | 22 +- ..._static_callcallcall_000_suicide_middle.py | 22 +- ...test_static_callcallcall_abcb_recursive.py | 6 +- .../test_static_callcallcallcode_001.py | 132 +- .../test_static_callcallcallcode_001_2.py | 126 +- .../test_static_callcallcallcode_001_ooge.py | 74 +- ...test_static_callcallcallcode_001_ooge_2.py | 136 +- ..._static_callcallcallcode_001_oogm_after.py | 48 +- ...static_callcallcallcode_001_oogm_after2.py | 52 +- ...tatic_callcallcallcode_001_oogm_after_2.py | 50 +- ...tatic_callcallcallcode_001_oogm_after_3.py | 52 +- ...static_callcallcallcode_001_oogm_before.py | 74 +- ...tatic_callcallcallcode_001_oogm_before2.py | 80 +- ...static_callcallcallcode_001_suicide_end.py | 22 +- ...tatic_callcallcallcode_001_suicide_end2.py | 22 +- ...tic_callcallcallcode_001_suicide_middle.py | 22 +- ...ic_callcallcallcode_001_suicide_middle2.py | 22 +- ..._static_callcallcallcode_abcb_recursive.py | 6 +- ...static_callcallcallcode_abcb_recursive2.py | 6 +- .../test_static_callcallcode_01_2.py | 78 +- .../test_static_callcallcode_01_ooge_2.py | 48 +- ...test_static_callcallcode_01_suicide_end.py | 22 +- ...est_static_callcallcode_01_suicide_end2.py | 22 +- .../test_static_callcallcodecall_010.py | 60 +- .../test_static_callcallcodecall_010_2.py | 46 +- .../test_static_callcallcodecall_010_ooge.py | 70 +- ...test_static_callcallcodecall_010_ooge_2.py | 82 +- ..._static_callcallcodecall_010_oogm_after.py | 66 +- ...static_callcallcodecall_010_oogm_after2.py | 78 +- ...tatic_callcallcodecall_010_oogm_after_2.py | 66 +- ...tatic_callcallcodecall_010_oogm_after_3.py | 50 +- ...static_callcallcodecall_010_oogm_before.py | 76 +- ...tatic_callcallcodecall_010_oogm_before2.py | 52 +- ...static_callcallcodecall_010_suicide_end.py | 22 +- ...tatic_callcallcodecall_010_suicide_end2.py | 22 +- ...tic_callcallcodecall_010_suicide_middle.py | 22 +- ...ic_callcallcodecall_010_suicide_middle2.py | 22 +- ..._static_callcallcodecall_abcb_recursive.py | 6 +- ...static_callcallcodecall_abcb_recursive2.py | 6 +- .../test_static_callcallcodecallcode_011.py | 60 +- .../test_static_callcallcodecallcode_011_2.py | 54 +- ...st_static_callcallcodecallcode_011_ooge.py | 80 +- ..._static_callcallcodecallcode_011_ooge_2.py | 60 +- ...tic_callcallcodecallcode_011_oogm_after.py | 44 +- ...ic_callcallcodecallcode_011_oogm_after2.py | 70 +- ...c_callcallcodecallcode_011_oogm_after_1.py | 58 +- ...c_callcallcodecallcode_011_oogm_after_2.py | 44 +- ...ic_callcallcodecallcode_011_oogm_before.py | 58 +- ...c_callcallcodecallcode_011_oogm_before2.py | 84 +- ...ic_callcallcodecallcode_011_suicide_end.py | 22 +- ...c_callcallcodecallcode_011_suicide_end2.py | 22 +- ...callcallcodecallcode_011_suicide_middle.py | 22 +- ...allcallcodecallcode_011_suicide_middle2.py | 22 +- ...tic_callcallcodecallcode_abcb_recursive.py | 6 +- ...ic_callcallcodecallcode_abcb_recursive2.py | 6 +- .../test_static_callcode_check_pc.py | 24 +- .../test_static_callcodecall_10.py | 49 +- .../test_static_callcodecall_10_2.py | 51 +- .../test_static_callcodecall_10_ooge.py | 48 +- .../test_static_callcodecall_10_ooge_2.py | 50 +- ...test_static_callcodecall_10_suicide_end.py | 38 +- ...est_static_callcodecall_10_suicide_end2.py | 22 +- .../test_static_callcodecallcall_100.py | 68 +- .../test_static_callcodecallcall_100_2.py | 66 +- .../test_static_callcodecallcall_100_ooge.py | 86 +- .../test_static_callcodecallcall_100_ooge2.py | 82 +- ..._static_callcodecallcall_100_oogm_after.py | 62 +- ...static_callcodecallcall_100_oogm_after2.py | 50 +- ...tatic_callcodecallcall_100_oogm_after_2.py | 62 +- ...tatic_callcodecallcall_100_oogm_after_3.py | 64 +- ...static_callcodecallcall_100_oogm_before.py | 56 +- ...tatic_callcodecallcall_100_oogm_before2.py | 64 +- ...static_callcodecallcall_100_suicide_end.py | 22 +- ...tatic_callcodecallcall_100_suicide_end2.py | 22 +- ...tic_callcodecallcall_100_suicide_middle.py | 22 +- ...ic_callcodecallcall_100_suicide_middle2.py | 22 +- ..._static_callcodecallcall_abcb_recursive.py | 6 +- ...static_callcodecallcall_abcb_recursive2.py | 6 +- .../test_static_callcodecallcallcode_101.py | 60 +- .../test_static_callcodecallcallcode_101_2.py | 52 +- ...st_static_callcodecallcallcode_101_ooge.py | 76 +- ..._static_callcodecallcallcode_101_ooge_2.py | 80 +- ...tic_callcodecallcallcode_101_oogm_after.py | 62 +- ...ic_callcodecallcallcode_101_oogm_after2.py | 76 +- ...c_callcodecallcallcode_101_oogm_after_1.py | 114 +- ...c_callcodecallcallcode_101_oogm_after_3.py | 138 +- ...ic_callcodecallcallcode_101_oogm_before.py | 86 +- ...c_callcodecallcallcode_101_oogm_before2.py | 88 +- ...ic_callcodecallcallcode_101_suicide_end.py | 22 +- ...c_callcodecallcallcode_101_suicide_end2.py | 22 +- ...callcodecallcallcode_101_suicide_middle.py | 22 +- ...allcodecallcallcode_101_suicide_middle2.py | 22 +- ...tic_callcodecallcallcode_abcb_recursive.py | 6 +- ...ic_callcodecallcallcode_abcb_recursive2.py | 6 +- .../test_static_callcodecallcodecall_110.py | 60 +- .../test_static_callcodecallcodecall_1102.py | 70 +- .../test_static_callcodecallcodecall_110_2.py | 62 +- ...st_static_callcodecallcodecall_110_ooge.py | 76 +- ...t_static_callcodecallcodecall_110_ooge2.py | 80 +- ...tic_callcodecallcodecall_110_oogm_after.py | 70 +- ...ic_callcodecallcodecall_110_oogm_after2.py | 72 +- ...c_callcodecallcodecall_110_oogm_after_2.py | 70 +- ...c_callcodecallcodecall_110_oogm_after_3.py | 72 +- ...ic_callcodecallcodecall_110_oogm_before.py | 78 +- ...c_callcodecallcodecall_110_oogm_before2.py | 82 +- ...ic_callcodecallcodecall_110_suicide_end.py | 22 +- ...c_callcodecallcodecall_110_suicide_end2.py | 22 +- ...callcodecallcodecall_110_suicide_middle.py | 22 +- ...allcodecallcodecall_110_suicide_middle2.py | 22 +- ...tic_callcodecallcodecall_abcb_recursive.py | 6 +- ...ic_callcodecallcodecall_abcb_recursive2.py | 6 +- ...allcodecallcodecallcode_111_suicide_end.py | 22 +- .../test_static_calldelcode_01.py | 49 +- .../test_static_calldelcode_01_ooge.py | 48 +- .../test_static_callto_return2.py | 22 +- .../test_static_check_call_cost_oog.py | 26 +- .../test_static_check_opcodes3.py | 48 +- .../test_static_check_opcodes4.py | 14 +- .../test_static_check_opcodes5.py | 36 +- ..._ask_more_gas_then_transaction_provided.py | 67 +- ...nt_leave_empty_contract_via_transaction.py | 39 +- ...tic_create_contract_suicide_during_init.py | 12 +- ...cide_during_init_then_store_then_return.py | 10 +- ...contract_suicide_during_init_with_value.py | 8 +- ..._create_empty_contract_and_call_it_0wei.py | 8 +- ..._contract_with_storage_and_call_it_0wei.py | 8 +- ..._that_ask_fore_gas_then_trabsaction_has.py | 6 +- ..._static_internal_call_hitting_gas_limit.py | 38 +- ...static_internal_call_hitting_gas_limit2.py | 38 +- ...t_static_internal_call_store_clears_oog.py | 8 +- .../test_static_log0_empty_mem.py | 24 +- ...test_static_log0_log_mem_start_too_high.py | 40 +- .../test_static_log0_log_memsize_too_high.py | 40 +- .../test_static_log0_log_memsize_zero.py | 34 +- .../test_static_log0_non_empty_mem.py | 34 +- ...static_log0_non_empty_mem_log_mem_size1.py | 34 +- ...empty_mem_log_mem_size1_log_mem_start31.py | 34 +- .../test_static_log1_empty_mem.py | 24 +- ...test_static_log1_log_mem_start_too_high.py | 42 +- .../test_static_log1_log_memsize_too_high.py | 42 +- .../test_static_log1_log_memsize_zero.py | 34 +- .../test_static_log1_max_topic.py | 42 +- .../stStaticCall/test_static_log_caller.py | 6 +- ...est_static_loop_calls_depth_then_revert.py | 6 +- ...st_static_loop_calls_depth_then_revert2.py | 6 +- ...st_static_loop_calls_depth_then_revert3.py | 11 +- .../test_static_loop_calls_then_revert.py | 49 +- .../stStaticCall/test_static_make_money.py | 26 +- .../test_static_post_to_return1.py | 22 +- .../test_static_raw_call_gas_ask.py | 36 +- .../stStaticCall/test_static_refund_call_a.py | 26 +- ...tatic_refund_call_to_suicide_no_storage.py | 6 +- ...est_static_refund_call_to_suicide_twice.py | 6 +- .../stStaticCall/test_static_return50000_2.py | 51 +- .../stStaticCall/test_static_return_bounds.py | 287 +- .../test_static_return_bounds_oog.py | 287 +- .../stStaticCall/test_static_return_test.py | 28 +- .../stStaticCall/test_static_return_test2.py | 32 +- .../stStaticCall/test_static_revert_depth2.py | 80 +- .../test_static_revert_opcode_calls.py | 24 +- ...st_static_zero_value_suicide_oog_revert.py | 6 +- ...call_to_precompile_from_called_contract.py | 46 +- ...precompile_from_contract_initialization.py | 4 +- ...aticcall_to_precompile_from_transaction.py | 4 +- ...code_to_precompile_from_called_contract.py | 272 +- ...precompile_from_contract_initialization.py | 6 +- ...callcode_to_precompile_from_transaction.py | 202 +- ...call_to_precompile_from_called_contract.py | 208 +- ...precompile_from_contract_initialization.py | 4 +- ...gatecall_to_precompile_from_transaction.py | 138 +- .../stSystemOperationsTest/test_ab_acalls0.py | 6 +- .../stSystemOperationsTest/test_ab_acalls1.py | 6 +- .../stSystemOperationsTest/test_ab_acalls2.py | 6 +- .../stSystemOperationsTest/test_ab_acalls3.py | 6 +- .../test_ab_acalls_suicide0.py | 6 +- .../test_ab_acalls_suicide1.py | 2 +- .../test_balance_input_address_too_big.py | 7 +- .../stSystemOperationsTest/test_call10.py | 12 +- .../test_call_recursive_bomb0.py | 40 +- ...l_recursive_bomb0_oog_at_max_call_depth.py | 7 +- .../test_call_recursive_bomb1.py | 7 +- .../test_call_recursive_bomb2.py | 7 +- .../test_call_recursive_bomb3.py | 7 +- .../test_call_recursive_bomb_log.py | 40 +- .../test_call_recursive_bomb_log2.py | 40 +- .../test_call_to_name_registrator0.py | 40 +- ...o_name_registrator_address_too_big_left.py | 8 +- ..._name_registrator_address_too_big_right.py | 8 +- ...trator_mem_oog_and_insufficient_balance.py | 40 +- ...ll_to_name_registrator_not_much_memory0.py | 40 +- ...ll_to_name_registrator_not_much_memory1.py | 40 +- ...est_call_to_name_registrator_out_of_gas.py | 40 +- ...ll_to_name_registrator_too_much_memory0.py | 40 +- ...ll_to_name_registrator_too_much_memory1.py | 40 +- ...ll_to_name_registrator_too_much_memory2.py | 40 +- ...ame_registrator_zeor_size_mem_expansion.py | 40 +- .../test_call_to_return1.py | 28 +- .../test_call_to_return1_for_dynamic_jump0.py | 28 +- .../test_call_to_return1_for_dynamic_jump1.py | 28 +- .../stSystemOperationsTest/test_call_value.py | 7 +- .../test_callcode_to0.py | 7 +- .../test_callcode_to_name_registrator0.py | 40 +- ...to_name_registrator_addres_too_big_left.py | 8 +- ...o_name_registrator_addres_too_big_right.py | 8 +- ...e_to_name_registrator_zero_mem_expanion.py | 40 +- .../test_callcode_to_return1.py | 28 +- .../test_caller_account_balance.py | 2 +- .../test_callto_return2.py | 32 +- .../test_create_hash_collision.py | 2 +- .../test_create_name_registrator.py | 12 +- ..._name_registrator_oog_mem_expansion_oov.py | 7 +- ...e_name_registrator_out_of_memory_bonds0.py | 7 +- ...e_name_registrator_out_of_memory_bonds1.py | 7 +- ..._create_name_registrator_value_too_high.py | 7 +- .../test_create_name_registrator_zero_mem.py | 12 +- .../test_create_name_registrator_zero_mem2.py | 12 +- ...ate_name_registrator_zero_mem_expansion.py | 12 +- .../test_create_with_invalid_opcode.py | 7 +- .../test_current_account_balance.py | 2 +- .../test_double_selfdestruct_test.py | 2 +- .../test_double_selfdestruct_touch_paris.py | 38 +- .../test_extcodecopy.py | 2 +- .../test_multi_selfdestruct.py | 23 +- .../test_post_to_return1.py | 30 +- .../stSystemOperationsTest/test_return0.py | 7 +- .../stSystemOperationsTest/test_return1.py | 7 +- .../stSystemOperationsTest/test_return2.py | 7 +- .../test_suicide_address.py | 7 +- .../test_suicide_caller.py | 13 +- ...test_suicide_caller_addres_too_big_left.py | 8 +- ...est_suicide_caller_addres_too_big_right.py | 2 +- .../test_suicide_not_existing_account.py | 2 +- .../test_suicide_origin.py | 13 +- .../test_suicide_send_ether_post_death.py | 7 +- .../test_suicide_send_ether_to_me.py | 7 +- .../test_test_name_registrator.py | 2 +- .../test_test_random_test.py | 2 +- .../test_sstore_combinations_initial.py | 251 - .../test_contract_store_clears_oog.py | 7 +- .../test_contract_store_clears_success.py | 7 +- .../test_create_message_reverted.py | 7 +- .../test_create_message_success.py | 7 +- .../test_create_transaction_success.py | 8 +- .../test_empty_transaction3.py | 8 +- .../test_high_gas_price_paris.py | 10 +- .../test_internal_call_hitting_gas_limit.py | 22 +- .../test_internal_call_hitting_gas_limit2.py | 22 +- ...internal_call_hitting_gas_limit_success.py | 22 +- .../test_internal_call_store_clears_oog.py | 10 +- ...test_internal_call_store_clears_success.py | 10 +- .../stTransactionTest/test_no_src_account.py | 5 +- .../test_no_src_account1559.py | 5 +- .../test_no_src_account_create.py | 5 +- .../test_no_src_account_create1559.py | 5 +- .../test_overflow_gas_require2.py | 10 +- .../test_point_at_infinity_ec_recover.py | 2 +- ...ears_and_internal_call_store_clears_oog.py | 10 +- ..._and_internal_call_store_clears_success.py | 10 +- .../test_store_gas_on_create.py | 6 +- ...nternal_call_suicides_bonus_gas_at_call.py | 16 +- ..._call_suicides_bonus_gas_at_call_failed.py | 23 +- ...suicides_and_internal_call_suicides_oog.py | 10 +- ...ides_and_internal_call_suicides_success.py | 16 +- ...nd_send_money_to_itself_ether_destroyed.py | 6 +- .../test_suicides_stop_after_suicide.py | 21 +- .../test_transaction_data_costs652.py | 8 +- .../test_transaction_sending_to_empty.py | 8 +- .../test_transaction_to_itself.py | 8 +- ...t_create_name_registrator_per_txs_after.py | 8 +- ...test_create_name_registrator_per_txs_at.py | 8 +- ..._create_name_registrator_per_txs_before.py | 8 +- .../test_delegatecall_after_transition.py | 38 +- .../test_delegatecall_at_transition.py | 38 +- .../test_delegatecall_before_transition.py | 38 +- .../test_day_limit_construction.py | 2 +- .../test_day_limit_construction_oog.py | 7 +- .../test_day_limit_construction_partial.py | 2 +- .../test_day_limit_reset_spent_today.py | 4 +- .../test_day_limit_set_daily_limit.py | 4 +- .../test_day_limit_set_daily_limit_no_data.py | 4 +- .../test_multi_owned_add_owner.py | 6 +- .../test_multi_owned_add_owner_add_myself.py | 6 +- .../test_multi_owned_change_owner.py | 4 +- ...multi_owned_change_owner_from_not_owner.py | 6 +- ...st_multi_owned_change_owner_no_argument.py | 6 +- ...st_multi_owned_change_owner_to_is_owner.py | 6 +- ...test_multi_owned_change_requirement_to0.py | 6 +- ...test_multi_owned_change_requirement_to1.py | 6 +- ...test_multi_owned_change_requirement_to2.py | 6 +- .../test_multi_owned_construction_correct.py | 2 +- ...multi_owned_construction_not_enough_gas.py | 8 +- ...ned_construction_not_enough_gas_partial.py | 8 +- .../test_multi_owned_is_owner_false.py | 11 +- .../test_multi_owned_is_owner_true.py | 6 +- .../test_multi_owned_remove_owner.py | 4 +- ...t_multi_owned_remove_owner_by_non_owner.py | 4 +- .../test_multi_owned_remove_owner_my_self.py | 6 +- ...i_owned_remove_owner_owner_is_not_owner.py | 6 +- .../test_multi_owned_revoke_nothing.py | 6 +- ...et_add_owner_remove_pending_transaction.py | 8 +- ...change_owner_remove_pending_transaction.py | 6 +- ..._requirement_remove_pending_transaction.py | 8 +- .../stWalletTest/test_wallet_confirm.py | 8 +- .../stWalletTest/test_wallet_construction.py | 2 +- .../test_wallet_construction_oog.py | 2 +- .../test_wallet_construction_partial.py | 2 +- .../stWalletTest/test_wallet_default.py | 11 +- .../test_wallet_default_with_out_value.py | 11 +- ...et_execute_over_daily_limit_multi_owner.py | 4 +- ...execute_over_daily_limit_only_one_owner.py | 4 +- ...ute_over_daily_limit_only_one_owner_new.py | 4 +- .../test_wallet_execute_under_daily_limit.py | 4 +- .../stWalletTest/test_wallet_kill.py | 4 +- .../test_wallet_kill_not_by_owner.py | 12 +- .../test_wallet_kill_to_wallet.py | 4 +- ...remove_owner_remove_pending_transaction.py | 6 +- ...ro_value_call_to_empty_oog_revert_paris.py | 12 +- ...lue_call_to_non_zero_balance_oog_revert.py | 12 +- ...all_to_one_storage_key_oog_revert_paris.py | 2 +- ...alue_callcode_to_empty_oog_revert_paris.py | 12 +- ...callcode_to_non_zero_balance_oog_revert.py | 12 +- ...ode_to_one_storage_key_oog_revert_paris.py | 2 +- ..._delegatecall_to_empty_oog_revert_paris.py | 12 +- ...gatecall_to_non_zero_balance_oog_revert.py | 12 +- ...all_to_one_storage_key_oog_revert_paris.py | 2 +- .../test_zero_value_suicide_oog_revert.py | 6 +- ...value_suicide_to_empty_oog_revert_paris.py | 28 +- ..._suicide_to_non_zero_balance_oog_revert.py | 28 +- ...ide_to_one_storage_key_oog_revert_paris.py | 24 +- .../test_zero_value_call_to_empty_paris.py | 12 +- ...est_zero_value_call_to_non_zero_balance.py | 12 +- ...ero_value_call_to_one_storage_key_paris.py | 2 +- ...test_zero_value_callcode_to_empty_paris.py | 12 +- ...zero_value_callcode_to_non_zero_balance.py | 12 +- ...value_callcode_to_one_storage_key_paris.py | 2 +- ..._zero_value_delegatecall_to_empty_paris.py | 12 +- ..._value_delegatecall_to_non_zero_balance.py | 12 +- ...e_delegatecall_to_one_storage_key_paris.py | 2 +- .../test_zero_value_suicide_to_empty_paris.py | 2 +- ..._zero_value_suicide_to_non_zero_balance.py | 2 +- ..._value_suicide_to_one_storage_key_paris.py | 2 +- ...ansaction_cal_lwith_data_to_empty_paris.py | 10 +- ...tion_cal_lwith_data_to_non_zero_balance.py | 10 +- ...o_value_transaction_call_to_empty_paris.py | 10 +- ...ue_transaction_call_to_non_zero_balance.py | 10 +- .../stZeroKnowledge/test_pairing_test.py | 9 +- .../vmArithmeticTest/test_add.py | 2 +- .../vmArithmeticTest/test_addmod.py | 2 +- .../vmArithmeticTest/test_arith.py | 2 +- .../vmArithmeticTest/test_div.py | 6 +- .../vmArithmeticTest/test_div_by_zero.py | 7 +- .../vmArithmeticTest/test_exp.py | 2 +- .../vmArithmeticTest/test_exp_power2.py | 2 +- .../vmArithmeticTest/test_exp_power256.py | 2 +- .../test_exp_power256_of256.py | 2 +- .../vmArithmeticTest/test_fib.py | 7 +- .../vmArithmeticTest/test_mod.py | 2 +- .../vmArithmeticTest/test_mul.py | 2 +- .../vmArithmeticTest/test_mulmod.py | 6 +- .../vmArithmeticTest/test_not.py | 2 +- .../vmArithmeticTest/test_sdiv.py | 2 +- .../vmArithmeticTest/test_signextend.py | 2 +- .../vmArithmeticTest/test_smod.py | 2 +- .../vmArithmeticTest/test_sub.py | 2 +- .../vmBitwiseLogicOperation/test_and.py | 2 +- .../vmBitwiseLogicOperation/test_byte.py | 2 +- .../vmBitwiseLogicOperation/test_eq.py | 6 +- .../vmBitwiseLogicOperation/test_gt.py | 6 +- .../vmBitwiseLogicOperation/test_iszero.py | 6 +- .../vmBitwiseLogicOperation/test_lt.py | 6 +- .../vmBitwiseLogicOperation/test_not.py | 2 +- .../vmBitwiseLogicOperation/test_or.py | 2 +- .../vmBitwiseLogicOperation/test_sgt.py | 6 +- .../vmBitwiseLogicOperation/test_slt.py | 6 +- .../vmBitwiseLogicOperation/test_xor.py | 2 +- .../vmIOandFlowOperations/test_codecopy.py | 34 +- .../vmIOandFlowOperations/test_gas.py | 6 +- .../vmIOandFlowOperations/test_jump.py | 6 +- .../test_jump_to_push.py | 122 +- .../vmIOandFlowOperations/test_jumpi.py | 2 +- .../test_loop_stacklimit.py | 6 +- .../test_loops_conditionals.py | 6 +- .../vmIOandFlowOperations/test_mload.py | 2 +- .../vmIOandFlowOperations/test_msize.py | 6 +- .../vmIOandFlowOperations/test_mstore.py | 2 +- .../vmIOandFlowOperations/test_mstore8.py | 2 +- .../vmIOandFlowOperations/test_pc.py | 6 +- .../vmIOandFlowOperations/test_pop.py | 6 +- .../vmIOandFlowOperations/test_return.py | 38 +- .../test_sstore_sload.py | 6 +- tests/ported_static/vmLogTest/test_log0.py | 6 +- tests/ported_static/vmLogTest/test_log1.py | 6 +- tests/ported_static/vmLogTest/test_log2.py | 6 +- tests/ported_static/vmLogTest/test_log3.py | 6 +- tests/ported_static/vmLogTest/test_log4.py | 6 +- .../ported_static/vmTests/test_block_info.py | 12 +- tests/ported_static/vmTests/test_env_info.py | 16 +- tests/ported_static/vmTests/test_random.py | 6 +- tests/ported_static/vmTests/test_sha3.py | 2 +- tests/ported_static/vmTests/test_suicide.py | 2 +- 2037 files changed, 26845 insertions(+), 33972 deletions(-) create mode 100755 scripts/verify_dynamic_addresses.sh delete mode 100644 tests/ported_static/stTimeConsuming/test_sstore_combinations_initial.py diff --git a/scripts/filler_to_python/analyzer.py b/scripts/filler_to_python/analyzer.py index e780f883294..62a90fcdba1 100644 --- a/scripts/filler_to_python/analyzer.py +++ b/scripts/filler_to_python/analyzer.py @@ -71,6 +71,199 @@ class NoIntResolver(_yaml.SafeLoader): # type: ignore[no-redef] "stTimeConsuming", } +# Ported tests (relative to ``tests/ported_static/``) that must keep +# hardcoded addresses. These do not converge under ``exact-no-stack`` +# with dynamic addresses because of patterns the analyzer's heuristics +# cannot cover: +# +# - EIP-2929 warm/cold gas accounting that depends on which addresses +# are warm at call time (baseline-specific layout). +# - CREATE2 collision semantics that depend on specific pre-state +# addresses colliding with computed CREATE2 targets. +# - Keccak-derived storage keys (Solidity mappings) baked into the +# pre-state on specific sender / contract addresses. +# - Structural transaction rejections sensitive to exact pre-state +# collisions (empty-but-code, init-colliding-with-non-empty). +# - Edge cases where dynamic allocation randomly picks an address +# with a leading zero byte, changing PUSH size. +# - Tag resolution mismatches (analyzer resolves +# to a fresh deterministic address, but baseline used the hint). +# +# Treat this list as an allowlist of "we've accepted the divergence +# here; don't try to make it dynamic". See trace-divergences.md for +# the per-file rationale. +FORCE_HARDCODED_TESTS: set[str] = { + # GAS_ONLY (29) — EIP-2929 warm/cold access cost differences + "stCallCodes/test_callcode_dynamic_code.py", + "stCallCodes/test_callcode_dynamic_code2_self_call.py", + "stCallCreateCallCodeTest/test_call1024_pre_calls.py", + "stCallCreateCallCodeTest/test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py", # noqa: E501 + "stCreate2/test_returndatacopy_following_create.py", + "stCreateTest/test_create_collision_to_empty2.py", + "stCreateTest/test_create_transaction_refund_ef.py", + "stDelegatecallTestHomestead/test_call1024_pre_calls.py", + "stDelegatecallTestHomestead/test_delegatecode_dynamic_code2_self_call.py", # noqa: E501 + "stEIP150singleCodeGasPrices/test_eip2929_oog.py", + "stEIP2930/test_manual_create.py", + "stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas_fail.py", + "stEIP3855_push0/test_push0.py", + "stEIP3855_push0/test_push0_gas2.py", + "stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py", # noqa: E501 + "stRandom/test_random_statetest282.py", + "stRandom/test_random_statetest287.py", + "stRandom/test_random_statetest384.py", + "stRandom2/test_random_statetest401.py", + "stRandom2/test_random_statetest508.py", + "stRevertTest/test_cost_revert.py", + "stRevertTest/test_revert_opcode_in_calls_on_non_empty_return_data.py", + "stRevertTest/test_revert_opcode_multiple_sub_calls.py", + "stRevertTest/test_revert_precompiled_touch_paris.py", + "stStackTests/test_underflow_test.py", + "stSystemOperationsTest/test_suicide_caller_addres_too_big_left.py", + "vmBitwiseLogicOperation/test_byte.py", + "vmIOandFlowOperations/test_jump_to_push.py", + "vmIOandFlowOperations/test_jumpi.py", + # EXECUTION_PATH_DIVERGED — remaining 8 (Categories B, C, D, E) + "stCreate2/test_create2_suicide.py", + "stCreate2/test_create2collision_code2.py", + "stCreate2/test_create2collision_selfdestructed2.py", + "stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract_oog.py", # noqa: E501 + "stLogTests/test_log1_non_empty_mem.py", + "stSystemOperationsTest/test_double_selfdestruct_touch_paris.py", + "stWalletTest/test_multi_owned_change_requirement_to1.py", + "stWalletTest/test_multi_owned_revoke_nothing.py", + # EXECUTION_PATH_DIVERGED + GAS (5) + "stCreate2/test_create2collision_code.py", + "stCreate2/test_create2collision_nonce.py", + "stCreate2/test_create2collision_selfdestructed.py", + "stCreate2/test_create2collision_selfdestructed_revert.py", + "stSStoreTest/test_sstore_gas_left.py", + # OUTPUT_DIFFERS — remaining 2 (Categories F, H) + "stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas.py", + "stWalletTest/test_multi_owned_is_owner_true.py", + # Precompile-as-EOA — tests fund precompile addresses as EOAs, + # then check nonce after calling the precompile. Dynamic EOAs + # land at different addresses than the precompile targets. + # STRUCTURAL — CREATE collision / EIP-3607 rejection behaviour. + # With dynamic addresses the collision doesn't happen, so the tx + # runs instead of being rejected → traces appear where baseline + # had none. + "stCreateTest/test_transaction_collision_to_empty_but_code.py", + "stCreateTest/test_transaction_collision_to_empty_but_nonce.py", + "stEIP3607/test_init_colliding_with_non_empty_account.py", + "stEIP3607/test_transaction_colliding_with_non_empty_account_calls.py", + "stEIP3607/test_transaction_colliding_with_non_empty_account_calls_itself.py", + "stEIP3607/test_transaction_colliding_with_non_empty_account_init_paris.py", + "stEIP3607/test_transaction_colliding_with_non_empty_account_send_paris.py", + # Remaining CI assertion failures — gas measurements, keccak storage, + # collision semantics, address-in-code, precompile interactions, etc. + # that are fundamentally incompatible with dynamic addresses. + "stBadOpcode/test_measure_gas.py", + "stBadOpcode/test_operation_diff_gas.py", + "stCallCodes/test_callcode_in_initcode_to_existing_contract_with_value_transfer.py", + "stCreate2/test_create2collision_balance.py", + "stCreate2/test_revert_depth_create_address_collision.py", + "stCreate2/test_revert_depth_create_address_collision_berlin.py", + "stCreateTest/test_create_empty_contract_with_storage.py", + "stCreateTest/test_transaction_collision_to_empty2.py", + "stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract.py", + "stEIP1153_transientStorage/test_trans_storage_ok.py", + "stEIP158Specific/test_call_one_v_call_suicide2.py", + "stInitCodeTest/test_out_of_gas_prefunded_contract_creation.py", + "stNonZeroCallsTest/test_non_zero_value_call_to_one_storage_key_paris.py", + "stNonZeroCallsTest/test_non_zero_value_callcode_to_one_storage_key_paris.py", + "stNonZeroCallsTest/test_non_zero_value_delegatecall_to_one_storage_key_paris.py", + "stNonZeroCallsTest/test_non_zero_value_suicide_to_empty_paris.py", + "stNonZeroCallsTest/test_non_zero_value_suicide_to_non_non_zero_balance.py", + "stNonZeroCallsTest/test_non_zero_value_suicide_to_one_storage_key_paris.py", + "stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_one_storage_key_paris.py", + "stNonZeroCallsTest/test_non_zero_value_transaction_call_to_one_storage_key_paris.py", + "stPreCompiledContracts2/test_call_ecrecover0.py", + "stPreCompiledContracts2/test_call_ecrecover0_complete_return_value.py", + "stPreCompiledContracts2/test_call_ecrecover0_gas3000.py", + "stPreCompiledContracts2/test_call_ecrecover0_overlapping_input_output.py", + "stPreCompiledContracts2/test_call_ecrecover_check_length.py", + "stPreCompiledContracts2/test_call_ecrecover_v_prefixed0.py", + "stPreCompiledContracts2/test_callcode_ecrecover0.py", + "stPreCompiledContracts2/test_callcode_ecrecover0_complete_return_value.py", + "stPreCompiledContracts2/test_callcode_ecrecover0_gas3000.py", + "stPreCompiledContracts2/test_callcode_ecrecover0_overlapping_input_output.py", + "stPreCompiledContracts2/test_callcode_ecrecover_v_prefixed0.py", + "stRandom/test_random_statetest144.py", + "stRandom2/test_random_statetest642.py", + "stRandom2/test_random_statetest645.py", + "stRandom2/test_random_statetest646.py", + "stRevertTest/test_revert_depth_create_address_collision.py", + "stRevertTest/test_revert_in_create_in_init_paris.py", + "stRevertTest/test_revert_prefound.py", + "stRevertTest/test_revert_prefound_empty_paris.py", + "stSpecialTest/test_failed_create_reverts_deletion_paris.py", + "stSystemOperationsTest/test_create_hash_collision.py", + "stSystemOperationsTest/test_test_random_test.py", + "stWalletTest/test_day_limit_construction.py", + "stWalletTest/test_day_limit_construction_partial.py", + "stWalletTest/test_day_limit_reset_spent_today.py", + "stWalletTest/test_day_limit_set_daily_limit.py", + "stWalletTest/test_day_limit_set_daily_limit_no_data.py", + "stWalletTest/test_multi_owned_add_owner_add_myself.py", + "stWalletTest/test_multi_owned_change_owner_from_not_owner.py", + "stWalletTest/test_multi_owned_change_owner_no_argument.py", + "stWalletTest/test_multi_owned_change_owner_to_is_owner.py", + "stWalletTest/test_multi_owned_change_requirement_to0.py", + "stWalletTest/test_multi_owned_change_requirement_to2.py", + "stWalletTest/test_multi_owned_construction_correct.py", + "stWalletTest/test_multi_owned_remove_owner_by_non_owner.py", + "stWalletTest/test_multi_owned_remove_owner_my_self.py", + "stWalletTest/test_multi_owned_remove_owner_owner_is_not_owner.py", + "stWalletTest/test_wallet_change_requirement_remove_pending_transaction.py", + "stWalletTest/test_wallet_construction.py", + "stWalletTest/test_wallet_construction_oog.py", + "stWalletTest/test_wallet_construction_partial.py", + "stWalletTest/test_wallet_kill.py", + "stWalletTest/test_wallet_kill_to_wallet.py", + "stWalletTest/test_wallet_remove_owner_remove_pending_transaction.py", + "stZeroCallsRevert/test_zero_value_call_to_one_storage_key_oog_revert_paris.py", + "stZeroCallsRevert/test_zero_value_callcode_to_one_storage_key_oog_revert_paris.py", + "stZeroCallsRevert/test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris.py", + "stZeroCallsRevert/test_zero_value_suicide_to_one_storage_key_oog_revert_paris.py", + "stZeroCallsTest/test_zero_value_call_to_one_storage_key_paris.py", + "stZeroCallsTest/test_zero_value_callcode_to_one_storage_key_paris.py", + "stZeroCallsTest/test_zero_value_delegatecall_to_one_storage_key_paris.py", + "stZeroCallsTest/test_zero_value_suicide_to_empty_paris.py", + "stZeroCallsTest/test_zero_value_suicide_to_non_zero_balance.py", + "stZeroCallsTest/test_zero_value_suicide_to_one_storage_key_paris.py", + "stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_one_storage_key_paris.py", + "stZeroCallsTest/test_zero_value_transaction_call_to_one_storage_key_paris.py", + # Slow-marked tests that fail with dynamic addresses (excluded from + # the main verification by -m "not slow" but exercised on full CI + # runs without that filter — same KV_CALL_FLIP / collision / + # ecrecover patterns as the non-slow allowlisted siblings). + "stQuadraticComplexityTest/test_return50000.py", + "stQuadraticComplexityTest/test_return50000_2.py", + "stStaticCall/test_static_call_ecrecover0.py", + "stStaticCall/test_static_call_ecrecover0_complete_return_value.py", + "stStaticCall/test_static_call_ecrecover0_gas3000.py", + "stStaticCall/test_static_call_ecrecover0_overlapping_input_output.py", + "stStaticCall/test_static_call_ecrecover_check_length.py", + "stStaticCall/test_static_call_ecrecover_v_prefixed0.py", + "stStaticCall/test_static_call_to_call_code_op_code_check.py", + "stStaticCall/test_static_call_to_call_op_code_check.py", + "stStaticCall/test_static_call_to_del_call_op_code_check.py", + "stStaticCall/test_static_call_to_static_op_code_check.py", + "stStaticCall/test_static_check_opcodes.py", + "stStaticCall/test_static_check_opcodes2.py", + "stStaticCall/test_static_check_opcodes3.py", + "stStaticCall/test_static_check_opcodes4.py", + "stStaticCall/test_static_check_opcodes5.py", +} + + +def _ported_rel_path(filler_path: Path) -> str: + """Return the ``/test_.py`` path for a filler.""" + category = filler_path.parent.name if filler_path.parent.name else "" + py_test_name = _filler_name_to_test_name(filler_path.stem) + return f"{category}/{py_test_name}.py" + class _AnalyzerAlloc(Alloc): """Alloc subclass that supports fund_eoa for analysis.""" @@ -125,6 +318,40 @@ def analyze( pre = _AnalyzerAlloc() tags = model.pre.setup(pre, all_deps) + # 2b. Honour precompile hint addresses for tagged EOAs. + # The static filler resolves ```` through + # ``eoa_from_hash`` (random placeholder address). LLL source code + # however references those addresses literally (e.g. + # ``(call gas 0x01 ...)``), so the bytecode lands at the precompile + # while the funded EOA lands somewhere else. Override the resolved + # address back to the literal hint when it falls in the precompile + # range (0x01-0x10) — that way ``addr_to_var`` registers 0x01 and + # tx-data / post-state resolutions stay consistent with bytecode. + # + # Track the override addresses so that the corresponding EOA can + # be pinned non-dynamic later. Without pinning, the variable in + # the generated test (``addr_5``) would still go through + # ``pre.fund_eoa()`` at runtime and land at a random address, + # while ``tx_data`` would carry that random address — breaking + # any contract that calls the literal precompile (0x01). + pinned_eoa_addrs: set[Address] = set() + for tag in model.pre.root.keys(): + if not isinstance(tag, SenderTag): + continue + name = tag.name + if not ( + isinstance(name, str) and name.startswith("0x") and len(name) == 42 + ): + continue + try: + hint_int = int(name, 16) + except ValueError: + continue + if 1 <= hint_int <= 0x10: + hint_addr = Address(hint_int) + tags[tag.name] = hint_addr + pinned_eoa_addrs.add(hint_addr) + # 3. Fork range (must sort chronologically, not alphabetically) all_fork_names = [str(f) for f in sorted(get_forks())] valid_forks_set = set(model.get_valid_at_forks()) @@ -141,6 +368,19 @@ def analyze( # 5. Build address -> variable name mapping addr_to_var = _assign_variable_names(model, tags) + # 5b. Resolve coinbase address for later use + coinbase_addr: Address | None = None + if isinstance(model.env.current_coinbase, Tag): + tag_name = model.env.current_coinbase.name + if tag_name in tags: + resolved = tags[tag_name] + if isinstance(resolved, Address): + coinbase_addr = resolved + else: + coinbase_addr = Address(int.from_bytes(resolved, "big")) + else: + coinbase_addr = model.env.current_coinbase + # 6. Identify sender sender_ir, sender_tag_name = _build_sender_ir(model, tags) @@ -163,8 +403,16 @@ def analyze( is_fork_dependent = not is_multi_case and len(model.expect) > 1 # 9. Build accounts + force_hardcoded = _ported_rel_path(filler_path) in FORCE_HARDCODED_TESTS accounts = _build_accounts( - model, tags, addr_to_var, sender_tag_name, imports + model, + tags, + addr_to_var, + sender_tag_name, + imports, + force_hardcoded=force_hardcoded, + coinbase_addr=coinbase_addr, + pinned_eoa_addrs=pinned_eoa_addrs, ) # Track if sender is not in the pre-state (for fund_eoa handling). @@ -181,6 +429,38 @@ def analyze( model, tags, addr_to_var, all_fork_names, imports ) + # 11b. If post-state has unresolvable addresses — either as account + # references (Address(0x...)) or as address-like storage values + # (large ints > 2^32 that weren't resolved to variable names) — + # disable dynamic for ALL accounts (including sender) so every + # address stays fixed and CREATE-derived addresses match baseline. + # Values above 2**32 are likely addresses, not small ints. + addr_like_threshold = 0x100000000 + has_unresolved = any( + "Address(0x" in a.var_ref + for entry in expect_entries + for a in entry.result + ) or any( + isinstance(v, int) and v >= addr_like_threshold + for entry in expect_entries + for a in entry.result + if a.storage is not None + for v in a.storage.values() + ) + if has_unresolved: + for acct in accounts: + acct.use_dynamic = False + + # Sender: dynamic unless unresolvable post-state or hardcoded allowlist. + sender_ir.use_dynamic = not force_hardcoded and not has_unresolved + + # 11c. Forced hardcoded (allowlist) also pins every EOA so coinbase + # rebinds and fund_eoa-generated EOAs don't leak into an otherwise + # hardcoded test. + if force_hardcoded: + for acct in accounts: + acct.use_dynamic = False + # 12. Build transaction IR transaction_ir, access_list_entries = _build_transaction_ir( model, @@ -195,7 +475,7 @@ def analyze( # 13. Address constants (non-tagged, non-sender addresses) address_constants = _build_address_constants( - model, tags, addr_to_var, sender_tag_name + model, tags, addr_to_var, sender_tag_name, accounts ) # 14. Import flags @@ -222,6 +502,31 @@ def analyze( # 16. Test name py_test_name = _filler_name_to_test_name(test_name) + # 17. Whether the test mutates the pre-allocation. The framework's + # ``assert_mutable()`` is triggered by: + # * ``pre[var] = Account(...)`` (any non-dynamic account) + # * ``EOA(key=...)`` (non-dynamic sender) + # * ``pre.deploy_contract(address=...)`` (non-dynamic contract) + # * ``pre.deploy_contract(..., nonce=0)`` (default emit when the + # filler's account had nonce 0 or unset) + # * ``pre.fund_eoa(nonce=...)`` (dynamic sender with explicit + # nonce — used for high-nonce senders) + # Tests not hitting any of these can run under the ``execute`` plugin. + # The template only emits ``pre.fund_eoa(nonce=...)`` when + # ``sender.nonce`` is truthy, and ``pre.deploy_contract(..., nonce=N)`` + # always emits N (defaulting to 0 when ``account.nonce`` is None). + # Mirror those conditions exactly. + sender_emits_nonce_kwarg = bool(sender_ir.nonce) + contract_nonce_zero = any( + not a.is_eoa and (a.nonce is None or a.nonce == 0) for a in accounts + ) + needs_mutable_pre = ( + not sender_ir.use_dynamic + or sender_emits_nonce_kwarg + or any(not a.use_dynamic for a in accounts) + or contract_nonce_zero + ) + return IntermediateTestModel( test_name=py_test_name, filler_path=str(filler_path), @@ -235,6 +540,7 @@ def analyze( ), is_multi_case=is_multi_case, is_fork_dependent=is_fork_dependent, + needs_mutable_pre=needs_mutable_pre, environment=environment_ir, accounts=accounts, sender=sender_ir, @@ -535,31 +841,40 @@ def _build_sender_ir( key_int = int.from_bytes(key, "big") else: key_int = 0 - # Find sender balance from pre-state + # Find sender balance and nonce from pre-state balance = 0 + nonce: int | None = None for address_or_tag, account in model.pre.root.items(): if isinstance(address_or_tag, SenderTag): if address_or_tag.name == tag_name: balance = int(account.balance) if account.balance else 0 + if account.nonce is not None: + nonce = int(account.nonce) break return ( - SenderIR(is_tagged=False, key=key_int, balance=balance), + SenderIR( + is_tagged=False, key=key_int, balance=balance, nonce=nonce + ), tag_name, ) else: - # Find sender balance from pre-state + # Find sender balance and nonce from pre-state eoa = EOA(key=model.transaction.secret_key) sender_addr = _addr_hex(eoa) balance = 0 + nonce = None for address_or_tag, account in model.pre.root.items(): if not isinstance(address_or_tag, Tag): if _addr_hex(address_or_tag) == sender_addr: balance = int(account.balance) if account.balance else 0 + if account.nonce is not None: + nonce = int(account.nonce) break return SenderIR( is_tagged=False, key=int.from_bytes(eoa.key, "big"), balance=balance, + nonce=nonce, ), None @@ -605,15 +920,139 @@ def _build_parameters(model: StateStaticTest) -> list[ParameterCaseIR]: return parameters +def _resolve_storage_values( + storage: dict[int, int], + addr_to_var: dict[Address | EOA, str], + imports: ImportsIR | None = None, +) -> dict[int, int | str]: + """Replace storage values matching known addresses with var names.""" + if not storage or not addr_to_var: + return storage + # Build int -> var_name lookup from addr_to_var + int_to_var: dict[int, str] = {} + for addr, var_name in addr_to_var.items(): + int_to_var[int.from_bytes(addr, "big")] = var_name + # Also build CREATE-derived address lookup + create_to_expr: dict[int, str] = {} + for addr, var_name in addr_to_var.items(): + for nonce in range(256): + created = compute_create_address(address=addr, nonce=nonce) + created_int = int.from_bytes(created, "big") + if created_int not in int_to_var: + create_to_expr[created_int] = ( + f"compute_create_address(address={var_name}," + f" nonce={nonce})" + ) + result: dict[int, int | str] = {} + for k, v in storage.items(): + if v in int_to_var: + result[k] = int_to_var[v] + elif v in create_to_expr: + if imports is not None: + imports.needs_compute_create_address = True + result[k] = create_to_expr[v] + else: + result[k] = v + return result + + +def _find_address_refs_in_bytecode( + code_bytes: bytes, + known_addresses: set[Address], +) -> dict[Address, int]: + """ + Find known addresses referenced in bytecode via PUSH. + + Return a mapping ``address -> minimum PUSH size observed``. + A push size < 20 means the baseline bytecode compiled the + address to fewer bytes (leading zero bytes); the referenced + contract must stay hardcoded so the compiler keeps emitting + the same short PUSH opcode and the trace stays aligned. + """ + refs: dict[Address, int] = {} + # Pre-compute int values for fast comparison + known_ints = {int.from_bytes(a, "big") for a in known_addresses} + i = 0 + while i < len(code_bytes): + opcode = code_bytes[i] + if 0x60 <= opcode <= 0x7F: # PUSH1..PUSH32 + push_size = opcode - 0x5F + push_data = code_bytes[i + 1 : i + 1 + push_size] + if len(push_data) == push_size: + # Addresses with leading zero bytes are compiled to + # a PUSH smaller than PUSH20 (down to PUSH1 for 1-byte + # addresses like 0x01). Match on int value against the + # known-address set — false positives would require a + # PUSHn that happens to push exactly a value already + # registered as a pre-state address, which is rare in + # practice. + val = int.from_bytes(push_data, "big") + if val in known_ints: + addr = Address(val) + if addr not in refs or push_size < refs[addr]: + refs[addr] = push_size + i += 1 + push_size + else: + i += 1 + return refs + + +def _topological_sort_contracts( + contract_addrs: list[Address], + deps: dict[Address, set[Address]], +) -> tuple[list[Address], set[Address]]: + """ + Return (sorted_addresses, cycle_addresses). + + If A's bytecode references B, B must be deployed before A. + """ + addr_set = set(contract_addrs) + # forward[B] = {A} means A depends on B, so B must come first + forward: dict[Address, set[Address]] = {a: set() for a in addr_set} # noqa: C420 + in_deg: dict[Address, int] = dict.fromkeys(addr_set, 0) + for a, dep_set in deps.items(): + if a not in addr_set: + continue + for b in dep_set: + if b in addr_set: + forward[b].add(a) + in_deg[a] += 1 + + # Kahn's algorithm + queue = [a for a in contract_addrs if in_deg[a] == 0] + sorted_addrs: list[Address] = [] + while queue: + node = queue.pop(0) + sorted_addrs.append(node) + for neighbor in forward[node]: + in_deg[neighbor] -= 1 + if in_deg[neighbor] == 0: + queue.append(neighbor) + + cycle_addrs = addr_set - set(sorted_addrs) + return sorted_addrs, cycle_addrs + + def _build_accounts( model: StateStaticTest, tags: TagDict, addr_to_var: dict[Address | EOA, str], sender_tag_name: str | None, imports: ImportsIR, + *, + force_hardcoded: bool = False, + coinbase_addr: Address | None = None, + pinned_eoa_addrs: set[Address] | None = None, ) -> list[AccountIR]: - """Build AccountIR list. Return (accounts, needs_op_import).""" - accounts: list[AccountIR] = [] + """Build AccountIR list with dependency-ordered contracts.""" + if pinned_eoa_addrs is None: + pinned_eoa_addrs = set() + # ------------------------------------------------------------------ + # Pass 1: gather account metadata and compile bytecode (no Op yet) + # ------------------------------------------------------------------ + raw_accounts: list[AccountIR] = [] + # Map address -> compiled code_bytes for contracts (for dep analysis) + code_bytes_map: dict[Address, bytes] = {} for address_or_tag, account in model.pre.root.items(): is_tagged = isinstance(address_or_tag, Tag) @@ -652,9 +1091,9 @@ def _build_accounts( # Non-tagged, no code — treat as EOA is_eoa = True - # Code processing + # Compile code but defer Op expression conversion source_comment = "" - code_expr = "" + code_bytes: bytes = b"" oversized_code = False if has_code: source_comment = _classify_code_source(account.code.source) @@ -662,49 +1101,290 @@ def _build_accounts( code_bytes = account.code.compiled(tags) if len(code_bytes) > MAX_BYTECODE_OP_SIZE: oversized_code = True - # TODO: To add `addr_to_var` here, we need to resolve - # dependency order. - op_expr = _bytes_to_op_expr(code_bytes) - if op_expr: - code_expr = op_expr - imports.needs_op = True - elif code_bytes: - code_expr = f'bytes.fromhex("{code_bytes.hex()}")' except Exception as e: warnings.warn( f"Code compilation failed for {var_name}: {e}", stacklevel=2, ) - code_expr = 'b""' # Storage - storage: dict[int, int] = {} + storage: dict[int, int | str] = {} if account.storage and account.storage.root: resolved_storage = account.storage.resolve(tags) for k, v in resolved_storage.items(): storage[int(k)] = int(v) + storage = _resolve_storage_values(storage, addr_to_var, imports) # Balance and nonce balance = int(account.balance) if account.balance is not None else 0 nonce = int(account.nonce) if account.nonce is not None else None - accounts.append( - AccountIR( - var_name=var_name, - is_tagged=is_tagged, - is_eoa=is_eoa, - is_sender=is_sender, - balance=balance, - nonce=nonce, - address=address, - source_comment=source_comment, - code_expr=code_expr, - storage=storage, - oversized_code=oversized_code, - ) + acct_ir = AccountIR( + var_name=var_name, + is_tagged=is_tagged, + is_eoa=is_eoa, + is_sender=is_sender, + balance=balance, + nonce=nonce, + address=address, + source_comment=source_comment, + code_expr="", + storage=storage, + oversized_code=oversized_code, + use_dynamic=True, ) - return accounts + # Oversized contracts must keep hardcoded address + if oversized_code: + acct_ir.use_dynamic = False + + # Coinbase account must keep hardcoded address so + # Environment(fee_recipient=coinbase) and the pre-state + # entry refer to the same address. + if ( + coinbase_addr is not None + and address is not None + and int.from_bytes(address, "big") + == int.from_bytes(coinbase_addr, "big") + ): + acct_ir.use_dynamic = False + + raw_accounts.append(acct_ir) + if code_bytes and address is not None: + code_bytes_map[address] = code_bytes + + # ------------------------------------------------------------------ + # Build dependency graph and topological sort for contracts + # ------------------------------------------------------------------ + known_contract_addrs: set[Address] = set() + for acct in raw_accounts: + if not acct.is_eoa and acct.address is not None: + known_contract_addrs.add(acct.address) + + # All known addresses (contracts + EOAs) for bytecode ref scanning + all_known_addrs: set[Address] = set() + for addr_or_eoa in addr_to_var: + if isinstance(addr_or_eoa, Address): + all_known_addrs.add(addr_or_eoa) + else: + all_known_addrs.add(Address(int.from_bytes(addr_or_eoa, "big"))) + + # Pre-state EOA addresses — used to recognise short-PUSH refs that + # point at funded EOAs (e.g. precompile addresses 0x01-0x10 listed + # as ```` in the filler) instead of contracts. + known_eoa_addrs: set[Address] = set() + for acct in raw_accounts: + if acct.is_eoa and acct.address is not None: + known_eoa_addrs.add(acct.address) + + deps: dict[Address, set[Address]] = {} + # Contract addresses referenced via PUSH<20 anywhere: baseline + # bytecode compiled them to a short PUSH because of leading zero + # bytes, so they must stay hardcoded to keep the opcode sequence + # aligned. + short_push_refs: set[Address] = set() + # EOA addresses referenced via PUSH<20 — pin those EOAs to their + # literal address so the funded account lands at the precompile + # (e.g. 0x01) instead of a random ``pre.fund_eoa`` address. + short_push_eoa_refs: set[Address] = set() + # True when a short-PUSH ref targets an address that is neither a + # pre-state contract nor a pre-state EOA (e.g. an external tag + # like only referenced from bytecode). No + # account can be pinned, so fall back to globally disabling + # dynamic addresses for the whole test. + short_push_unpinnable = False + for addr, cb in code_bytes_map.items(): + refs = _find_address_refs_in_bytecode(cb, all_known_addrs) + # Track deps on other contracts. Keep self-references — they + # create self-loops detected as cycles, forcing hardcoded addr. + deps[addr] = set(refs) & known_contract_addrs + for ref_addr, push_size in refs.items(): + if push_size < 20: + if ref_addr in known_contract_addrs: + short_push_refs.add(ref_addr) + elif ref_addr in known_eoa_addrs: + short_push_eoa_refs.add(ref_addr) + else: + short_push_unpinnable = True + + contract_addrs_ordered = [ + acct.address + for acct in raw_accounts + if not acct.is_eoa and acct.address is not None + ] + sorted_addrs, cycle_addrs = _topological_sort_contracts( + contract_addrs_ordered, deps + ) + + # Mark cycle contracts as non-dynamic, then propagate: any contract + # referenced by a non-dynamic contract must also be non-dynamic + # (because the non-dynamic bytecode contains the old address). + non_dynamic_addrs = set(cycle_addrs) + for acct in raw_accounts: + if acct.oversized_code and acct.address is not None: + non_dynamic_addrs.add(acct.address) + # Short-PUSH refs: pin the referenced contract so its address keeps + # the same leading-zero profile as baseline. + non_dynamic_addrs.update(short_push_refs) + + changed = True + while changed: + changed = False + for addr in list(non_dynamic_addrs): + for ref in deps.get(addr, set()): + if ( + ref not in non_dynamic_addrs + and ref in known_contract_addrs + ): + non_dynamic_addrs.add(ref) + changed = True + + for acct in raw_accounts: + if acct.address in non_dynamic_addrs: + acct.use_dynamic = False + + # Pin EOAs whose addresses are referenced via short PUSH so the + # funded account lands at the literal address (e.g. precompile + # 0x01) instead of a random ``pre.fund_eoa`` address. + for acct in raw_accounts: + if acct.address in short_push_eoa_refs: + acct.use_dynamic = False + + # Pin EOAs whose tags were hint-overridden into the precompile + # range. The override registered the literal address in + # ``addr_to_var`` so tx-data and post-state resolutions point at + # ``addr_X`` (a variable). The variable must hold the literal + # precompile address at runtime, not whatever ``pre.fund_eoa`` + # picks. + for acct in raw_accounts: + if acct.address in pinned_eoa_addrs: + acct.use_dynamic = False + + # ------------------------------------------------------------------ + # Pass 2: convert bytecode to Op expressions + # ------------------------------------------------------------------ + # Collect all address variable names for arithmetic detection + addr_var_names = set(addr_to_var.values()) + + for acct in raw_accounts: + cb = code_bytes_map.get(acct.address) if acct.address else None + if not cb: + continue + try: + if acct.use_dynamic: + # Try with addr_to_var for symbolic references + op_expr = _bytes_to_op_expr(cb, addr_to_var) + if op_expr is None: + # Fallback: without addr_to_var (keep dynamic) + op_expr = _bytes_to_op_expr(cb) + else: + op_expr = _bytes_to_op_expr(cb) + + if op_expr: + acct.code_expr = op_expr + imports.needs_op = True + elif cb: + acct.code_expr = f'bytes.fromhex("{cb.hex()}")' + except Exception: + acct.code_expr = 'b""' + + # ------------------------------------------------------------------ + # Check for address variables used in arithmetic operations. + # Pattern: Op.ADD(contract_0, ...) means contracts are at + # sequential addresses and cannot be dynamically assigned. + # If found, disable dynamic for ALL contracts. + # ------------------------------------------------------------------ + arith_ops = {"Op.ADD(", "Op.SUB(", "Op.MUL(", "Op.DIV("} + has_addr_arithmetic = False + for acct in raw_accounts: + if not acct.code_expr: + continue + for var_name in addr_var_names: + for arith_op in arith_ops: + if f"{arith_op}{var_name}" in acct.code_expr: + has_addr_arithmetic = True + break + if has_addr_arithmetic: + break + if has_addr_arithmetic: + break + + # ------------------------------------------------------------------ + # Computed call targets: CALL/STATICCALL/DELEGATECALL/CALLCODE + # receiving `address=` from arithmetic or memory reads. Tests that + # do this usually rely on specific pre-state contract addresses + # (dispatch-by-offset) and won't survive dynamic allocation. + # ------------------------------------------------------------------ + computed_addr_patterns = ( + "address=Op.ADD(", + "address=Op.SUB(", + "address=Op.MUL(", + "address=Op.DIV(", + "address=Op.MOD(", + "address=Op.MLOAD(", + "address=Op.SLOAD(", + "address=Op.CALLDATALOAD(", + ) + has_computed_call_target = False + for acct in raw_accounts: + if not acct.code_expr: + continue + for pat in computed_addr_patterns: + if pat in acct.code_expr: + has_computed_call_target = True + break + if has_computed_call_target: + break + + if ( + has_addr_arithmetic + or short_push_unpinnable + or has_computed_call_target + or force_hardcoded + ): + # Disable dynamic for all contracts and re-generate Op + # expressions without addr_to_var. Triggers: + # * address arithmetic (Op.ADD(var, ...)) assumes sequential + # addresses that dynamic allocation can't preserve. + # * a short-PUSH ref that points outside the pre-state has no + # contract to pin, so the whole test must keep the filler's + # resolved addresses. + # * computed call targets (CALL with address=Op.ADD/MLOAD/ + # CALLDATALOAD/...) dispatch by baseline-relative offsets. + # * the test is on the FORCE_HARDCODED_TESTS allowlist — we've + # accepted that it can't converge under exact-no-stack with + # dynamic addresses (see module docstring on that set). + for acct in raw_accounts: + if not acct.is_eoa: + acct.use_dynamic = False + cb = code_bytes_map.get(acct.address) if acct.address else None + if not cb: + continue + try: + op_expr = _bytes_to_op_expr(cb) + if op_expr: + acct.code_expr = op_expr + elif cb: + acct.code_expr = f'bytes.fromhex("{cb.hex()}")' + except Exception: + acct.code_expr = 'b""' + + # ------------------------------------------------------------------ + # Reorder: EOAs first (filler order), then contracts (topo order) + # ------------------------------------------------------------------ + eoa_accounts = [a for a in raw_accounts if a.is_eoa] + contract_by_addr = {a.address: a for a in raw_accounts if not a.is_eoa} + # Sorted contracts first, then any cycle contracts in filler order + ordered_contracts: list[AccountIR] = [] + for addr in sorted_addrs: + if addr in contract_by_addr: + ordered_contracts.append(contract_by_addr[addr]) + # Append cycle contracts (non-dynamic) in their original filler order + for acct in raw_accounts: + if not acct.is_eoa and acct.address in cycle_addrs: + ordered_contracts.append(acct) + + return eoa_accounts + ordered_contracts def _build_environment( @@ -856,13 +1536,16 @@ def _build_expect_entries( continue # Storage (including ANY keys) - storage: dict[int, int] | None = None + storage: dict[int, int | str] | None = None storage_any_keys: list[int] = [] if account_expect.storage is not None: storage = {} resolved_storage = account_expect.storage.resolve(tags) for k, v in resolved_storage.items(): storage[int(k)] = int(v) + storage = _resolve_storage_values( + storage, addr_to_var, imports + ) # Capture ANY keys from _any_map if hasattr(resolved_storage, "_any_map"): for k in resolved_storage._any_map: @@ -954,12 +1637,24 @@ def _resolve_access_list(data_box_al): for al_entry in data_box_al: if isinstance(al_entry.address, Tag): resolved_al = al_entry.address.resolve(tags) - al_addr = str(Address(resolved_al)) + al_address = Address(resolved_al) + else: + al_address = al_entry.address + # Try to resolve to variable name + var_name = addr_to_var.get(al_address) + if var_name: + al_addr_str = var_name + al_dynamic = True else: - al_addr = str(al_entry.address) + al_addr_str = str(al_address) + al_dynamic = False al_keys = [str(k) for k in al_entry.storage_keys] entries.append( - AccessListEntryIR(address=al_addr, storage_keys=al_keys) + AccessListEntryIR( + address=al_addr_str, + storage_keys=al_keys, + use_dynamic=al_dynamic, + ) ) return entries @@ -1050,12 +1745,20 @@ def _build_address_constants( tags: TagDict, addr_to_var: dict[Address | EOA, str], sender_tag_name: str | None, + accounts: list[AccountIR], ) -> list[dict[str, str]]: """Build list of address constants for the function body.""" constants: list[dict[str, str]] = [] seen: set[Address | EOA] = set() - # Coinbase (tagged or not) + # Collect addresses of dynamic EOAs — these are handled by + # pre.fund_eoa() in the accounts section, not as constants. + dynamic_eoa_addrs: set[Address | EOA] = set() + for acct in accounts: + if acct.is_eoa and acct.use_dynamic and acct.address is not None: + dynamic_eoa_addrs.add(acct.address) + + # Coinbase (tagged or not) — always keep as hardcoded constant if isinstance(model.env.current_coinbase, Tag): tag_name = model.env.current_coinbase.name resolved = tags.get(tag_name) @@ -1084,6 +1787,9 @@ def _build_address_constants( continue resolved = tags.get(tag_name) if resolved: + # Skip dynamic EOAs (handled by fund_eoa) + if resolved in dynamic_eoa_addrs: + continue var_name = addr_to_var.get(resolved, tag_name) if resolved not in seen and var_name != "coinbase": constants.append( @@ -1091,6 +1797,9 @@ def _build_address_constants( ) seen.add(resolved) else: + # Skip dynamic EOAs (handled by fund_eoa) + if address_or_tag in dynamic_eoa_addrs: + continue var_name = addr_to_var.get(address_or_tag) if ( var_name @@ -1206,12 +1915,26 @@ def _resolve_address( if addr == var_addr: return var # Check if the address is the result of contract creation from a known - # address. + # address. Use a larger range to cover high-nonce senders. for var_addr, var in addr_to_var.items(): - max_created_contracts = 256 - for nonce in range(max_created_contracts): + for nonce in range(10000): if addr == compute_create_address(address=var_addr, nonce=nonce): imports.needs_compute_create_address = True return f"compute_create_address(address={var}, nonce={nonce})" + # Nested CREATE: address created by a contract that was itself created + # by a known address (2 levels deep, small nonce range to keep + # generation fast — most contracts CREATE only a few children). + for var_addr, var in addr_to_var.items(): + for n1 in range(16): + child = compute_create_address(address=var_addr, nonce=n1) + for n2 in range(16): + if addr == compute_create_address(address=child, nonce=n2): + imports.needs_compute_create_address = True + return ( + f"compute_create_address(" + f"address=compute_create_address(" + f"address={var}, nonce={n1}), nonce={n2})" + ) + return f"Address({addr})" diff --git a/scripts/filler_to_python/ir.py b/scripts/filler_to_python/ir.py index 2712d4f3635..18214cf9cb1 100644 --- a/scripts/filler_to_python/ir.py +++ b/scripts/filler_to_python/ir.py @@ -36,6 +36,7 @@ class AccountIR: code_expr: str = "" storage: dict = field(default_factory=dict) oversized_code: bool = False + use_dynamic: bool = True @dataclass @@ -80,6 +81,7 @@ class AccessListEntryIR: address: str = "" storage_keys: list = field(default_factory=list) + use_dynamic: bool = False @dataclass @@ -108,7 +110,9 @@ class SenderIR: is_tagged: bool = False key: int | None = None balance: int = 0 + nonce: int | None = None not_in_pre: bool = False + use_dynamic: bool = True @dataclass @@ -136,6 +140,7 @@ class IntermediateTestModel: is_slow: bool = False is_multi_case: bool = False is_fork_dependent: bool = False + needs_mutable_pre: bool = False environment: EnvironmentIR = field( default_factory=lambda: EnvironmentIR( coinbase_var="coinbase", number=0, timestamp=0 diff --git a/scripts/filler_to_python/render.py b/scripts/filler_to_python/render.py index b5be4ea56df..000abe511f5 100644 --- a/scripts/filler_to_python/render.py +++ b/scripts/filler_to_python/render.py @@ -42,7 +42,11 @@ def format_storage(d: dict) -> str: return "{}" items = [] for k in sorted(d.keys()): - items.append(f"{format_int(k)}: {format_int(d[k])}") + v = d[k] + if isinstance(v, str): + items.append(f"{format_int(k)}: {v}") + else: + items.append(f"{format_int(k)}: {format_int(v)}") single = "{" + ", ".join(items) + "}" if len(single) <= 50: return single @@ -271,6 +275,7 @@ def render_test(ir: IntermediateTestModel) -> str: "is_slow": ir.is_slow, "is_multi_case": ir.is_multi_case, "is_fork_dependent": ir.is_fork_dependent, + "needs_mutable_pre": ir.needs_mutable_pre, "has_exceptions": has_exceptions, "env": ir.environment, "accounts": ir.accounts, diff --git a/scripts/filler_to_python/templates/state_test.py.j2 b/scripts/filler_to_python/templates/state_test.py.j2 index 0b9c52a6dd5..5f0e7559e1d 100644 --- a/scripts/filler_to_python/templates/state_test.py.j2 +++ b/scripts/filler_to_python/templates/state_test.py.j2 @@ -159,7 +159,9 @@ def _storage_with_any(base: dict, any_keys: list) -> Storage: {% if has_exceptions and not is_multi_case %} @pytest.mark.exception_test {% endif %} +{% if needs_mutable_pre %} @pytest.mark.pre_alloc_mutable +{% endif %} def {{ test_name }}( state_test: StateTestFiller, pre: Alloc, @@ -176,7 +178,13 @@ def {{ test_name }}( {% for addr in address_constants %} {{ addr.var_name }} = Address({{ addr.hex }}) {% endfor %} -{% if sender.not_in_pre %} +{% if sender.use_dynamic %} +{% if sender.nonce %} + sender = pre.fund_eoa(amount={{ sender.balance | format_int }}, nonce={{ sender.nonce }}) +{% else %} + sender = pre.fund_eoa(amount={{ sender.balance | format_int }}) +{% endif %} +{% elif sender.not_in_pre %} sender = pre.fund_eoa(amount=0) {% else %} sender = EOA( @@ -205,15 +213,19 @@ def {{ test_name }}( {# Pre-state account setup #} {% for account in accounts %} -{% if account.is_sender %} +{% if account.is_sender and sender.use_dynamic %} +{# Sender balance already set via pre.fund_eoa() above #} +{% elif account.is_sender %} pre[sender] = Account(balance={{ account.balance | format_int }}{{ ", nonce=%d" | format(account.nonce) if account.nonce }}{{ ", storage=%s" | format(account.storage | format_storage) if account.storage }}{{ ", code=%s" | format(account.code_expr | wrap_op_chain(indent=8)) if account.code_expr }}) +{% elif account.is_eoa and account.use_dynamic %} + {{ account.var_name }} = pre.fund_eoa(amount={{ account.balance | format_int }}) # noqa: F841 {% elif account.is_eoa %} pre[{{ account.var_name }}] = Account(balance={{ account.balance | format_int }}{{ ", nonce=%d" | format(account.nonce) if account.nonce }}{{ ", storage=%s" | format(account.storage | format_storage) if account.storage }}{{ ", code=%s" | format(account.code_expr | wrap_op_chain(indent=8)) if account.code_expr }}) {% else %} {# Contract: source comment + deploy #} {{ account.source_comment }} {% if account.oversized_code %} - {{ account.var_name }} = Address({{ account.address }}) + {{ account.var_name }} = Address({{ account.address }}) # oversized contract pre[{{ account.var_name }}] = Account( code={{ account.code_expr | wrap_op_chain(indent=8) }}, {% if account.storage %} @@ -238,7 +250,9 @@ def {{ test_name }}( {% if account.nonce is not none %} nonce={{ account.nonce }}, {% endif %} +{% if not account.use_dynamic %} address=Address({{ account.address }}), # noqa: E501 +{% endif %} ) {% endif %} {% endif %} @@ -287,7 +301,11 @@ def {{ test_name }}( {{ d_idx }}: [ {% for al in al_entries %} AccessList( + {% if al.use_dynamic %} + address={{ al.address }}, + {% else %} address=Address({{ al.address }}), + {% endif %} storage_keys=[ {% for sk in al.storage_keys %} Hash("{{ sk }}"), # noqa: E501 @@ -357,7 +375,11 @@ def {{ test_name }}( access_list=[ {% for al in tx.access_list %} AccessList( +{% if al.use_dynamic %} + address={{ al.address }}, +{% else %} address=Address({{ al.address }}), +{% endif %} storage_keys=[ {% for sk in al.storage_keys %} Hash( diff --git a/scripts/verify_dynamic_addresses.sh b/scripts/verify_dynamic_addresses.sh new file mode 100755 index 00000000000..3cbd19becaa --- /dev/null +++ b/scripts/verify_dynamic_addresses.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Verify that filler_to_python with dynamic addresses produces +# trace-equivalent tests. Assumes output/traces_baseline/ already +# exists (generated once before any code changes). +set -euo pipefail + +export TMPDIR=./.tmp +mkdir -p "$TMPDIR" output/traces_new + +if [ ! -d "output/traces_baseline" ]; then + echo "ERROR: output/traces_baseline/ not found." + echo "Generate baseline first (before code changes):" + echo " TMPDIR=./.tmp uv run fill tests/ported_static/ --evm-dump-dir output/traces_baseline -n 10 -m 'not slow'" + exit 1 +fi + +# Step 1: Run filler_to_python (overwrites tests/ported_static/) +echo "=== Step 1: Running filler_to_python ===" +uv run python -m scripts.filler_to_python \ + --fillers tests/static/static/state_tests/ \ + --output tests/ported_static/ + +# Step 2: Fill new tests + verify against baseline +echo "=== Step 2: Filling new tests and verifying traces ===" +uv run fill \ + tests/ported_static/ \ + --evm-dump-dir output/traces_new \ + --verify-traces output/traces_baseline \ + --verify-traces-comparator exact-no-stack \ + -n 10 \ + -m "not slow" + +echo "=== Done. Check output above for trace mismatches ===" +echo "=== Use 'git diff tests/ported_static/' to see code changes ===" diff --git a/tests/ported_static/stArgsZeroOneBalance/test_add_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_add_non_const.py index dc88ee7d6a4..0a24f5ffbc1 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_add_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_add_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_add_non_const( ) -> None: """Test_add_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_add_non_const( nonce=0, address=Address(0xF1722FE346FA35E045DE07E47CF6AF9BAE8ADE0A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_addmod_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_addmod_non_const.py index 5ece0a6d078..fae816dfd1e 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_addmod_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_addmod_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_addmod_non_const( ) -> None: """Test_addmod_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_addmod_non_const( nonce=0, address=Address(0x92D2FC80312ACD8C37857696D2224AF18CE6F966), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_and_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_and_non_const.py index 6aa34d3742e..8eb6f763863 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_and_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_and_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_and_non_const( ) -> None: """Test_and_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_and_non_const( nonce=0, address=Address(0x4C26357E0D164B702BCEB18690FC742EE1D36913), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_balance_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_balance_non_const.py index 047cbe231ed..ae940bbaa03 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_balance_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_balance_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_balance_non_const( ) -> None: """Test_balance_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_balance_non_const( nonce=0, address=Address(0xEE6A324B2ECE5EACDF881ABFDCC62B5361D0FB50), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_byte_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_byte_non_const.py index 22f411f7fc8..544001d697d 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_byte_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_byte_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_byte_non_const( ) -> None: """Test_byte_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_byte_non_const( nonce=0, address=Address(0x86D606901085BA78C64D2E0B16831E6AFD89DE2D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_call_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_call_non_const.py index 50d5d6e71eb..a8e915e499a 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_call_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_call_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_call_non_const( ) -> None: """Test_call_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -104,7 +101,6 @@ def test_call_non_const( nonce=0, address=Address(0x7D7E1645AF7DF916DA558F0695E9DEDD23B1215E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_callcode_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_callcode_non_const.py index 00e40277640..e24b3d5f963 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_callcode_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_callcode_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_callcode_non_const( ) -> None: """Test_callcode_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -104,7 +101,6 @@ def test_callcode_non_const( nonce=0, address=Address(0x443A994E18105C3EA686D3931729A1AC3D8FDD93), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_calldatacopy_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_calldatacopy_non_const.py index cc1f0bc30c9..9a0b8f9f9c2 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_calldatacopy_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_calldatacopy_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -70,9 +69,7 @@ def test_calldatacopy_non_const( ) -> None: """Test_calldatacopy_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_calldatacopy_non_const( nonce=0, address=Address(0x444C2681920E1105C9104FB32249DDBB41CBA4A0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_calldataload_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_calldataload_non_const.py index 0f521dfd5c0..dc0f8b82b2e 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_calldataload_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_calldataload_non_const.py @@ -83,6 +83,7 @@ def test_calldataload_non_const( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]](CALLDATALOAD (BALANCE )) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -98,7 +99,6 @@ def test_calldataload_non_const( nonce=0, address=Address(0x148F97630D3668441F1A33A5E509F268B64F998F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_codecopy_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_codecopy_non_const.py index 0a91590d3ba..c097c5f467e 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_codecopy_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_codecopy_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_codecopy_non_const( ) -> None: """Test_codecopy_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -89,7 +86,6 @@ def test_codecopy_non_const( nonce=0, address=Address(0xEDD4D7CDACB700CA3E28F8DDBCFB6AAC31F64925), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_create_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_create_non_const.py index 07f20342560..5106ec78a51 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_create_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_create_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.forks import Fork from execution_testing.specs.static_state.expect_section import ( @@ -59,9 +59,7 @@ def test_create_non_const( """Test_create_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,7 +91,6 @@ def test_create_non_const( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { @@ -101,7 +98,9 @@ def test_create_non_const( "network": [">=Cancun"], "result": { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, ), }, }, @@ -110,7 +109,9 @@ def test_create_non_const( "network": [">=Cancun"], "result": { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, ), }, }, diff --git a/tests/ported_static/stArgsZeroOneBalance/test_delegatecall_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_delegatecall_non_const.py index 717e9d7461c..2fc22d2747d 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_delegatecall_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_delegatecall_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_delegatecall_non_const( ) -> None: """Test_delegatecall_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_delegatecall_non_const( nonce=0, address=Address(0x365AAE42316E918DA716D904FE31EEA4134112C4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_div_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_div_non_const.py index 5f14e9d6612..754da2814ab 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_div_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_div_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_div_non_const( ) -> None: """Test_div_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_div_non_const( nonce=0, address=Address(0x61FD7E3E20CEEA9426C3021F589E9EB7754D486F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_eq_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_eq_non_const.py index d13706a6429..09c30fc9052 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_eq_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_eq_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_eq_non_const( ) -> None: """Test_eq_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_eq_non_const( nonce=0, address=Address(0x197F978175CEA58C57CFAB837CF028D4C8D12EF3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_exp_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_exp_non_const.py index ac4fc485544..72f6aace5a0 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_exp_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_exp_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_exp_non_const( ) -> None: """Test_exp_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_exp_non_const( nonce=0, address=Address(0xCFCD07426079DA1457676DE53F8DBE738C832D7F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_extcodecopy_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_extcodecopy_non_const.py index 467dbb25bf4..1b0cd7e9c8c 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_extcodecopy_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_extcodecopy_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_extcodecopy_non_const( ) -> None: """Test_extcodecopy_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,7 +89,6 @@ def test_extcodecopy_non_const( nonce=0, address=Address(0xF7A7FBF01DBCFEFDFD9AE65E4892C576994F31BF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_extcodesize_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_extcodesize_non_const.py index 09dd1a82bfb..e67e53ea57c 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_extcodesize_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_extcodesize_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_extcodesize_non_const( ) -> None: """Test_extcodesize_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_extcodesize_non_const( nonce=0, address=Address(0x4CD5F424AC9E070C2A651452C5666CF8A05F27A7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_gt_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_gt_non_const.py index 0f5c50be9a5..d8db68a6f82 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_gt_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_gt_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_gt_non_const( ) -> None: """Test_gt_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_gt_non_const( nonce=0, address=Address(0xF5176EDE711CCF689D689BFCEBDAE4C04910517E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_iszero_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_iszero_non_const.py index 0e8bbc2e666..dc4585cd190 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_iszero_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_iszero_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_iszero_non_const( ) -> None: """Test_iszero_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -84,7 +81,6 @@ def test_iszero_non_const( nonce=0, address=Address(0x2623813A00DFDC5BC378481671D8D9E38AD9956C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_jump_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_jump_non_const.py index 3f2cc19767b..a7a6d0ed8b7 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_jump_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_jump_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_jump_non_const( ) -> None: """Test_jump_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,7 +78,6 @@ def test_jump_non_const( nonce=0, address=Address(0xA82AE24D0D34B26FCB664DACD3E18371C9315E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_jumpi_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_jumpi_non_const.py index 189ce2386ef..8ad626d763f 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_jumpi_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_jumpi_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_jumpi_non_const( ) -> None: """Test_jumpi_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -84,7 +81,6 @@ def test_jumpi_non_const( nonce=0, address=Address(0xEEF87925C20B97E4EE58E24DD39D7C09785362BA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_log0_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_log0_non_const.py index 58db051b494..365c39eaccf 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_log0_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_log0_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_log0_non_const( ) -> None: """Test_log0_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_log0_non_const( nonce=0, address=Address(0x39332A3856E9E6DBAEBCDBD67B72B3E7209FFCB2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_log1_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_log1_non_const.py index b56919288b4..83826d6f6b3 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_log1_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_log1_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_log1_non_const( ) -> None: """Test_log1_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -89,7 +86,6 @@ def test_log1_non_const( nonce=0, address=Address(0x99914055ED765EA48582ACC6C8196D07835DA7D7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_log2_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_log2_non_const.py index 3f62eda5c24..418cb6e8be0 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_log2_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_log2_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_log2_non_const( ) -> None: """Test_log2_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -90,7 +87,6 @@ def test_log2_non_const( nonce=0, address=Address(0x007631BF0FC6669FE93C41401498B2612BBF41CF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_log3_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_log3_non_const.py index 0833cc82b95..4a34ed3a76c 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_log3_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_log3_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_log3_non_const( ) -> None: """Test_log3_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,7 +90,6 @@ def test_log3_non_const( nonce=0, address=Address(0x02724F6CB897BBC3E063A03633D2CE4E83DA8678), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_lt_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_lt_non_const.py index ae40ef0a737..34354330ff4 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_lt_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_lt_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_lt_non_const( ) -> None: """Test_lt_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_lt_non_const( nonce=0, address=Address(0x2538BC735B54983A8F85ED92072DC2D0F07A2797), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_mload_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_mload_non_const.py index 9e87e6a1aa5..244fefd710b 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_mload_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_mload_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mload_non_const( ) -> None: """Test_mload_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_mload_non_const( nonce=0, address=Address(0x14DD543A6D90CE85F819B764F0F38AFC1DF76C48), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_mod_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_mod_non_const.py index c00fed827db..bda76416253 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_mod_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_mod_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mod_non_const( ) -> None: """Test_mod_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_mod_non_const( nonce=0, address=Address(0x1FD117CCD0620EDE7967DAF31CDD8926B5B4EF5C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_mstore8_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_mstore8_non_const.py index 5c0c1874156..0447a50df4c 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_mstore8_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_mstore8_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mstore8_non_const( ) -> None: """Test_mstore8_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_mstore8_non_const( nonce=0, address=Address(0xF9BB7A1F4D45DD4F87D9C94A491CE7606BA41276), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_mstore_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_mstore_non_const.py index 695a50beda3..8b021a9b2cd 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_mstore_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_mstore_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mstore_non_const( ) -> None: """Test_mstore_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_mstore_non_const( nonce=0, address=Address(0x2737DAE115785244CFD2540FD942DC496B37CB71), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_mul_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_mul_non_const.py index 7c3111f0d28..76886038831 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_mul_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_mul_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mul_non_const( ) -> None: """Test_mul_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_mul_non_const( nonce=0, address=Address(0xB64C7A374E0080660379EBD421077AB5866CC9EF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_mulmod_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_mulmod_non_const.py index 59985f33687..cd61591b4c6 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_mulmod_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_mulmod_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mulmod_non_const( ) -> None: """Test_mulmod_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_mulmod_non_const( nonce=0, address=Address(0x9793633B7AD5CA376BA862E9D9B098A0EF8E71D8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_not_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_not_non_const.py index 51221b43f20..5ff4ec0e605 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_not_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_not_non_const.py @@ -71,6 +71,7 @@ def test_not_non_const( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]](NOT (BALANCE )) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_not_non_const( nonce=0, address=Address(0xCB87599782F7101D77A9B56283A67CD13FA0D97E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_or_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_or_non_const.py index a5532b43e08..343f19c2fec 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_or_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_or_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_or_non_const( ) -> None: """Test_or_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_or_non_const( nonce=0, address=Address(0x60DA449405B736A6920D45831CD6B173520FDF34), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_return_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_return_non_const.py index 56dc8ca8bec..4e790b391e0 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_return_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_return_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_return_non_const( ) -> None: """Test_return_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_return_non_const( nonce=0, address=Address(0xC40D7523B9B65560BE87507FD6FF17AB29DFCFF0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_sdiv_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_sdiv_non_const.py index 3c4672de6ca..fe11f8c49a8 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_sdiv_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_sdiv_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_sdiv_non_const( ) -> None: """Test_sdiv_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_sdiv_non_const( nonce=0, address=Address(0xA652FE2C234233D6EB3D62B283D56F67C76635BD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_sgt_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_sgt_non_const.py index c3e46f512dd..8e955bebd63 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_sgt_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_sgt_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_sgt_non_const( ) -> None: """Test_sgt_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_sgt_non_const( nonce=0, address=Address(0x696E25C48BC937162438ECD7B3CCD13B4EA2B98B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_sha3_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_sha3_non_const.py index 12c10c258da..6efbe2105b6 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_sha3_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_sha3_non_const.py @@ -71,6 +71,7 @@ def test_sha3_non_const( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]](KECCAK256 (BALANCE ) (BALANCE )) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -89,7 +90,6 @@ def test_sha3_non_const( nonce=0, address=Address(0x8F7ECEEA4B37C6F7FAF5D64D64FBFFBCD14B79A4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_signext_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_signext_non_const.py index e054c35c391..ca26efca5c8 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_signext_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_signext_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_signext_non_const( ) -> None: """Test_signext_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_signext_non_const( nonce=0, address=Address(0x36325C04EB27ABE09CFFAF61AC7823254B193AC8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_sload_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_sload_non_const.py index 46d0645894e..253acce3f33 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_sload_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_sload_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_sload_non_const( ) -> None: """Test_sload_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -86,7 +83,6 @@ def test_sload_non_const( nonce=0, address=Address(0x14F6D924BBF6563DD087359472133FFE566E60B1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_slt_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_slt_non_const.py index 3cadd977b14..4785add59ca 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_slt_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_slt_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_slt_non_const( ) -> None: """Test_slt_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_slt_non_const( nonce=0, address=Address(0x31D72308BB942D557F1F7AD5987321FB3D75C896), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_smod_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_smod_non_const.py index 7189d613739..1408d1dbfb2 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_smod_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_smod_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_smod_non_const( ) -> None: """Test_smod_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_smod_non_const( nonce=0, address=Address(0xB5ACE6E2AD4512822412E4E09FA278096CE8C63D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_sstore_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_sstore_non_const.py index cbf15ed8db1..8f1e6ba7914 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_sstore_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_sstore_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_sstore_non_const( ) -> None: """Test_sstore_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -84,7 +81,6 @@ def test_sstore_non_const( nonce=0, address=Address(0x82D3D8BE7168E697ED33F2A50810FA614393171E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_sub_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_sub_non_const.py index ee8e39636b5..311cc71bfa2 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_sub_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_sub_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_sub_non_const( ) -> None: """Test_sub_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_sub_non_const( nonce=0, address=Address(0xF9A85AC17DF3D37B898990AED6481E88D77DFA36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stArgsZeroOneBalance/test_suicide_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_suicide_non_const.py index f4b82e58e0e..3cbaaecceb4 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_suicide_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_suicide_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_suicide_non_const( """Test_suicide_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,7 +78,6 @@ def test_suicide_non_const( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stArgsZeroOneBalance/test_xor_non_const.py b/tests/ported_static/stArgsZeroOneBalance/test_xor_non_const.py index a9aeaa75f22..1ca082aca84 100644 --- a/tests/ported_static/stArgsZeroOneBalance/test_xor_non_const.py +++ b/tests/ported_static/stArgsZeroOneBalance/test_xor_non_const.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_xor_non_const( ) -> None: """Test_xor_non_const.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -85,7 +82,6 @@ def test_xor_non_const( nonce=0, address=Address(0x49A48E464281CDA5C9CA67F9A29A7CBD7CF86590), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stAttackTest/test_contract_creation_spam.py b/tests/ported_static/stAttackTest/test_contract_creation_spam.py index 6129e04b060..1805f8cc254 100644 --- a/tests/ported_static/stAttackTest/test_contract_creation_spam.py +++ b/tests/ported_static/stAttackTest/test_contract_creation_spam.py @@ -48,6 +48,7 @@ def test_contract_creation_spam( gas_limit=100000000000, ) + pre[sender] = Account(balance=0xC9F2C9CD04674EDEA40000000) # Source: hex # 0x7f6004600c60003960046000f3600035ff00000000000000000000000000000000600052602060006000f0600054805b6001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1506001018060005260008060208180876006f1505a616000106200002f57600055 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -626,7 +627,6 @@ def test_contract_creation_spam( nonce=0, address=Address(0x6A0A0FC761C612C340A0E98D33B37A75E5268472), # noqa: E501 ) - pre[sender] = Account(balance=0xC9F2C9CD04674EDEA40000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stAttackTest/test_crashing_transaction.py b/tests/ported_static/stAttackTest/test_crashing_transaction.py index 8ad213c6b79..8f8320dd1b8 100644 --- a/tests/ported_static/stAttackTest/test_crashing_transaction.py +++ b/tests/ported_static/stAttackTest/test_crashing_transaction.py @@ -7,13 +7,13 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -32,9 +32,7 @@ def test_crashing_transaction( ) -> None: """Https://ropsten.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=3270) env = Environment( fee_recipient=coinbase, @@ -45,8 +43,6 @@ def test_crashing_transaction( gas_limit=4712388, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=3270) - tx = Transaction( sender=sender, to=None, @@ -101,7 +97,7 @@ def test_crashing_transaction( post = { sender: Account(nonce=3271), - Address(0xECBF9AA676D9E0BBBA7E517D1350C1B64F8C6779): Account( + compute_create_address(address=sender, nonce=3270): Account( code=bytes.fromhex("60606040526008565b00"), balance=1, nonce=124, diff --git a/tests/ported_static/stBadOpcode/test_eip2315_not_removed.py b/tests/ported_static/stBadOpcode/test_eip2315_not_removed.py index f96607816e1..f2d0943b19d 100644 --- a/tests/ported_static/stBadOpcode/test_eip2315_not_removed.py +++ b/tests/ported_static/stBadOpcode/test_eip2315_not_removed.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_eip2315_not_removed( ) -> None: """Test_eip2315_not_removed.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x31B5AF02B012484AE954B3A43943242EDE546A2E76FC0A6ACC17435107C385EB - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -57,9 +54,7 @@ def test_eip2315_not_removed( + Op.TSTORE, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x147943601B1281618E4D824D11073025CD2AC623), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stBadOpcode/test_invalid_addr.py b/tests/ported_static/stBadOpcode/test_invalid_addr.py index 0f87ed31c7d..2f3e97b7ed8 100644 --- a/tests/ported_static/stBadOpcode/test_invalid_addr.py +++ b/tests/ported_static/stBadOpcode/test_invalid_addr.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -554,9 +553,7 @@ def test_invalid_addr( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -1036,7 +1033,6 @@ def test_invalid_addr( nonce=0, address=Address(0x2D876FD03A90703F170C256363BA225F9494E604), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("048071d3") + Hash(0x31) + Hash(0x1) + Hash(0x0), diff --git a/tests/ported_static/stBadOpcode/test_measure_gas.py b/tests/ported_static/stBadOpcode/test_measure_gas.py index 00c734e99ec..b262b96b127 100644 --- a/tests/ported_static/stBadOpcode/test_measure_gas.py +++ b/tests/ported_static/stBadOpcode/test_measure_gas.py @@ -139,6 +139,7 @@ def test_measure_gas( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # berlin { # pop(create(0, 0, 0x200)) @@ -175,80 +176,6 @@ def test_measure_gas( ) # Source: yul # berlin { - # let retval := call(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) - # } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF1), # noqa: E501 - ) - # Source: yul - # berlin { - # let retval := callcode(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF2), # noqa: E501 - ) - # Source: yul - # berlin { - # let retval := delegatecall(gas(), 0xCA11, 0, 0x100, 0, 0x100) - # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF4), # noqa: E501 - ) - # Source: yul - # berlin { - # let retval := staticcall(gas(), 0xCA11, 0, 0x100, 0, 0x100) - # } - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEFA), # noqa: E501 - ) - # Source: yul - # berlin { # let useless := mload(0xB000) # } contract_7 = pre.deploy_contract( # noqa: F841 @@ -289,23 +216,6 @@ def test_measure_gas( ) # Source: yul # berlin { - # let addr := 0xCA11 - # extcodecopy(addr, 0, 0, extcodesize(addr)) - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH2[0xCA11] - + Op.PUSH1[0x0] - + Op.DUP1 - + Op.EXTCODESIZE(address=Op.DUP3) - + Op.SWAP3 - + Op.EXTCODECOPY - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DE3B), # noqa: E501 - ) - # Source: yul - # berlin { # // Find the operation's cost in gas # let min := 0 # let max := 60000 @@ -361,7 +271,97 @@ def test_measure_gas( nonce=1, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) + # Source: yul + # berlin { + # let retval := call(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) + # } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEF1), # noqa: E501 + ) + # Source: yul + # berlin { + # let addr := 0xCA11 + # extcodecopy(addr, 0, 0, extcodesize(addr)) + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH2[0xCA11] + + Op.PUSH1[0x0] + + Op.DUP1 + + Op.EXTCODESIZE(address=Op.DUP3) + + Op.SWAP3 + + Op.EXTCODECOPY + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DE3B), # noqa: E501 + ) + # Source: yul + # berlin { + # let retval := staticcall(gas(), 0xCA11, 0, 0x100, 0, 0x100) + # } + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEFA), # noqa: E501 + ) + # Source: yul + # berlin { + # let retval := delegatecall(gas(), 0xCA11, 0, 0x100, 0, 0x100) + # } + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEF4), # noqa: E501 + ) + # Source: yul + # berlin { + # let retval := callcode(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEF2), # noqa: E501 + ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stBadOpcode/test_operation_diff_gas.py b/tests/ported_static/stBadOpcode/test_operation_diff_gas.py index d92e6b68f5d..82a3e5c4cbd 100644 --- a/tests/ported_static/stBadOpcode/test_operation_diff_gas.py +++ b/tests/ported_static/stBadOpcode/test_operation_diff_gas.py @@ -139,6 +139,7 @@ def test_operation_diff_gas( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # berlin { # sstore(0,create(0, 0, 0x200)) @@ -170,80 +171,6 @@ def test_operation_diff_gas( ) # Source: yul # berlin { - # let retval := call(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) - # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF1), # noqa: E501 - ) - # Source: yul - # berlin { - # let retval := callcode(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) - # } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF2), # noqa: E501 - ) - # Source: yul - # berlin { - # let retval := delegatecall(gas(), 0xCA11, 0, 0x100, 0, 0x100) - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF4), # noqa: E501 - ) - # Source: yul - # berlin { - # let retval := staticcall(gas(), 0xCA11, 0, 0x100, 0, 0x100) - # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x100, - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEFA), # noqa: E501 - ) - # Source: yul - # berlin { # mstore(0, 0xDEADBEEF) # return(0, 0x100) # } @@ -296,23 +223,6 @@ def test_operation_diff_gas( ) # Source: yul # berlin { - # let addr := 0xCA11 - # extcodecopy(addr, 0, 0, extcodesize(addr)) - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH2[0xCA11] - + Op.PUSH1[0x0] - + Op.DUP1 - + Op.EXTCODESIZE(address=Op.DUP3) - + Op.SWAP3 - + Op.EXTCODECOPY - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000C0DE3B), # noqa: E501 - ) - # Source: yul - # berlin { # // Run the operation with gasAmt, gasAmt+gasDiff, gasAmt+2*gasDiff, etc. # noqa: E501 # let gasAmt := calldataload(0x24) # let gasDiff := calldataload(0x44) @@ -356,7 +266,97 @@ def test_operation_diff_gas( nonce=1, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) + # Source: yul + # berlin { + # let retval := call(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) + # } + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEF1), # noqa: E501 + ) + # Source: yul + # berlin { + # let addr := 0xCA11 + # extcodecopy(addr, 0, 0, extcodesize(addr)) + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH2[0xCA11] + + Op.PUSH1[0x0] + + Op.DUP1 + + Op.EXTCODESIZE(address=Op.DUP3) + + Op.SWAP3 + + Op.EXTCODECOPY + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DE3B), # noqa: E501 + ) + # Source: yul + # berlin { + # let retval := staticcall(gas(), 0xCA11, 0, 0x100, 0, 0x100) + # } + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEFA), # noqa: E501 + ) + # Source: yul + # berlin { + # let retval := delegatecall(gas(), 0xCA11, 0, 0x100, 0, 0x100) + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEF4), # noqa: E501 + ) + # Source: yul + # berlin { + # let retval := callcode(gas(), 0xCA11, 0, 0, 0x100, 0, 0x100) + # } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x100, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0000000000000000000000000000000000C0DEF2), # noqa: E501 + ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192.py b/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192.py index 1e3900a095f..ebb0afbf4b4 100644 --- a/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192.py +++ b/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192( ) -> None: """Test: tis is a canon example of a test found by fuzzing with EVMlab,...""" # noqa: E501 coinbase = Address(0xDF5277352F687058BEC2D433F2E2D1B7F0C970AE) - sender = EOA( - key=0xEDDB5B1A0109F06919449A6279E9DE92A892086BDD851894EB8FFA6C8FF4E563 - ) + sender = pre.fund_eoa(amount=0x5D8FDD3FF54298B4, nonce=28) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192( addr = pre.deploy_contract( # noqa: F841 code=Op.SELFDESTRUCT(address=0xABCDEF), nonce=28, - address=Address(0x589D1B72331C25EFFEE38732D79F48F729681853), # noqa: E501 ) # Source: raw # 0x61dead6000600060006000600061dead5af162abcdef3f600155 @@ -72,7 +68,6 @@ def test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192( nonce=28, address=Address(0xDF5277352F687058BEC2D433F2E2D1B7F0C970AE), # noqa: E501 ) - pre[sender] = Account(balance=0x5D8FDD3FF54298B4, nonce=28) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_london.py b/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_london.py index 02b325d3db7..254bb3ee7f4 100644 --- a/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_london.py +++ b/tests/ported_static/stBugs/test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_london.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_lo ) -> None: """Test: tis is a canon example of a test found by fuzzing with EVMlab,...""" # noqa: E501 coinbase = Address(0xDF5277352F687058BEC2D433F2E2D1B7F0C970AE) - sender = EOA( - key=0xEDDB5B1A0109F06919449A6279E9DE92A892086BDD851894EB8FFA6C8FF4E563 - ) + sender = pre.fund_eoa(amount=0x5D8FDD3FF54298B4, nonce=28) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_lo addr = pre.deploy_contract( # noqa: F841 code=Op.SELFDESTRUCT(address=0xABCDEF), nonce=28, - address=Address(0x589D1B72331C25EFFEE38732D79F48F729681853), # noqa: E501 ) # Source: raw # 0x61dead6000600060006000600061dead5af162abcdef3f600155 @@ -72,7 +68,6 @@ def test_random_statetest_default_minus_tue_07_58_41_minus_15153_minus_575192_lo nonce=28, address=Address(0xDF5277352F687058BEC2D433F2E2D1B7F0C970AE), # noqa: E501 ) - pre[sender] = Account(balance=0x5D8FDD3FF54298B4, nonce=28) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stBugs/test_returndatacopy_python_bug_tue_03_48_41_minus_1432.py b/tests/ported_static/stBugs/test_returndatacopy_python_bug_tue_03_48_41_minus_1432.py index 394c61cf9ef..2e34a2366d4 100644 --- a/tests/ported_static/stBugs/test_returndatacopy_python_bug_tue_03_48_41_minus_1432.py +++ b/tests/ported_static/stBugs/test_returndatacopy_python_bug_tue_03_48_41_minus_1432.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,7 +58,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( state_test: StateTestFiller, pre: Alloc, @@ -70,9 +68,7 @@ def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( ) -> None: """Fuzzer generated bug.""" coinbase = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x7B8E1B8983BDCF0DF1A8A35F27CE0D6E94E340D0C15BD288E587771F560B3570 - ) + sender = pre.fund_eoa(amount=0x38BEEC8FEECA2598) env = Environment( fee_recipient=coinbase, @@ -83,7 +79,6 @@ def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( gas_limit=23826461031063688, ) - pre[sender] = Account(balance=0x38BEEC8FEECA2598) # Source: raw # 0x7b1db054ccc801c0666b34b3c6242bbfc5e98f20c14fb95e0118be9ad054326f33d50e215ff59297861847ea911a6a9d566103a560a860fb60cb6342a46f5073b94f5374fce5edbc8e2a8697c15331677e6ebf0b632c1e2816f26d135e2f826dc603850e0db21d105b778732a34b873c7d943050b8659794f0bd3e841d35a2231ef6027e97f8cde11728fa2051e87933cf858e4e5e91baa74fc1e9ffe4c7b15ba600e8678f095989dc68f47e67d704be2b41c7f8670a # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -111,7 +106,6 @@ def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( + Op.EXP(0xD704BE2B41C7F867, 0x8F095989DC68F47E), balance=0x2CE99FC81ED55962, nonce=63, - address=Address(0xF4C98E0DDA63A5C89847CA3E6DDF34F23443370F), # noqa: E501 ) # Source: raw # 0x610326610100fd79c940b5f2046740058558468f238b85db7f6bbe3f3d51e92a3e326102d85268b7f7c4147541c695f376705288410b81b217e80726fb9e4c5c7b4c49eca0c1b6b9137e117c16c26c9816459f38396ffc36da48d65defdc7d055cbc846c07e81cfab0607c6cbc968774d4de7df8e3236f581e688cc2081a96b1cad9e0fb6103ca601361019f6101016364b68c8e73ffffffffffffffffffffffffffffffffffffffff63200fbd63f16017610215610161610119635af7465b73000000000000000000000000000000000000000863792c6916f1799bf4fddda49ae97714e7d325ceab23acd5f4a15b52104741161261023f608ff360197021a04ff3f933b9ad91b735bfbfe41da7066b499c5d47b6de1fe398cb91fd68f681cbb8661dd457cf713cef75dabf5ea496d7012f4c56b9fee6c4208461022d61021661036e610200630277795a73ffffffffffffffffffffffffffffffffffffffff6333d3d55ff1644720e3ce666101ad526b874cead08499d57a5497d3776102fa60ff60f561014863202b2ea873d94f5374fce5edbc8e2a8697c15331677e6ebf0b6302e83dbef1327144ce205e051f296fb116fc9e5f3c280919af70f3c93c5d5cefff338db2b1165b4918f1780a73852663192a9579a68b50eefdc639ca0b62ab4d5230 # noqa: E501 @@ -121,7 +115,6 @@ def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( ), balance=0x442F5872DD93B01A, nonce=28, - address=Address(0x786208C0F93DAC2045BEC6A3F8A41B73AB845593), # noqa: E501 ) # Source: raw # 0x6102dd6103e06103146052632318d76f7332f4d5419b41e6887cca98e0943f141a5c66df986347cfe65df16abd0c6d6c4cec6593afaa8c7de1769c96cd0751aa76a98c8196fa8c92e70d7bda1799c91c7f05de318110659b819438774667f9ec15a6e0233f75669e43360bd4e0a0764e9f395117afcd072774ce12d13dc73305858002a921407eb6508e3a3be377d4825dbf618a393c7c061e75a8a496a33afe0f017f2e3354789e321838b083d48893f23dced4592e9ea08fe3f80970d6334b626c6f1f6ede8bcc81d03a7ccc244231cb6606db986101d761010761031c61025673ffffffffffffffffffffffffffffffffffffffff6311ecd01bfa7aa6d0c1c5158ef0db6994192acbd4cac6abc8449d80fc2c3247194668e0d9606bd390266d7f78712766f4765076283ad67450d7ab4df6f3f6ee014ab802ec9d55727ed96dc0b9ce7bd14b193dc1f0d11ce19283c77ef651d4d2e7c180715ff7fcbc995ea8b27613cc516dad16d17f29a93220ce0d6edb0a65d3d474dbc39cba5bcb3d4fcf6a9fef19107dc04511df2752fb346103ce6101c163459d135bf0712ab2475fbb2ba0720711a903dbecfa0429bf6811e6e90cbb0f13d4ee61050c7052c865e0216b4096186fc604fb563fa59f761263ee91d55e407fdffe82ca1558f793f3a218dd9ba69084621fdea97de498f0b0e1874331115e31aaad4d87227362a9ec3e1c1be11cdb23097bbc600c64692eeadfa97f1616b8aec24564487dc74f8e17e6a133b5dbe576838697de73f856197203ef1a733a54f7edb0dbd60f9d52db6b5c1477169b77f0d86917ed731a20db4b9e5b836bd26bffefab084a31c4afda166f8156612f281da0be688e5bdb1f31ed7869bc62343a7665abad657369482449e68b3acfe820997d3ddf5785384d51aaa0612dab5ddbf2a9bf550736ad42293387d70693587d74f6ccfae5218d01559bac159497edb6a665eae52f52784975568a159c0cae9044d258c55b10f4d1008d29ab1df7fceb76b789e2a8cdbaa9c67c42cd1ebe81716ead0e94c721279d77d3a0b3de311596d547292878449ccce511e6991b3dc636a16278159a9f61014a6102216342ce224df06f3d9a062274cd9a67ccba17c2cb06de46628e0bf703610106602e636db4b55bf06102056102c9633ff89b31f0788e55af17e19973f2c3f5d4c21c169890b9a92491f91aa1e714605d526103a1601f609b6103ee73d94f5374fce5edbc8e2a8697c15331677e6ebf0b6335adeabdf46d26060d385ed594e21b02b23a6c4c157350e7ab6a3ef66f83a29845b4ba85c4fdfbd0054a620123ad6893eff4b525b0f4b08d73285f36f3bcac6a985b906c348472b7cbc5a02e61678666f0c50eecdc1167f20fc1dc41c2fd95856d7752e55ede4e56f4f536a04d436a7fd418a1ca44c0173c10f1806ba284f9c9c7c13670005de594dec538cd56c2743b66fdfa7683ae0df6917b8bbcb53461be606ef617322e6448e3e4124dbe061257a8f486529de36997f08ce92502957f85587a18082b5b5b49e36de5a83e8a270663088571bf2fdf8f5f29b949976b41e3859928a237f5e5df84c17d3c431e82328f9093e64defbdd07d74d84835800999791abc41260472d96f9362604d077b198e859adc806beae7200cf116d2b55e89ddd564abc3900e69a68b0f6f0e9e4f12998728815d01c42f3b109ed25561027b610132635f449586f06101726101ec631fe4bdc3f06101316101246103b33e60bd19610284610305fd6102db6102e4631ea09dc6f06b72a6cf13500241c2a5e5c4e1777ea9ed9b05ba9b57d70dd270ece76ecf21d3a41ad554f795167084dcab761d4c8437774cad4bb13b2bece16d40358df93ec0f49abe102cd44e475560476101f3fd605b61030a6328f7e2e9f032604a547db71c0237247865fa2add74c8b27041c5718a2554a72662720296dff5b3b5327d59df4558b8a5b2c9e7d15eb3947a70064f935c8fdf0a4e6f644aa31b42c17d0280e50ea92a366c3d060c12c6a16a75522fbeb3d7cca702807f521781ab6101b252639cceb9e27f37ee8fde4ed3a23d3ec8db334ac1caa7e06523b0132dd615cf3fc16140d34c19761617823c3af47c42bc36b69cb4385463595c7f6f9ea451396fe05303603e0cd401e13df744e2a67382774d943941551704ff14dfa8646efbb2d8abc4ac6e258e99240372924b8001f8f0650d66b37411d484b18f41e779702bd1c169fa52bbfc8af4a45f20acb0ef956edb2ecbc0d4eadbbbf6732f8bd33b367a33c0faf0cf1970bcd38093a50a44fd253b0e74f2706239c499217b7bdae332e21d5d5e7e795c998cceed14cf46977e7d3cbb3c79ef0530c36fa8ac3fd8d49f10bb0ae919fa149adead7f67dae0b9ba628e056e0e87e029b8e5f42821d775338e6774301ecb428b3938237c6ee22b0b5edf2ad6997869f427ba0672a7168614233e85f61dae5ed428643a53f605116d6dad586dce62833a62ca8c914c646b1f861a5b1c4ea7298a95029e63cb849fe08b6c943cb9d854c7d50ad04cfdfe64718e2868b8f2b53e55fe01a152c8496cbcc69956787447062b734cebde6c6452e9efc4aba5bf071cbff56208a52561a8ef635f52399b724f3369d988884f58166d734881774eff46d77b76b189c89c55b1c6591f178d2d21bf2b023adf9bc5b862127935e3346d98d56047a3f71241fd5a24abbb0cfc463fb8a5e67e327b055696fe51258dd07526ebd8439bcebb514ae26dc12d653a5c1263707c5109097ec5dcdb3918ab114985f709d3003b50e58fba91007825a6b80073f644eaa306051808460fc3b2d8e276b2187c583f7ef29ee0b0c34f9ee57bac9ebb996402e3300ddf06c760fc5f531f6b1e2beda77fa15c07f90f92422822e8d33c5d2409ea75197f7cd6d61770eddb078206cfc7c57b006cd0e9a9ec65fa4fc683da22cfaf6dfc995feb5f8386a052851fc58b7402f32e7ef9343d4633def4c0a4b9be12f2cd7c646073e14ca3fb977524f677714c3d994ea05f1997a246537d2fc0ab20ed2a5958f3712602bee2a270429abbd3ff3b9945f72f58dcf4f86eb344417a87dfa1ebd701a0ff381bb40b620bb8287cd7781d2ef7c0fd8695f705465fbadf99fdffef2afd94b0e76531b6ea0d537a23d2332d13c20368a0724e41bc1130a6b1ebc3464527e34c26a43751649f9dfe4f8e7957981a9fc08558c90d38079f1921b60fe6fa448171fec55c4c630575e811712211cf72f489a4e83a2f5427eab647b075a91064929de0a65517 # noqa: E501 @@ -131,7 +124,6 @@ def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( ), balance=0x161150E7531F1933, nonce=29, - address=Address(0x47A24DD3A5F1A6A8238EFDB32782A0B56AB9A1DD), # noqa: E501 ) # Source: raw # 0x7e4fc1426b49cd8e2c770339616ce9c501fb746715dd4a20219229d0673ac05575993bd089a6663f6dff488574195b848fbb357eb7be1f61026352605861011761027f60e373c94f5374fce5edbc8e2a8697c15331677e6ebf0b63748b4abbfa60e76101bc6103f33e60d861036a6315193f47f07aff076e997770d03b70288679871dc28aa5a1399b21c8afa8155ecd7e75dd05f9d7eb42fa3e79c6a2109dff2a1e53e612fbe000bed18eec8345f00574f537c72820d8b97350ae523a8f7467ae14a8bd9aae6be55862b685e32476cc67ae2c6a40cf55729540d111f44c63629458da68e7ad2a9b389ed3bb60682169ea8a7b3a1bcf92621919c062413cb5986101236103596101776103be73d94f5374fce5edbc8e2a8697c15331677e6ebf0b631f6d9dfffa6103716101f760163e76d609ca9a51645238e4f1f8268f973c3a01a0b67479a34563d1e70065610173525b64e6d218af5474c3d8045447d06c726801695cfa26fdfaa6460a868569cd662855a55716140ae07eb1e25aeaf04ae7cf54e8aa7a22206da5a6e52bdd3ef82ad40a4681d25811167f7b0a3f66a727652592924dc1291a6085d537c5da2d6272a54f882460bc76407d666361c40cc56bc8778a8bc9a9b45d44c78cfe4333fe0c49418dd61f183d41132f755340e48ababb825a26ebc0ca693a8b465121200fd21a727b4c365a65a3255278f6705e5ca0f6146fccd3766a6e5b9decfb6e50968851e829313a2cc9d5b518e2586166c31ba04ed3f5a377310bd9993aa534b007858d9545342410ce8c156d780a8cb477a65efed30aa9d6bd63c48a134c9cb0c677ecda48aacef0c17c91de37e3cfdae69153742406995ea81bbae6a201663b9b37a6a9f597ae8d5a634f40e44e517174ea92616bc228ced0d712c265c2925470326102f26102146101b13e601d6103a360726103ec73ffffffffffffffffffffffffffffffffffffffff6319628a1bf4740e5f285d15a08a263b0a444516266bd51fe7266771604469df3c080d07dd47c4eb9e7344a87541ddc5a6971632a021033eb3542b375cd06bd0dfb48f6acde07152794b556839563efff1afed3b0a857615166526175e7184b83cc2dedf61ec5d65d1eee66efcb87b4f2c73335db9fba49e3d40638cd7f462f1d3b315f18dc1f692a68b24036102c16101f36102f23e783d6331b166ee517c71a4ba159dd322b9fa5f3237dfb85d2594edd580948177bd72d2244f767352371e3428d28bc6356c553b18d00e6b3cf602061672c2abbd7763059f61940b0d19fde33f7b5a960861025b61021d6101d361035173b94f5374fce5edbc8e2a8697c15331677e6ebf0b635ba25f69f4790d251e9ae89c718dd41c3f57b0c304fbb83978de28d23499bdd1729c04301ff527ccc9f7ed74a8dbd906b468d4487ffba738f193e3047b02e40beb08b4f11707681ef103ec1b00585a85f27227a179917ef15e97a359268b06ff34bcee23a869974fbca6e201cb16179743ac0f8c9f867003d5e26a5aad5217ebfff31407169237230772efaab6cd87fbc9fd408d4ac5a048e43fb4e7a261037c6101f76103e13e # noqa: E501 @@ -141,7 +133,6 @@ def test_returndatacopy_python_bug_tue_03_48_41_minus_1432( ), balance=0x16B3E0323B4F717D, nonce=28, - address=Address(0xD1F0BEFC94D951FB4B787ADA0927F60A9A94CE12), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stBugs/test_staticcall_createfails.py b/tests/ported_static/stBugs/test_staticcall_createfails.py index fae119fdb8f..4d63012c711 100644 --- a/tests/ported_static/stBugs/test_staticcall_createfails.py +++ b/tests/ported_static/stBugs/test_staticcall_createfails.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_staticcall_createfails( contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_2 = Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x38BEEC8FEECA2598) env = Environment( fee_recipient=coinbase, @@ -72,7 +69,6 @@ def test_staticcall_createfails( gas_limit=23826461031063688, ) - pre[sender] = Account(balance=0x38BEEC8FEECA2598) # Source: lll # { [[1]] (STATICCALL 70000 (CALLDATALOAD 0) 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs1.py b/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs1.py index aff20e0dffb..e8b77af0ac3 100644 --- a/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs1.py +++ b/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_oog_additional_gas_costs1( ) -> None: """Call(oog during init) -> code .""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,12 +44,19 @@ def test_call_oog_additional_gas_costs1( ) pre[coinbase] = Account(balance=0, nonce=1) + # Source: raw + # 0x6000 + addr = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0], + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { (CALL 6000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x1770, - address=0xD0735F094C16E509E8D76999D9EE2E4FD5166C2E, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,17 +66,7 @@ def test_call_oog_additional_gas_costs1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEF8DD89DEA93DC2BFF0CE3A1196188496E6C28DC), # noqa: E501 - ) - # Source: raw - # 0x6000 - addr = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0], - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xD0735F094C16E509E8D76999D9EE2E4FD5166C2E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs2.py b/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs2.py index 6049be60cf3..fe9d6e75686 100644 --- a/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs2.py +++ b/tests/ported_static/stCallCodes/test_call_oog_additional_gas_costs2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_oog_additional_gas_costs2( ) -> None: """Call(oog during init) -> code .""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,12 @@ def test_call_oog_additional_gas_costs2( ) pre[coinbase] = Account(balance=0, nonce=1) + # Source: raw + # 0x6000 + addr = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0], + nonce=0, + ) # Source: lll # { [[0]] (CALL 6000 1 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +57,7 @@ def test_call_oog_additional_gas_costs2( key=0x0, value=Op.CALL( gas=0x1770, - address=0x89CD1CB7AD11C6949BEC0C8C7533DC073960C54F, + address=addr, value=0x1, args_offset=0x0, args_size=0x40, @@ -66,16 +69,7 @@ def test_call_oog_additional_gas_costs2( storage={0: 2}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC1F36F15E971B13F8178B8C0C5C4F5E6B1B2B2C3), # noqa: E501 - ) - # Source: raw - # 0x6000 - addr = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0], - nonce=0, - address=Address(0x89CD1CB7AD11C6949BEC0C8C7533DC073960C54F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcall_00.py b/tests/ported_static/stCallCodes/test_callcall_00.py index 43fed748cd3..b3738552685 100644 --- a/tests/ported_static/stCallCodes/test_callcall_00.py +++ b/tests/ported_static/stCallCodes/test_callcall_00.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcall_00( ) -> None: """Call -> call -> code, params check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,18 @@ def test_callcall_00( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0xC3E151E887921D1EDB46AAE9B4A3FFC5B85E2A89, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE))} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 250000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +64,7 @@ def test_callcall_00( key=0x1, value=Op.CALL( gas=0x3D090, - address=0x33F368F0B54063613CF5944941E8E0E4EEB64697, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,24 +75,26 @@ def test_callcall_00( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC3E151E887921D1EDB46AAE9B4A3FFC5B85E2A89), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE))} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x33F368F0B54063613CF5944941E8E0E4EEB64697), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -114,10 +107,10 @@ def test_callcall_00( addr_2: Account( storage={ 2: 1, - 4: 0xC3E151E887921D1EDB46AAE9B4A3FFC5B85E2A89, + 4: addr, 7: 2, - 230: 0x33F368F0B54063613CF5944941E8E0E4EEB64697, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: addr_2, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallCodes/test_callcall_00_ooge.py b/tests/ported_static/stCallCodes/test_callcall_00_ooge.py index 042a62087c6..531f8276f0b 100644 --- a/tests/ported_static/stCallCodes/test_callcall_00_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcall_00_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcall_00_ooge( ) -> None: """Call -> call -> code oog .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,12 @@ def test_callcall_00_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x249F0, - address=0x9196F97BCA1B117E521275693C79420479D9CC90, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4353E77718BE108D4C149D88B34CACEDA42C5C66), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 20020 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +58,7 @@ def test_callcall_00_ooge( key=0x1, value=Op.CALL( gas=0x4E34, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,18 +69,26 @@ def test_callcall_00_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x9196F97BCA1B117E521275693C79420479D9CC90), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x249F0, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcall_00_ooge_value_transfer.py b/tests/ported_static/stCallCodes/test_callcall_00_ooge_value_transfer.py index 5070853c5a7..1116a38c40a 100644 --- a/tests/ported_static/stCallCodes/test_callcall_00_ooge_value_transfer.py +++ b/tests/ported_static/stCallCodes/test_callcall_00_ooge_value_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcall_00_ooge_value_transfer( ) -> None: """Call -> call -> code oog .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,12 @@ def test_callcall_00_ooge_value_transfer( ) # Source: lll - # { [[ 0 ]] (CALL 800000 20 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0xA781AD010268E97D590D07E5B442975243B2F05B, - value=0x14, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB06C4FF2E2503BB892CC3C9237A1AE465A759616), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 10 0 64 0 64 ) [[11]] 1} # noqa: E501 @@ -73,7 +58,7 @@ def test_callcall_00_ooge_value_transfer( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0xA, args_offset=0x0, args_size=0x40, @@ -84,18 +69,26 @@ def test_callcall_00_ooge_value_transfer( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0xA781AD010268E97D590D07E5B442975243B2F05B), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALL 800000 20 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x14, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcall_00_suicide_end.py b/tests/ported_static/stCallCodes/test_callcall_00_suicide_end.py index 758337ec1d7..86d19960801 100644 --- a/tests/ported_static/stCallCodes/test_callcall_00_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcall_00_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcall_00_suicide_end( ) -> None: """Call -> (call -> code) suicide .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcall_00_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_callcall_00_suicide_end( nonce=0, address=Address(0xF741CFEE7B7FB1025DCCEF3DB5A3CBC8FFB776F8), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_000.py b/tests/ported_static/stCallCodes/test_callcallcall_000.py index abc28fb0d5c..e4289de543f 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_000.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_000( ) -> None: """Call -> call -> call -> code, params check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcallcall_000( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0x55730, - address=0x9073671D2BFB351331716FD279282EACF50824AD, - value=0x1, + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcallcall_000( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcallcall_000( key=0x1, value=Op.CALL( gas=0x493E0, - address=0x62441CBE78AA4A4244E084D4F86098E31DCED749, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcallcall_000( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9073671D2BFB351331716FD279282EACF50824AD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - value=0x3, + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcallcall_000( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x62441CBE78AA4A4244E084D4F86098E31DCED749), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -134,10 +126,10 @@ def test_callcallcall_000( addr_3: Account( storage={ 3: 1, - 4: 0x62441CBE78AA4A4244E084D4F86098E31DCED749, + 4: addr_2, 7: 3, - 330: 0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_000_ooge.py b/tests/ported_static/stCallCodes/test_callcallcall_000_ooge.py index d9a3951ff1b..77f967932fc 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_000_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_000_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_000_ooge( ) -> None: """Call -> call -> call -> code oog .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcallcall_000_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcallcall_000_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcallcall_000_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcallcall_000_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcallcall_000_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_after.py b/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_after.py index 25d6bc1d554..11cc5e458fb 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_000_oogm_after( ) -> None: """Call -> (call -> call -> code) oog .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcallcall_000_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcallcall_000_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1F4CB3E7976BA5835015B9C3B0075AEA78AAA482), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcallcall_000_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcallcall_000_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcallcall_000_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_before.py b/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_before.py index d9cbe3c259d..c5391539ca9 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_000_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_000_oogm_before( ) -> None: """Call -> call -> oog call -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcallcall_000_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcallcall_000_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcallcall_000_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x51A61D678EC27711369C527E5D42A9DE66A5727F, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcallcall_000_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcallcall_000_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x51A61D678EC27711369C527E5D42A9DE66A5727F), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_end.py b/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_end.py index 92469a30501..1ddf3839b34 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_000_suicide_end( ) -> None: """Call -> call -> (call -> code) suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcall_000_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0xCB6497F0337B6CD0F7239A8819295EC7D1DAFD34), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcallcall_000_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xCB6497F0337B6CD0F7239A8819295EC7D1DAFD34), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_middle.py index 664858c25e6..3c0d5a31284 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_000_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_000_suicide_middle( ) -> None: """Call -> call -> suicide, call -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcall_000_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcallcall_000_suicide_middle( nonce=0, address=Address(0xBA5A575C914981FB64BFB082DC59434C66EB2714), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcall_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcallcall_abcb_recursive.py index 81c86f0e48d..7a87fcd56c9 100644 --- a/tests/ported_static/stCallCodes/test_callcallcall_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcallcall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcall_abcb_recursive( ) -> None: """Call -> call <-> call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcallcall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_001.py b/tests/ported_static/stCallCodes/test_callcallcallcode_001.py index 03a2b46a55e..ca7c0a3198c 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_001.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_001.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_001( ) -> None: """Call -> call -> callcode - > code, params check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcallcallcode_001( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0x9073671D2BFB351331716FD279282EACF50824AD, - value=0x1, + key=0x2, + value=Op.CALLCODE( + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcallcallcode_001( key=0x1, value=Op.CALL( gas=0x493E0, - address=0xFFFFAEB931552E5F094CA96A70BE612DA56B887, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9073671D2BFB351331716FD279282EACF50824AD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x3, + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0FFFFAEB931552E5F094CA96A70BE612DA56B887), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -135,10 +127,10 @@ def test_callcallcallcode_001( storage={ 2: 1, 3: 1, - 4: 0xFFFFAEB931552E5F094CA96A70BE612DA56B887, + 4: addr_2, 7: 3, - 330: 0xFFFFAEB931552E5F094CA96A70BE612DA56B887, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_2, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_001_ooge.py b/tests/ported_static/stCallCodes/test_callcallcallcode_001_ooge.py index d006261d6f7..e8e85b353f4 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_001_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_001_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_001_ooge( ) -> None: """Call -> call -> callcode -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcallcallcode_001_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcallcallcode_001_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcallcallcode_001_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcallcallcode_001_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcallcallcode_001_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_after.py b/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_after.py index 5f1b1edd8b7..0c425122802 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_001_oogm_after( ) -> None: """Call -> (call -> callcode -> code) oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcallcallcode_001_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcallcallcode_001_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE54CCFA5E33A84943997885F0AB9C19C587D8C4F), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcallcallcode_001_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xBE2D28F50CB59FFBD66D2EB6A3E8D34F3561D8B, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcallcallcode_001_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcallcallcode_001_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0BE2D28F50CB59FFBD66D2EB6A3E8D34F3561D8B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_before.py b/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_before.py index 68dd3ecba8d..965ca6c1752 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_001_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_001_oogm_before( ) -> None: """Call -> call -> oog callcode -> code .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcallcallcode_001_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcallcallcode_001_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcallcallcode_001_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xD33AB78AC3965E7D6F9548DFF5839138A9F69C5, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcallcallcode_001_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcallcallcode_001_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0D33AB78AC3965E7D6F9548DFF5839138A9F69C5), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_end.py b/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_end.py index 31b589b0576..10bf588c464 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_001_suicide_end( ) -> None: """Call -> call -> ( callcode - > code ) suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcallcode_001_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcallcallcode_001_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_middle.py index 89332f1db52..8819bcc98d8 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_001_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_001_suicide_middle( ) -> None: """Call -> call -> (suicide) callcode - > code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcallcode_001_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcallcallcode_001_suicide_middle( nonce=0, address=Address(0x23A077E1E6B0740D6BFBC41DE582F2930ABD1762), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcallcode_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcallcallcode_abcb_recursive.py index 483de6610b2..14f3e6c6cad 100644 --- a/tests/ported_static/stCallCodes/test_callcallcallcode_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcallcode_abcb_recursive( ) -> None: """Call -> call <-> callcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcallcallcode_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcode_01.py b/tests/ported_static/stCallCodes/test_callcallcode_01.py index caadf28c8a3..f57fa53ef1d 100644 --- a/tests/ported_static/stCallCodes/test_callcallcode_01.py +++ b/tests/ported_static/stCallCodes/test_callcallcode_01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcode_01( ) -> None: """Call -> callcode -> code, params check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,18 @@ def test_callcallcode_01( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0x69142B38329C92930601FE8DA12DC5866CDE11C3, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 250000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +64,7 @@ def test_callcallcode_01( key=0x1, value=Op.CALLCODE( gas=0x3D090, - address=0xB096ECA04CD5C92C88BA466F92627D4F04D53C95, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,24 +75,26 @@ def test_callcallcode_01( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x69142B38329C92930601FE8DA12DC5866CDE11C3), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB096ECA04CD5C92C88BA466F92627D4F04D53C95), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -115,10 +108,10 @@ def test_callcallcode_01( storage={ 1: 1, 2: 1, - 4: 0x69142B38329C92930601FE8DA12DC5866CDE11C3, + 4: addr, 7: 2, - 230: 0x69142B38329C92930601FE8DA12DC5866CDE11C3, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: addr, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallCodes/test_callcallcode_01_ooge.py b/tests/ported_static/stCallCodes/test_callcallcode_01_ooge.py index a6dc9536fce..bde8c6665fe 100644 --- a/tests/ported_static/stCallCodes/test_callcallcode_01_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcallcode_01_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcode_01_ooge( ) -> None: """Call -> callcode -> code oog .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,12 @@ def test_callcallcode_01_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +58,7 @@ def test_callcallcode_01_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,18 +69,26 @@ def test_callcallcode_01_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcode_01_suicide_end.py b/tests/ported_static/stCallCodes/test_callcallcode_01_suicide_end.py index 9ba100a0daa..fb4a9010a5e 100644 --- a/tests/ported_static/stCallCodes/test_callcallcode_01_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcallcode_01_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcode_01_suicide_end( ) -> None: """Call -> (callcode -> code) suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcode_01_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_callcallcode_01_suicide_end( nonce=0, address=Address(0x799DA5A3C983A22F9C430DE1BF99134EE561E856), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_010.py b/tests/ported_static/stCallCodes/test_callcallcodecall_010.py index e51b9b6e0a9..ba39016c1c6 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_010.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_010.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_010( ) -> None: """Call -> callcode -> call -> code, params check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcallcodecall_010( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0x55730, - address=0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, - value=0x1, + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcallcodecall_010( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcallcodecall_010( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0x62441CBE78AA4A4244E084D4F86098E31DCED749, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcallcodecall_010( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x3, + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcallcodecall_010( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x62441CBE78AA4A4244E084D4F86098E31DCED749), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -135,10 +127,10 @@ def test_callcallcodecall_010( addr_3: Account( storage={ 3: 1, - 4: 0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, + 4: addr, 7: 3, - 330: 0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_010_ooge.py b/tests/ported_static/stCallCodes/test_callcallcodecall_010_ooge.py index 36afdde2292..59d81ad6585 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_010_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_010_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_010_ooge( ) -> None: """Call -> callcode -> call -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcallcodecall_010_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcallcodecall_010_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcallcodecall_010_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x8232556DC6A7EED9EBE5B86C640A52AADF2C29AF, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcallcodecall_010_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcallcodecall_010_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x8232556DC6A7EED9EBE5B86C640A52AADF2C29AF), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_after.py b/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_after.py index d9f534f0c0e..fa22c791099 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_010_oogm_after( ) -> None: """Call -> (callcode -> call -> code) oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcallcodecall_010_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcallcodecall_010_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE54CCFA5E33A84943997885F0AB9C19C587D8C4F), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcallcodecall_010_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcallcodecall_010_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcallcodecall_010_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_before.py b/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_before.py index f81ed05bb29..09664f945ba 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_010_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_010_oogm_before( ) -> None: """Call -> callcode -> oog call -> code .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcallcodecall_010_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcallcodecall_010_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcallcodecall_010_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x51A61D678EC27711369C527E5D42A9DE66A5727F, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcallcodecall_010_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcallcodecall_010_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x51A61D678EC27711369C527E5D42A9DE66A5727F), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_end.py b/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_end.py index 7df47b616e3..f58f5b44ccc 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_010_suicide_end( ) -> None: """Call -> callcode -> (call -> code) (suicide).""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcodecall_010_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcallcodecall_010_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_middle.py index a5961caa24e..ba15575df15 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_010_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_010_suicide_middle( ) -> None: """Call -> callcode -> (suicide) call -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcodecall_010_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcallcodecall_010_suicide_middle( nonce=0, address=Address(0xAC90BB4611B91D4C6292BD64E8656110822E01ED), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecall_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcallcodecall_abcb_recursive.py index 0019fe7bc0d..7df4c42b423 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecall_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecall_abcb_recursive( ) -> None: """Call -> callcode <-> call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcallcodecall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011.py index d23bfc2d2a8..f9b66fda98b 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecallcode_011( ) -> None: """Call -> callcode -> callcode -> code, check params.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcallcodecallcode_011( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, - value=0x1, + key=0x2, + value=Op.CALLCODE( + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcallcodecallcode_011( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0xFFFFAEB931552E5F094CA96A70BE612DA56B887, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - value=0x3, + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0FFFFAEB931552E5F094CA96A70BE612DA56B887), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -136,10 +128,10 @@ def test_callcallcodecallcode_011( 1: 1, 2: 1, 3: 1, - 4: 0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, + 4: addr, 7: 3, - 330: 0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_ooge.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_ooge.py index 178bca74a1d..ce3e20242b0 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecallcode_011_ooge( ) -> None: """Call -> callcode -> callcode -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcallcodecallcode_011_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcallcodecallcode_011_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcallcodecallcode_011_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcallcodecallcode_011_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcallcodecallcode_011_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_after.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_after.py index c4d0cf4304e..284456ca466 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecallcode_011_oogm_after( ) -> None: """Call -> callcode oog -> callcode -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcallcodecallcode_011_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcallcodecallcode_011_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x497A77DDB638324A7B8EBF99E189F9FF8C118F19), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcallcodecallcode_011_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x926DFBCC20B2AB686FC85331883541D174CCC738, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcallcodecallcode_011_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcallcodecallcode_011_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x926DFBCC20B2AB686FC85331883541D174CCC738), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_before.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_before.py index a7b86531004..7065ab4fb25 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecallcode_011_oogm_before( ) -> None: """Call -> callcode -> oog callcode -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcallcodecallcode_011_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcallcodecallcode_011_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcallcodecallcode_011_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcallcodecallcode_011_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcallcodecallcode_011_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_end.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_end.py index a96e623ecaf..7891fd9c1cb 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecallcode_011_suicide_end( ) -> None: """Call -> callcode -> (callcode -> code) (suicide).""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcallcodecallcode_011_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcallcodecallcode_011_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_middle.py index 59940814ba0..ad05de3c39c 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_011_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_suicide_middle( ) -> None: """Call -> callcode -> (suicide) callcode -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecallcode_011_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -111,15 +116,6 @@ def test_callcallcodecallcode_011_suicide_middle( nonce=0, address=Address(0x58DED445D89963DFB8668B9A16B24AFA6F9B83A8), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcallcodecallcode_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcallcodecallcode_abcb_recursive.py index 0b1a1708987..8cbf5fa938c 100644 --- a/tests/ported_static/stCallCodes/test_callcallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcodecallcode_abcb_recursive( ) -> None: """Call -> callcode <-> callcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcallcodecallcode_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcode_check_pc.py b/tests/ported_static/stCallCodes/test_callcode_check_pc.py index 938961feb34..8f16fd6661e 100644 --- a/tests/ported_static/stCallCodes/test_callcode_check_pc.py +++ b/tests/ported_static/stCallCodes/test_callcode_check_pc.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_check_pc( ) -> None: """Check the PC after doing call to a contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,13 +43,20 @@ def test_callcode_check_pc( gas_limit=3000000000, ) + # Source: lll + # { [[0]] 1 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + ) # Source: lll # { (CALL 1000000 0 0 64 0 64 ) [[3]] (PC) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0xF4240, - address=0xFA7FC61138EE12431F8693335FB2BF5AF4051632, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -64,17 +68,7 @@ def test_callcode_check_pc( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6861B8D2BA9A24E77F63623E4A5E83E2BC6A30DF), # noqa: E501 - ) - # Source: lll - # { [[0]] 1 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xFA7FC61138EE12431F8693335FB2BF5AF4051632), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcode_dynamic_code.py b/tests/ported_static/stCallCodes/test_callcode_dynamic_code.py index 334f4b1f1d3..b9d711740ab 100644 --- a/tests/ported_static/stCallCodes/test_callcode_dynamic_code.py +++ b/tests/ported_static/stCallCodes/test_callcode_dynamic_code.py @@ -89,6 +89,7 @@ def test_callcode_dynamic_code( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (CALL 800000 (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -263,7 +264,6 @@ def test_callcode_dynamic_code( nonce=0, address=Address(0x4000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) expect_entries_: list[dict] = [ { @@ -273,11 +273,13 @@ def test_callcode_dynamic_code( contract_1: Account( storage={ 0: 1, - 10: 0x13136008B64FF592819B2FA6D43F2835C452020E, + 10: compute_create_address( + address=contract_1, nonce=0 + ), 11: 1, - 20: 0x1000000000000000000000000000000000000000, - 21: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 22: 0x1000000000000000000000000000000000000000, + 20: contract_1, + 21: sender, + 22: contract_1, }, ), }, @@ -291,9 +293,9 @@ def test_callcode_dynamic_code( 0: 1, 10: 0x2D39FAD743351D4CF3F4717907D3DDA5E0A689A7, 11: 1, - 20: 0x2000000000000000000000000000000000000000, - 21: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 22: 0x2000000000000000000000000000000000000000, + 20: contract_2, + 21: sender, + 22: contract_2, }, ), }, @@ -307,9 +309,13 @@ def test_callcode_dynamic_code( 0: 1, 10: 0xBF1676BE6038AB86D66E00824C2E3577858040F6, 11: 1, - 20: 0x4B86C4ED99B87F0F396BC0C76885453C343916ED, - 21: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 22: 0x4B86C4ED99B87F0F396BC0C76885453C343916ED, + 20: compute_create_address( + address=contract_3, nonce=0 + ), + 21: sender, + 22: compute_create_address( + address=contract_3, nonce=0 + ), }, code=b"", balance=0, @@ -326,9 +332,13 @@ def test_callcode_dynamic_code( 0: 1, 10: 0xF2D6BF688FAE45DA62AB2DD4F36945BC924CC61, 11: 1, - 20: 0xA51C188504A60578914FCAE68F7A1F0DCBB856A9, - 21: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 22: 0xA51C188504A60578914FCAE68F7A1F0DCBB856A9, + 20: compute_create_address( + address=contract_4, nonce=0 + ), + 21: sender, + 22: compute_create_address( + address=contract_4, nonce=0 + ), }, code=b"", balance=0, diff --git a/tests/ported_static/stCallCodes/test_callcode_dynamic_code2_self_call.py b/tests/ported_static/stCallCodes/test_callcode_dynamic_code2_self_call.py index 70df0338618..258217d6fae 100644 --- a/tests/ported_static/stCallCodes/test_callcode_dynamic_code2_self_call.py +++ b/tests/ported_static/stCallCodes/test_callcode_dynamic_code2_self_call.py @@ -75,6 +75,7 @@ def test_callcode_dynamic_code2_self_call( gas_limit=10000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (CALL 800000 (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -156,7 +157,6 @@ def test_callcode_dynamic_code2_self_call( nonce=0, address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) expect_entries_: list[dict] = [ { @@ -164,11 +164,7 @@ def test_callcode_dynamic_code2_self_call( "network": [">=Cancun"], "result": { compute_create_address(address=contract_1, nonce=0): Account( - storage={ - 11: 1, - 12: 0xA000000000000000000000000000000000000000, - }, - balance=1, + storage={11: 1, 12: contract_1}, balance=1 ), }, }, @@ -179,11 +175,13 @@ def test_callcode_dynamic_code2_self_call( contract_2: Account( storage={ 0: 1, - 10: 0x13136008B64FF592819B2FA6D43F2835C452020E, + 10: compute_create_address( + address=contract_2, nonce=0 + ), 11: 1, - 20: 0x1000000000000000000000000000000000000000, - 21: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 22: 0x1000000000000000000000000000000000000000, + 20: contract_2, + 21: sender, + 22: contract_2, }, nonce=1, ), diff --git a/tests/ported_static/stCallCodes/test_callcode_emptycontract.py b/tests/ported_static/stCallCodes/test_callcode_emptycontract.py index 72ad304c6de..4e33f02ada6 100644 --- a/tests/ported_static/stCallCodes/test_callcode_emptycontract.py +++ b/tests/ported_static/stCallCodes/test_callcode_emptycontract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_emptycontract( ) -> None: """Test_callcode_emptycontract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -64,9 +61,7 @@ def test_callcode_emptycontract( + Op.STOP, balance=1000, nonce=0, - address=Address(0x594F6A1A002FC9949AC40616CC146845680302E1), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_empty_contract.py b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_empty_contract.py index 6e5eb5efdb9..edd2ad15114 100644 --- a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_empty_contract.py +++ b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_empty_contract.py @@ -75,6 +75,7 @@ def test_callcode_in_initcode_to_empty_contract( gas_limit=10000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (CALL 300000 (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -146,7 +147,6 @@ def test_callcode_in_initcode_to_empty_contract( nonce=0, address=Address(0x2000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money.py b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money.py index e2ea6f2641f..12715a68d24 100644 --- a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money.py +++ b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money.py @@ -78,6 +78,7 @@ def test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (CALL 300000 (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -95,12 +96,20 @@ def test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money( address=Address(0x1100000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # {(seq (CREATE 0 0 (lll (seq [[1]] (CALLCODE 500000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) ) )} # noqa: E501 - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x28] - + Op.CODECOPY(dest_offset=0x0, offset=0xF, size=Op.DUP1) + # { (SSTORE 2 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: lll + # {(seq (CREATE2 0 0 (lll (seq [[1]] (CALLCODE 500000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) 0) )} # noqa: E501 + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.PUSH1[0x28] + + Op.CODECOPY(dest_offset=0x0, offset=0x11, size=Op.DUP1) + Op.PUSH1[0x0] * 2 - + Op.CREATE + + Op.CREATE2 + Op.STOP + Op.INVALID + Op.SSTORE( @@ -118,16 +127,15 @@ def test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money( + Op.STOP, balance=10000, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 + address=Address(0x2000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # {(seq (CREATE2 0 0 (lll (seq [[1]] (CALLCODE 500000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) 0) )} # noqa: E501 - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.PUSH1[0x28] - + Op.CODECOPY(dest_offset=0x0, offset=0x11, size=Op.DUP1) + # {(seq (CREATE 0 0 (lll (seq [[1]] (CALLCODE 500000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) ) )} # noqa: E501 + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x28] + + Op.CODECOPY(dest_offset=0x0, offset=0xF, size=Op.DUP1) + Op.PUSH1[0x0] * 2 - + Op.CREATE2 + + Op.CREATE + Op.STOP + Op.INVALID + Op.SSTORE( @@ -145,16 +153,8 @@ def test_callcode_in_initcode_to_exis_contract_with_v_transfer_ne_money( + Op.STOP, balance=10000, nonce=0, - address=Address(0x2000000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { (SSTORE 2 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract.py b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract.py index 9bc6495e615..68451f0f3ad 100644 --- a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract.py +++ b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract.py @@ -78,6 +78,7 @@ def test_callcode_in_initcode_to_existing_contract( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (CALL 300000 (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -95,13 +96,21 @@ def test_callcode_in_initcode_to_existing_contract( address=Address(0x1100000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # {(seq (CREATE 1 0 (lll (seq [[1]] (CALLCODE 50000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) ) )} # noqa: E501 - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x27] - + Op.CODECOPY(dest_offset=0x0, offset=0xF, size=Op.DUP1) + # { (SSTORE 2 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: lll + # {(seq (CREATE2 1 0 (lll (seq [[1]] (CALLCODE 50000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) 0) )} # noqa: E501 + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.PUSH1[0x27] + + Op.CODECOPY(dest_offset=0x0, offset=0x11, size=Op.DUP1) + Op.PUSH1[0x0] + Op.PUSH1[0x1] - + Op.CREATE + + Op.CREATE2 + Op.STOP + Op.INVALID + Op.SSTORE( @@ -119,17 +128,16 @@ def test_callcode_in_initcode_to_existing_contract( + Op.STOP, balance=10000, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 + address=Address(0x2000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # {(seq (CREATE2 1 0 (lll (seq [[1]] (CALLCODE 50000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) 0) )} # noqa: E501 - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.PUSH1[0x27] - + Op.CODECOPY(dest_offset=0x0, offset=0x11, size=Op.DUP1) + # {(seq (CREATE 1 0 (lll (seq [[1]] (CALLCODE 50000 0x1000000000000000000000000000000000000001 1 0 0 0 0)) 0) ) )} # noqa: E501 + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x27] + + Op.CODECOPY(dest_offset=0x0, offset=0xF, size=Op.DUP1) + Op.PUSH1[0x0] + Op.PUSH1[0x1] - + Op.CREATE2 + + Op.CREATE + Op.STOP + Op.INVALID + Op.SSTORE( @@ -147,16 +155,8 @@ def test_callcode_in_initcode_to_existing_contract( + Op.STOP, balance=10000, nonce=0, - address=Address(0x2000000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { (SSTORE 2 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract_with_value_transfer.py b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract_with_value_transfer.py index bea3369e032..4822486a1ea 100644 --- a/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract_with_value_transfer.py +++ b/tests/ported_static/stCallCodes/test_callcode_in_initcode_to_existing_contract_with_value_transfer.py @@ -51,6 +51,7 @@ def test_callcode_in_initcode_to_existing_contract_with_value_transfer( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (MSTORE 0 0x6040600060406000600573945304eb96065b2a98b57a48a06ae28d285a71b562) (MSTORE 32 0x0186a0f260005500000000000000000000000000000000000000000000000000) (CREATE 5 0 64) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -75,7 +76,6 @@ def test_callcode_in_initcode_to_existing_contract_with_value_transfer( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecall_10.py b/tests/ported_static/stCallCodes/test_callcodecall_10.py index f00336ab22f..d35ec4f4c3d 100644 --- a/tests/ported_static/stCallCodes/test_callcodecall_10.py +++ b/tests/ported_static/stCallCodes/test_callcodecall_10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecall_10( ) -> None: """Callcode -> call -> code, params check .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,18 @@ def test_callcodecall_10( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0xC3E151E887921D1EDB46AAE9B4A3FFC5B85E2A89, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 250000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +64,7 @@ def test_callcodecall_10( key=0x1, value=Op.CALL( gas=0x3D090, - address=0xB096ECA04CD5C92C88BA466F92627D4F04D53C95, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,24 +75,26 @@ def test_callcodecall_10( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC3E151E887921D1EDB46AAE9B4A3FFC5B85E2A89), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB096ECA04CD5C92C88BA466F92627D4F04D53C95), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -115,10 +108,10 @@ def test_callcodecall_10( addr_2: Account( storage={ 2: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 7: 2, - 230: 0xB096ECA04CD5C92C88BA466F92627D4F04D53C95, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: addr_2, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallCodes/test_callcodecall_10_ooge.py b/tests/ported_static/stCallCodes/test_callcodecall_10_ooge.py index 63ff2db291d..a91fce61861 100644 --- a/tests/ported_static/stCallCodes/test_callcodecall_10_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcodecall_10_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecall_10_ooge( ) -> None: """Callcode -> call -> code oog .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,12 @@ def test_callcodecall_10_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +58,7 @@ def test_callcodecall_10_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,18 +69,26 @@ def test_callcodecall_10_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecall_10_suicide_end.py b/tests/ported_static/stCallCodes/test_callcodecall_10_suicide_end.py index 8db6fa27f1e..9c9e867ae0b 100644 --- a/tests/ported_static/stCallCodes/test_callcodecall_10_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcodecall_10_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecall_10_suicide_end( ) -> None: """CALLCODE -> (CALL -> code) (suicide).""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcodecall_10_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_callcodecall_10_suicide_end( nonce=0, address=Address(0xF741CFEE7B7FB1025DCCEF3DB5A3CBC8FFB776F8), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_100.py b/tests/ported_static/stCallCodes/test_callcodecallcall_100.py index f613d36220a..ae6e5485b21 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_100.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_100.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_100( ) -> None: """CALLCODE -> CALL -> CALL-> code, params check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcodecallcall_100( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x9073671D2BFB351331716FD279282EACF50824AD, - value=0x1, + key=0x2, + value=Op.CALL( + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcodecallcall_100( key=0x1, value=Op.CALL( gas=0x493E0, - address=0x62441CBE78AA4A4244E084D4F86098E31DCED749, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9073671D2BFB351331716FD279282EACF50824AD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x3, + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x62441CBE78AA4A4244E084D4F86098E31DCED749), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -136,10 +128,10 @@ def test_callcodecallcall_100( addr_3: Account( storage={ 3: 1, - 4: 0x62441CBE78AA4A4244E084D4F86098E31DCED749, + 4: addr_2, 7: 3, - 330: 0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_100_ooge.py b/tests/ported_static/stCallCodes/test_callcodecallcall_100_ooge.py index d5c14cc93b9..73f66d5b3ce 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_100_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_100_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_100_ooge( ) -> None: """Callcode -> call -> call -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcodecallcall_100_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcodecallcall_100_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcodecallcall_100_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x8232556DC6A7EED9EBE5B86C640A52AADF2C29AF, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcodecallcall_100_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcodecallcall_100_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x8232556DC6A7EED9EBE5B86C640A52AADF2C29AF), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_after.py b/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_after.py index d022528f8e1..ea93eb8f53f 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_100_oogm_after( ) -> None: """Callcode -> (call -> call -> code) oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcodecallcall_100_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcodecallcall_100_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x400347DADA8C51A2AAC4B4C31AE726BA8551E2B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcodecallcall_100_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcodecallcall_100_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcodecallcall_100_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_before.py b/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_before.py index b598b08b48b..d2ea7d3209f 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_100_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_100_oogm_before( ) -> None: """Callcode -> call -> oog call -> code .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcodecallcall_100_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcodecallcall_100_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcodecallcall_100_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x4A780315E172DB6C0A08FE70FF4362B0E061B668, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcodecallcall_100_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcodecallcall_100_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4A780315E172DB6C0A08FE70FF4362B0E061B668), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_end.py b/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_end.py index 3f11ed553b6..a3d8aa6d8fc 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_100_suicide_end( ) -> None: """CALLCODE -> CALL -> (CALL-> code) (suicide).""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcodecallcall_100_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcall_100_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_middle.py index 98c839bd1a6..15ad5968229 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_100_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_100_suicide_middle( ) -> None: """CALLCODE -> CALL -> (suicide) CALL-> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcodecallcall_100_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcodecallcall_100_suicide_middle( nonce=0, address=Address(0xAC90BB4611B91D4C6292BD64E8656110822E01ED), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcall_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcodecallcall_abcb_recursive.py index 8a2c8759e19..98afc48d9db 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcall_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcall_abcb_recursive( ) -> None: """CALLCODE -> CALL <-> CALL.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101.py index e73fc0219ec..ed620198470 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcallcode_101( ) -> None: """CALLCODE -> CALL -> CALLCODE -> code parameters check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcodecallcallcode_101( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0x55730, - address=0x9073671D2BFB351331716FD279282EACF50824AD, - value=0x1, + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcodecallcallcode_101( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcodecallcallcode_101( key=0x1, value=Op.CALL( gas=0x493E0, - address=0xFFFFAEB931552E5F094CA96A70BE612DA56B887, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcodecallcallcode_101( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9073671D2BFB351331716FD279282EACF50824AD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - value=0x3, + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcodecallcallcode_101( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0FFFFAEB931552E5F094CA96A70BE612DA56B887), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -136,10 +128,10 @@ def test_callcodecallcallcode_101( storage={ 2: 1, 3: 1, - 4: 0xFFFFAEB931552E5F094CA96A70BE612DA56B887, + 4: addr_2, 7: 3, - 330: 0xFFFFAEB931552E5F094CA96A70BE612DA56B887, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_2, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_ooge.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_ooge.py index 9aa2eaf0700..585d1c19276 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcallcode_101_ooge( ) -> None: """Callcode -> call -> callcode -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcodecallcallcode_101_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcodecallcallcode_101_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcodecallcallcode_101_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x3568EC0DDA63B253E338FBC4990869FD168AB515, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcodecallcallcode_101_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcodecallcallcode_101_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3568EC0DDA63B253E338FBC4990869FD168AB515), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_after.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_after.py index 9cb13642b85..5a7ee2f591e 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcallcode_101_oogm_after( ) -> None: """Callcode -> call oog -> callcode -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcodecallcallcode_101_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcodecallcallcode_101_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x400347DADA8C51A2AAC4B4C31AE726BA8551E2B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcodecallcallcode_101_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x926DFBCC20B2AB686FC85331883541D174CCC738, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcodecallcallcode_101_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcodecallcallcode_101_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x926DFBCC20B2AB686FC85331883541D174CCC738), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_before.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_before.py index 8b49a1bf1c3..0fb2b0dcefd 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcallcode_101_oogm_before( ) -> None: """Callcode -> call -> oog callcode -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcodecallcallcode_101_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0xCECED485B74F13EAFA913073424DC443A976CF14, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcodecallcallcode_101_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcodecallcallcode_101_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcodecallcallcode_101_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0xCECED485B74F13EAFA913073424DC443A976CF14), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcodecallcallcode_101_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_end.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_end.py index b3e2e6d7eb6..7c20c53bf1a 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcallcode_101_suicide_end( ) -> None: """CALLCODE -> CALL -> (CALLCODE -> code) (suicide).""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcodecallcallcode_101_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcallcode_101_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_middle.py index c3be0d60442..6fe65bcb0de 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_101_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -39,9 +38,7 @@ def test_callcodecallcallcode_101_suicide_middle( contract_1 = Address(0x1000000000000000000000000000000000000001) contract_2 = Address(0x1000000000000000000000000000000000000002) contract_3 = Address(0x1000000000000000000000000000000000000003) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,6 +49,14 @@ def test_callcodecallcallcode_101_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0x1000000000000000000000000000000000000001 0 0 64 0 64 ) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -115,15 +120,6 @@ def test_callcodecallcallcode_101_suicide_middle( nonce=0, address=Address(0x1000000000000000000000000000000000000002), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcallcode_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcodecallcallcode_abcb_recursive.py index 981396950fa..c4ad5a066d8 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcallcode_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcallcode_abcb_recursive( ) -> None: """CALLCODE -> CALL <-> CALLCODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcallcode_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcode_11.py b/tests/ported_static/stCallCodes/test_callcodecallcode_11.py index 3109a855d6d..ae4f5601541 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcode_11.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcode_11.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcode_11( ) -> None: """CALLCODE -> CALLCODE -> code, check parameters.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,18 @@ def test_callcodecallcode_11( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x69142B38329C92930601FE8DA12DC5866CDE11C3, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 250000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +64,7 @@ def test_callcodecallcode_11( key=0x1, value=Op.CALLCODE( gas=0x3D090, - address=0xB096ECA04CD5C92C88BA466F92627D4F04D53C95, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,24 +75,26 @@ def test_callcodecallcode_11( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x69142B38329C92930601FE8DA12DC5866CDE11C3), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB096ECA04CD5C92C88BA466F92627D4F04D53C95), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -116,10 +109,10 @@ def test_callcodecallcode_11( 0: 1, 1: 1, 2: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 7: 2, - 230: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: target, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcode_11_ooge.py b/tests/ported_static/stCallCodes/test_callcodecallcode_11_ooge.py index c6f00447617..675cb20b369 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcode_11_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcode_11_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcode_11_ooge( ) -> None: """Callcode -> callcode -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,12 @@ def test_callcodecallcode_11_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +58,7 @@ def test_callcodecallcode_11_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,18 +69,26 @@ def test_callcodecallcode_11_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcode_11_suicide_end.py b/tests/ported_static/stCallCodes/test_callcodecallcode_11_suicide_end.py index c51aa95a6fd..eed97ff5128 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcode_11_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcode_11_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcode_11_suicide_end( ) -> None: """CALLCODE -> (CALLCODE -> code) selfdestruct.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcodecallcode_11_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_callcodecallcode_11_suicide_end( nonce=0, address=Address(0x799DA5A3C983A22F9C430DE1BF99134EE561E856), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110.py index d6c5a55057e..554208349a6 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecall_110( ) -> None: """CALLCODE -> CALLCODE -> CALL -> code, check parameters.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcodecallcodecall_110( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, - value=0x1, + key=0x2, + value=Op.CALL( + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcodecallcodecall_110( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcodecallcodecall_110( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0x62441CBE78AA4A4244E084D4F86098E31DCED749, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcodecallcodecall_110( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - value=0x3, + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcodecallcodecall_110( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x62441CBE78AA4A4244E084D4F86098E31DCED749), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -135,10 +127,10 @@ def test_callcodecallcodecall_110( addr_3: Account( storage={ 3: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 7: 3, - 330: 0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_ooge.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_ooge.py index c7eecb6d462..12893a6eea3 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecall_110_ooge( ) -> None: """Callcode -> callcode -> call -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcodecallcodecall_110_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcodecallcodecall_110_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcodecallcodecall_110_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xDB067DDF10E702A0CDCAA489117330E5395155CB, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcodecallcodecall_110_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcodecallcodecall_110_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xDB067DDF10E702A0CDCAA489117330E5395155CB), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_after.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_after.py index 2404fb708f9..3dcb2cbd581 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecall_110_oogm_after( ) -> None: """Callcode -> callcode (oog) -> call -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,19 @@ def test_callcodecallcodecall_110_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,11 +64,8 @@ def test_callcodecallcodecall_110_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x400347DADA8C51A2AAC4B4C31AE726BA8551E2B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -74,7 +74,7 @@ def test_callcodecallcodecall_110_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x83B7D129B58AB5315B795F9A8D34294EC60C9D63, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,16 +85,15 @@ def test_callcodecallcodecall_110_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -102,18 +101,11 @@ def test_callcodecallcodecall_110_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x83B7D129B58AB5315B795F9A8D34294EC60C9D63), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_before.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_before.py index 4594be6a819..728e22c7664 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecall_110_oogm_before( ) -> None: """Callcode -> callcode -> (oog) call -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_callcodecallcodecall_110_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -62,9 +66,7 @@ def test_callcodecallcodecall_110_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -73,7 +75,7 @@ def test_callcodecallcodecall_110_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x51A61D678EC27711369C527E5D42A9DE66A5727F, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,17 +86,15 @@ def test_callcodecallcodecall_110_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,17 +103,9 @@ def test_callcodecallcodecall_110_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x51A61D678EC27711369C527E5D42A9DE66A5727F), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_end.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_end.py index 50518f7770f..b988b59cc26 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecall_110_suicide_end( ) -> None: """CALLCODE -> CALLCODE -> (CALL -> code) (suicide) .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_callcodecallcodecall_110_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcodecall_110_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_middle.py index 7ee840b9663..23e3bf3b6fb 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_110_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_suicide_middle( ) -> None: """CALLCODE -> CALLCODE -> (suicide) CALL -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecall_110_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -111,15 +116,6 @@ def test_callcodecallcodecall_110_suicide_middle( nonce=0, address=Address(0xAC90BB4611B91D4C6292BD64E8656110822E01ED), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecall_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcodecallcodecall_abcb_recursive.py index ed3259ddce9..ce4795cb975 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecall_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecall_abcb_recursive( ) -> None: """CALLCODE -> CALLCODE <-> CALL .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcodecall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111.py index 80d01c74f5e..3eecfb14554 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecallcode_111( ) -> None: """CALLCODE -> CALLCODE -> CALLCODE -> code check parameter opcodes.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,14 +44,28 @@ def test_callcodecallcodecallcode_111( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0x55730, - address=0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, - value=0x1, + gas=0x3D090, + address=addr_3, + value=0x3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,7 +75,6 @@ def test_callcodecallcodecallcode_111( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 @@ -73,7 +83,7 @@ def test_callcodecallcodecallcode_111( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0xFFFFAEB931552E5F094CA96A70BE612DA56B887, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -84,17 +94,16 @@ def test_callcodecallcodecallcode_111( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x3, + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcodecallcodecallcode_111( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0FFFFAEB931552E5F094CA96A70BE612DA56B887), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -137,10 +129,10 @@ def test_callcodecallcodecallcode_111( 1: 1, 2: 1, 3: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 7: 3, - 330: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_ooge.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_ooge.py index 09bbf7ae59f..3f6392ba446 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_ooge.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecallcodecallcode_111_ooge( ) -> None: """Callcode -> callcode -> callcode -> code oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,21 @@ def test_callcodecallcodecallcode_111_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -61,10 +66,9 @@ def test_callcodecallcodecallcode_111_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -73,7 +77,7 @@ def test_callcodecallcodecallcode_111_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -83,16 +87,15 @@ def test_callcodecallcodecallcode_111_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -100,21 +103,10 @@ def test_callcodecallcodecallcode_111_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_after.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_after.py index 6179c11c429..68d26a9b033 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_after.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_oogm_after( ) -> None: """Callcode -> (callcode -> callcode -> code) oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,19 @@ def test_callcodecallcodecallcode_111_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -63,11 +66,8 @@ def test_callcodecallcodecallcode_111_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x400347DADA8C51A2AAC4B4C31AE726BA8551E2B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +76,7 @@ def test_callcodecallcodecallcode_111_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x926DFBCC20B2AB686FC85331883541D174CCC738, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -87,16 +87,15 @@ def test_callcodecallcodecallcode_111_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -104,18 +103,11 @@ def test_callcodecallcodecallcode_111_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x926DFBCC20B2AB686FC85331883541D174CCC738), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_before.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_before.py index 9fa8ba21d2d..d42b32ac321 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_before.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_oogm_before( ) -> None: """Callcode -> callcode -> (OOG) callcode -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcodecallcodecallcode_111_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0xA4173498C0DA91570D8AF9A128C337A67A6B4E69, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -64,9 +68,7 @@ def test_callcodecallcodecallcode_111_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[ 11 ]] 1 } # noqa: E501 @@ -75,7 +77,7 @@ def test_callcodecallcodecallcode_111_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,17 +88,15 @@ def test_callcodecallcodecallcode_111_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0xA4173498C0DA91570D8AF9A128C337A67A6B4E69), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -105,17 +105,9 @@ def test_callcodecallcodecallcode_111_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_end.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_end.py index 2a1e9fa896d..d3b29c3988d 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_end.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_suicide_end( ) -> None: """CALLCODE -> CALLCODE -> (CALLCODE -> code) suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecallcode_111_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcodecallcodecallcode_111_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_middle.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_middle.py index 6b45f27f269..16b7662f27c 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_middle.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_111_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_suicide_middle( ) -> None: """CALLCODE -> CALLCODE -> (suicide) CALLCODE -> code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecallcode_111_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -111,15 +116,6 @@ def test_callcodecallcodecallcode_111_suicide_middle( nonce=0, address=Address(0x23A077E1E6B0740D6BFBC41DE582F2930ABD1762), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_abcb_recursive.py b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_abcb_recursive.py index 259d15a6457..0c73ba78c27 100644 --- a/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stCallCodes/test_callcodecallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_abcb_recursive( ) -> None: """CALLCODE -> CALLCODE2 -> CALLCODE3 -> CALLCODE2 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -108,7 +105,6 @@ def test_callcodecallcodecallcode_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call1024_balance_too_low.py b/tests/ported_static/stCallCreateCallCodeTest/test_call1024_balance_too_low.py index c040b61a267..8eeee9b6815 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call1024_balance_too_low.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call1024_balance_too_low.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,10 +33,7 @@ def test_call1024_balance_too_low( ) -> None: """Calldepth with balance too low.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,7 @@ def test_call1024_balance_too_low( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (CALL 0xfffffffffff @@0 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call1024_oog.py b/tests/ported_static/stCallCreateCallCodeTest/test_call1024_oog.py index 4026f673053..127b02327fd 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call1024_oog.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call1024_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -70,10 +69,7 @@ def test_call1024_oog( ) -> None: """Calldepth with oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -84,8 +80,7 @@ def test_call1024_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (CALL (MUL (SUB (GAS) 10000) (SUB 1 (DIV @@0 1025))) 0 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_lose_gas_oog.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_lose_gas_oog.py index 58e9eb27744..ccae45c2c76 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_lose_gas_oog.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_lose_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_call_lose_gas_oog( ) -> None: """Recursive call.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_call_lose_gas_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (CALL (ADD 1(MUL @@0 100000)) 0 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_output1.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_output1.py index 823868777ca..36f89a60db9 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_output1.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_output1.py @@ -46,6 +46,15 @@ def test_call_output1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALL 150000 0 0 0 0 0) [[ 0 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output1( + Op.POP( Op.CALL( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_call_output1( nonce=0, address=Address(0x62C381FD04B6E4F31BA6D6F58C6A0D34EEE4FC52), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_output2.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_output2.py index c0d5b521751..ca7edcd92d1 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_output2.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_output2.py @@ -46,6 +46,15 @@ def test_call_output2( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALL 150000 0 0 32 0 0) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output2( + Op.POP( Op.CALL( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x20, @@ -70,15 +79,6 @@ def test_call_output2( nonce=0, address=Address(0x7ECEED6F6DD8B5ED0637DC20761945256E2BAFC7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3.py index 383c1c366fc..ba359981dcd 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3.py @@ -46,6 +46,15 @@ def test_call_output3( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALL 150000 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output3( + Op.POP( Op.CALL( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_call_output3( nonce=0, address=Address(0xD4E4BFA87DC8F20706BF63F45861945315BE24F0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3_fail.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3_fail.py index 6d59e7c7668..68e27013ea7 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3_fail.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3_fail.py @@ -46,6 +46,15 @@ def test_call_output3_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALL 50000 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output3_fail( + Op.POP( Op.CALL( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_call_output3_fail( nonce=0, address=Address(0x3D63522C16B6DCC36F08DB61FCDCF5ECEA92F4D4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial.py index 1e612c2e7d2..43d7672e0c9 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial.py @@ -46,6 +46,15 @@ def test_call_output3partial( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALL 150000 0 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output3partial( + Op.POP( Op.CALL( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_call_output3partial( nonce=0, address=Address(0x24BC72D274AB8E9445BB449BBEA2CCD492F6A2BF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial_fail.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial_fail.py index b99e075fdd0..b18c1007da4 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial_fail.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_output3partial_fail.py @@ -46,6 +46,15 @@ def test_call_output3partial_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALL 50000 0 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output3partial_fail( + Op.POP( Op.CALL( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_call_output3partial_fail( nonce=0, address=Address(0x974E2490EAC79CA8AA70E20696E15F538EE8F02F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_recursive_bomb_pre_call.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_recursive_bomb_pre_call.py index bd56e0ee1f5..2261b2901e2 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_recursive_bomb_pre_call.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_recursive_bomb_pre_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_call_recursive_bomb_pre_call( ) -> None: """Recursive call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x77F65B71F1F16A75476F469F7106D1B60BFEC266AE25B8DA16A9091D223AA24A - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,26 @@ def test_call_recursive_bomb_pre_call( gas_limit=9223372036854775807, ) + # Source: lll + # { [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224000) (ADDRESS) 0 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(Op.SLOAD(key=0x0), 0x1)) + + Op.SSTORE( + key=0x1, + value=Op.CALL( + gas=Op.SUB(Op.GAS, 0x36B00), + address=Op.ADDRESS, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { (CALL 100000 0xbad304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0) (CALL 0x7ffffffffffffff 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,7 +82,7 @@ def test_call_recursive_bomb_pre_call( ) + Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x1B3F200856856EDC2E98EFCD637775C6E341E3C0, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -75,30 +92,7 @@ def test_call_recursive_bomb_pre_call( + Op.STOP, balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, nonce=0, - address=Address(0x55BD941930D381E552D261D75ED997BE59E36350), # noqa: E501 - ) - # Source: lll - # { [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224000) (ADDRESS) 0 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(Op.SLOAD(key=0x0), 0x1)) - + Op.SSTORE( - key=0x1, - value=Op.CALL( - gas=Op.SUB(Op.GAS, 0x36B00), - address=Op.ADDRESS, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1B3F200856856EDC2E98EFCD637775C6E341E3C0), # noqa: E501 ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value.py index 4fb18cca231..8f1c61f19fb 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_with_high_value( ) -> None: """Call with value and not enough value to send.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,13 @@ def test_call_with_high_value( gas_limit=30000000, ) + # Source: lll + # { [[2]] 1 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 150000 1000000000000000001 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +57,7 @@ def test_call_with_high_value( key=0x0, value=Op.CALL( gas=0x249F0, - address=0x9D8C3FED067968360493F6DEB5B169A720DAC8A2, + address=addr, value=0xDE0B6B3A7640001, args_offset=0x0, args_size=0x40, @@ -64,17 +68,7 @@ def test_call_with_high_value( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCCC6849CD07C3E5B61AB6D7E798D3C4007615284), # noqa: E501 - ) - # Source: lll - # { [[2]] 1 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=23, - nonce=0, - address=Address(0x9D8C3FED067968360493F6DEB5B169A720DAC8A2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_gas_oog.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_gas_oog.py index 626523845cd..5240cae80cd 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_gas_oog.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_gas_oog.py @@ -73,6 +73,17 @@ def test_call_with_high_value_and_gas_oog( gas_limit=30000000, ) + pre[sender] = Account(balance=0x3635C9ADC5DEA00000) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 0xffffffffffffffffffffffff 100000000000000000000 0 64 0 2 ) [[1]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,7 +99,7 @@ def test_call_with_high_value_and_gas_oog( key=0x0, value=Op.CALL( gas=0xFFFFFFFFFFFFFFFFFFFFFFFF, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, value=0x56BC75E2D63100000, args_offset=0x0, args_size=0x40, @@ -103,17 +114,6 @@ def test_call_with_high_value_and_gas_oog( nonce=0, address=Address(0xDFAD372452688759EDD82C422BF3976EAFC89C2B), # noqa: E501 ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 - ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_oo_gat_tx_level.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_oo_gat_tx_level.py index 4710f7fc257..d105d652d73 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_oo_gat_tx_level.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_and_oo_gat_tx_level.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_call_with_high_value_and_oo_gat_tx_level( ) -> None: """Call with value.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,6 +70,15 @@ def test_call_with_high_value_and_oo_gat_tx_level( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 3000001 100001 0 0 0 0 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +86,7 @@ def test_call_with_high_value_and_oo_gat_tx_level( key=0x0, value=Op.CALL( gas=0x2DC6C1, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, value=0x186A1, args_offset=0x0, args_size=0x0, @@ -92,19 +98,7 @@ def test_call_with_high_value_and_oo_gat_tx_level( storage={0: 5}, balance=0x186A0, nonce=0, - address=Address(0x9001FA64DBBA07E3EB711A42CF25B34CCEE2BD2B), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_oo_gin_call.py b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_oo_gin_call.py index f0e04383313..e460ca99647 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_oo_gin_call.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_call_with_high_value_oo_gin_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_with_high_value_oo_gin_call( ) -> None: """Call with value and oog happens inside.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_call_with_high_value_oo_gin_call( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (ADD (CALL 10000 1000000000000000000 0 0 0 0 ) 1) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +62,7 @@ def test_call_with_high_value_oo_gin_call( value=Op.ADD( Op.CALL( gas=0x2710, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, value=0xDE0B6B3A7640000, args_offset=0x0, args_size=0x0, @@ -69,19 +75,7 @@ def test_call_with_high_value_oo_gin_call( + Op.STOP, balance=0xDE0B6B3A7640001, nonce=0, - address=Address(0xAB77465B5ABF0C394945E4186C02776F8EB9F2E7), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_balance_too_low.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_balance_too_low.py index 8174d8d6f5f..ba34a69fc14 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_balance_too_low.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_balance_too_low.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,10 +35,7 @@ def test_callcode1024_balance_too_low( ) -> None: """Calldepth and balance.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -50,8 +46,7 @@ def test_callcode1024_balance_too_low( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (CALLCODE 0xfffffffffff @@0 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_oog.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_oog.py index 73ca11492f4..2b2f42bd104 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_oog.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode1024_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,10 +57,7 @@ def test_callcode1024_oog( ) -> None: """Calldepth and oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -72,8 +68,7 @@ def test_callcode1024_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (CALLCODE (MUL (SUB (GAS) 10000) (SUB 1 (DIV @@0 1025))) 0 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_lose_gas_oog.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_lose_gas_oog.py index a7d23d52a50..8ed143eb578 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_lose_gas_oog.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_lose_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,10 +63,7 @@ def test_callcode_lose_gas_oog( ) -> None: """Recursive call.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -78,8 +74,7 @@ def test_callcode_lose_gas_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (CALLCODE (ADD 1(MUL @@0 100000)) 0 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output1.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output1.py index ea3758057ae..20ab325d5ce 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output1.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output1.py @@ -46,6 +46,15 @@ def test_callcode_output1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALLCODE 150000 0 0 0 0 0) [[ 0 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_callcode_output1( + Op.POP( Op.CALLCODE( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_callcode_output1( nonce=0, address=Address(0x64636CC2405B11C8D19AB153EAC44CCCE0FB70F9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output2.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output2.py index a7d547f6781..ca92837a551 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output2.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output2.py @@ -46,6 +46,15 @@ def test_callcode_output2( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALLCODE 50000 0 0 32 0 0) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_callcode_output2( + Op.POP( Op.CALLCODE( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x20, @@ -70,15 +79,6 @@ def test_callcode_output2( nonce=0, address=Address(0xE6470A86A9862D2CE7DB006EE9C99092CD5E71BB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3.py index 4a7adaf4b6c..3cc762fbdae 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3.py @@ -46,6 +46,15 @@ def test_callcode_output3( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALLCODE 150000 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_callcode_output3( + Op.POP( Op.CALLCODE( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_callcode_output3( nonce=0, address=Address(0xADFA10B17CF59BBEC369DCAAA1413070463820C0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3_fail.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3_fail.py index 991eb190c1e..d13ae6c8bfe 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3_fail.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3_fail.py @@ -46,6 +46,15 @@ def test_callcode_output3_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALLCODE 50000 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_callcode_output3_fail( + Op.POP( Op.CALLCODE( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_callcode_output3_fail( nonce=0, address=Address(0xFBF2D514AAD518CDF2E9D81E541C85FCDDEF6509), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial.py index 542d62b1236..27445c6e3ca 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial.py @@ -46,6 +46,15 @@ def test_callcode_output3partial( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALLCODE 150000 0 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_callcode_output3partial( + Op.POP( Op.CALLCODE( gas=0x249F0, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,15 +79,6 @@ def test_callcode_output3partial( nonce=0, address=Address(0x8E33B4F8EB53A43A1E8EF9B4B46A65FB94FEF790), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial_fail.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial_fail.py index 443ee494efd..a63d7360ced 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial_fail.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_output3partial_fail.py @@ -48,6 +48,15 @@ def test_callcode_output3partial_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (CALLCODE 50000 0 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +67,7 @@ def test_callcode_output3partial_fail( + Op.POP( Op.CALLCODE( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,15 +81,6 @@ def test_callcode_output3partial_fail( nonce=0, address=Address(0xEE172F045CFA9101EE8C62FAF6975D8F4C1E2099), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value.py index 7aa916b48e2..7289130c10b 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_with_high_value( ) -> None: """Callcode with high value fails.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_callcode_with_high_value( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALLCODE 50000 1000000000000000001 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +59,7 @@ def test_callcode_with_high_value( key=0x0, value=Op.CALLCODE( gas=0xC350, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, value=0xDE0B6B3A7640001, args_offset=0x0, args_size=0x40, @@ -64,19 +70,7 @@ def test_callcode_with_high_value( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x177BD06BAD8F3FE1B5D335D0ABA2F2A6B18B2FC6), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value_and_gas_oog.py b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value_and_gas_oog.py index 2a20e198ee8..920a5c06d3e 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value_and_gas_oog.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_callcode_with_high_value_and_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_with_high_value_and_gas_oog( ) -> None: """Callcode with high value fails.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_callcode_with_high_value_and_gas_oog( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 0xffffffffffffffffffffffff 100000000000000000000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +69,7 @@ def test_callcode_with_high_value_and_gas_oog( key=0x0, value=Op.CALLCODE( gas=0xFFFFFFFFFFFFFFFFFFFFFFFF, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, value=0x56BC75E2D63100000, args_offset=0x0, args_size=0x40, @@ -74,19 +80,7 @@ def test_callcode_with_high_value_and_gas_oog( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0B4E1C683C41F86DC747FBF0DD02CD4398B41373), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py b/tests/ported_static/stCallCreateCallCodeTest/test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py index 766264636b4..8571a26ae45 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py @@ -77,6 +77,14 @@ def test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided pre[sender] = Account(balance=0x10C8E0) # Source: lll + # {(SSTORE 1 1)} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0x186A0, + nonce=0, + address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: lll # {(CALL 50000 0x1000000000000000000000000000000000000001 0 0 64 0 64)} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.CALL( @@ -93,14 +101,6 @@ def test_contract_creation_make_call_that_ask_more_gas_then_transaction_provided nonce=0, address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - # Source: lll - # {(SSTORE 1 1)} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_fail_balance_too_low.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_fail_balance_too_low.py index b4d763f0196..a9036d4c58c 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_fail_balance_too_low.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_fail_balance_too_low.py @@ -75,6 +75,7 @@ def test_create_fail_balance_too_low( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE 0 0x6001600255 ) (SELFDESTRUCT (CREATE 1000000000000000024 27 5)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_create_fail_balance_too_low( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination.py index 165464c4568..4ad74976023 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination.py @@ -48,6 +48,7 @@ def test_create_init_fail_bad_jump_destination( gas_limit=1000000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE8 0 0x56 ) (SELFDESTRUCT (CREATE 1 0 1)) } target = pre.deploy_contract( # noqa: F841 @@ -58,7 +59,6 @@ def test_create_init_fail_bad_jump_destination( nonce=0, address=Address(0x866B704865D7D80842E1D7C2C1C8BF682A3A437C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination2.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination2.py index 87700b137f3..d5ec37b9225 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination2.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_bad_jump_destination2.py @@ -48,6 +48,7 @@ def test_create_init_fail_bad_jump_destination2( gas_limit=1000000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE 0 0x61ffff56 ) (SELFDESTRUCT (CREATE 1 28 4)) } target = pre.deploy_contract( # noqa: F841 @@ -58,7 +59,6 @@ def test_create_init_fail_bad_jump_destination2( nonce=0, address=Address(0x9CC12364004E761C5C594F6DCE3787CFF273029C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init.py index 7d41287d39b..464d32eb2c5 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init.py @@ -49,6 +49,7 @@ def test_create_init_fail_oo_gduring_init( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE8 0 0x5a ) (SELFDESTRUCT (CREATE 1 0 1)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +60,6 @@ def test_create_init_fail_oo_gduring_init( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init2.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init2.py index 7237548682c..565c4fd1974 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init2.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_oo_gduring_init2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_create_init_fail_oo_gduring_init2( """Test_create_init_fail_oo_gduring_init2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_create_init_fail_oo_gduring_init2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_size_larger_than1024.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_size_larger_than1024.py index 46899013d65..4b568b6fd9e 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_size_larger_than1024.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_size_larger_than1024.py @@ -48,6 +48,7 @@ def test_create_init_fail_stack_size_larger_than1024( gas_limit=1000000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE 0 0x6103ff6000525b7f0102030405060708090a0102030405060708090a01020304) (MSTORE 32 0x05060708090a0102600160005103600052600051600657000000000000000000 ) (SELFDESTRUCT (CREATE 1 0 64)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,7 +66,6 @@ def test_create_init_fail_stack_size_larger_than1024( nonce=0, address=Address(0x0EE6DB8C4A76CAB3BB0584E06916CEA75D307DB0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_underflow.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_underflow.py index 5935349d306..b00eaa43c05 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_underflow.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_stack_underflow.py @@ -48,6 +48,7 @@ def test_create_init_fail_stack_underflow( gas_limit=1000000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE8 0 0x01 ) (SELFDESTRUCT (CREATE 1 0 1)) } target = pre.deploy_contract( # noqa: F841 @@ -58,7 +59,6 @@ def test_create_init_fail_stack_underflow( nonce=0, address=Address(0x1EC952083E988EEB19FCAB317760FFC6671246FD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction.py index 376cf052d85..bf25c3a23a2 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_init_fail_undefined_instruction( ) -> None: """Create fails because init code has undefined opcode, trying to...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,26 @@ def test_create_init_fail_undefined_instruction( gas_limit=1000000000, ) + # Source: lll + # {(MSTORE8 0 0xf9 ) (SELFDESTRUCT (CREATE 1 0 1)) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xF9) + + Op.SELFDESTRUCT(address=Op.CREATE(value=0x1, offset=0x0, size=0x1)) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) + # Source: lll + # {(MSTORE8 0 0xf9 ) (SELFDESTRUCT (CREATE2 1 0 1 0)) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xF9) + + Op.SELFDESTRUCT( + address=Op.CREATE2(value=0x1, offset=0x0, size=0x1, salt=0x0) + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[0]] (CALL 400000 0 0 0 0 0) [[1]] (CALL 400000 0 0 0 0 0) [[2]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +72,7 @@ def test_create_init_fail_undefined_instruction( key=0x0, value=Op.CALL( gas=0x61A80, - address=0x552F200B75457440EE6DF9159D6B188E9D18C222, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -67,7 +84,7 @@ def test_create_init_fail_undefined_instruction( key=0x1, value=Op.CALL( gas=0x61A80, - address=0x183FEB7335D767D4D6AE41BBDEA7AFB27227860, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -79,31 +96,7 @@ def test_create_init_fail_undefined_instruction( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x73E58FF0AB0C422709D507EFB9D4889740040144), # noqa: E501 - ) - # Source: lll - # {(MSTORE8 0 0xf9 ) (SELFDESTRUCT (CREATE 1 0 1)) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xF9) - + Op.SELFDESTRUCT(address=Op.CREATE(value=0x1, offset=0x0, size=0x1)) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x552F200B75457440EE6DF9159D6B188E9D18C222), # noqa: E501 - ) - # Source: lll - # {(MSTORE8 0 0xf9 ) (SELFDESTRUCT (CREATE2 1 0 1 0)) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xF9) - + Op.SELFDESTRUCT( - address=Op.CREATE2(value=0x1, offset=0x0, size=0x1, salt=0x0) - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0183FEB7335D767D4D6AE41BBDEA7AFB27227860), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction2.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction2.py index bbfe14a1a0a..d1c8ed82d72 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction2.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_fail_undefined_instruction2.py @@ -48,6 +48,7 @@ def test_create_init_fail_undefined_instruction2( gas_limit=1000000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # {(MSTORE8 0 0xf4 ) (SELFDESTRUCT (CREATE 1 0 1)) } target = pre.deploy_contract( # noqa: F841 @@ -58,7 +59,6 @@ def test_create_init_fail_undefined_instruction2( nonce=0, address=Address(0xCB1256D163AB8CC6FEFA7F8EEE45BA8DB7EA9946), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_oo_gfor_create.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_oo_gfor_create.py index d31c685489d..7207b0ccaa1 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_init_oo_gfor_create.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_init_oo_gfor_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_create_init_oo_gfor_create( """Suicide to a dynamic created contract, oog on create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_create_init_oo_gfor_create( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_js_example_contract.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_js_example_contract.py index 0c158d8a8b1..98e50dcbe48 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_js_example_contract.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_js_example_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_js_example_contract( ) -> None: """Deploy legacy contract normally.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x6600370D1F9991E2D92FFE661C84E7C8C6ECAFC094774F0F3DB0F8DD663590E9 - ) + sender = pre.fund_eoa(amount=0x9184E72A000) env = Environment( fee_recipient=coinbase, @@ -385,17 +382,15 @@ def test_create_js_example_contract( + Op.POP + Op.JUMP, storage={ - 0: 0xBCC416D85E26124EA4EC199A92CF495584A99831, + 0: sender, 1: 66, 2: 35, - 3: 0xBCC416D85E26124EA4EC199A92CF495584A99831, + 3: sender, 5: 0x54C98C81, }, balance=0x186A0, nonce=0, - address=Address(0x1119D4CCF86B65812D85F2FF3E9B2D851E40BA5A), # noqa: E501 ) - pre[sender] = Account(balance=0x9184E72A000) tx = Transaction( sender=sender, @@ -410,10 +405,10 @@ def test_create_js_example_contract( post = { addr: Account( storage={ - 0: 0xBCC416D85E26124EA4EC199A92CF495584A99831, + 0: sender, 1: 66, 2: 35, - 3: 0xBCC416D85E26124EA4EC199A92CF495584A99831, + 3: sender, 5: 0x54C98C81, }, code=bytes.fromhex( diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_js_no_collision.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_js_no_collision.py index c0d5e34a231..98c0900c511 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_js_no_collision.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_js_no_collision.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stCallCreateCallCodeTest/createJS_NoCollisionFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_js_no_collision( state_test: StateTestFiller, pre: Alloc, ) -> None: """Deploy legacy contract normally.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x9184E72A000) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_create_js_no_collision( gas_limit=1000000, ) - pre[sender] = Account(balance=0x9184E72A000) - tx = Transaction( sender=sender, to=None, @@ -60,13 +54,7 @@ def test_create_js_no_collision( post = { compute_create_address(address=sender, nonce=0): Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 66, - 2: 35, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 5: 1000, - }, + storage={0: sender, 1: 66, 2: 35, 3: sender, 5: 1000}, ), } diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs.py index a07e267b25d..5a456ae36ae 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -28,16 +27,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_name_registrator_per_txs( state_test: StateTestFiller, pre: Alloc, ) -> None: """Legacy Test from Christoph.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,6 @@ def test_create_name_registrator_per_txs( gas_limit=10000000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs_not_enough_gas.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs_not_enough_gas.py index f8e2d3275e8..a6159ad7409 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs_not_enough_gas.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_per_txs_not_enough_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -49,7 +48,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_create_name_registrator_per_txs_not_enough_gas( state_test: StateTestFiller, pre: Alloc, @@ -60,9 +58,7 @@ def test_create_name_registrator_per_txs_not_enough_gas( ) -> None: """Legacy Test from Christoph.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,8 +69,6 @@ def test_create_name_registrator_per_txs_not_enough_gas( gas_limit=10000000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - expect_entries_: list[dict] = [ { "indexes": {"data": -1, "gas": 0, "value": -1}, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_pre_store1_not_enough_gas.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_pre_store1_not_enough_gas.py index f8ada3d1acb..cc76b3587f5 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_pre_store1_not_enough_gas.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registrator_pre_store1_not_enough_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_create_name_registrator_pre_store1_not_enough_gas( """Legacy Test from Christoph.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,9 +60,7 @@ def test_create_name_registrator_pre_store1_not_enough_gas( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registratorendowment_too_high.py b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registratorendowment_too_high.py index 22cff80aa69..208b26f09cb 100644 --- a/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registratorendowment_too_high.py +++ b/tests/ported_static/stCallCreateCallCodeTest/test_create_name_registratorendowment_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_name_registratorendowment_too_high( ) -> None: """Legacy Test from Christoph.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,9 +59,7 @@ def test_create_name_registratorendowment_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x84D56FC4FEFC05A5BCE6C569883A47EE499EE0DA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001.py index 77196705072..34843e7be67 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001( ) -> None: """Test_callcallcallcode_001.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,27 @@ def test_callcallcallcode_001( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8, - value=0x1, + key=0x2, + value=Op.DELEGATECALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -66,7 +76,6 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 @@ -75,7 +84,7 @@ def test_callcallcallcode_001( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0x6F50426AA1BBB3CBD865847823F377D918757C07, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -86,16 +95,16 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4C0DE71B93DE6B7055A3686E4BF93ADD02B39ED8), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x3D090, - address=0xC534813374D4D5C43DD9A367926A3DBEECD02964, + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -105,24 +114,7 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6F50426AA1BBB3CBD865847823F377D918757C07), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x5, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0xC534813374D4D5C43DD9A367926A3DBEECD02964), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -138,10 +130,10 @@ def test_callcallcallcode_001( 1: 1, 2: 1, 3: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 5: 2, - 330: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_ooge.py index 1a9883e8374..9c823864d91 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_ooge( ) -> None: """CALLCODE -> CALLCODE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,30 @@ def test_callcallcallcode_001_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -75,7 +78,7 @@ def test_callcallcallcode_001_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,37 +88,26 @@ def test_callcallcallcode_001_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_after.py index b2cc6f68b29..1d4bbe04a14 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_oogm_after( ) -> None: """CALLCODE -> (CALLCODE -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,25 +46,27 @@ def test_callcallcallcode_001_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7DABF2BB39AAF74720CFA113AE52F673BF477E2B), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +75,7 @@ def test_callcallcallcode_001_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x7B1ED5FA290739659102E7C47B650EFD2EBA625B, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -87,34 +86,27 @@ def test_callcallcallcode_001_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7B1ED5FA290739659102E7C47B650EFD2EBA625B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_before.py index 91a2eccbcb8..3ddc82e6af5 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_oogm_before( ) -> None: """CALLCODE -> CALLCODE -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,20 @@ def test_callcallcallcode_001_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, - value=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,9 +67,7 @@ def test_callcallcallcode_001_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcallcallcode_001_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xEFE4727369C5F495AEBF4EA778CC48D1155BF978, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,17 +87,16 @@ def test_callcallcallcode_001_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,17 +104,9 @@ def test_callcallcallcode_001_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEFE4727369C5F495AEBF4EA778CC48D1155BF978), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_end.py index 5a469406500..98081b8eff6 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_suicide_end( ) -> None: """Test_callcallcallcode_001_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcallcode_001_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcallcallcode_001_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_middle.py index 688285aefc7..21882d10003 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_001_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_suicide_middle( ) -> None: """Test_callcallcallcode_001_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcallcode_001_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_callcallcallcode_001_suicide_middle( nonce=0, address=Address(0x124B38FA011C9D36B7FE193DC636813A2F8BDAA7), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_abcb_recursive.py index 651c9af114c..df4566923a7 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_abcb_recursive( ) -> None: """CALLCODE -> CALLCODE1 -> DELEGATECALL2 -> CALLCODE1 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_callcallcallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01.py index 98ac67d238e..62281359646 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcode_01( ) -> None: """Test_callcallcode_01.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,18 @@ def test_callcallcode_01( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x1CCCCF19D84280C8A0E94209761296DABD87B3C9, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +66,7 @@ def test_callcallcode_01( key=0x1, value=Op.DELEGATECALL( gas=0x3D090, - address=0xD42CD48F1D9A88F4B75BFB5E46E754C1128BD7FB, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,24 +76,26 @@ def test_callcallcode_01( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1CCCCF19D84280C8A0E94209761296DABD87B3C9), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x5, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD42CD48F1D9A88F4B75BFB5E46E754C1128BD7FB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -117,10 +110,10 @@ def test_callcallcode_01( 0: 1, 1: 1, 2: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 5: 1, - 230: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: target, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_ooge.py index 1ea8c1b1226..cd659ce1b7c 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcode_01_ooge( ) -> None: """CALLCODE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,12 @@ def test_callcallcode_01_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +60,7 @@ def test_callcallcode_01_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,18 +70,26 @@ def test_callcallcode_01_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_suicide_end.py index d75b4d1d777..8e30857302f 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcode_01_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcode_01_suicide_end( ) -> None: """Test_callcallcode_01_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcode_01_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,15 +93,6 @@ def test_callcallcode_01_suicide_end( nonce=0, address=Address(0x1CCA6E93108EC94304AE5EB121D323E6C317FE7A), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010.py index b9df8c5b644..1b71c97c2cc 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010( ) -> None: """Test_callcallcodecall_010.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,38 @@ def test_callcallcodecall_010( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 6 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x6, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 2 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0x55730, - address=0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D, - value=0x1, + gas=0x3D090, + address=addr_3, + value=0x2, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0x5, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +86,7 @@ def test_callcallcodecall_010( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x8738AB5302009E8BAD163C8A9E91E72926B09D34, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,45 +96,26 @@ def test_callcallcodecall_010( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 2 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x3D090, - address=0xB8601B04BFD9EB63BC6FF0263567113D4CB874E4, - value=0x2, + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0x5, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8738AB5302009E8BAD163C8A9E91E72926B09D34), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 6 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x6, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0xB8601B04BFD9EB63BC6FF0263567113D4CB874E4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -139,11 +131,11 @@ def test_callcallcodecall_010( 1: 1, 2: 1, 3: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 5: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, + 5: target, 6: 2, - 330: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_ooge.py index cec776e5836..e0ad0d14f1b 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_ooge( ) -> None: """CALLCODE -> DELEGATE -> CALLCODE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,21 @@ def test_callcallcodecall_010_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -63,10 +68,9 @@ def test_callcallcodecall_010_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +79,7 @@ def test_callcallcodecall_010_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,16 +88,15 @@ def test_callcallcodecall_010_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -101,21 +104,10 @@ def test_callcallcodecall_010_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_after.py index ab71dd0b2e4..a3e4b5fa7d8 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_oogm_after( ) -> None: """CALLCODE -> (DELEGATE -> CALLCODE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,19 @@ def test_callcallcodecall_010_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -63,11 +66,8 @@ def test_callcallcodecall_010_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x400347DADA8C51A2AAC4B4C31AE726BA8551E2B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +76,7 @@ def test_callcallcodecall_010_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x926DFBCC20B2AB686FC85331883541D174CCC738, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -86,16 +86,15 @@ def test_callcallcodecall_010_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,18 +102,11 @@ def test_callcallcodecall_010_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x926DFBCC20B2AB686FC85331883541D174CCC738), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_before.py index aea320f79c3..518da115c97 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_oogm_before( ) -> None: """CALLCODE -> DELEGATE -> OOG CALLCODE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcallcodecall_010_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.CALLCODE( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -64,9 +68,7 @@ def test_callcallcodecall_010_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +77,7 @@ def test_callcallcodecall_010_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xD33AB78AC3965E7D6F9548DFF5839138A9F69C5, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,17 +87,15 @@ def test_callcallcodecall_010_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -104,17 +104,9 @@ def test_callcallcodecall_010_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0D33AB78AC3965E7D6F9548DFF5839138A9F69C5), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_end.py index 9280e3f4a68..02e73911b14 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_suicide_end( ) -> None: """Test_callcallcodecall_010_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecall_010_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcallcodecall_010_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_middle.py index aad98acb1bf..c381640d752 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_010_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_suicide_middle( ) -> None: """Test_callcallcodecall_010_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecall_010_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_callcallcodecall_010_suicide_middle( nonce=0, address=Address(0x23A077E1E6B0740D6BFBC41DE582F2930ABD1762), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_abcb_recursive.py index 5104bfd5fc9..cb858cf97a2 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_abcb_recursive( ) -> None: """CALLCODE -> DELEGATECALL -> CALLCODE2 -> DELEGATECALL -> CALLCODE2...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_callcallcodecall_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011.py index cdbf453e523..48ad74e3fd5 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011( ) -> None: """Test_callcallcodecallcode_011.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,27 @@ def test_callcallcodecallcode_011( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 6 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x6, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 200000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x66F7A765DC70598F71B119F636A53AAA43C4CCA1, - value=0x1, + key=0x2, + value=Op.DELEGATECALL( + gas=0x30D40, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,9 +74,7 @@ def test_callcallcodecallcode_011( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +83,7 @@ def test_callcallcodecallcode_011( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x563B277206F3BAB1099C59ABB457C3D14E2DEF7B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,16 +92,16 @@ def test_callcallcodecallcode_011( ) + Op.STOP, nonce=0, - address=Address(0x66F7A765DC70598F71B119F636A53AAA43C4CCA1), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 200000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x30D40, - address=0xB8601B04BFD9EB63BC6FF0263567113D4CB874E4, + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -101,25 +109,9 @@ def test_callcallcodecallcode_011( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x563B277206F3BAB1099C59ABB457C3D14E2DEF7B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 6 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x6, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0xB8601B04BFD9EB63BC6FF0263567113D4CB874E4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -135,10 +127,10 @@ def test_callcallcodecallcode_011( 1: 1, 2: 1, 3: 1, - 4: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, + 4: target, 6: 1, - 330: 0xDB43306B16C521B9CC3667FBE7D1B697BB1F9605, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_ooge.py index 719acdb81c8..b682d1c1536 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_ooge( ) -> None: """CALLCODE -> DELEGATE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,30 @@ def test_callcallcodecallcode_011_ooge( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9E57433AFAFF8A546FBC43CF0330AFB6561DC550), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +78,7 @@ def test_callcallcodecallcode_011_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,37 +87,26 @@ def test_callcallcodecallcode_011_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_after.py index aaf83252bea..65bd6cdcd38 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_oogm_after( ) -> None: """CALLCODE -> (DELEGATE -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,25 +46,27 @@ def test_callcallcodecallcode_011_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x400347DADA8C51A2AAC4B4C31AE726BA8551E2B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +75,7 @@ def test_callcallcodecallcode_011_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -86,34 +85,27 @@ def test_callcallcodecallcode_011_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALLCODE 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALLCODE( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_before.py index ee68769dfe6..f720fd6f4c2 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_oogm_before( ) -> None: """CALLCODE -> DELEGATE -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,20 @@ def test_callcallcodecallcode_011_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0xB5104F0F7758CE0CAAC73F593C6D63EB9A5EF905, - value=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.DELEGATECALL( + gas=0x4E34, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,9 +67,7 @@ def test_callcallcodecallcode_011_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA74CA10B765DCDA3B60687F73F2881E2A56EDA64), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 40080 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcallcodecallcode_011_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x9C90, - address=0xC176D297FF74C0F684B73D6CC8617E7F5FFE34FE, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,17 +86,16 @@ def test_callcallcodecallcode_011_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0xB5104F0F7758CE0CAAC73F593C6D63EB9A5EF905), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x4E34, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,17 +103,9 @@ def test_callcallcodecallcode_011_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC176D297FF74C0F684B73D6CC8617E7F5FFE34FE), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_end.py index 14d94305a76..8ff0ce634da 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_suicide_end( ) -> None: """Test_callcallcodecallcode_011_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecallcode_011_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcallcodecallcode_011_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_middle.py index cf4da259665..749ef20c287 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_011_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_suicide_middle( ) -> None: """Test_callcallcodecallcode_011_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecallcode_011_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcallcodecallcode_011_suicide_middle( nonce=0, address=Address(0x6A45EC7F08C71B222CFC454A9608BC278E87F0AB), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_abcb_recursive.py index 500f361ef0d..c4c99123100 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_abcb_recursive( ) -> None: """CALLCODE -> DELEGATECALL1 -> DELEGATECALL2 -> DELEGATECALL1 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcallcodecallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10.py index da20457d81f..89451d38412 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecall_10( ) -> None: """Test_callcodecall_10.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,18 @@ def test_callcodecall_10( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x69142B38329C92930601FE8DA12DC5866CDE11C3, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 250000 2 0 64 0 64 ) } # noqa: E501 @@ -74,7 +66,7 @@ def test_callcodecall_10( key=0x1, value=Op.CALLCODE( gas=0x3D090, - address=0xD42CD48F1D9A88F4B75BFB5E46E754C1128BD7FB, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -85,24 +77,25 @@ def test_callcodecall_10( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x69142B38329C92930601FE8DA12DC5866CDE11C3), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x5, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD42CD48F1D9A88F4B75BFB5E46E754C1128BD7FB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -117,10 +110,10 @@ def test_callcodecall_10( 0: 1, 1: 1, 2: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, + 4: target, 5: 2, - 230: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: target, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_ooge.py index 86919a9f3f1..1094066e048 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecall_10_ooge( ) -> None: """DELEGATE -> CALLCODE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,12 @@ def test_callcodecall_10_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +60,7 @@ def test_callcodecall_10_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,18 +71,25 @@ def test_callcodecall_10_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_suicide_end.py index 982c40cde74..ed560a050f0 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecall_10_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecall_10_suicide_end( ) -> None: """Test_callcodecall_10_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecall_10_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,15 +93,6 @@ def test_callcodecall_10_suicide_end( nonce=0, address=Address(0x799DA5A3C983A22F9C430DE1BF99134EE561E856), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100.py index ec29432b357..571626d265a 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100( ) -> None: """Test_callcodecallcall_100.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,28 @@ def test_callcodecallcall_100( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 6 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x6, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 2 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0xBCC37470FBB132DE68B5746FF4463735A31B5F0C, + key=0x2, + value=Op.CALLCODE( + gas=0x3D090, + address=addr_3, + value=0x2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -65,7 +77,6 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 1 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 @@ -74,7 +85,7 @@ def test_callcodecallcall_100( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0x47F860829F84284269E427671425E1991A340EFA, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x40, @@ -86,17 +97,15 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBCC37470FBB132DE68B5746FF4463735A31B5F0C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 2 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x3D090, - address=0x9BA8D9F7285EBC9BCAAF9DD90F3C123797489566, - value=0x2, + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -106,24 +115,7 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x47F860829F84284269E427671425E1991A340EFA), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 6 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x6, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x9BA8D9F7285EBC9BCAAF9DD90F3C123797489566), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -139,11 +131,11 @@ def test_callcodecallcall_100( 1: 1, 2: 1, 3: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 5: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 4: target, + 5: sender, 6: 2, - 330: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_ooge.py index a7ff09c97c3..c1b01da23e8 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_ooge( ) -> None: """DELEGATE -> CALLCODE -> CALLCODE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,31 @@ def test_callcodecallcall_100_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -74,7 +79,7 @@ def test_callcodecallcall_100_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,38 +89,25 @@ def test_callcodecallcall_100_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0x6389DE20837EC4A47465AED415C7912598FEDC96, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x6322DC554ACDCADA01CBF7AC6A163D207C34DED2), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6389DE20837EC4A47465AED415C7912598FEDC96), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_after.py index d064a7ece5c..df871326fe5 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_oogm_after( ) -> None: """DELEGATE -> (CALLCODE -> CALLCODE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,28 @@ def test_callcodecallcall_100_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcodecallcall_100_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x926DFBCC20B2AB686FC85331883541D174CCC738, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,35 +87,26 @@ def test_callcodecallcall_100_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x926DFBCC20B2AB686FC85331883541D174CCC738), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_before.py index 48768eeac7f..2f8db11c656 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_oogm_before( ) -> None: """DELEGATE -> CALLCODE -> OOG CALLCODE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,21 @@ def test_callcodecallcall_100_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +68,7 @@ def test_callcodecallcall_100_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +77,7 @@ def test_callcodecallcall_100_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,18 +88,15 @@ def test_callcodecallcall_100_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,17 +104,9 @@ def test_callcodecallcall_100_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDBB53599A5D13E0C465E1CC4FF24D7F00D780DF4), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_end.py index 31fd107b872..51991cb8e36 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_suicide_end( ) -> None: """Test_callcodecallcall_100_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcall_100_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcodecallcall_100_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_middle.py index 6ca245f1dc9..c61cace9877 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_100_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_suicide_middle( ) -> None: """Test_callcodecallcall_100_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcall_100_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_callcodecallcall_100_suicide_middle( nonce=0, address=Address(0x23A077E1E6B0740D6BFBC41DE582F2930ABD1762), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_abcb_recursive.py index 8d3fe4532d7..1265bc7fe0b 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_abcb_recursive( ) -> None: """DELEGATE -> CALLCODE1 -> CALLCODE2 -> CALLCODE1 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_callcodecallcall_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101.py index 96619969f01..9104aa608e2 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101( ) -> None: """Test_callcodecallcallcode_101.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,37 @@ def test_callcodecallcallcode_101( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) (SSTORE 6 (CALLER)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0x55730, - address=0xCC06DD0686D0E620FBD99F6A023BA77440119F71, + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 300000 1 0 64 0 64 ) (SSTORE 5 (CALLER)) } # noqa: E501 @@ -74,7 +85,7 @@ def test_callcodecallcallcode_101( key=0x1, value=Op.CALLCODE( gas=0x493E0, - address=0xAE5F44E50ECBF16179774393C643204383FDE833, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x40, @@ -86,44 +97,25 @@ def test_callcodecallcallcode_101( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCC06DD0686D0E620FBD99F6A023BA77440119F71), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) (SSTORE 6 (CALLER)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAE5F44E50ECBF16179774393C643204383FDE833), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -139,12 +131,12 @@ def test_callcodecallcallcode_101( 1: 1, 2: 1, 3: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 5: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 6: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, + 4: target, + 5: sender, + 6: target, 7: 1, - 330: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_ooge.py index 31d66ba2680..5ef5accb284 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_ooge( ) -> None: """DELEGATE -> CALLCODE -> CALLCODE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,30 @@ def test_callcodecallcallcode_101_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) } # noqa: E501 @@ -74,7 +78,7 @@ def test_callcodecallcallcode_101_ooge( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xFCF790146E167FB47D128896C5BA30B0265B1780, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,37 +88,25 @@ def test_callcodecallcallcode_101_ooge( ) + Op.STOP, nonce=0, - address=Address(0x913CF7A18F61BAB7BCCF5607DFA9B730C5976000), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xFCF790146E167FB47D128896C5BA30B0265B1780), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_after.py index 00c31515253..6dd1d8b9f58 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_oogm_after( ) -> None: """DELEGATE -> (CALLCODE -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,27 @@ def test_callcodecallcallcode_101_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5AFCCF55D80F6C4C95515CFFD8E7D51D2C4C9F4A), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +75,7 @@ def test_callcodecallcallcode_101_oogm_after( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,34 +86,26 @@ def test_callcodecallcallcode_101_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x37E72DD6FF3C2AC8C1DDAB092A26164A2AD5988C), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_before.py index 1977bfc9684..dcf7c6314dd 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_oogm_before( ) -> None: """DELEGATE -> CALLCODE -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcodecallcallcode_101_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +67,7 @@ def test_callcodecallcallcode_101_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALLCODE 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +76,7 @@ def test_callcodecallcallcode_101_oogm_before( key=0x1, value=Op.CALLCODE( gas=0x927C0, - address=0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,17 +87,15 @@ def test_callcodecallcallcode_101_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8E6E134402F2EECA8E910E8EC62B45B36EE31F30), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,17 +103,9 @@ def test_callcodecallcallcode_101_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_end.py index abacbbe93f7..c83fec414f8 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_suicide_end( ) -> None: """Test_callcodecallcallcode_101_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcallcode_101_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcallcode_101_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_middle.py index ae12911a59f..631811f181d 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_101_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -39,9 +38,7 @@ def test_callcodecallcallcode_101_suicide_middle( contract_1 = Address(0x1000000000000000000000000000000000000001) contract_2 = Address(0x1000000000000000000000000000000000000002) contract_3 = Address(0x1000000000000000000000000000000000000003) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,6 +49,14 @@ def test_callcodecallcallcode_101_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0x1000000000000000000000000000000000000001 0 64 0 64 ) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -113,15 +118,6 @@ def test_callcodecallcallcode_101_suicide_middle( nonce=0, address=Address(0x1000000000000000000000000000000000000002), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_abcb_recursive.py index 58660cb13c6..277bfc1c57d 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_abcb_recursive( ) -> None: """DELEGATECALL -> CALLCODE -> DELEGATECALL2 -> CALLCODE ->...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11.py index 6d4c0175869..b9187af14a7 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcode_11( ) -> None: """Test_callcodecallcode_11.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,18 @@ def test_callcodecallcode_11( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +66,7 @@ def test_callcodecallcode_11( key=0x1, value=Op.DELEGATECALL( gas=0x3D090, - address=0xD42CD48F1D9A88F4B75BFB5E46E754C1128BD7FB, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,24 +75,25 @@ def test_callcodecallcode_11( ) + Op.STOP, nonce=0, - address=Address(0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 5 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x5, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD42CD48F1D9A88F4B75BFB5E46E754C1128BD7FB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -115,9 +108,9 @@ def test_callcodecallcode_11( 0: 1, 1: 1, 2: 1, - 4: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 230: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 4: sender, + 230: target, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_ooge.py index 368a7961641..61e6338b5b9 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcode_11_ooge( ) -> None: """DELEGATE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,12 @@ def test_callcodecallcode_11_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0xECB18A704984B0E051E46358D64EF7811F2945BA, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1} # noqa: E501 @@ -74,7 +60,7 @@ def test_callcodecallcode_11_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,18 +70,25 @@ def test_callcodecallcode_11_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0xECB18A704984B0E051E46358D64EF7811F2945BA), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_suicide_end.py index 24a34b71978..98290b68642 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcode_11_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcode_11_suicide_end( ) -> None: """Test_callcodecallcode_11_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcode_11_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_callcodecallcode_11_suicide_end( nonce=0, address=Address(0x1CCA6E93108EC94304AE5EB121D323E6C317FE7A), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110.py index 4acb67de28a..7329364f7f2 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110( ) -> None: """Test_callcodecallcodecall_110.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,38 @@ def test_callcodecallcodecall_110( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 250000 1 0 64 0 64 ) (SSTORE 6 (CALLER))} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x669E33B1AA30351139B73C3942ACDE1B09E75BCD, + key=0x2, + value=Op.CALLCODE( + gas=0x3D090, + address=addr_3, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 @@ -74,7 +86,7 @@ def test_callcodecallcodecall_110( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x2F1DBD8E6A5782A1A446D6CED65D3B316C857B55, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,45 +97,25 @@ def test_callcodecallcodecall_110( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x669E33B1AA30351139B73C3942ACDE1B09E75BCD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 250000 1 0 64 0 64 ) (SSTORE 6 (CALLER))} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x1, + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2F1DBD8E6A5782A1A446D6CED65D3B316C857B55), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -139,12 +131,12 @@ def test_callcodecallcodecall_110( 1: 1, 2: 1, 3: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 5: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 6: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 4: target, + 5: sender, + 6: sender, 7: 1, - 330: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_ooge.py index 018fbdca539..e52fb64f847 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_ooge( ) -> None: """DELEGATE -> DELEGATE -> CALLCODE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,31 @@ def test_callcodecallcodecall_110_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +79,7 @@ def test_callcodecallcodecall_110_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x3568EC0DDA63B253E338FBC4990869FD168AB515, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,38 +88,25 @@ def test_callcodecallcodecall_110_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) [[11]] 1} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3568EC0DDA63B253E338FBC4990869FD168AB515), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_after.py index d6ec6cd3204..19362172d87 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_oogm_after( ) -> None: """DELEGATE -> (DELEGATE -> CALLCODE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,28 @@ def test_callcodecallcodecall_110_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcodecallcodecall_110_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xBE2D28F50CB59FFBD66D2EB6A3E8D34F3561D8B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,35 +86,26 @@ def test_callcodecallcodecall_110_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0BE2D28F50CB59FFBD66D2EB6A3E8D34F3561D8B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_before.py index ce98c5c7c69..490de6e49aa 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_oogm_before( ) -> None: """DELEGATE -> DELEGATE -> OOG CALLCODE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,21 @@ def test_callcodecallcodecall_110_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALLCODE( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +68,7 @@ def test_callcodecallcodecall_110_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +77,7 @@ def test_callcodecallcodecall_110_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xD33AB78AC3965E7D6F9548DFF5839138A9F69C5, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,18 +87,15 @@ def test_callcodecallcodecall_110_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALLCODE 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALLCODE( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,17 +103,9 @@ def test_callcodecallcodecall_110_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0D33AB78AC3965E7D6F9548DFF5839138A9F69C5), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_end.py index cce14db4d56..39e4bd7fee8 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_suicide_end( ) -> None: """Test_callcodecallcodecall_110_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecall_110_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcodecall_110_suicide_end( nonce=0, address=Address(0x94C8F980AEECBB6575B12AE614A249FC3E836F21), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_middle.py index 3828c237c68..7a5f1346336 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_110_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_suicide_middle( ) -> None: """Test_callcodecallcodecall_110_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecall_110_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcodecallcodecall_110_suicide_middle( nonce=0, address=Address(0x23A077E1E6B0740D6BFBC41DE582F2930ABD1762), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_abcb_recursive.py index 775d02a13a1..b671556b16a 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_abcb_recursive( ) -> None: """DELEGATECALL -> DELEGATECALL2 -> CALLCODE -> DELEGATECALL2 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcodecall_abcb_recursive( nonce=0, address=Address(0xA71333D8C0291CFD6DA54BEC5A3957563AB16C1C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111.py index 2d25cef8fd2..4c12782ba77 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111( ) -> None: """Test_callcodecallcodecallcode_111.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,27 @@ def test_callcodecallcodecallcode_111( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0x55730, - address=0x66F7A765DC70598F71B119F636A53AAA43C4CCA1, + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +74,7 @@ def test_callcodecallcodecallcode_111( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +83,7 @@ def test_callcodecallcodecallcode_111( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x12BDAB5AF7FD144E2841E58CB6CF90D467054643, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,16 +92,15 @@ def test_callcodecallcodecallcode_111( ) + Op.STOP, nonce=0, - address=Address(0x66F7A765DC70598F71B119F636A53AAA43C4CCA1), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -100,25 +108,9 @@ def test_callcodecallcodecallcode_111( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x12BDAB5AF7FD144E2841E58CB6CF90D467054643), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -134,9 +126,9 @@ def test_callcodecallcodecallcode_111( 1: 1, 2: 1, 3: 1, - 4: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 330: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 4: sender, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_ooge.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_ooge.py index 3918ea8ec11..bf14e1278f1 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_ooge.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_ooge( ) -> None: """DELEGATE -> DELEGATE -> OOG DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,30 @@ def test_callcodecallcodecallcode_111_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +78,7 @@ def test_callcodecallcodecallcode_111_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,37 +87,25 @@ def test_callcodecallcodecallcode_111_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_after.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_after.py index ebc6c1b78bc..4d17a391930 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_oogm_after( ) -> None: """DELEGATE -> (DELEGATE -> OOG DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,27 @@ def test_callcodecallcodecallcode_111_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +75,7 @@ def test_callcodecallcodecallcode_111_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,34 +85,26 @@ def test_callcodecallcodecallcode_111_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_before.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_before.py index 0af1ded1f67..cee5b30363f 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_oogm_before( ) -> None: """DELEGATE -> DELEGATE -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcodecallcodecallcode_111_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +67,7 @@ def test_callcodecallcodecallcode_111_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +76,7 @@ def test_callcodecallcodecallcode_111_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,17 +86,15 @@ def test_callcodecallcodecallcode_111_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -102,17 +102,9 @@ def test_callcodecallcodecallcode_111_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_end.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_end.py index 48d8fa626cd..de51b0fb329 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_suicide_end( ) -> None: """Test_callcodecallcodecallcode_111_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecallcode_111_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcodecallcodecallcode_111_suicide_end( nonce=0, address=Address(0xB207980945728D64A3C9F905932314C8F130EE38), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_middle.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_middle.py index 95dfb7b9826..5bfe55fa878 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_111_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_suicide_middle( ) -> None: """Test_callcodecallcodecallcode_111_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecallcode_111_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcodecallcodecallcode_111_suicide_middle( nonce=0, address=Address(0x124B38FA011C9D36B7FE193DC636813A2F8BDAA7), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_abcb_recursive.py index f13c6854ae9..57136f08e9f 100644 --- a/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesCallCodeHomestead/test_callcodecallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_abcb_recursive( ) -> None: """DELEGATECALL -> DELEGATECALL1 -> DELEGATECALL2 -> DELEGATECAL1 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -105,7 +102,6 @@ def test_callcodecallcodecallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001.py index 99e15bedad6..521fce6999d 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001( ) -> None: """Test_callcallcallcode_001.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,27 @@ def test_callcallcallcode_001( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0x9073671D2BFB351331716FD279282EACF50824AD, - value=0x1, + key=0x2, + value=Op.DELEGATECALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -66,7 +76,6 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 2 0 64 0 64 ) } # noqa: E501 @@ -75,7 +84,7 @@ def test_callcallcallcode_001( key=0x1, value=Op.CALL( gas=0x493E0, - address=0x6F50426AA1BBB3CBD865847823F377D918757C07, + address=addr_2, value=0x2, args_offset=0x0, args_size=0x40, @@ -86,16 +95,16 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9073671D2BFB351331716FD279282EACF50824AD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -105,24 +114,7 @@ def test_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6F50426AA1BBB3CBD865847823F377D918757C07), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -138,10 +130,10 @@ def test_callcallcallcode_001( storage={ 2: 1, 3: 1, - 4: 0x9073671D2BFB351331716FD279282EACF50824AD, + 4: addr, 7: 2, - 330: 0x6F50426AA1BBB3CBD865847823F377D918757C07, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_2, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_ooge.py index ff8b0b335e7..b138b7b3994 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_ooge( ) -> None: """CALL -> CALL -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,30 @@ def test_callcallcallcode_001_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -75,7 +78,7 @@ def test_callcallcallcode_001_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,37 +88,26 @@ def test_callcallcallcode_001_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_after.py index 599e3cee3b1..e969889555f 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_oogm_after( ) -> None: """CALL -> (CALL -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,25 +46,27 @@ def test_callcallcallcode_001_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB501C5662091E198627416E5579D42ACEE74DBFC), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +75,7 @@ def test_callcallcallcode_001_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x7B1ED5FA290739659102E7C47B650EFD2EBA625B, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -87,34 +86,27 @@ def test_callcallcallcode_001_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7B1ED5FA290739659102E7C47B650EFD2EBA625B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_before.py index eba31f72e76..2f1530511a9 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_oogm_before( ) -> None: """CALL -> CALL -> OOG DELEGATE -> CODE .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,20 @@ def test_callcallcallcode_001_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, - value=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,9 +67,7 @@ def test_callcallcallcode_001_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcallcallcode_001_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xEFE4727369C5F495AEBF4EA778CC48D1155BF978, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,17 +87,16 @@ def test_callcallcallcode_001_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,17 +104,9 @@ def test_callcallcallcode_001_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEFE4727369C5F495AEBF4EA778CC48D1155BF978), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_end.py index 70ef39f5872..9d145663f00 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_suicide_end( ) -> None: """Test_callcallcallcode_001_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcallcode_001_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcallcallcode_001_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_middle.py index 6b821257b63..9bddbd06ff9 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_001_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_001_suicide_middle( ) -> None: """Test_callcallcallcode_001_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcallcode_001_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_callcallcallcode_001_suicide_middle( nonce=0, address=Address(0x124B38FA011C9D36B7FE193DC636813A2F8BDAA7), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_abcb_recursive.py index 46d4631c08f..6800472a043 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcallcode_abcb_recursive( ) -> None: """CALL -> CALL2 -> DELEGATECALL -> CALL2 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_callcallcallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01.py index ff3d2f63c6b..b507415274d 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcallcode_01( ) -> None: """Test_callcallcode_01.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,24 +44,18 @@ def test_callcallcode_01( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 @@ -73,7 +64,7 @@ def test_callcallcode_01( key=0x1, value=Op.DELEGATECALL( gas=0x3D090, - address=0xB096ECA04CD5C92C88BA466F92627D4F04D53C95, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -82,24 +73,26 @@ def test_callcallcode_01( ) + Op.STOP, nonce=0, - address=Address(0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB096ECA04CD5C92C88BA466F92627D4F04D53C95), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -114,10 +107,10 @@ def test_callcallcode_01( storage={ 1: 1, 2: 1, - 4: 0xEB09FF15547417853F6F4B240B8804769C37B0F1, + 4: target, 7: 1, - 230: 0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: addr, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_ooge.py index 3e6b9587516..cbb050fc430 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcode_01_ooge( ) -> None: """CALL -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,12 @@ def test_callcallcode_01_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x42473C2734EB62B91E4E2AC3DAB63AB2443F4236, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +60,7 @@ def test_callcallcode_01_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,18 +70,26 @@ def test_callcallcode_01_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x42473C2734EB62B91E4E2AC3DAB63AB2443F4236), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_suicide_end.py index 5ed7010f9d6..9ce57b4ea26 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcode_01_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcode_01_suicide_end( ) -> None: """Test_callcallcode_01_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcode_01_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,15 +93,6 @@ def test_callcallcode_01_suicide_end( nonce=0, address=Address(0x1CCA6E93108EC94304AE5EB121D323E6C317FE7A), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010.py index 8f3563a79f4..2887e55659b 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010( ) -> None: """Test_callcallcodecall_010.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,38 @@ def test_callcallcodecall_010( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 2 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0x55730, - address=0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D, - value=0x1, + gas=0x3D090, + address=addr_3, + value=0x2, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0x5, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +86,7 @@ def test_callcallcodecall_010( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0xA297E445DC76A67BF6FC17C444C1EC2C389CE53D, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,45 +96,26 @@ def test_callcallcodecall_010( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 2 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x2, + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0x5, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA297E445DC76A67BF6FC17C444C1EC2C389CE53D), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -134,21 +126,15 @@ def test_callcallcodecall_010( post = { target: Account(storage={0: 1, 2: 0}), - addr: Account( - storage={ - 1: 1, - 2: 1, - 5: 0xEB09FF15547417853F6F4B240B8804769C37B0F1, - }, - ), + addr: Account(storage={1: 1, 2: 1, 5: target}), addr_2: Account(storage={2: 0}), addr_3: Account( storage={ 3: 1, - 4: 0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D, + 4: addr, 7: 2, - 330: 0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_ooge.py index bab5a831b42..422ac1d273e 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_ooge( ) -> None: """CALL -> DELEGATE -> CALL -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,21 @@ def test_callcallcodecall_010_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -63,10 +68,9 @@ def test_callcallcodecall_010_ooge( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +79,7 @@ def test_callcallcodecall_010_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,16 +88,15 @@ def test_callcallcodecall_010_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -101,21 +104,10 @@ def test_callcallcodecall_010_ooge( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_after.py index 4ae34f45ed9..7c63c9cccec 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_oogm_after( ) -> None: """CALL -> (DELEGATE -> CALL -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,19 @@ def test_callcallcodecall_010_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -63,11 +66,8 @@ def test_callcallcodecall_010_oogm_after( ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE54CCFA5E33A84943997885F0AB9C19C587D8C4F), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +76,7 @@ def test_callcallcodecall_010_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -86,16 +86,15 @@ def test_callcallcodecall_010_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -103,18 +102,11 @@ def test_callcallcodecall_010_oogm_after( ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_before.py index ae6beb28c44..7ee856213d8 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_oogm_before( ) -> None: """CALL -> DELEGATE -> OOG CALL -> CODE .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcallcodecall_010_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.CALL( - gas=0xC3500, - address=0x97367129E262C26FF9D41B4424EB9E460270F83F, + gas=0x61A80, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -64,9 +68,7 @@ def test_callcallcodecall_010_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +77,7 @@ def test_callcallcodecall_010_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x51A61D678EC27711369C527E5D42A9DE66A5727F, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,17 +87,15 @@ def test_callcallcodecall_010_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x97367129E262C26FF9D41B4424EB9E460270F83F), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, value=0x0, args_offset=0x0, args_size=0x40, @@ -104,17 +104,9 @@ def test_callcallcodecall_010_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x51A61D678EC27711369C527E5D42A9DE66A5727F), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_end.py index 99d0542a791..3e51d28ac20 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_suicide_end( ) -> None: """Test_callcallcodecall_010_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecall_010_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcallcodecall_010_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_middle.py index c11a4441b94..d4585d7fbae 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_010_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_010_suicide_middle( ) -> None: """Test_callcallcodecall_010_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecall_010_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_callcallcodecall_010_suicide_middle( nonce=0, address=Address(0xAC90BB4611B91D4C6292BD64E8656110822E01ED), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_abcb_recursive.py index 4fc3c1777d1..bd68d956080 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecall_abcb_recursive( ) -> None: """CALL -> DELEGATECALL -> CALL2 -> DELEGATECALL -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_callcallcodecall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011.py index 9b42b70e097..2230e5e1316 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011( ) -> None: """Test_callcallcodecallcode_011.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,27 @@ def test_callcallcodecallcode_011( ) # Source: lll - # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x55730, - address=0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D, - value=0x1, + key=0x2, + value=Op.DELEGATECALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -66,7 +76,6 @@ def test_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEB09FF15547417853F6F4B240B8804769C37B0F1), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +84,7 @@ def test_callcallcodecallcode_011( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x6F50426AA1BBB3CBD865847823F377D918757C07, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,16 +94,16 @@ def test_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 350000 1 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, + key=0x0, + value=Op.CALL( + gas=0x55730, + address=addr, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,24 +113,7 @@ def test_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6F50426AA1BBB3CBD865847823F377D918757C07), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -137,10 +129,10 @@ def test_callcallcodecallcode_011( 1: 1, 2: 1, 3: 1, - 4: 0xEB09FF15547417853F6F4B240B8804769C37B0F1, + 4: target, 7: 1, - 330: 0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_ooge.py index 022dccc1c98..238a89aa72a 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_ooge( ) -> None: """CALL -> DELEGATE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,30 @@ def test_callcallcodecallcode_011_ooge( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -75,7 +78,7 @@ def test_callcallcodecallcode_011_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,37 +87,26 @@ def test_callcallcodecallcode_011_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_after.py index 51b8a844b89..23e7b6217ef 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_oogm_after( ) -> None: """CALL -> (DELEGATE -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,25 +46,27 @@ def test_callcallcodecallcode_011_oogm_after( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, - value=0x0, + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE54CCFA5E33A84943997885F0AB9C19C587D8C4F), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -76,7 +75,7 @@ def test_callcallcodecallcode_011_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -86,34 +85,27 @@ def test_callcallcodecallcode_011_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_before.py index a5483d53c71..5aecfe71aec 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_oogm_before( ) -> None: """CALL -> DELEGATE -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,20 @@ def test_callcallcodecallcode_011_oogm_before( ) # Source: lll - # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, - value=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.DELEGATECALL( + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,9 +67,7 @@ def test_callcallcodecallcode_011_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335B558774699D81F685543CFBCDE5C4E5407686), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcallcodecallcode_011_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,17 +86,16 @@ def test_callcallcodecallcode_011_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (CALL 800000 0 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0xC3500, + address=addr, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,17 +103,9 @@ def test_callcallcodecallcode_011_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_end.py index 4cc2489884e..2f8cd246a17 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_suicide_end( ) -> None: """Test_callcallcodecallcode_011_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecallcode_011_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcallcodecallcode_011_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_middle.py index ffff6216d4f..7b2dd08bcdd 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_011_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_011_suicide_middle( ) -> None: """Test_callcallcodecallcode_011_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcallcodecallcode_011_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 150000 0 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcallcodecallcode_011_suicide_middle( nonce=0, address=Address(0x6A45EC7F08C71B222CFC454A9608BC278E87F0AB), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_abcb_recursive.py index 6d2774dc6e4..f50349c2e61 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcallcodecallcode_abcb_recursive( ) -> None: """Test_callcallcodecallcode_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcallcodecallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10.py index 568577c4b72..b689ffd226d 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcodecall_10( ) -> None: """Test_callcodecall_10.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,23 +44,18 @@ def test_callcodecall_10( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0xFD0CC1F9A105E057B84065348C4C878DD79FA4BE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 250000 1 0 64 0 64 ) } # noqa: E501 @@ -72,7 +64,7 @@ def test_callcodecall_10( key=0x1, value=Op.CALL( gas=0x3D090, - address=0xCB4336321FAC69281BD2902D427F4EF9E8584251, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x40, @@ -83,24 +75,25 @@ def test_callcodecall_10( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFD0CC1F9A105E057B84065348C4C878DD79FA4BE), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCB4336321FAC69281BD2902D427F4EF9E8584251), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -114,10 +107,10 @@ def test_callcodecall_10( addr_2: Account( storage={ 2: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, + 4: target, 7: 1, - 230: 0xCB4336321FAC69281BD2902D427F4EF9E8584251, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 230: addr_2, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_ooge.py index 8fc338cf753..4bd43c7abf0 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecall_10_ooge( ) -> None: """DELEGATE -> CALL -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,12 @@ def test_callcodecall_10_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +60,7 @@ def test_callcodecall_10_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,18 +71,25 @@ def test_callcodecall_10_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_suicide_end.py index 6dca2ecffde..10a12ffbe2a 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecall_10_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecall_10_suicide_end( ) -> None: """Test_callcodecall_10_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecall_10_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,15 +93,6 @@ def test_callcodecall_10_suicide_end( nonce=0, address=Address(0xF741CFEE7B7FB1025DCCEF3DB5A3CBC8FFB776F8), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100.py index 41f4d5753dd..ce2dc3a924e 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100( ) -> None: """Test_callcodecallcall_100.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,28 @@ def test_callcodecallcall_100( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 2 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x3C83297C6DCBC0520CD68714F85DC444469FB287, + key=0x2, + value=Op.CALL( + gas=0x3D090, + address=addr_3, + value=0x2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -65,7 +77,6 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 1 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 @@ -74,7 +85,7 @@ def test_callcodecallcall_100( key=0x1, value=Op.CALL( gas=0x493E0, - address=0x5F6EACDE5A1E97F48C5DB4EE84FDF614F9DD9756, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x40, @@ -86,17 +97,15 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3C83297C6DCBC0520CD68714F85DC444469FB287), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 2 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - value=0x2, + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -106,24 +115,7 @@ def test_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5F6EACDE5A1E97F48C5DB4EE84FDF614F9DD9756), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -133,21 +125,15 @@ def test_callcodecallcall_100( ) post = { - target: Account( - storage={ - 0: 1, - 1: 1, - 5: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), + target: Account(storage={0: 1, 1: 1, 5: sender}), addr_2: Account(storage={2: 1}), addr_3: Account( storage={ 3: 1, - 4: 0x5F6EACDE5A1E97F48C5DB4EE84FDF614F9DD9756, + 4: addr_2, 7: 2, - 330: 0x181B4ED322E192361633CC3C0A418F259AB0CF4B, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_ooge.py index 69354b1b130..ecd3d7ab292 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_ooge( ) -> None: """DELEGATE -> CALL -> CALL -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,31 @@ def test_callcodecallcall_100_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -74,7 +79,7 @@ def test_callcodecallcall_100_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,38 +89,25 @@ def test_callcodecallcall_100_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_after.py index 10b4c1a88f1..53369cc5493 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_oogm_after( ) -> None: """DELEGATE -> (CALL -> CALL -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,28 @@ def test_callcodecallcall_100_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcodecallcall_100_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,35 +87,26 @@ def test_callcodecallcall_100_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8D7270785422B63A97D83BADA6AAC80BEBC3A99D), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_before.py index caf3da961e0..b2020ce01e8 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_oogm_before( ) -> None: """DELEGATE -> CALL -> OOG CALL -> CODE .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,21 @@ def test_callcodecallcall_100_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +68,7 @@ def test_callcodecallcall_100_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +77,7 @@ def test_callcodecallcall_100_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x4A780315E172DB6C0A08FE70FF4362B0E061B668, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,18 +88,15 @@ def test_callcodecallcall_100_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,17 +104,9 @@ def test_callcodecallcall_100_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4A780315E172DB6C0A08FE70FF4362B0E061B668), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_end.py index 91b43e03733..37c468d6f04 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_suicide_end( ) -> None: """Test_callcodecallcall_100_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcall_100_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcodecallcall_100_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_middle.py index 8042f6d2d9d..2a652b6170e 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_100_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_100_suicide_middle( ) -> None: """Test_callcodecallcall_100_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcall_100_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_callcodecallcall_100_suicide_middle( nonce=0, address=Address(0xAC90BB4611B91D4C6292BD64E8656110822E01ED), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_abcb_recursive.py index 40128493628..c9b8a4c7e21 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcall_abcb_recursive( ) -> None: """DELEGATECALL -> CALL1 -> CALL2 -> CALL1 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_callcodecallcall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101.py index a827215ead4..626025ac0f5 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101( ) -> None: """Test_callcodecallcallcode_101.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,37 @@ def test_callcodecallcallcode_101( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) (SSTORE 6 (CALLER)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0x55730, - address=0x63F88DCF511E5686BC6B446D10538E665BF81A8, + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 300000 1 0 64 0 64 ) (SSTORE 5 (CALLER)) } # noqa: E501 @@ -74,7 +85,7 @@ def test_callcodecallcallcode_101( key=0x1, value=Op.CALL( gas=0x493E0, - address=0xAE5F44E50ECBF16179774393C643204383FDE833, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x40, @@ -86,44 +97,25 @@ def test_callcodecallcallcode_101( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x063F88DCF511E5686BC6B446D10538E665BF81A8), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) (SSTORE 6 (CALLER)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAE5F44E50ECBF16179774393C643204383FDE833), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -133,23 +125,17 @@ def test_callcodecallcallcode_101( ) post = { - target: Account( - storage={ - 0: 1, - 1: 1, - 5: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), + target: Account(storage={0: 1, 1: 1, 5: sender}), addr: Account(storage={1: 0, 2: 0}), addr_2: Account( storage={ 2: 1, 3: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 6: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, + 4: target, + 6: target, 7: 1, - 330: 0xAE5F44E50ECBF16179774393C643204383FDE833, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_2, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_ooge.py index 8f533bad735..7cb6eac1873 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_ooge( ) -> None: """DELEGATE -> CALL -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,30 @@ def test_callcodecallcallcode_101_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) } # noqa: E501 @@ -74,7 +78,7 @@ def test_callcodecallcallcode_101_ooge( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -84,37 +88,25 @@ def test_callcodecallcallcode_101_ooge( ) + Op.STOP, nonce=0, - address=Address(0xBBDCE54B3C571B853032CB3A637E8F5B81DBAF0D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_after.py index ada29bdd72e..74bb7a20506 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_oogm_after( ) -> None: """DELEGATE -> (CALL -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,27 @@ def test_callcodecallcallcode_101_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0xB5D1A486869D27225126C47727513F57D329A01A, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +75,7 @@ def test_callcodecallcallcode_101_oogm_after( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -86,34 +86,26 @@ def test_callcodecallcallcode_101_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xB5D1A486869D27225126C47727513F57D329A01A), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_before.py index 4edab8fa54d..1e145c9cbf4 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_oogm_before( ) -> None: """DELEGATE -> CALL -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcodecallcallcode_101_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x471072D55A5A95044C2326F0E94A6D8DF5B8089E, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +67,7 @@ def test_callcodecallcallcode_101_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (CALL 600000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +76,7 @@ def test_callcodecallcallcode_101_oogm_before( key=0x1, value=Op.CALL( gas=0x927C0, - address=0x2640FCBA4A90A13A6438EED47FAFBD5D59ECBC47, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x40, @@ -85,17 +87,15 @@ def test_callcodecallcallcode_101_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x471072D55A5A95044C2326F0E94A6D8DF5B8089E), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,17 +103,9 @@ def test_callcodecallcallcode_101_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2640FCBA4A90A13A6438EED47FAFBD5D59ECBC47), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_end.py index 58e4ae8b72d..af4852ff563 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_101_suicide_end( ) -> None: """Test_callcodecallcallcode_101_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcallcode_101_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcallcode_101_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_middle.py index 4b57701e1e9..5ff96f90136 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_101_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -39,9 +38,7 @@ def test_callcodecallcallcode_101_suicide_middle( contract_1 = Address(0x1000000000000000000000000000000000000001) contract_2 = Address(0x1000000000000000000000000000000000000002) contract_3 = Address(0x1000000000000000000000000000000000000003) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,6 +49,14 @@ def test_callcodecallcallcode_101_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0x1000000000000000000000000000000000000001 0 64 0 64 ) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -113,15 +118,6 @@ def test_callcodecallcallcode_101_suicide_middle( nonce=0, address=Address(0x1000000000000000000000000000000000000002), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_abcb_recursive.py index 36ecb9cdc93..152c6ca4597 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcallcode_abcb_recursive( ) -> None: """DELEGATECALL -> CALL -> DELEGATECALL2 -> CALL -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11.py index 4ed95f6bb46..bc8e57b4105 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcode_11( ) -> None: """Test_callcodecallcode_11.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,18 @@ def test_callcodecallcode_11( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +66,7 @@ def test_callcodecallcode_11( key=0x1, value=Op.DELEGATECALL( gas=0x3D090, - address=0xCB4336321FAC69281BD2902D427F4EF9E8584251, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,24 +75,25 @@ def test_callcodecallcode_11( ) + Op.STOP, nonce=0, - address=Address(0x2B0691CD58A1CF4628D642E9ACA9AB04946E3EC9), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCB4336321FAC69281BD2902D427F4EF9E8584251), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -115,9 +108,9 @@ def test_callcodecallcode_11( 0: 1, 1: 1, 2: 1, - 4: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 230: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 232: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 4: sender, + 230: target, + 232: sender, 236: 64, 238: 34, 240: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_ooge.py index e4affe72a3c..3211880c454 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcode_11_ooge( ) -> None: """DELEGATE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,12 @@ def test_callcodecallcode_11_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0xECB18A704984B0E051E46358D64EF7811F2945BA, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1} # noqa: E501 @@ -74,7 +60,7 @@ def test_callcodecallcode_11_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x766B2CF0691F51029181FC511395B7AB71353A88, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,18 +70,25 @@ def test_callcodecallcode_11_ooge( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0xECB18A704984B0E051E46358D64EF7811F2945BA), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x766B2CF0691F51029181FC511395B7AB71353A88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_suicide_end.py index 5c43845f10c..4675d8f476b 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcode_11_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcode_11_suicide_end( ) -> None: """Test_callcodecallcode_11_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcode_11_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_callcodecallcode_11_suicide_end( nonce=0, address=Address(0x1CCA6E93108EC94304AE5EB121D323E6C317FE7A), # noqa: E501 ) - # Source: lll - # { (SSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110.py index d4f927d755d..6ff719a5e6c 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110( ) -> None: """Test_callcodecallcodecall_110.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,38 @@ def test_callcodecallcodecall_110( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 250000 1 0 64 0 64 ) (SSTORE 6 (CALLER))} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x669E33B1AA30351139B73C3942ACDE1B09E75BCD, + key=0x2, + value=Op.CALL( + gas=0x3D090, + address=addr_3, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) (SSTORE 5 (CALLER))} # noqa: E501 @@ -74,7 +86,7 @@ def test_callcodecallcodecall_110( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x78B5BD809B0B6FE0B8E371F286D7AA6A3B930718, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,45 +97,25 @@ def test_callcodecallcodecall_110( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x669E33B1AA30351139B73C3942ACDE1B09E75BCD), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 250000 1 0 64 0 64 ) (SSTORE 6 (CALLER))} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - value=0x1, + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0x6, value=Op.CALLER) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x78B5BD809B0B6FE0B8E371F286D7AA6A3B930718), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -133,22 +125,14 @@ def test_callcodecallcodecall_110( ) post = { - target: Account( - storage={ - 0: 1, - 1: 1, - 2: 1, - 5: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 6: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), + target: Account(storage={0: 1, 1: 1, 2: 1, 5: sender, 6: sender}), addr_3: Account( storage={ 3: 1, - 4: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, + 4: target, 7: 1, - 330: 0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 330: addr_3, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_ooge.py index 6d9d3a49b4d..4ef197b46b0 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_ooge( ) -> None: """DELEGATE -> DELEGATE -> CALL -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,31 @@ def test_callcodecallcodecall_110_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +79,7 @@ def test_callcodecallcodecall_110_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,38 +88,25 @@ def test_callcodecallcodecall_110_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xB11130CF7EEF6D3F1552623D3506A5BBB07B12CE), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_after.py index 8ced610a466..1c133ee31b4 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_oogm_after( ) -> None: """DELEGATE -> (DELEGATE -> CALL -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,28 @@ def test_callcodecallcodecall_110_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +76,7 @@ def test_callcodecallcodecall_110_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x83B7D129B58AB5315B795F9A8D34294EC60C9D63, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,35 +86,26 @@ def test_callcodecallcodecall_110_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x83B7D129B58AB5315B795F9A8D34294EC60C9D63), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_before.py index cf5d70c0265..fa9b7278710 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_oogm_before( ) -> None: """DELEGATE -> DELEGATE -> OOG CALL -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,21 @@ def test_callcodecallcodecall_110_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=0x61A80, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +68,7 @@ def test_callcodecallcodecall_110_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +77,7 @@ def test_callcodecallcodecall_110_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x51A61D678EC27711369C527E5D42A9DE66A5727F, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,18 +87,15 @@ def test_callcodecallcodecall_110_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (CALL 400000 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, - value=0x0, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,17 +103,9 @@ def test_callcodecallcodecall_110_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x51A61D678EC27711369C527E5D42A9DE66A5727F), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_end.py index 1d53a3f34f7..1c41be7b462 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_suicide_end( ) -> None: """Test_callcodecallcodecall_110_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecall_110_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_callcodecallcodecall_110_suicide_end( nonce=0, address=Address(0xD957E143AD2C011BC6A2B142795F1A9BA70D0680), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_middle.py index a36ca0c3fd4..30952c011df 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_110_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_110_suicide_middle( ) -> None: """Test_callcodecallcodecall_110_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecall_110_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_callcodecallcodecall_110_suicide_middle( nonce=0, address=Address(0xAC90BB4611B91D4C6292BD64E8656110822E01ED), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_abcb_recursive.py index e1e242f9a32..61c2398da8c 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecall_abcb_recursive( ) -> None: """DELEGATECALL -> DELEGATECALL2 -> CALL -> DELEGATECALL2 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -106,7 +103,6 @@ def test_callcodecallcodecall_abcb_recursive( nonce=0, address=Address(0x91A8703C1BEF34C1E76E152C1F7FB8C336C3BE24), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111.py index 3f7bb7777aa..79b74221b0c 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111( ) -> None: """Test_callcodecallcodecallcode_111.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,27 @@ def test_callcodecallcodecallcode_111( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0x55730, - address=0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D, + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -65,7 +76,6 @@ def test_callcodecallcodecallcode_111( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 300000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +84,7 @@ def test_callcodecallcodecallcode_111( key=0x1, value=Op.DELEGATECALL( gas=0x493E0, - address=0x6F50426AA1BBB3CBD865847823F377D918757C07, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,16 +94,15 @@ def test_callcodecallcodecallcode_111( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFED08E44AE95ECE264BC94A1FC45AF8BC4EF4F1D), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,24 +112,7 @@ def test_callcodecallcodecallcode_111( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6F50426AA1BBB3CBD865847823F377D918757C07), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -136,9 +128,9 @@ def test_callcodecallcodecallcode_111( 1: 1, 2: 1, 3: 1, - 4: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - 330: 0xD26E26D5A4796D450BFA296D70C05F02DBC1A4B9, - 332: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, + 4: sender, + 330: target, + 332: sender, 336: 64, 338: 39, 340: 10, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_ooge.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_ooge.py index 06776a0a461..ee9b0bcea8a 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_ooge.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_ooge( ) -> None: """DELEGATE -> DELEGATE -> DELEGATE -> CODE OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,23 +46,30 @@ def test_callcodecallcodecallcode_111_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x69A0017A51AD556682F48B32235D0B61ABDF4DA4, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) } # noqa: E501 @@ -74,7 +78,7 @@ def test_callcodecallcodecallcode_111_ooge( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,37 +87,25 @@ def test_callcodecallcodecallcode_111_ooge( ) + Op.STOP, nonce=0, - address=Address(0x69A0017A51AD556682F48B32235D0B61ABDF4DA4), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0x1DD747F92062BB53BB8E867EC2902792435F1748, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3E423A7B1FBA04D0C3F9423A3AE2A180D2878D5B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (KECCAK256 0x00 0x2fffff) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1DD747F92062BB53BB8E867EC2902792435F1748), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_after.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_after.py index 044057ae223..6601196e797 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_after.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_oogm_after( ) -> None: """DELEGATE -> (DELEGATE -> DELEGATE -> CODE) OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,24 +46,27 @@ def test_callcodecallcodecallcode_111_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) - + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74ECD5F6537B2B48EBBFF8D66AEE8EB8F98430A3), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) (KECCAK256 0x00 0x2fffff) } # noqa: E501 @@ -75,7 +75,7 @@ def test_callcodecallcodecallcode_111_oogm_after( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,34 +85,26 @@ def test_callcodecallcodecallcode_111_oogm_after( + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x1ADAE71AD3AEEC97978E38BE04DA2A1773DFC506), # noqa: E501 ) # Source: lll - # { [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) [[11]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x2, + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ), ) + + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDA11FDF0CE02240C6B4711F56AFCD9763B44D3DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_before.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_before.py index 7398b1f9a3e..a78bec5f2aa 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_before.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_oogm_before( ) -> None: """DELEGATE -> DELEGATE -> OOG DELEGATE -> CODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,20 @@ def test_callcodecallcodecallcode_111_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE( + key=0x2, value=Op.DELEGATECALL( - gas=0xC3500, - address=0x29F893B720E998CCD5971409FA9A8802822FDCBC, + gas=0x61A80, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,9 +67,7 @@ def test_callcodecallcodecallcode_111_oogm_before( ), ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0E7163A4A90126C4A13E52F48E84C74600E844DA), # noqa: E501 ) # Source: lll # { [[ 1 ]] (DELEGATECALL 600000 0 64 0 64 ) [[11]] 1 } # noqa: E501 @@ -74,7 +76,7 @@ def test_callcodecallcodecallcode_111_oogm_before( key=0x1, value=Op.DELEGATECALL( gas=0x927C0, - address=0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,17 +86,15 @@ def test_callcodecallcodecallcode_111_oogm_before( + Op.SSTORE(key=0xB, value=0x1) + Op.STOP, nonce=0, - address=Address(0x29F893B720E998CCD5971409FA9A8802822FDCBC), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) [[ 2 ]] (DELEGATECALL 400000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE( - key=0x2, + # { [[ 0 ]] (DELEGATECALL 800000 0 64 0 64 ) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.DELEGATECALL( - gas=0x61A80, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xC3500, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -102,17 +102,9 @@ def test_callcodecallcodecallcode_111_oogm_before( ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x71E7E95D2DFE9F65B4522F2D3AA71FB33F49920C), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_end.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_end.py index 09ca3b8d348..881e54676f3 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_end.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_suicide_end( ) -> None: """Test_callcodecallcodecallcode_111_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecallcode_111_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -106,15 +111,6 @@ def test_callcodecallcodecallcode_111_suicide_end( nonce=0, address=Address(0xAC521409E2FA9526BFE6B827805783D2E307C4CE), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_middle.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_middle.py index 9686f938293..7b62d827fbf 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_middle.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_111_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_111_suicide_middle( ) -> None: """Test_callcodecallcodecallcode_111_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,14 @@ def test_callcodecallcodecallcode_111_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (SSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_callcodecallcodecallcode_111_suicide_middle( nonce=0, address=Address(0x124B38FA011C9D36B7FE193DC636813A2F8BDAA7), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x73B954EBC05BB0FF4A0F6A13A054D50AD1584099), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_abcb_recursive.py b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_abcb_recursive.py index c9ea5f54475..4b7748b2981 100644 --- a/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stCallDelegateCodesHomestead/test_callcodecallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcodecallcodecallcode_abcb_recursive( ) -> None: """DELEGATECALL -> DELEGATECALL2 -> DELEGATECALl3 -> DELEGATECALL2 -> .""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -105,7 +102,6 @@ def test_callcodecallcodecallcode_abcb_recursive( nonce=0, address=Address(0xA72F0E2F2FC5FD0878AF9B8E4AAED09983670929), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCodeCopyTest/test_ext_code_copy_target_range_longer_than_code_tests.py b/tests/ported_static/stCodeCopyTest/test_ext_code_copy_target_range_longer_than_code_tests.py index e1f1e7c93b1..714f03d6c34 100644 --- a/tests/ported_static/stCodeCopyTest/test_ext_code_copy_target_range_longer_than_code_tests.py +++ b/tests/ported_static/stCodeCopyTest/test_ext_code_copy_target_range_longer_than_code_tests.py @@ -49,24 +49,25 @@ def test_ext_code_copy_target_range_longer_than_code_tests( ) pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + # Source: raw + # 0x1122334455667788991011121314151617181920212223242526272829303132 + addr = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "1122334455667788991011121314151617181920212223242526272829303132" + ), + nonce=1, + address=Address(0x7AC02E797F450C7EA62753383F618E1903CD6BBA), # noqa: E501 + ) # Source: lll # { (MSTORE 32 0x1234) (EXTCODECOPY 0 0 64) [[0]] (MLOAD 0) [[1]] (MLOAD 32) (MSTORE 96 0x5678) (EXTCODECOPY 64 0 64) [[2]] (MLOAD 64) [[3]] (MLOAD 96)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x20, value=0x1234) - + Op.EXTCODECOPY( - address=0x7AC02E797F450C7EA62753383F618E1903CD6BBA, - dest_offset=0x0, - offset=0x0, - size=0x40, - ) + + Op.EXTCODECOPY(address=addr, dest_offset=0x0, offset=0x0, size=0x40) + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x20)) + Op.MSTORE(offset=0x60, value=0x5678) + Op.EXTCODECOPY( - address=0x4768B5E50B0EBE91AE38D84A47E3179E615F9C40, - dest_offset=0x40, - offset=0x0, - size=0x40, + address=sender, dest_offset=0x40, offset=0x0, size=0x40 ) + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x40)) + Op.SSTORE(key=0x3, value=Op.MLOAD(offset=0x60)) @@ -75,15 +76,6 @@ def test_ext_code_copy_target_range_longer_than_code_tests( nonce=0, address=Address(0x48D8F710AB8CB48F77B602D24696926E31787A17), # noqa: E501 ) - # Source: raw - # 0x1122334455667788991011121314151617181920212223242526272829303132 - addr = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "1122334455667788991011121314151617181920212223242526272829303132" - ), - nonce=1, - address=Address(0x7AC02E797F450C7EA62753383F618E1903CD6BBA), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCodeCopyTest/test_ext_code_copy_tests_paris.py b/tests/ported_static/stCodeCopyTest/test_ext_code_copy_tests_paris.py index 3970d6a1ae3..a3324ff89b2 100644 --- a/tests/ported_static/stCodeCopyTest/test_ext_code_copy_tests_paris.py +++ b/tests/ported_static/stCodeCopyTest/test_ext_code_copy_tests_paris.py @@ -51,6 +51,17 @@ def test_ext_code_copy_tests_paris( ) pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + pre[contract_1] = Account(balance=10) + pre[contract_2] = Account(balance=0, nonce=1) + # Source: raw + # 0x1122334455667788991011121314151617181920212223242526272829303132 + contract_3 = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "1122334455667788991011121314151617181920212223242526272829303132" + ), + nonce=1, + address=Address(0xEEEF5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + ) # Source: lll # { (EXTCODECOPY 0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b 1 10 2) [[2]] (MLOAD 0) (EXTCODECOPY 0xcccf5374fce5edbc8e2a8697c15331677e6ebf0b 1 10 2) [[3]] (MLOAD 0) (EXTCODECOPY 0xdddf5374fce5edbc8e2a8697c15331677e6ebf0b 1 10 2) [[4]] (MLOAD 0) (EXTCODECOPY 0xeeef5374fce5edbc8e2a8697c15331677e6ebf0b 1 10 2) [[5]] (MLOAD 0) (EXTCODECOPY 0xeeef5374fce5edbc8e2a8697c15331677e6ebf0b 1 10 200) [[6]] (MLOAD 0)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -62,31 +73,19 @@ def test_ext_code_copy_tests_paris( ) + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x0)) + Op.EXTCODECOPY( - address=0xCCCF5374FCE5EDBC8E2A8697C15331677E6EBF0B, - dest_offset=0x1, - offset=0xA, - size=0x2, + address=contract_1, dest_offset=0x1, offset=0xA, size=0x2 ) + Op.SSTORE(key=0x3, value=Op.MLOAD(offset=0x0)) + Op.EXTCODECOPY( - address=0xDDDF5374FCE5EDBC8E2A8697C15331677E6EBF0B, - dest_offset=0x1, - offset=0xA, - size=0x2, + address=contract_2, dest_offset=0x1, offset=0xA, size=0x2 ) + Op.SSTORE(key=0x4, value=Op.MLOAD(offset=0x0)) + Op.EXTCODECOPY( - address=0xEEEF5374FCE5EDBC8E2A8697C15331677E6EBF0B, - dest_offset=0x1, - offset=0xA, - size=0x2, + address=contract_3, dest_offset=0x1, offset=0xA, size=0x2 ) + Op.SSTORE(key=0x5, value=Op.MLOAD(offset=0x0)) + Op.EXTCODECOPY( - address=0xEEEF5374FCE5EDBC8E2A8697C15331677E6EBF0B, - dest_offset=0x1, - offset=0xA, - size=0xC8, + address=contract_3, dest_offset=0x1, offset=0xA, size=0xC8 ) + Op.SSTORE(key=0x6, value=Op.MLOAD(offset=0x0)) + Op.STOP, @@ -94,17 +93,6 @@ def test_ext_code_copy_tests_paris( nonce=0, address=Address(0xAAAF5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - pre[contract_1] = Account(balance=10) - pre[contract_2] = Account(balance=0, nonce=1) - # Source: raw - # 0x1122334455667788991011121314151617181920212223242526272829303132 - contract_3 = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "1122334455667788991011121314151617181920212223242526272829303132" - ), - nonce=1, - address=Address(0xEEEF5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCodeSizeLimit/test_codesize_init.py b/tests/ported_static/stCodeSizeLimit/test_codesize_init.py index 29901cff4a5..fbffc7f5b40 100644 --- a/tests/ported_static/stCodeSizeLimit/test_codesize_init.py +++ b/tests/ported_static/stCodeSizeLimit/test_codesize_init.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stCodeSizeLimit/codesizeInitFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_codesize_init( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_codesize_init.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_codesize_init( gas_limit=20000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py b/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py index caa1b2c2744..1ee550de908 100644 --- a/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py +++ b/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -44,7 +43,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_codesize_oog_invalid_size( state_test: StateTestFiller, pre: Alloc, @@ -55,9 +53,7 @@ def test_codesize_oog_invalid_size( ) -> None: """Test_codesize_oog_invalid_size.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -68,8 +64,6 @@ def test_codesize_oog_invalid_size( gas_limit=20000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - tx_data = [ Op.CODECOPY(dest_offset=0x0, offset=0xD, size=0x600D) + Op.RETURN(offset=0x0, size=0x600D), diff --git a/tests/ported_static/stCodeSizeLimit/test_codesize_valid.py b/tests/ported_static/stCodeSizeLimit/test_codesize_valid.py index d47adc32b68..b0a4a1fd5ff 100644 --- a/tests/ported_static/stCodeSizeLimit/test_codesize_valid.py +++ b/tests/ported_static/stCodeSizeLimit/test_codesize_valid.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -44,7 +43,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_codesize_valid( state_test: StateTestFiller, pre: Alloc, @@ -55,9 +53,7 @@ def test_codesize_valid( ) -> None: """Test_codesize_valid.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -68,8 +64,6 @@ def test_codesize_valid( gas_limit=20000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - tx_data = [ Op.CODECOPY(dest_offset=0x0, offset=0xD, size=0x5ED5) + Op.RETURN(offset=0x0, size=0x5ED5), diff --git a/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py b/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py index 87925cd7322..da4d856ee9b 100644 --- a/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py +++ b/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_create_code_size_limit( """Test_create_code_size_limit.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBEBC200) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_create_code_size_limit( gas_limit=20000000, ) - pre[sender] = Account(balance=0xBEBC200) # Source: yul # berlin # { @@ -90,7 +86,6 @@ def test_create_code_size_limit( + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -101,7 +96,7 @@ def test_create_code_size_limit( sender: Account(nonce=1), contract_0: Account( storage={ - 0: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 0: compute_create_address(address=contract_0, nonce=0), 1: 1, }, ), diff --git a/tests/ported_static/stCreate2/test_call_outsize_then_create2_successful_then_returndatasize.py b/tests/ported_static/stCreate2/test_call_outsize_then_create2_successful_then_returndatasize.py index 7d667973bce..3c2976dd8f9 100644 --- a/tests/ported_static/stCreate2/test_call_outsize_then_create2_successful_then_returndatasize.py +++ b/tests/ported_static/stCreate2/test_call_outsize_then_create2_successful_then_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_call_outsize_then_create2_successful_then_returndatasize( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0AABBCCDD5C57F15886F9B263E2F6D2D6C7B5EC6) contract_1 = Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -60,7 +57,6 @@ def test_call_outsize_then_create2_successful_then_returndatasize( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x0AABBCCDD5C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) # Source: lll # { (seq (CALL 0x0900000000 0x0aabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0 0x20) (CREATE2 0 0 (lll (seq (mstore 0 0x112233) (RETURN 0 32) (STOP) ) 0) 0) (SSTORE 0 (RETURNDATASIZE)) (STOP) )} # noqa: E501 @@ -68,7 +64,7 @@ def test_call_outsize_then_create2_successful_then_returndatasize( code=Op.POP( Op.CALL( gas=0x900000000, - address=0xAABBCCDD5C57F15886F9B263E2F6D2D6C7B5EC6, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -89,9 +85,7 @@ def test_call_outsize_then_create2_successful_then_returndatasize( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_call_then_create2_successful_then_returndatasize.py b/tests/ported_static/stCreate2/test_call_then_create2_successful_then_returndatasize.py index f18bfea9374..ff1f8f14b55 100644 --- a/tests/ported_static/stCreate2/test_call_then_create2_successful_then_returndatasize.py +++ b/tests/ported_static/stCreate2/test_call_then_create2_successful_then_returndatasize.py @@ -50,6 +50,7 @@ def test_call_then_create2_successful_then_returndatasize( gas_limit=47244640256, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (seq (MSTORE 0 0x0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff) (RETURN 0 32) (STOP) ) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,7 @@ def test_call_then_create2_successful_then_returndatasize( code=Op.POP( Op.CALL( gas=0x900000000, - address=0xAABBCCDD5C57F15886F9B263E2F6D2D6C7B5EC6, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -91,7 +92,6 @@ def test_call_then_create2_successful_then_returndatasize( nonce=0, address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_create2_bounds.py b/tests/ported_static/stCreate2/test_create2_bounds.py index 1c07f41f5c4..42c5cb34ec6 100644 --- a/tests/ported_static/stCreate2/test_create2_bounds.py +++ b/tests/ported_static/stCreate2/test_create2_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,8 +56,8 @@ def test_create2_bounds( """Test_create2_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -84,10 +83,6 @@ def test_create2_bounds( + Op.STOP, balance=100, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stCreate2/test_create2_bounds2.py b/tests/ported_static/stCreate2/test_create2_bounds2.py index a0c038b8ab3..175cddce83a 100644 --- a/tests/ported_static/stCreate2/test_create2_bounds2.py +++ b/tests/ported_static/stCreate2/test_create2_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,8 +56,8 @@ def test_create2_bounds2( """Test_create2_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -83,10 +82,6 @@ def test_create2_bounds2( + Op.STOP, balance=100, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stCreate2/test_create2_bounds3.py b/tests/ported_static/stCreate2/test_create2_bounds3.py index 520895bbdac..d7c3c6c325f 100644 --- a/tests/ported_static/stCreate2/test_create2_bounds3.py +++ b/tests/ported_static/stCreate2/test_create2_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -63,8 +62,8 @@ def test_create2_bounds3( """Test_create2_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -160,10 +159,6 @@ def test_create2_bounds3( + Op.STOP, balance=100, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stCreate2/test_create2_contract_suicide_during_init_then_store_then_return.py b/tests/ported_static/stCreate2/test_create2_contract_suicide_during_init_then_store_then_return.py index c150ecb451b..faa8f7c9a01 100644 --- a/tests/ported_static/stCreate2/test_create2_contract_suicide_during_init_then_store_then_return.py +++ b/tests/ported_static/stCreate2/test_create2_contract_suicide_during_init_then_store_then_return.py @@ -52,12 +52,26 @@ def test_create2_contract_suicide_during_init_then_store_then_return( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { (MSTORE 0 0x6d64600c6000556000526005601bf36000526001ff) (CREATE2 1 11 21 0) [[0]] 11 (RETURN 18 14) } # noqa: E501 + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, value=0x6D64600C6000556000526005601BF36000526001FF + ) + + Op.POP(Op.CREATE2(value=0x1, offset=0xB, size=0x15, salt=0x0)) + + Op.SSTORE(key=0x0, value=0xB) + + Op.RETURN(offset=0x12, size=0xE) + + Op.STOP, + balance=0xE8D4A51000, + nonce=0, + address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + ) + # Source: lll # { (CALL 150000 0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b 1 0 0 0 32) (SSTORE 1 (MLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x249F0, - address=0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x1, args_offset=0x0, args_size=0x0, @@ -71,20 +85,6 @@ def test_create2_contract_suicide_during_init_then_store_then_return( nonce=0, address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - # Source: lll - # { (MSTORE 0 0x6d64600c6000556000526005601bf36000526001ff) (CREATE2 1 11 21 0) [[0]] 11 (RETURN 18 14) } # noqa: E501 - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, value=0x6D64600C6000556000526005601BF36000526001FF - ) - + Op.POP(Op.CREATE2(value=0x1, offset=0xB, size=0x15, salt=0x0)) - + Op.SSTORE(key=0x0, value=0xB) - + Op.RETURN(offset=0x12, size=0xE) - + Op.STOP, - balance=0xE8D4A51000, - nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata.py b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata.py index 570c4c2ffff..acbce0f8db4 100644 --- a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata.py +++ b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,9 +56,7 @@ def test_create2_oo_gafter_init_code_returndata( """Call RETURNDATASIZE and RETURNDATACOPY (BufferOverrun) after...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -70,7 +67,6 @@ def test_create2_oo_gafter_init_code_returndata( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) [[ 1 ]] (RETURNDATASIZE) (RETURNDATACOPY 0 0 32) [[ 2 ]] (MLOAD 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -82,7 +78,6 @@ def test_create2_oo_gafter_init_code_returndata( + Op.STOP, storage={1: 1, 2: 1}, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata3.py b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata3.py index fdf9fe491f6..075f116015f 100644 --- a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata3.py +++ b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_create2_oo_gafter_init_code_returndata3( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,21 @@ def test_create2_oo_gafter_init_code_returndata3( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) } + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) + + Op.CREATE2(value=0x0, offset=0x12, size=0xE, salt=0x0) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALLCODE (GAS) 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) (RETURNDATACOPY 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=Op.GAS, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,16 +73,6 @@ def test_create2_oo_gafter_init_code_returndata3( + Op.STOP, storage={1: 1}, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) - + Op.CREATE2(value=0x0, offset=0x12, size=0xE, salt=0x0) - + Op.STOP, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata_size.py b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata_size.py index ebdc5af07dd..77799dc86dd 100644 --- a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata_size.py +++ b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_returndata_size.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create2_oo_gafter_init_code_returndata_size( """Calls a contract that runs CREATE2 which deploy a code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create2_oo_gafter_init_code_returndata_size( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x6960016001556001600255600052600a6016f3) (CREATE2 0 13 19 0) (EXP 2 (RETURNDATASIZE)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +55,6 @@ def test_create2_oo_gafter_init_code_returndata_size( + Op.EXP(0x2, Op.RETURNDATASIZE) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert.py b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert.py index 9432309bf4f..7bc66a9747b 100644 --- a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert.py +++ b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert.py @@ -51,12 +51,22 @@ def test_create2_oo_gafter_init_code_revert( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) (REVERT 0 32) } # noqa: E501 + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) + + Op.POP(Op.CREATE2(value=0x0, offset=0x12, size=0xE, salt=0x0)) + + Op.REVERT(offset=0x0, size=0x20) + + Op.STOP, + nonce=0, + address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + ) + # Source: lll # { (CALL (GAS) 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=Op.GAS, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,16 +80,6 @@ def test_create2_oo_gafter_init_code_revert( nonce=0, address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - # Source: lll - # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) (REVERT 0 32) } # noqa: E501 - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) - + Op.POP(Op.CREATE2(value=0x0, offset=0x12, size=0xE, salt=0x0)) - + Op.REVERT(offset=0x0, size=0x20) - + Op.STOP, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert2.py b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert2.py index 6f939986e27..2b48b4cb0bd 100644 --- a/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert2.py +++ b/tests/ported_static/stCreate2/test_create2_oo_gafter_init_code_revert2.py @@ -51,12 +51,22 @@ def test_create2_oo_gafter_init_code_revert2( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) (REVERT 0 32) } # noqa: E501 + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) + + Op.POP(Op.CREATE2(value=0x0, offset=0x12, size=0xE, salt=0x0)) + + Op.REVERT(offset=0x0, size=0x20) + + Op.STOP, + nonce=0, + address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + ) + # Source: lll # { (CALL 33000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x80E8, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -70,16 +80,6 @@ def test_create2_oo_gafter_init_code_revert2( nonce=0, address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - # Source: lll - # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE2 0 18 14 0) (REVERT 0 32) } # noqa: E501 - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) - + Op.POP(Op.CREATE2(value=0x0, offset=0x12, size=0xE, salt=0x0)) - + Op.REVERT(offset=0x0, size=0x20) - + Op.STOP, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_create2_oog_from_call_refunds.py b/tests/ported_static/stCreate2/test_create2_oog_from_call_refunds.py index 22aaf9cea01..41fa4bb6e0d 100644 --- a/tests/ported_static/stCreate2/test_create2_oog_from_call_refunds.py +++ b/tests/ported_static/stCreate2/test_create2_oog_from_call_refunds.py @@ -318,6 +318,76 @@ def test_create2_oog_from_call_refunds( # Source: yul # berlin # { + # // Simple SSTORE to zero to get a refund + # sstore(1, 0) + # } + contract_25 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, + storage={1: 1}, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DEA), # noqa: E501 + ) + # Source: yul + # berlin + # { + # selfdestruct(origin()) + # } + contract_26 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=Op.ORIGIN), + storage={1: 1}, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DED), # noqa: E501 + ) + # Source: yul + # berlin + # { + # mstore(0, 0xff) + # log0(0, 32) + # log1(0, 32, 0xfa) + # log2(0, 32, 0xfa, 0xfb) + # log3(0, 32, 0xfa, 0xfb, 0xfc) + # log4(0, 32, 0xfa, 0xfb, 0xfc, 0xfd) + # } + contract_27 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0xFF) + + Op.LOG0(offset=0x0, size=0x20) + + Op.LOG1(offset=0x0, size=0x20, topic_1=0xFA) + + Op.LOG2(offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB) + + Op.LOG3( + offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB, topic_3=0xFC + ) + + Op.LOG4( + offset=0x0, + size=0x20, + topic_1=0xFA, + topic_2=0xFB, + topic_3=0xFC, + topic_4=0xFD, + ) + + Op.STOP, + storage={1: 1}, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DE0), # noqa: E501 + ) + # Source: yul + # berlin + # { + # sstore(0, 1) + # sstore(0, 0) + # return(0, 1) + # } + contract_28 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.SSTORE(key=Op.DUP1, value=Op.DUP1) + + Op.PUSH1[0x1] + + Op.SWAP1 + + Op.RETURN, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DE1), # noqa: E501 + ) + # Source: yul + # berlin + # { # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 # return(0, 1) @@ -327,7 +397,7 @@ def test_create2_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -349,7 +419,7 @@ def test_create2_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -364,6 +434,31 @@ def test_create2_oog_from_call_refunds( # berlin # { # sstore(0, 1) + # sstore(1, 1) + # pop(delegatecall(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0)) # noqa: E501 + # invalid() + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.SSTORE(key=Op.DUP1, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=Op.GAS, + address=contract_25, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=0x0, + ) + ) + + Op.INVALID, + nonce=0, + address=Address(0x000000000000000000000000000000000000003C), # noqa: E501 + ) + # Source: yul + # berlin + # { + # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 # invalid() # } @@ -372,7 +467,7 @@ def test_create2_oog_from_call_refunds( + Op.POP( Op.CALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -398,7 +493,7 @@ def test_create2_oog_from_call_refunds( + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.DELEGATECALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, @@ -413,15 +508,16 @@ def test_create2_oog_from_call_refunds( # { # sstore(0, 1) # sstore(1, 1) - # pop(delegatecall(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0)) # noqa: E501 + # pop(callcode(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 # return(0, 5000) # } - contract_8 = pre.deploy_contract( # noqa: F841 + contract_11 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.DELEGATECALL( + + Op.CALLCODE( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, + value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, @@ -429,7 +525,7 @@ def test_create2_oog_from_call_refunds( ) + Op.RETURN(offset=0x0, size=0x1388), nonce=0, - address=Address(0x000000000000000000000000000000000000003B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000004B), # noqa: E501 ) # Source: yul # berlin @@ -437,49 +533,22 @@ def test_create2_oog_from_call_refunds( # sstore(0, 1) # sstore(1, 1) # pop(delegatecall(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0)) # noqa: E501 - # invalid() - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xC0DEA, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=0x0, - ) - ) - + Op.INVALID, - nonce=0, - address=Address(0x000000000000000000000000000000000000003C), # noqa: E501 - ) - # Source: yul - # berlin - # { - # sstore(0, 1) - # sstore(1, 1) - # pop(callcode(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 1) - # let noOpt := msize() + # return(0, 5000) # } - contract_10 = pre.deploy_contract( # noqa: F841 + contract_8 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.CALLCODE( + + Op.DELEGATECALL( gas=Op.GAS, - address=0xC0DEA, - value=Op.DUP1, + address=contract_25, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1), + + Op.RETURN(offset=0x0, size=0x1388), nonce=0, - address=Address(0x000000000000000000000000000000000000004A), # noqa: E501 + address=Address(0x000000000000000000000000000000000000003B), # noqa: E501 ) # Source: yul # berlin @@ -487,23 +556,24 @@ def test_create2_oog_from_call_refunds( # sstore(0, 1) # sstore(1, 1) # pop(callcode(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 5000) + # return(0, 1) + # let noOpt := msize() # } - contract_11 = pre.deploy_contract( # noqa: F841 + contract_10 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.CALLCODE( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1388), + + Op.RETURN(offset=0x0, size=0x1), nonce=0, - address=Address(0x000000000000000000000000000000000000004B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000004A), # noqa: E501 ) # Source: yul # berlin @@ -519,7 +589,7 @@ def test_create2_oog_from_call_refunds( + Op.POP( Op.CALLCODE( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -536,45 +606,45 @@ def test_create2_oog_from_call_refunds( # { # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deD, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 1) - # let noOpt := msize() + # return(0, 5000) # } - contract_13 = pre.deploy_contract( # noqa: F841 + contract_14 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DED, + address=contract_26, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1), + + Op.RETURN(offset=0x0, size=0x1388), nonce=0, - address=Address(0x000000000000000000000000000000000000005A), # noqa: E501 + address=Address(0x000000000000000000000000000000000000005B), # noqa: E501 ) # Source: yul # berlin # { # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deD, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 5000) + # return(0, 1) + # let noOpt := msize() # } - contract_14 = pre.deploy_contract( # noqa: F841 + contract_13 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DED, + address=contract_26, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1388), + + Op.RETURN(offset=0x0, size=0x1), nonce=0, - address=Address(0x000000000000000000000000000000000000005B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000005A), # noqa: E501 ) # Source: yul # berlin @@ -588,7 +658,7 @@ def test_create2_oog_from_call_refunds( + Op.POP( Op.CALL( gas=Op.GAS, - address=0xC0DED, + address=contract_26, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -612,7 +682,7 @@ def test_create2_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DE0, + address=contract_27, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -634,7 +704,7 @@ def test_create2_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DE0, + address=contract_27, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -657,7 +727,7 @@ def test_create2_oog_from_call_refunds( + Op.POP( Op.CALL( gas=Op.GAS, - address=0xC0DE0, + address=contract_27, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -678,44 +748,10 @@ def test_create2_oog_from_call_refunds( # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create(0, 0, initcodelength)) - # return(add(initcodelength, 1), 1) - # let noOptimization := msize() - # } - contract_19 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x1] - + Op.PUSH1[0x0] - + Op.SSTORE(key=Op.DUP2, value=Op.DUP2) - + Op.SSTORE(key=Op.DUP3, value=Op.DUP1) - + Op.DUP2 - + Op.SWAP1 - + Op.PUSH3[0xC0DE1] - + Op.EXTCODESIZE(address=Op.DUP1) - + Op.SWAP2 - + Op.DUP3 - + Op.SWAP2 - + Op.DUP2 - + Op.SWAP1 - + Op.EXTCODECOPY - + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) - + Op.ADD - + Op.RETURN, - nonce=0, - address=Address(0x000000000000000000000000000000000000007A), # noqa: E501 - ) - # Source: yul - # berlin - # { - # sstore(0, 1) - # sstore(1, 1) - # sstore(1, 0) - # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 - # let initcodelength := extcodesize(initcodeaddr) - # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create(0, 0, initcodelength)) + # pop(create2(0, 0, initcodelength, 0)) # return(add(initcodelength, 1), 5000) # } - contract_20 = pre.deploy_contract( # noqa: F841 + contract_23 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) @@ -729,42 +765,13 @@ def test_create2_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) + + Op.POP( + Op.CREATE2(value=Op.DUP1, offset=Op.DUP2, size=Op.DUP2, salt=0x0) + ) + Op.ADD + Op.RETURN, nonce=0, - address=Address(0x000000000000000000000000000000000000007B), # noqa: E501 - ) - # Source: yul - # berlin - # { - # sstore(0, 1) - # sstore(1, 1) - # sstore(1, 0) - # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 - # let initcodelength := extcodesize(initcodeaddr) - # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create(0, 0, initcodelength)) - # invalid() - # } - contract_21 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.SSTORE(key=0x1, value=0x0) - + Op.PUSH1[0x0] - + Op.PUSH3[0xC0DE1] - + Op.DUP2 - + Op.EXTCODESIZE(address=Op.DUP2) - + Op.SWAP3 - + Op.DUP4 - + Op.SWAP3 - + Op.EXTCODECOPY - + Op.PUSH1[0x0] - + Op.DUP1 - + Op.POP(Op.CREATE) - + Op.INVALID, - nonce=0, - address=Address(0x000000000000000000000000000000000000007C), # noqa: E501 + address=Address(0x000000000000000000000000000000000000008B), # noqa: E501 ) # Source: yul # berlin @@ -812,9 +819,41 @@ def test_create2_oog_from_call_refunds( # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) # pop(create2(0, 0, initcodelength, 0)) + # invalid() + # } + contract_24 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.SSTORE(key=Op.DUP1, value=0x1) + + Op.SSTORE(key=0x1, value=0x0) + + Op.PUSH1[0x0] + + Op.DUP1 + + Op.PUSH3[0xC0DE1] + + Op.DUP2 + + Op.EXTCODESIZE(address=Op.DUP2) + + Op.SWAP3 + + Op.DUP4 + + Op.SWAP3 + + Op.EXTCODECOPY + + Op.DUP2 + + Op.DUP1 + + Op.POP(Op.CREATE2) + + Op.INVALID, + nonce=0, + address=Address(0x000000000000000000000000000000000000008C), # noqa: E501 + ) + # Source: yul + # berlin + # { + # sstore(0, 1) + # sstore(1, 1) + # sstore(1, 0) + # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 + # let initcodelength := extcodesize(initcodeaddr) + # extcodecopy(initcodeaddr, 0, 0, initcodelength) + # pop(create(0, 0, initcodelength)) # return(add(initcodelength, 1), 5000) # } - contract_23 = pre.deploy_contract( # noqa: F841 + contract_20 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) @@ -828,13 +867,11 @@ def test_create2_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.POP( - Op.CREATE2(value=Op.DUP1, offset=Op.DUP2, size=Op.DUP2, salt=0x0) - ) + + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) + Op.ADD + Op.RETURN, nonce=0, - address=Address(0x000000000000000000000000000000000000008B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000007B), # noqa: E501 ) # Source: yul # berlin @@ -845,15 +882,14 @@ def test_create2_oog_from_call_refunds( # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create2(0, 0, initcodelength, 0)) + # pop(create(0, 0, initcodelength)) # invalid() # } - contract_24 = pre.deploy_contract( # noqa: F841 + contract_21 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) + Op.PUSH1[0x0] - + Op.DUP1 + Op.PUSH3[0xC0DE1] + Op.DUP2 + Op.EXTCODESIZE(address=Op.DUP2) @@ -861,82 +897,46 @@ def test_create2_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.DUP2 + + Op.PUSH1[0x0] + Op.DUP1 - + Op.POP(Op.CREATE2) + + Op.POP(Op.CREATE) + Op.INVALID, nonce=0, - address=Address(0x000000000000000000000000000000000000008C), # noqa: E501 - ) - # Source: yul - # berlin - # { - # // Simple SSTORE to zero to get a refund - # sstore(1, 0) - # } - contract_25 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, - storage={1: 1}, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DEA), # noqa: E501 - ) - # Source: yul - # berlin - # { - # selfdestruct(origin()) - # } - contract_26 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=Op.ORIGIN), - storage={1: 1}, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DED), # noqa: E501 - ) - # Source: yul - # berlin - # { - # mstore(0, 0xff) - # log0(0, 32) - # log1(0, 32, 0xfa) - # log2(0, 32, 0xfa, 0xfb) - # log3(0, 32, 0xfa, 0xfb, 0xfc) - # log4(0, 32, 0xfa, 0xfb, 0xfc, 0xfd) - # } - contract_27 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0xFF) - + Op.LOG0(offset=0x0, size=0x20) - + Op.LOG1(offset=0x0, size=0x20, topic_1=0xFA) - + Op.LOG2(offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB) - + Op.LOG3( - offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB, topic_3=0xFC - ) - + Op.LOG4( - offset=0x0, - size=0x20, - topic_1=0xFA, - topic_2=0xFB, - topic_3=0xFC, - topic_4=0xFD, - ) - + Op.STOP, - storage={1: 1}, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DE0), # noqa: E501 + address=Address(0x000000000000000000000000000000000000007C), # noqa: E501 ) # Source: yul # berlin # { # sstore(0, 1) - # sstore(0, 0) - # return(0, 1) + # sstore(1, 1) + # sstore(1, 0) + # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 + # let initcodelength := extcodesize(initcodeaddr) + # extcodecopy(initcodeaddr, 0, 0, initcodelength) + # pop(create(0, 0, initcodelength)) + # return(add(initcodelength, 1), 1) + # let noOptimization := msize() # } - contract_28 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.SSTORE(key=Op.DUP1, value=Op.DUP1) - + Op.PUSH1[0x1] + contract_19 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x1] + + Op.PUSH1[0x0] + + Op.SSTORE(key=Op.DUP2, value=Op.DUP2) + + Op.SSTORE(key=Op.DUP3, value=Op.DUP1) + + Op.DUP2 + Op.SWAP1 + + Op.PUSH3[0xC0DE1] + + Op.EXTCODESIZE(address=Op.DUP1) + + Op.SWAP2 + + Op.DUP3 + + Op.SWAP2 + + Op.DUP2 + + Op.SWAP1 + + Op.EXTCODECOPY + + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) + + Op.ADD + Op.RETURN, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DE1), # noqa: E501 + nonce=0, + address=Address(0x000000000000000000000000000000000000007A), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stCreate2/test_create2_smart_init_code.py b/tests/ported_static/stCreate2/test_create2_smart_init_code.py index 54d4808eb37..0d5a967638e 100644 --- a/tests/ported_static/stCreate2/test_create2_smart_init_code.py +++ b/tests/ported_static/stCreate2/test_create2_smart_init_code.py @@ -74,6 +74,7 @@ def test_create2_smart_init_code( gas_limit=47244640256, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (MSTORE 0 0x600060015414601157600a6000f3601a565b60016001556001ff5b) [[1]](CREATE2 1 5 27 0) [[2]](CREATE2 1 5 27 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -114,7 +115,6 @@ def test_create2_smart_init_code( nonce=0, address=Address(0x1F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) # Source: lll # { (CALL (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } contract_2 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stCreate2/test_create2call_precompiles.py b/tests/ported_static/stCreate2/test_create2call_precompiles.py index b5cad298253..969be62840e 100644 --- a/tests/ported_static/stCreate2/test_create2call_precompiles.py +++ b/tests/ported_static/stCreate2/test_create2call_precompiles.py @@ -190,11 +190,7 @@ def test_create2call_precompiles( "result": { sender: Account(nonce=1), Address(0xF68E26002DB0F9CA9B54367C57C25E474C581622): Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, + storage={0: sender, 1: 1, 2: 1} ), }, }, diff --git a/tests/ported_static/stCreate2/test_create2check_fields_in_initcode.py b/tests/ported_static/stCreate2/test_create2check_fields_in_initcode.py index e54ba4b04b5..4f883160226 100644 --- a/tests/ported_static/stCreate2/test_create2check_fields_in_initcode.py +++ b/tests/ported_static/stCreate2/test_create2check_fields_in_initcode.py @@ -136,6 +136,68 @@ def test_create2check_fields_in_initcode( address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll + # { (CREATE2 0 0 (lll (seq [[0]] (ADDRESS) [[1]] (BALANCE (ADDRESS)) [[2]] (ORIGIN) [[3]] (CALLER) [[4]] (CALLVALUE) [[5]] (CALLDATASIZE) [[6]] (CODESIZE) [[7]] (GASPRICE) (STOP) ) 0) 0) (STOP) } # noqa: E501 + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.PUSH1[0x23] + + Op.CODECOPY(dest_offset=0x0, offset=0x13, size=Op.DUP1) + + Op.PUSH1[0x0] * 2 + + Op.POP(Op.CREATE2) + + Op.STOP * 2 + + Op.INVALID + + Op.SSTORE(key=0x0, value=Op.ADDRESS) + + Op.SSTORE(key=0x1, value=Op.BALANCE(address=Op.ADDRESS)) + + Op.SSTORE(key=0x2, value=Op.ORIGIN) + + Op.SSTORE(key=0x3, value=Op.CALLER) + + Op.SSTORE(key=0x4, value=Op.CALLVALUE) + + Op.SSTORE(key=0x5, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x6, value=Op.CODESIZE) + + Op.SSTORE(key=0x7, value=Op.GASPRICE) + + Op.STOP * 2, + nonce=0, + address=Address(0xF000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll + # { (CREATE2 0 0 (lll (seq [0] (ADDRESS) [32] (BALANCE (ADDRESS)) [64] (ORIGIN) [96] (CALLER) [128] (CALLVALUE) [160] (CALLDATASIZE) [192] (CODESIZE) [224] (GASPRICE) (RETURN 0 256) (STOP) ) 0) 0) } # noqa: E501 + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.PUSH1[0x29] + + Op.CODECOPY(dest_offset=0x0, offset=0x11, size=Op.DUP1) + + Op.PUSH1[0x0] * 2 + + Op.CREATE2 + + Op.STOP + + Op.INVALID + + Op.MSTORE(offset=0x0, value=Op.ADDRESS) + + Op.MSTORE(offset=0x20, value=Op.BALANCE(address=Op.ADDRESS)) + + Op.MSTORE(offset=0x40, value=Op.ORIGIN) + + Op.MSTORE(offset=0x60, value=Op.CALLER) + + Op.MSTORE(offset=0x80, value=Op.CALLVALUE) + + Op.MSTORE(offset=0xA0, value=Op.CALLDATASIZE) + + Op.MSTORE(offset=0xC0, value=Op.CODESIZE) + + Op.MSTORE(offset=0xE0, value=Op.GASPRICE) + + Op.RETURN(offset=0x0, size=0x100) + + Op.STOP * 2, + nonce=0, + address=Address(0xF200000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll + # { (DELEGATECALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0) (STOP) } # noqa: E501 + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.DELEGATECALL( + gas=Op.GAS, + address=0xF000000000000000000000000000000000000000, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + ) + + Op.STOP * 2, + nonce=0, + address=Address(0x3000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll # { (CALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0 0) } contract_1 = pre.deploy_contract( # noqa: F841 code=Op.CALL( @@ -152,20 +214,19 @@ def test_create2check_fields_in_initcode( address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # { (CREATE2 0 0 (lll (seq (CALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0 0) (STOP) ) 0) 0) (STOP) } # noqa: E501 - contract_2 = pre.deploy_contract( # noqa: F841 + # { (CREATE2 0 0 (lll (seq (DELEGATECALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0) (STOP) ) 0) 0) (STOP) } # noqa: E501 + contract_6 = pre.deploy_contract( # noqa: F841 code=Op.PUSH1[0x0] - + Op.PUSH1[0x24] + + Op.PUSH1[0x22] + Op.CODECOPY(dest_offset=0x0, offset=0x13, size=Op.DUP1) + Op.PUSH1[0x0] * 2 + Op.POP(Op.CREATE2) + Op.STOP * 2 + Op.INVALID + Op.POP( - Op.CALL( + Op.DELEGATECALL( gas=Op.GAS, address=0xF000000000000000000000000000000000000000, - value=0x0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -174,7 +235,7 @@ def test_create2check_fields_in_initcode( ) + Op.STOP * 2, nonce=0, - address=Address(0x1100000000000000000000000000000000000000), # noqa: E501 + address=Address(0x3300000000000000000000000000000000000000), # noqa: E501 ) # Source: lll # { (CALLCODE (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0 0) } @@ -193,8 +254,8 @@ def test_create2check_fields_in_initcode( address=Address(0x2000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # { (CREATE2 0 0 (lll (seq (CALLCODE (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0 0) (STOP) ) 0) 0) (STOP) } # noqa: E501 - contract_4 = pre.deploy_contract( # noqa: F841 + # { (CREATE2 0 0 (lll (seq (CALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0 0) (STOP) ) 0) 0) (STOP) } # noqa: E501 + contract_2 = pre.deploy_contract( # noqa: F841 code=Op.PUSH1[0x0] + Op.PUSH1[0x24] + Op.CODECOPY(dest_offset=0x0, offset=0x13, size=Op.DUP1) @@ -203,7 +264,7 @@ def test_create2check_fields_in_initcode( + Op.STOP * 2 + Op.INVALID + Op.POP( - Op.CALLCODE( + Op.CALL( gas=Op.GAS, address=0xF000000000000000000000000000000000000000, value=0x0, @@ -215,39 +276,23 @@ def test_create2check_fields_in_initcode( ) + Op.STOP * 2, nonce=0, - address=Address(0x2200000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { (DELEGATECALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0) (STOP) } # noqa: E501 - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xF000000000000000000000000000000000000000, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - ) - + Op.STOP * 2, - nonce=0, - address=Address(0x3000000000000000000000000000000000000000), # noqa: E501 + address=Address(0x1100000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # { (CREATE2 0 0 (lll (seq (DELEGATECALL (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0) (STOP) ) 0) 0) (STOP) } # noqa: E501 - contract_6 = pre.deploy_contract( # noqa: F841 + # { (CREATE2 0 0 (lll (seq (CALLCODE (GAS) 0xf000000000000000000000000000000000000000 0 0 0 0 0) (STOP) ) 0) 0) (STOP) } # noqa: E501 + contract_4 = pre.deploy_contract( # noqa: F841 code=Op.PUSH1[0x0] - + Op.PUSH1[0x22] + + Op.PUSH1[0x24] + Op.CODECOPY(dest_offset=0x0, offset=0x13, size=Op.DUP1) + Op.PUSH1[0x0] * 2 + Op.POP(Op.CREATE2) + Op.STOP * 2 + Op.INVALID + Op.POP( - Op.DELEGATECALL( + Op.CALLCODE( gas=Op.GAS, address=0xF000000000000000000000000000000000000000, + value=0x0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -256,25 +301,7 @@ def test_create2check_fields_in_initcode( ) + Op.STOP * 2, nonce=0, - address=Address(0x3300000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { (STATICCALL (GAS) 0xf200000000000000000000000000000000000000 0 0 0 256) [[10]] (MLOAD 0) } # noqa: E501 - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xF200000000000000000000000000000000000000, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x100, - ) - ) - + Op.SSTORE(key=0xA, value=Op.MLOAD(offset=0x0)) - + Op.STOP, - nonce=0, - address=Address(0x4000000000000000000000000000000000000000), # noqa: E501 + address=Address(0x2200000000000000000000000000000000000000), # noqa: E501 ) # Source: lll # { (CREATE2 0 0 (lll (seq (STATICCALL (GAS) 0xf200000000000000000000000000000000000000 0 0 0 256) [[10]] (MLOAD 0) (STOP) ) 0) 0 ) } # noqa: E501 @@ -302,49 +329,22 @@ def test_create2check_fields_in_initcode( address=Address(0x4400000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # { (CREATE2 0 0 (lll (seq [[0]] (ADDRESS) [[1]] (BALANCE (ADDRESS)) [[2]] (ORIGIN) [[3]] (CALLER) [[4]] (CALLVALUE) [[5]] (CALLDATASIZE) [[6]] (CODESIZE) [[7]] (GASPRICE) (STOP) ) 0) 0) (STOP) } # noqa: E501 - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.PUSH1[0x23] - + Op.CODECOPY(dest_offset=0x0, offset=0x13, size=Op.DUP1) - + Op.PUSH1[0x0] * 2 - + Op.POP(Op.CREATE2) - + Op.STOP * 2 - + Op.INVALID - + Op.SSTORE(key=0x0, value=Op.ADDRESS) - + Op.SSTORE(key=0x1, value=Op.BALANCE(address=Op.ADDRESS)) - + Op.SSTORE(key=0x2, value=Op.ORIGIN) - + Op.SSTORE(key=0x3, value=Op.CALLER) - + Op.SSTORE(key=0x4, value=Op.CALLVALUE) - + Op.SSTORE(key=0x5, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x6, value=Op.CODESIZE) - + Op.SSTORE(key=0x7, value=Op.GASPRICE) - + Op.STOP * 2, - nonce=0, - address=Address(0xF000000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { (CREATE2 0 0 (lll (seq [0] (ADDRESS) [32] (BALANCE (ADDRESS)) [64] (ORIGIN) [96] (CALLER) [128] (CALLVALUE) [160] (CALLDATASIZE) [192] (CODESIZE) [224] (GASPRICE) (RETURN 0 256) (STOP) ) 0) 0) } # noqa: E501 - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.PUSH1[0x29] - + Op.CODECOPY(dest_offset=0x0, offset=0x11, size=Op.DUP1) - + Op.PUSH1[0x0] * 2 - + Op.CREATE2 - + Op.STOP - + Op.INVALID - + Op.MSTORE(offset=0x0, value=Op.ADDRESS) - + Op.MSTORE(offset=0x20, value=Op.BALANCE(address=Op.ADDRESS)) - + Op.MSTORE(offset=0x40, value=Op.ORIGIN) - + Op.MSTORE(offset=0x60, value=Op.CALLER) - + Op.MSTORE(offset=0x80, value=Op.CALLVALUE) - + Op.MSTORE(offset=0xA0, value=Op.CALLDATASIZE) - + Op.MSTORE(offset=0xC0, value=Op.CODESIZE) - + Op.MSTORE(offset=0xE0, value=Op.GASPRICE) - + Op.RETURN(offset=0x0, size=0x100) - + Op.STOP * 2, + # { (STATICCALL (GAS) 0xf200000000000000000000000000000000000000 0 0 0 256) [[10]] (MLOAD 0) } # noqa: E501 + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=0xF200000000000000000000000000000000000000, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x100, + ) + ) + + Op.SSTORE(key=0xA, value=Op.MLOAD(offset=0x0)) + + Op.STOP, nonce=0, - address=Address(0xF200000000000000000000000000000000000000), # noqa: E501 + address=Address(0x4000000000000000000000000000000000000000), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -356,8 +356,8 @@ def test_create2check_fields_in_initcode( storage={ 0: 0xDAF9F53E732F21FE517E624B6DFE92DC8D0E51E0, 1: 0, - 2: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 3: 0xF000000000000000000000000000000000000000, + 2: sender, + 3: contract_9, 4: 0, 5: 0, 6: 35, @@ -377,8 +377,8 @@ def test_create2check_fields_in_initcode( storage={ 0: 0xDFAD1C567F12D848FABB8D9D8872C42E7AA81E95, 1: 0, - 2: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 3: 0x2000000000000000000000000000000000000000, + 2: sender, + 3: contract_3, 4: 0, 5: 0, 6: 35, @@ -398,8 +398,8 @@ def test_create2check_fields_in_initcode( storage={ 0: 0x3FF16480055C6CCC070257C61FA902448F4AE111, 1: 0, - 2: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 3: 0x3000000000000000000000000000000000000000, + 2: sender, + 3: contract_5, 4: 0, 5: 0, 6: 35, @@ -424,7 +424,7 @@ def test_create2check_fields_in_initcode( storage={ 0: 0x7CE21E3C16D63738CBBB697C919555C910504278, 1: 0, - 2: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2: sender, 3: 0x9D25FBABDEB081B9ECD0645B9B6ABA8C7EB3821D, 4: 0, 5: 0, @@ -445,7 +445,7 @@ def test_create2check_fields_in_initcode( storage={ 0: 0xBB1B88EA45D33397F45583CA612ADEA3EB267318, 1: 0, - 2: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2: sender, 3: 0x45DDE7FBF9F1CF09E18C4E584BA93C82E83C8898, 4: 0, 5: 0, diff --git a/tests/ported_static/stCreate2/test_returndatacopy_0_0_following_successful_create.py b/tests/ported_static/stCreate2/test_returndatacopy_0_0_following_successful_create.py index 15bf5bc6a66..dcf711122d6 100644 --- a/tests/ported_static/stCreate2/test_returndatacopy_0_0_following_successful_create.py +++ b/tests/ported_static/stCreate2/test_returndatacopy_0_0_following_successful_create.py @@ -49,6 +49,7 @@ def test_returndatacopy_0_0_following_successful_create( gas_limit=47244640256, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (create2 0 0 (lll (seq (SSTORE 0 1) (STOP) ) 0) 0) (RETURNDATACOPY 0 0 0) (SSTORE 0 0) (STOP) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_returndatacopy_0_0_following_successful_create( nonce=0, address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_returndatacopy_after_failing_create.py b/tests/ported_static/stCreate2/test_returndatacopy_after_failing_create.py index 234eee3caf2..e08efa80d4d 100644 --- a/tests/ported_static/stCreate2/test_returndatacopy_after_failing_create.py +++ b/tests/ported_static/stCreate2/test_returndatacopy_after_failing_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_returndatacopy_after_failing_create( """Returndatacopy after failing create case due to 0xfd code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,9 +55,7 @@ def test_returndatacopy_after_failing_create( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_returndatacopy_following_create.py b/tests/ported_static/stCreate2/test_returndatacopy_following_create.py index 8660d373803..323a9dda6c8 100644 --- a/tests/ported_static/stCreate2/test_returndatacopy_following_create.py +++ b/tests/ported_static/stCreate2/test_returndatacopy_following_create.py @@ -74,6 +74,7 @@ def test_returndatacopy_following_create( gas_limit=47244640256, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (CALL (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -129,7 +130,6 @@ def test_returndatacopy_following_create( nonce=0, address=Address(0x1F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreate2/test_returndatacopy_following_revert_in_create.py b/tests/ported_static/stCreate2/test_returndatacopy_following_revert_in_create.py index b7b35d77683..f1a7794a0bc 100644 --- a/tests/ported_static/stCreate2/test_returndatacopy_following_revert_in_create.py +++ b/tests/ported_static/stCreate2/test_returndatacopy_following_revert_in_create.py @@ -49,6 +49,7 @@ def test_returndatacopy_following_revert_in_create( gas_limit=47244640256, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (seq (CREATE2 0 0 (lll (seq (MSTORE 0 0x0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff) (REVERT 0 32) (STOP) ) 0) 0) (RETURNDATACOPY 0 0 32) (SSTORE 0 (MLOAD 0)) (STOP) )} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_returndatacopy_following_revert_in_create( nonce=0, address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_returndatacopy_following_successful_create.py b/tests/ported_static/stCreate2/test_returndatacopy_following_successful_create.py index fae60ef6167..aa1c2c33f7a 100644 --- a/tests/ported_static/stCreate2/test_returndatacopy_following_successful_create.py +++ b/tests/ported_static/stCreate2/test_returndatacopy_following_successful_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_returndatacopy_following_successful_create( """Returndatacopy_following_successful_create for CREATE2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -64,9 +61,7 @@ def test_returndatacopy_following_successful_create( + Op.STOP * 2, storage={0: 2}, nonce=0, - address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_returndatasize_following_successful_create.py b/tests/ported_static/stCreate2/test_returndatasize_following_successful_create.py index 17fc295caa0..7d2fd9b8afc 100644 --- a/tests/ported_static/stCreate2/test_returndatasize_following_successful_create.py +++ b/tests/ported_static/stCreate2/test_returndatasize_following_successful_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_returndatasize_following_successful_create( """Returndatasize_following_successful_create for create2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_returndatasize_following_successful_create( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreate2/test_revert_depth_create2_oog.py b/tests/ported_static/stCreate2/test_revert_depth_create2_oog.py index 00db52a17f2..293fe888c7a 100644 --- a/tests/ported_static/stCreate2/test_revert_depth_create2_oog.py +++ b/tests/ported_static/stCreate2/test_revert_depth_create2_oog.py @@ -111,6 +111,16 @@ def test_revert_depth_create2_oog( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x8) + + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) + + Op.SSTORE(key=0x3, value=0xC) + + Op.STOP, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll # { [[0]] 1 [[1]] (CALL (CALLDATALOAD 0) 0xb000000000000000000000000000000000000000 0 0 0 0 0) [[4]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -118,7 +128,7 @@ def test_revert_depth_create2_oog( key=0x1, value=Op.CALL( gas=Op.CALLDATALOAD(offset=0x0), - address=0xB000000000000000000000000000000000000000, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -132,16 +142,6 @@ def test_revert_depth_create2_oog( nonce=54, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - # Source: lll - # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x8) - + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) - + Op.SSTORE(key=0x3, value=0xC) - + Op.STOP, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreate2/test_revert_depth_create2_oog_berlin.py b/tests/ported_static/stCreate2/test_revert_depth_create2_oog_berlin.py index d2e3e235f10..e55f6b2a6ef 100644 --- a/tests/ported_static/stCreate2/test_revert_depth_create2_oog_berlin.py +++ b/tests/ported_static/stCreate2/test_revert_depth_create2_oog_berlin.py @@ -111,6 +111,16 @@ def test_revert_depth_create2_oog_berlin( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x8) + + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) + + Op.SSTORE(key=0x3, value=0xC) + + Op.STOP, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll # { [[0]] 1 [[1]] (CALL (CALLDATALOAD 0) 0xb000000000000000000000000000000000000000 0 0 0 0 0) [[4]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -118,7 +128,7 @@ def test_revert_depth_create2_oog_berlin( key=0x1, value=Op.CALL( gas=Op.CALLDATALOAD(offset=0x0), - address=0xB000000000000000000000000000000000000000, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -132,16 +142,6 @@ def test_revert_depth_create2_oog_berlin( nonce=54, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - # Source: lll - # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x8) - + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) - + Op.SSTORE(key=0x3, value=0xC) - + Op.STOP, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreate2/test_revert_depth_create_address_collision.py b/tests/ported_static/stCreate2/test_revert_depth_create_address_collision.py index 3f58cf63110..3cd45030619 100644 --- a/tests/ported_static/stCreate2/test_revert_depth_create_address_collision.py +++ b/tests/ported_static/stCreate2/test_revert_depth_create_address_collision.py @@ -111,6 +111,16 @@ def test_revert_depth_create_address_collision( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x8) + + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) + + Op.SSTORE(key=0x3, value=0xC) + + Op.STOP, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll # { [[0]] 1 [[1]] (CALL (CALLDATALOAD 0) 0xb000000000000000000000000000000000000000 0 0 0 0 0) [[4]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -132,16 +142,6 @@ def test_revert_depth_create_address_collision( nonce=54, address=Address(0x3E180B1862F9D158ABB5E519A6D8605540C23682), # noqa: E501 ) - # Source: lll - # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x8) - + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) - + Op.SSTORE(key=0x3, value=0xC) - + Op.STOP, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreate2/test_revert_depth_create_address_collision_berlin.py b/tests/ported_static/stCreate2/test_revert_depth_create_address_collision_berlin.py index 1ab423c2600..72fca5e4127 100644 --- a/tests/ported_static/stCreate2/test_revert_depth_create_address_collision_berlin.py +++ b/tests/ported_static/stCreate2/test_revert_depth_create_address_collision_berlin.py @@ -113,6 +113,16 @@ def test_revert_depth_create_address_collision_berlin( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x8) + + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) + + Op.SSTORE(key=0x3, value=0xC) + + Op.STOP, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll # { [[0]] 1 [[1]] (CALL (CALLDATALOAD 0) 0xb000000000000000000000000000000000000000 0 0 0 0 0) [[4]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -134,16 +144,6 @@ def test_revert_depth_create_address_collision_berlin( nonce=54, address=Address(0x3E180B1862F9D158ABB5E519A6D8605540C23682), # noqa: E501 ) - # Source: lll - # { [[2]] 8 (CREATE2 0 0 0 0) [[3]] 12} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x8) - + Op.POP(Op.CREATE2(value=0x0, offset=0x0, size=0x0, salt=0x0)) - + Op.SSTORE(key=0x3, value=0xC) - + Op.STOP, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreate2/test_revert_opcode_create.py b/tests/ported_static/stCreate2/test_revert_opcode_create.py index 8aa0d0e884f..73c21783789 100644 --- a/tests/ported_static/stCreate2/test_revert_opcode_create.py +++ b/tests/ported_static/stCreate2/test_revert_opcode_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_revert_opcode_create( """RevertOpcodeCreate for CREATE2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -72,7 +69,6 @@ def test_revert_opcode_create( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x600160005560016000fd6011600155 ) [[1]](CREATE2 1 17 15 0) [[0]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -85,7 +81,6 @@ def test_revert_opcode_create( + Op.STOP, balance=1, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stCreate2/test_revert_opcode_in_create_returns_create2.py b/tests/ported_static/stCreate2/test_revert_opcode_in_create_returns_create2.py index 80922bb0655..6ead4a1821d 100644 --- a/tests/ported_static/stCreate2/test_revert_opcode_in_create_returns_create2.py +++ b/tests/ported_static/stCreate2/test_revert_opcode_in_create_returns_create2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_revert_opcode_in_create_returns_create2( """RevertOpcodeInCreateReturns for CREATE2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -63,9 +60,7 @@ def test_revert_opcode_in_create_returns_create2( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stCreateTest/test_code_in_constructor.py b/tests/ported_static/stCreateTest/test_code_in_constructor.py index 0afb00eae1c..1a33dbe1033 100644 --- a/tests/ported_static/stCreateTest/test_code_in_constructor.py +++ b/tests/ported_static/stCreateTest/test_code_in_constructor.py @@ -16,6 +16,7 @@ Hash, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.forks import Fork from execution_testing.specs.static_state.expect_section import ( @@ -74,6 +75,7 @@ def test_code_in_constructor( gas_limit=4294967296, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # (def 'counterLoc 0) @@ -157,7 +159,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -169,7 +171,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -181,7 +183,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -193,7 +195,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -206,7 +208,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -221,7 +223,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -233,7 +235,7 @@ def test_code_in_constructor( + Op.POP( Op.CALL( gas=0xFFFFFF, - address=0xDA7A, + address=contract_0, value=0x0, args_offset=0x260, args_size=0x20, @@ -247,7 +249,6 @@ def test_code_in_constructor( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { @@ -258,7 +259,7 @@ def test_code_in_constructor( storage={ 0: 8, 1: 10, - 2: 0x8AF6A7AF30D840BA137E8F3F34D54CFB8BEBA6E2, + 2: compute_create_address(address=contract_1, nonce=0), 3: 262, 4: 0, 5: 0x610100610100610100395861026052600060006020610260600061DA7A62FFFF, # noqa: E501 diff --git a/tests/ported_static/stCreateTest/test_create2_refund_ef.py b/tests/ported_static/stCreateTest/test_create2_refund_ef.py index e164c202495..f2b5c529ecc 100644 --- a/tests/ported_static/stCreateTest/test_create2_refund_ef.py +++ b/tests/ported_static/stCreateTest/test_create2_refund_ef.py @@ -92,7 +92,7 @@ def test_create2_refund_ef( + Op.POP( Op.CALL( gas=0xC350, - address=0x5EF94D, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, diff --git a/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py b/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py index f37fd4efd34..56b4a02b6c9 100644 --- a/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py +++ b/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py @@ -256,46 +256,6 @@ def test_create_address_warm_after_fail( pre[sender] = Account(balance=0xE8D4A51001) # Source: yul - # london - # object "C" { - # code { - # let failType := calldataload(4) - # let initcode_size - # - # // The return values of various actions. Done twice to see if there is a difference # noqa: E501 - # let create_1 := 0 - # let call_created_1 := 2 - # let call_created_2 := 3 - # let call_empty_1 := 4 - # let call_empty_2 := 5 - # - # // The costs of those operations - # let create_1_cost := 10 - # let call_created_1_cost := 12 - # let call_created_2_cost := 13 - # let call_empty_1_cost := 14 - # let call_empty_2_cost := 15 - # - # // Make the storage cells we use here are warm - # sstore(create_1, 0xdead60A7) - # sstore(call_created_1, 0xdead60A7) - # sstore(call_created_2, 0xdead60A7) - # sstore(call_empty_1, 0xdead60A7) - # sstore(call_empty_2, 0xdead60A7) - # sstore(call_created_1_cost, 0xdead60A7) - # sstore(call_created_2_cost, 0xdead60A7) - # sstore(call_empty_1_cost, 0xdead60A7) - # sstore(call_empty_2_cost, 0xdead60A7) - # ... (173 more lines) - contract_0 = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "6004356000906002600390600493600593600c90600d96600e90600f9863dead60a7865563dead60a7875563dead60a7885563dead60a7825563dead60a7895563dead60a7855563dead60a7815563dead60a7835563dead60a78a5573d4e7ae083132925a4927c1f5816238ba17b82a00938060001461044c5780600a1461040e57806001146103dc5780600b146103a357806002146103715780600c1461033257806003146102f757806004146102bb578060051461027f5780600d146102435780600e1461020657806006146101d4578060101461019b5780600714610169576011146100ed57600080fd5b60009788808080809b9a819b9a829b73f7fef4b66b1570a057d7d5cec5c58846befa5b5c92615a1760058061049488398680f590555b5a825583808080348782f190555a81540390555a8755349082f190555a81540390555a825583808080348782f190555a81540390555a8755349082f190555a8154039055005b5060009788808080809b9a819b9a829b6000805160206104998339815191529260058061049487398580f09055610123565b5060009788808080809b9a819b9a829b73562d97e3e4d6d3c6e791ea64bb73d820871aa2199284600a8061048a83398180f59055610123565b5060009788808080809b9a819b9a829b60008051602061049983398151915292600a8061048a87398580f09055610123565b5060009788808080809b9a819b9a829b73d70df326038a3c7ca8fac785a99162bfe75ccc469284808080806420c0de100662010000f19055610123565b5060009788808080809b9a819b9a829b73d70df326038a3c7ca8fac785a99162bfe75ccc469284808080806420c0de1006617000f19055610123565b5060009788808080809b9a819b9a829b73b2050fc27ab6d6d42dc0ce6f7c0bf9481a4c3fc392848080808063c0deffff62010000f19055610123565b5060009788808080809b9a819b9a829b73a5a6a95fd9554f15ab6986a57519092be209512592848080808063c0de100662010000f19055610123565b5060009788808080809b9a819b9a829b73a5a6a95fd9554f15ab6986a57519092be209512592848080808063c0de1006617000f19055610123565b5060009788808080809b9a819b9a829b73a13d43586820e5d97a3fd1960625d537c86dc4e79284600665fe60106000f360d01b82528180f59055610123565b5060009788808080809b9a819b9a829b6000805160206104998339815191529260018061048987398580f09055610123565b5060009788808080809b9a819b9a829b73014001fdbede82315f4b8c2a7d45e980a8a4a12e928460068061048383398180f59055610123565b5060009788808080809b9a819b9a829b6000805160206104998339815191529260068061048387398580f09055610123565b5060009788808080809b9a819b9a829b7343255ee039968e0254887fc8c7172736983d878c928460056460006000fd60d81b82528180f59055610123565b5060009788808080809b9a819b9a829b6000805160206104998339815191529260048061047f87398580f0905561012356fe600080fd6160016000f3fe60ef60005360106000f360016000f3000000000000000000000000d4e7ae083132925a4927c1f5816238ba17b82a65" # noqa: E501 - ), - balance=4096, - nonce=0, - address=Address(0x00000000000000000000000000000000000C0DEC), # noqa: E501 - ) - # Source: yul # berlin # object "C" { # code { @@ -376,6 +336,46 @@ def test_create_address_warm_after_fail( nonce=18446744073709551615, address=Address(0x00000000000000000000000000000000C0DEFFFF), # noqa: E501 ) + # Source: yul + # london + # object "C" { + # code { + # let failType := calldataload(4) + # let initcode_size + # + # // The return values of various actions. Done twice to see if there is a difference # noqa: E501 + # let create_1 := 0 + # let call_created_1 := 2 + # let call_created_2 := 3 + # let call_empty_1 := 4 + # let call_empty_2 := 5 + # + # // The costs of those operations + # let create_1_cost := 10 + # let call_created_1_cost := 12 + # let call_created_2_cost := 13 + # let call_empty_1_cost := 14 + # let call_empty_2_cost := 15 + # + # // Make the storage cells we use here are warm + # sstore(create_1, 0xdead60A7) + # sstore(call_created_1, 0xdead60A7) + # sstore(call_created_2, 0xdead60A7) + # sstore(call_empty_1, 0xdead60A7) + # sstore(call_empty_2, 0xdead60A7) + # sstore(call_created_1_cost, 0xdead60A7) + # sstore(call_created_2_cost, 0xdead60A7) + # sstore(call_empty_1_cost, 0xdead60A7) + # sstore(call_empty_2_cost, 0xdead60A7) + # ... (173 more lines) + contract_0 = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "6004356000906002600390600493600593600c90600d96600e90600f9863dead60a7865563dead60a7875563dead60a7885563dead60a7825563dead60a7895563dead60a7855563dead60a7815563dead60a7835563dead60a78a5573d4e7ae083132925a4927c1f5816238ba17b82a00938060001461044c5780600a1461040e57806001146103dc5780600b146103a357806002146103715780600c1461033257806003146102f757806004146102bb578060051461027f5780600d146102435780600e1461020657806006146101d4578060101461019b5780600714610169576011146100ed57600080fd5b60009788808080809b9a819b9a829b73f7fef4b66b1570a057d7d5cec5c58846befa5b5c92615a1760058061049488398680f590555b5a825583808080348782f190555a81540390555a8755349082f190555a81540390555a825583808080348782f190555a81540390555a8755349082f190555a8154039055005b5060009788808080809b9a819b9a829b6000805160206104998339815191529260058061049487398580f09055610123565b5060009788808080809b9a819b9a829b73562d97e3e4d6d3c6e791ea64bb73d820871aa2199284600a8061048a83398180f59055610123565b5060009788808080809b9a819b9a829b60008051602061049983398151915292600a8061048a87398580f09055610123565b5060009788808080809b9a819b9a829b73d70df326038a3c7ca8fac785a99162bfe75ccc469284808080806420c0de100662010000f19055610123565b5060009788808080809b9a819b9a829b73d70df326038a3c7ca8fac785a99162bfe75ccc469284808080806420c0de1006617000f19055610123565b5060009788808080809b9a819b9a829b73b2050fc27ab6d6d42dc0ce6f7c0bf9481a4c3fc392848080808063c0deffff62010000f19055610123565b5060009788808080809b9a819b9a829b73a5a6a95fd9554f15ab6986a57519092be209512592848080808063c0de100662010000f19055610123565b5060009788808080809b9a819b9a829b73a5a6a95fd9554f15ab6986a57519092be209512592848080808063c0de1006617000f19055610123565b5060009788808080809b9a819b9a829b73a13d43586820e5d97a3fd1960625d537c86dc4e79284600665fe60106000f360d01b82528180f59055610123565b5060009788808080809b9a819b9a829b6000805160206104998339815191529260018061048987398580f09055610123565b5060009788808080809b9a819b9a829b73014001fdbede82315f4b8c2a7d45e980a8a4a12e928460068061048383398180f59055610123565b5060009788808080809b9a819b9a829b6000805160206104998339815191529260068061048387398580f09055610123565b5060009788808080809b9a819b9a829b7343255ee039968e0254887fc8c7172736983d878c928460056460006000fd60d81b82528180f59055610123565b5060009788808080809b9a819b9a829b6000805160206104998339815191529260048061047f87398580f0905561012356fe600080fd6160016000f3fe60ef60005360106000f360016000f3000000000000000000000000d4e7ae083132925a4927c1f5816238ba17b82a65" # noqa: E501 + ), + balance=4096, + nonce=0, + address=Address(0x00000000000000000000000000000000000C0DEC), # noqa: E501 + ) expect_entries_: list[dict] = [ { @@ -742,7 +742,7 @@ def test_create_address_warm_after_fail( sender: Account(nonce=1), contract_0: Account( storage={ - 0: 0xD4E7AE083132925A4927C1F5816238BA17B82A65, + 0: compute_create_address(address=contract_0, nonce=0), 2: 1, 3: 1, 4: 1, @@ -766,7 +766,7 @@ def test_create_address_warm_after_fail( sender: Account(nonce=1), contract_0: Account( storage={ - 0: 0xD4E7AE083132925A4927C1F5816238BA17B82A65, + 0: compute_create_address(address=contract_0, nonce=0), 2: 1, 3: 1, 4: 1, diff --git a/tests/ported_static/stCreateTest/test_create_collision_results.py b/tests/ported_static/stCreateTest/test_create_collision_results.py index a049dc54458..19688d523ef 100644 --- a/tests/ported_static/stCreateTest/test_create_collision_results.py +++ b/tests/ported_static/stCreateTest/test_create_collision_results.py @@ -71,6 +71,7 @@ def test_create_collision_results( gas_limit=4294967296, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] 0x001D @@ -166,7 +167,7 @@ def test_create_collision_results( offset=0x640, value=Op.CALL( gas=0xFFFF, - address=0x8AF6A7AF30D840BA137E8F3F34D54CFB8BEBA6E2, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -181,7 +182,7 @@ def test_create_collision_results( offset=0x640, value=Op.CALL( gas=0xFFFF, - address=0x40F1299359EA754AC29EB2662A1900752BF8275F, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -192,27 +193,17 @@ def test_create_collision_results( + Op.SSTORE(key=0x22, value=Op.PC) + Op.SSTORE(key=0x14, value=Op.SUB(Op.MLOAD(offset=0x640), 0x1)) + Op.SSTORE(key=0x15, value=Op.RETURNDATASIZE) - + Op.SSTORE( - key=0x30, - value=Op.EXTCODESIZE( - address=0x8AF6A7AF30D840BA137E8F3F34D54CFB8BEBA6E2 - ), - ) + + Op.SSTORE(key=0x30, value=Op.EXTCODESIZE(address=contract_0)) + Op.EXTCODECOPY( - address=0x8AF6A7AF30D840BA137E8F3F34D54CFB8BEBA6E2, + address=contract_0, dest_offset=0x660, offset=0x0, size=Op.SLOAD(key=0x30), ) + Op.SSTORE(key=0x31, value=Op.MLOAD(offset=0x660)) - + Op.SSTORE( - key=0x32, - value=Op.EXTCODESIZE( - address=0x40F1299359EA754AC29EB2662A1900752BF8275F - ), - ) + + Op.SSTORE(key=0x32, value=Op.EXTCODESIZE(address=contract_1)) + Op.EXTCODECOPY( - address=0x40F1299359EA754AC29EB2662A1900752BF8275F, + address=contract_1, dest_offset=0x660, offset=0x0, size=Op.SLOAD(key=0x32), @@ -245,7 +236,6 @@ def test_create_collision_results( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("01"), diff --git a/tests/ported_static/stCreateTest/test_create_collision_to_empty2.py b/tests/ported_static/stCreateTest/test_create_collision_to_empty2.py index 3dd526bd61a..a8cb5f0f42e 100644 --- a/tests/ported_static/stCreateTest/test_create_collision_to_empty2.py +++ b/tests/ported_static/stCreateTest/test_create_collision_to_empty2.py @@ -139,6 +139,8 @@ def test_create_collision_to_empty2( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[contract_4] = Account(balance=10) + pre[contract_5] = Account(balance=0, nonce=2) # Source: lll # { (CALL 80000 (CALLDATALOAD 0) 0 0 0 0 0) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -182,8 +184,6 @@ def test_create_collision_to_empty2( nonce=0, address=Address(0x3000000000000000000000000000000000000000), # noqa: E501 ) - pre[contract_4] = Account(balance=10) - pre[contract_5] = Account(balance=0, nonce=2) # Source: raw # 0x1122334455 contract_6 = pre.deploy_contract( # noqa: F841 @@ -207,10 +207,7 @@ def test_create_collision_to_empty2( "network": [">=Cancun"], "result": { sender: Account(nonce=1), - contract_1: Account( - storage={1: 0x13136008B64FF592819B2FA6D43F2835C452020E}, - nonce=1, - ), + contract_1: Account(storage={1: contract_4}, nonce=1), contract_4: Account( storage={1: 1}, code=b"", balance=10, nonce=1 ), diff --git a/tests/ported_static/stCreateTest/test_create_contract_return_big_offset.py b/tests/ported_static/stCreateTest/test_create_contract_return_big_offset.py index a4993192b76..ceb298ae540 100644 --- a/tests/ported_static/stCreateTest/test_create_contract_return_big_offset.py +++ b/tests/ported_static/stCreateTest/test_create_contract_return_big_offset.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,7 +55,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_create_contract_return_big_offset( state_test: StateTestFiller, pre: Alloc, @@ -67,9 +65,7 @@ def test_create_contract_return_big_offset( ) -> None: """Test_create_contract_return_big_offset.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x9184E72A000) env = Environment( fee_recipient=coinbase, @@ -80,8 +76,6 @@ def test_create_contract_return_big_offset( gas_limit=89128960, ) - pre[sender] = Account(balance=0x9184E72A000) - tx_data = [ Op.RETURN(offset=0x74AC2, size=0x10000), Op.RETURN(offset=0x74AC2, size=0x51EB8), diff --git a/tests/ported_static/stCreateTest/test_create_contract_sstore_during_init.py b/tests/ported_static/stCreateTest/test_create_contract_sstore_during_init.py index aa8602eee32..a84b5c722a0 100644 --- a/tests/ported_static/stCreateTest/test_create_contract_sstore_during_init.py +++ b/tests/ported_static/stCreateTest/test_create_contract_sstore_during_init.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stCreateTest/CREATE_ContractSSTOREDuringInitFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_contract_sstore_during_init( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_create_contract_sstore_during_init.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x174876E800) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_create_contract_sstore_during_init( gas_limit=10000000, ) - pre[sender] = Account(balance=0x174876E800) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stCreateTest/test_create_e_contract_create_e_contract_in_init_tr.py b/tests/ported_static/stCreateTest/test_create_e_contract_create_e_contract_in_init_tr.py index 1e9a91225d0..d3288602010 100644 --- a/tests/ported_static/stCreateTest/test_create_e_contract_create_e_contract_in_init_tr.py +++ b/tests/ported_static/stCreateTest/test_create_e_contract_create_e_contract_in_init_tr.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_create_e_contract_create_e_contract_in_init_tr( """Test_create_e_contract_create_e_contract_in_init_tr.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,12 @@ def test_create_e_contract_create_e_contract_in_init_tr( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # {[[1]]12} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, balance=0xE8D4A51000, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_oog_tr.py b/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_oog_tr.py index 21592d31e33..c5b2fbd670f 100644 --- a/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_oog_tr.py +++ b/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_oog_tr.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_create_e_contract_create_ne_contract_in_init_oog_tr( """Test_create_e_contract_create_ne_contract_in_init_oog_tr.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -74,14 +71,12 @@ def test_create_e_contract_create_ne_contract_in_init_oog_tr( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # {[[1]]12} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, balance=0xE8D4A51000, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -93,8 +88,9 @@ def test_create_e_contract_create_ne_contract_in_init_oog_tr( compute_create_address(address=sender, nonce=0): Account( nonce=2 ), - Address( - 0xA42676447B7CEDFA5FDE894D1D3DF24AAB362701 + compute_create_address( + address=compute_create_address(address=sender, nonce=0), + nonce=0, ): Account.NONEXISTENT, }, }, @@ -106,8 +102,9 @@ def test_create_e_contract_create_ne_contract_in_init_oog_tr( compute_create_address( address=sender, nonce=0 ): Account.NONEXISTENT, - Address( - 0xA42676447B7CEDFA5FDE894D1D3DF24AAB362701 + compute_create_address( + address=compute_create_address(address=sender, nonce=0), + nonce=0, ): Account.NONEXISTENT, }, }, diff --git a/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_tr.py b/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_tr.py index 0d015961f02..67efdc53a18 100644 --- a/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_tr.py +++ b/tests/ported_static/stCreateTest/test_create_e_contract_create_ne_contract_in_init_tr.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_create_e_contract_create_ne_contract_in_init_tr( """Test_create_e_contract_create_ne_contract_in_init_tr.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,12 @@ def test_create_e_contract_create_ne_contract_in_init_tr( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # {[[1]]12} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, balance=0xE8D4A51000, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( @@ -81,9 +76,9 @@ def test_create_e_contract_create_ne_contract_in_init_tr( post = { contract_0: Account(storage={1: 12}), compute_create_address(address=sender, nonce=0): Account(nonce=2), - Address(0x64E2EBD6405AF8CB348AEC519084D3FFF42EBBA6): Account( - code=bytes.fromhex("600c600055") - ), + compute_create_address( + address=compute_create_address(address=sender, nonce=0), nonce=1 + ): Account(code=bytes.fromhex("600c600055")), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stCreateTest/test_create_e_contract_then_call_to_non_existent_acc.py b/tests/ported_static/stCreateTest/test_create_e_contract_then_call_to_non_existent_acc.py index 8ca5125d13c..f752c8b1f6b 100644 --- a/tests/ported_static/stCreateTest/test_create_e_contract_then_call_to_non_existent_acc.py +++ b/tests/ported_static/stCreateTest/test_create_e_contract_then_call_to_non_existent_acc.py @@ -86,7 +86,7 @@ def test_create_e_contract_then_call_to_non_existent_acc( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x7ABF8, 3: 1, 100: 0x6F50B, diff --git a/tests/ported_static/stCreateTest/test_create_empty000_createin_init_code_transaction.py b/tests/ported_static/stCreateTest/test_create_empty000_createin_init_code_transaction.py index 40e0530a282..6161631fc90 100644 --- a/tests/ported_static/stCreateTest/test_create_empty000_createin_init_code_transaction.py +++ b/tests/ported_static/stCreateTest/test_create_empty000_createin_init_code_transaction.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_create_empty000_createin_init_code_transaction( """Test_create_empty000_createin_init_code_transaction.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,12 @@ def test_create_empty000_createin_init_code_transaction( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # {[[1]]12} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, balance=0xE8D4A51000, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( @@ -80,8 +75,8 @@ def test_create_empty000_createin_init_code_transaction( post = { contract_0: Account(storage={1: 12}), compute_create_address(address=sender, nonce=0): Account(nonce=2), - Address( - 0xA42676447B7CEDFA5FDE894D1D3DF24AAB362701 + compute_create_address( + address=compute_create_address(address=sender, nonce=0), nonce=0 ): Account.NONEXISTENT, } diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract.py b/tests/ported_static/stCreateTest/test_create_empty_contract.py index 3c22a1e5e52..9790df29d6c 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_empty_contract( """Test_create_empty_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create_empty_contract( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) [[1]] (CREATE 0 0 32) [[100]] (GAS) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -57,7 +53,6 @@ def test_create_empty_contract( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( @@ -72,7 +67,7 @@ def test_create_empty_contract( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 100: 0x7ABF8, }, ), diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_0wei.py b/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_0wei.py index 8bad278c56e..b8efc72b9a5 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_0wei.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_0wei.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_empty_contract_and_call_it_0wei( """Test_create_empty_contract_and_call_it_0wei.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create_empty_contract_and_call_it_0wei( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) [[1]] (CREATE 0 0 32) [[2]](GAS) [[3]] (CALL 60000 (SLOAD 1) 0 0 0 0 0) [[100]] (GAS) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +80,7 @@ def test_create_empty_contract_and_call_it_0wei( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x7ABF8, 3: 1, 100: 0x6FE6B, diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_1wei.py b/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_1wei.py index 14bf2963be4..1b35d16c1b5 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_1wei.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract_and_call_it_1wei.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_empty_contract_and_call_it_1wei( """Test_create_empty_contract_and_call_it_1wei.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create_empty_contract_and_call_it_1wei( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) [[1]] (CREATE 0 0 32) [[2]](GAS) [[3]](CALL 60000 (SLOAD 1) 1 0 0 0 0) [[100]] (GAS) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -85,7 +81,7 @@ def test_create_empty_contract_and_call_it_1wei( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x7ABF8, 3: 1, 100: 0x6E43F, diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract_with_balance.py b/tests/ported_static/stCreateTest/test_create_empty_contract_with_balance.py index b87c0a3a6af..60862e9022b 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract_with_balance.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract_with_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_empty_contract_with_balance( """Test_create_empty_contract_with_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create_empty_contract_with_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) [[1]] (CREATE 1 0 32) [[100]] (GAS) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,6 @@ def test_create_empty_contract_with_balance( + Op.STOP, balance=1, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( @@ -72,7 +67,7 @@ def test_create_empty_contract_with_balance( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 100: 0x7ABF8, }, ), diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage.py b/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage.py index 0f4bd290243..9ca299282ef 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage.py @@ -88,7 +88,7 @@ def test_create_empty_contract_with_storage( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 100: 0x6F4F0, }, ), diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_0wei.py b/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_0wei.py index 177563f4064..d7940716427 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_0wei.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_0wei.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -38,9 +37,7 @@ def test_create_empty_contract_with_storage_and_call_it_0wei( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,7 +48,6 @@ def test_create_empty_contract_with_storage_and_call_it_0wei( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) (MSTORE 0 0x600c6000556000600060006000600073c94f5374fce5edbc8e2a8697c1533167) (MSTORE 32 0x7e6ebf0b61ea60f1000000000000000000000000000000000000000000000000) [[1]] (CREATE 0 0 64) [[2]] (GAS) [[3]] (CALL 60000 (SLOAD 1) 0 0 0 0 0) [[100]] (GAS) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -103,7 +99,7 @@ def test_create_empty_contract_with_storage_and_call_it_0wei( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x6F4F0, 3: 1, 100: 0x64763, diff --git a/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_1wei.py b/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_1wei.py index 9fcff78541d..cbd15afeba3 100644 --- a/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_1wei.py +++ b/tests/ported_static/stCreateTest/test_create_empty_contract_with_storage_and_call_it_1wei.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -38,9 +37,7 @@ def test_create_empty_contract_with_storage_and_call_it_1wei( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,7 +48,6 @@ def test_create_empty_contract_with_storage_and_call_it_1wei( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) (MSTORE 0 0x600c6000556000600060006000600073c94f5374fce5edbc8e2a8697c1533167) (MSTORE 32 0x7e6ebf0b61ea60f1000000000000000000000000000000000000000000000000) [[1]] (CREATE 0 0 64) [[2]] (GAS) [[3]] (CALL 60000 (SLOAD 1) 1 0 0 0 0) [[100]] (GAS) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -104,7 +100,7 @@ def test_create_empty_contract_with_storage_and_call_it_1wei( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x6F4F0, 3: 1, 100: 0x62D37, diff --git a/tests/ported_static/stCreateTest/test_create_fail_result.py b/tests/ported_static/stCreateTest/test_create_fail_result.py index 9750c30d2b4..c87f3c0ec2d 100644 --- a/tests/ported_static/stCreateTest/test_create_fail_result.py +++ b/tests/ported_static/stCreateTest/test_create_fail_result.py @@ -16,6 +16,7 @@ Hash, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.forks import Fork from execution_testing.specs.static_state.expect_section import ( @@ -131,6 +132,7 @@ def test_create_fail_result( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # berlin # { @@ -161,18 +163,29 @@ def test_create_fail_result( nonce=1, address=Address(0x0000000000000000000000000000000000000BAD), # noqa: E501 ) - # Source: yul - # berlin - # { - # mstore(0, 0x600D) - # return(0, 0x20) - # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x600D) - + Op.RETURN(offset=0x0, size=0x20), - balance=0xBA1A9CE0BA1A9CE, + # Source: raw + # 0x600100 + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x1] + Op.STOP, + balance=24589, nonce=1, - address=Address(0x000000000000000000000000000000000000600D), # noqa: E501 + address=Address(0xBB0237AB04970E3CF3E813C02064662ADC89336B), # noqa: E501 + ) + # Source: raw + # 0x600100 + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x1] + Op.STOP, + balance=24589, + nonce=1, + address=Address(0x13C950F8740FFAEA1869A88D70B029E8B0C9A8DA), # noqa: E501 + ) + # Source: raw + # 0x600100 + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x1] + Op.STOP, + balance=24589, + nonce=1, + address=Address(0xF9D1EA8EAB6963659EE85B3E0B4D8A57E7EDBA2B), # noqa: E501 ) # Source: yul # berlin @@ -183,7 +196,6 @@ def test_create_fail_result( # sstore(0x12, mload(0x100)) # sstore(0x13, mload(0x120)) # - # # // Read the constructor code from the appropriate contract # let srcAddr := calldataload(0) // either 600D or BAD # @@ -191,7 +203,7 @@ def test_create_fail_result( # extcodecopy(srcAddr, 0, 0, codeSize) # # // Create - # sstore(0,create(0, 0, codeSize)) + # sstore(0,create2(0, 0, codeSize, 0x5A17)) # # // If we have a returned buffer, see what it is # sstore(1,returndatasize()) @@ -199,12 +211,12 @@ def test_create_fail_result( # sstore(2, mload(0x200)) # sstore(3, mload(0x220)) # } - contract_3 = pre.deploy_contract( # noqa: F841 + contract_4 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x10, value=Op.CALL( gas=Op.GAS, - address=0xDA7A, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP1, args_size=0x0, @@ -215,6 +227,7 @@ def test_create_fail_result( + Op.SSTORE(key=0x11, value=Op.RETURNDATASIZE) + Op.SSTORE(key=0x12, value=Op.MLOAD(offset=0x100)) + Op.SSTORE(key=0x13, value=Op.MLOAD(offset=0x120)) + + Op.PUSH2[0x5A17] + Op.PUSH1[0x0] + Op.CALLDATALOAD(offset=Op.DUP1) + Op.DUP2 @@ -225,7 +238,7 @@ def test_create_fail_result( + Op.EXTCODECOPY + Op.PUSH1[0x0] + Op.DUP1 - + Op.SSTORE(key=0x0, value=Op.CREATE) + + Op.SSTORE(key=0x0, value=Op.CREATE2) + Op.SSTORE(key=0x1, value=Op.RETURNDATASIZE) + Op.RETURNDATACOPY( dest_offset=0x200, offset=0x0, size=Op.RETURNDATASIZE @@ -235,7 +248,7 @@ def test_create_fail_result( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF0), # noqa: E501 + address=Address(0x0000000000000000000000000000000000C0DEF5), # noqa: E501 ) # Source: yul # berlin @@ -253,7 +266,7 @@ def test_create_fail_result( # extcodecopy(srcAddr, 0, 0, codeSize) # # // Create - # sstore(0,create2(0, 0, codeSize, 0x5A17)) + # sstore(0,create(0, 0, codeSize)) # # // If we have a returned buffer, see what it is # sstore(1,returndatasize()) @@ -261,12 +274,12 @@ def test_create_fail_result( # sstore(2, mload(0x200)) # sstore(3, mload(0x220)) # } - contract_4 = pre.deploy_contract( # noqa: F841 + contract_8 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x10, value=Op.CALL( gas=Op.GAS, - address=0xDA7A, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP1, args_size=0x0, @@ -277,7 +290,6 @@ def test_create_fail_result( + Op.SSTORE(key=0x11, value=Op.RETURNDATASIZE) + Op.SSTORE(key=0x12, value=Op.MLOAD(offset=0x100)) + Op.SSTORE(key=0x13, value=Op.MLOAD(offset=0x120)) - + Op.PUSH2[0x5A17] + Op.PUSH1[0x0] + Op.CALLDATALOAD(offset=Op.DUP1) + Op.DUP2 @@ -288,7 +300,7 @@ def test_create_fail_result( + Op.EXTCODECOPY + Op.PUSH1[0x0] + Op.DUP1 - + Op.SSTORE(key=0x0, value=Op.CREATE2) + + Op.SSTORE(key=0x0, value=Op.CREATE) + Op.SSTORE(key=0x1, value=Op.RETURNDATASIZE) + Op.RETURNDATACOPY( dest_offset=0x200, offset=0x0, size=Op.RETURNDATASIZE @@ -298,7 +310,81 @@ def test_create_fail_result( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEF5), # noqa: E501 + address=Address(0x0000000000000000000000000000000000C0DEEE), # noqa: E501 + ) + # Source: yul + # berlin + # { + # // The operation to run + # // F0 - CREATE + # // F5 - CREATE2 + # let oper := calldataload(0x04) + # + # // The condition for it + # // 0x0006 - OUT OF GAS + # // 0x0BAD - REVERT with data + # // 0x600D - Success + # let cond := calldataload(0x24) + # let addr := add(0xC0DE00, oper) + # + # + # + # // Before the main call, call DA7A to fill up the return buffer + # sstore(0x10, call(gas(), 0xDA7A, 0, 0, 0, 0x100, 0x40)) + # sstore(0x11, returndatasize()) + # sstore(0x12, mload(0x100)) + # sstore(0x13, mload(0x120)) + # + # + # let gasAmt := gas() + # + # // Out Of Gas, CREATE[2] always costs more than 32k in gas + # // but we need to also pay for the four SSTOREs that verify DA7A was + # // called correctly + # if eq(cond,0x0006) { gasAmt := add(30000,mul(22100,4)) } + # + # ... (14 more lines) + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x20] + + Op.PUSH2[0x200] + + Op.DUP2 + + Op.PUSH1[0x0] + + Op.DUP1 + + Op.ADD(Op.CALLDATALOAD(offset=0x4), 0xC0DE00) + + Op.CALLDATALOAD(offset=0x24) + + Op.SSTORE( + key=0x10, + value=Op.CALL( + gas=Op.GAS, + address=contract_0, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP5, + ret_offset=0x100, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x11, value=Op.RETURNDATASIZE) + + Op.SSTORE(key=0x12, value=Op.MLOAD(offset=0x100)) + + Op.SSTORE(key=0x13, value=Op.MLOAD(offset=0x120)) + + Op.GAS + + Op.SWAP1 + + Op.JUMPI(pc=0x52, condition=Op.EQ(Op.DUP2, 0x6)) + + Op.JUMPDEST + + Op.DUP4 + + Op.MSTORE + + Op.SSTORE(key=0x0, value=Op.CALL) + + Op.SSTORE(key=0x1, value=Op.RETURNDATASIZE) + + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x200)) + + Op.STOP + + Op.JUMPDEST + + Op.PUSH3[0x1CE80] + + Op.SWAP2 + + Op.POP + + Op.JUMP(pc=0x3F), + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) # Source: yul # berlin @@ -309,6 +395,7 @@ def test_create_fail_result( # sstore(0x12, mload(0x100)) # sstore(0x13, mload(0x120)) # + # # // Read the constructor code from the appropriate contract # let srcAddr := calldataload(0) // either 600D or BAD # @@ -316,7 +403,7 @@ def test_create_fail_result( # extcodecopy(srcAddr, 0, 0, codeSize) # # // Create - # sstore(0,create2(0, 0, codeSize, 0xBAD05A17)) + # sstore(0,create(0, 0, codeSize)) # # // If we have a returned buffer, see what it is # sstore(1,returndatasize()) @@ -324,12 +411,12 @@ def test_create_fail_result( # sstore(2, mload(0x200)) # sstore(3, mload(0x220)) # } - contract_5 = pre.deploy_contract( # noqa: F841 + contract_3 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x10, value=Op.CALL( gas=Op.GAS, - address=0xDA7A, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP1, args_size=0x0, @@ -340,7 +427,6 @@ def test_create_fail_result( + Op.SSTORE(key=0x11, value=Op.RETURNDATASIZE) + Op.SSTORE(key=0x12, value=Op.MLOAD(offset=0x100)) + Op.SSTORE(key=0x13, value=Op.MLOAD(offset=0x120)) - + Op.PUSH4[0xBAD05A17] + Op.PUSH1[0x0] + Op.CALLDATALOAD(offset=Op.DUP1) + Op.DUP2 @@ -351,7 +437,7 @@ def test_create_fail_result( + Op.EXTCODECOPY + Op.PUSH1[0x0] + Op.DUP1 - + Op.SSTORE(key=0x0, value=Op.CREATE2) + + Op.SSTORE(key=0x0, value=Op.CREATE) + Op.SSTORE(key=0x1, value=Op.RETURNDATASIZE) + Op.RETURNDATACOPY( dest_offset=0x200, offset=0x0, size=Op.RETURNDATASIZE @@ -361,23 +447,7 @@ def test_create_fail_result( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEFF), # noqa: E501 - ) - # Source: raw - # 0x600100 - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x1] + Op.STOP, - balance=24589, - nonce=1, - address=Address(0xBB0237AB04970E3CF3E813C02064662ADC89336B), # noqa: E501 - ) - # Source: raw - # 0x600100 - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x1] + Op.STOP, - balance=24589, - nonce=1, - address=Address(0x13C950F8740FFAEA1869A88D70B029E8B0C9A8DA), # noqa: E501 + address=Address(0x0000000000000000000000000000000000C0DEF0), # noqa: E501 ) # Source: yul # berlin @@ -395,7 +465,7 @@ def test_create_fail_result( # extcodecopy(srcAddr, 0, 0, codeSize) # # // Create - # sstore(0,create(0, 0, codeSize)) + # sstore(0,create2(0, 0, codeSize, 0xBAD05A17)) # # // If we have a returned buffer, see what it is # sstore(1,returndatasize()) @@ -403,12 +473,12 @@ def test_create_fail_result( # sstore(2, mload(0x200)) # sstore(3, mload(0x220)) # } - contract_8 = pre.deploy_contract( # noqa: F841 + contract_5 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x10, value=Op.CALL( gas=Op.GAS, - address=0xDA7A, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP1, args_size=0x0, @@ -419,6 +489,7 @@ def test_create_fail_result( + Op.SSTORE(key=0x11, value=Op.RETURNDATASIZE) + Op.SSTORE(key=0x12, value=Op.MLOAD(offset=0x100)) + Op.SSTORE(key=0x13, value=Op.MLOAD(offset=0x120)) + + Op.PUSH4[0xBAD05A17] + Op.PUSH1[0x0] + Op.CALLDATALOAD(offset=Op.DUP1) + Op.DUP2 @@ -429,7 +500,7 @@ def test_create_fail_result( + Op.EXTCODECOPY + Op.PUSH1[0x0] + Op.DUP1 - + Op.SSTORE(key=0x0, value=Op.CREATE) + + Op.SSTORE(key=0x0, value=Op.CREATE2) + Op.SSTORE(key=0x1, value=Op.RETURNDATASIZE) + Op.RETURNDATACOPY( dest_offset=0x200, offset=0x0, size=Op.RETURNDATASIZE @@ -439,91 +510,21 @@ def test_create_fail_result( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x0000000000000000000000000000000000C0DEEE), # noqa: E501 - ) - # Source: raw - # 0x600100 - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x1] + Op.STOP, - balance=24589, - nonce=1, - address=Address(0xF9D1EA8EAB6963659EE85B3E0B4D8A57E7EDBA2B), # noqa: E501 + address=Address(0x0000000000000000000000000000000000C0DEFF), # noqa: E501 ) # Source: yul # berlin # { - # // The operation to run - # // F0 - CREATE - # // F5 - CREATE2 - # let oper := calldataload(0x04) - # - # // The condition for it - # // 0x0006 - OUT OF GAS - # // 0x0BAD - REVERT with data - # // 0x600D - Success - # let cond := calldataload(0x24) - # let addr := add(0xC0DE00, oper) - # - # - # - # // Before the main call, call DA7A to fill up the return buffer - # sstore(0x10, call(gas(), 0xDA7A, 0, 0, 0, 0x100, 0x40)) - # sstore(0x11, returndatasize()) - # sstore(0x12, mload(0x100)) - # sstore(0x13, mload(0x120)) - # - # - # let gasAmt := gas() - # - # // Out Of Gas, CREATE[2] always costs more than 32k in gas - # // but we need to also pay for the four SSTOREs that verify DA7A was - # // called correctly - # if eq(cond,0x0006) { gasAmt := add(30000,mul(22100,4)) } - # - # ... (14 more lines) - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x20] - + Op.PUSH2[0x200] - + Op.DUP2 - + Op.PUSH1[0x0] - + Op.DUP1 - + Op.ADD(Op.CALLDATALOAD(offset=0x4), 0xC0DE00) - + Op.CALLDATALOAD(offset=0x24) - + Op.SSTORE( - key=0x10, - value=Op.CALL( - gas=Op.GAS, - address=0xDA7A, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP5, - ret_offset=0x100, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x11, value=Op.RETURNDATASIZE) - + Op.SSTORE(key=0x12, value=Op.MLOAD(offset=0x100)) - + Op.SSTORE(key=0x13, value=Op.MLOAD(offset=0x120)) - + Op.GAS - + Op.SWAP1 - + Op.JUMPI(pc=0x52, condition=Op.EQ(Op.DUP2, 0x6)) - + Op.JUMPDEST - + Op.DUP4 - + Op.MSTORE - + Op.SSTORE(key=0x0, value=Op.CALL) - + Op.SSTORE(key=0x1, value=Op.RETURNDATASIZE) - + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x200)) - + Op.STOP - + Op.JUMPDEST - + Op.PUSH3[0x1CE80] - + Op.SWAP2 - + Op.POP - + Op.JUMP(pc=0x3F), + # mstore(0, 0x600D) + # return(0, 0x20) + # } + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x600D) + + Op.RETURN(offset=0x0, size=0x20), balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 + address=Address(0x000000000000000000000000000000000000600D), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) expect_entries_: list[dict] = [ { @@ -549,7 +550,7 @@ def test_create_fail_result( "result": { contract_3: Account( storage={ - 0: 0xB44F2C88D3D4283CD1E54E418C4FF7E6A6C73202, + 0: compute_create_address(address=contract_3, nonce=1), 1: 0, 2: 0, 3: 0, diff --git a/tests/ported_static/stCreateTest/test_create_large_result.py b/tests/ported_static/stCreateTest/test_create_large_result.py index c64ed955641..936dde89a2a 100644 --- a/tests/ported_static/stCreateTest/test_create_large_result.py +++ b/tests/ported_static/stCreateTest/test_create_large_result.py @@ -16,6 +16,7 @@ Hash, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.forks import Fork from execution_testing.specs.static_state.expect_section import ( @@ -159,6 +160,7 @@ def test_create_large_result( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # london # { @@ -217,9 +219,9 @@ def test_create_large_result( + Op.CALLDATALOAD(offset=0x44) + Op.SWAP1 + Op.PUSH1[0x1] - + Op.EXTCODESIZE(address=0xC0DE) + + Op.EXTCODESIZE(address=contract_0) + Op.EXTCODECOPY( - address=0xC0DE, dest_offset=Op.DUP1, offset=0x0, size=Op.DUP1 + address=contract_0, dest_offset=Op.DUP1, offset=0x0, size=Op.DUP1 ) + Op.SUB + Op.MSTORE8 @@ -248,7 +250,6 @@ def test_create_large_result( nonce=1, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) expect_entries_: list[dict] = [ { @@ -257,7 +258,7 @@ def test_create_large_result( "result": { contract_1: Account( storage={ - 0: 0x553E6C30AF61E7A3576F31311EA8A620F80D047E, + 0: compute_create_address(address=contract_1, nonce=1), 1: 0x1777F, 2: 0xD956C0ABD597440481902014A37B733358EE7685461EB1B5916EEFD83381E6D9, # noqa: E501 }, @@ -293,7 +294,7 @@ def test_create_large_result( "result": { contract_1: Account( storage={ - 0: 0x553E6C30AF61E7A3576F31311EA8A620F80D047E, + 0: compute_create_address(address=contract_1, nonce=1), 1: 0x4BBCE4, 2: 0xDCBCC213F0C91B71D38DEDD06C95CCB99467B9B05F275BED536DE1044F5F18FA, # noqa: E501 }, diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code.py index df4d57600ef..8a4e086e17c 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_create_oo_gafter_init_code( """Test_create_oo_gafter_init_code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_create_oo_gafter_init_code( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -81,7 +77,6 @@ def test_create_oo_gafter_init_code( + Op.CREATE(value=0x0, offset=0x12, size=0xE) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata.py index 0fd6daa2fbd..5b0054ddd8b 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,9 +56,7 @@ def test_create_oo_gafter_init_code_returndata( """Call RETURNDATASIZE and RETURNDATACOPY after CREATE deploy a contract.""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -70,7 +67,6 @@ def test_create_oo_gafter_init_code_returndata( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) [[ 1 ]] (RETURNDATASIZE) (RETURNDATACOPY 0 0 32) [[ 2 ]] (MLOAD 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -81,7 +77,6 @@ def test_create_oo_gafter_init_code_returndata( + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x0)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata3.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata3.py index 7aba3a6ffbf..f7506f2dde7 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata3.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_create_oo_gafter_init_code_returndata3( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +46,21 @@ def test_create_oo_gafter_init_code_returndata3( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) } + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) + + Op.CREATE(value=0x0, offset=0x12, size=0xE) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALLCODE (GAS) 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) (RETURNDATACOPY 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=Op.GAS, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -68,16 +72,6 @@ def test_create_oo_gafter_init_code_returndata3( + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) + Op.STOP, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) - + Op.CREATE(value=0x0, offset=0x12, size=0xE) - + Op.STOP, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata_size.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata_size.py index ddb8a1557dc..6f458740e9d 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata_size.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_returndata_size.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_create_oo_gafter_init_code_returndata_size( """Calls a contract that runs CREATE which deploy a code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_create_oo_gafter_init_code_returndata_size( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x6960016001556001600255600052600a6016f3) (CREATE 0 13 19) (EXP 2 (RETURNDATASIZE)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -61,7 +57,6 @@ def test_create_oo_gafter_init_code_returndata_size( + Op.EXP(0x2, Op.RETURNDATASIZE) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert.py index 17c72824f33..5efacdc166e 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert.py @@ -52,23 +52,11 @@ def test_create_oo_gafter_init_code_revert( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (CALL (GAS) 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.CALL( - gas=Op.GAS, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x20, - ) - ) - + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) - + Op.STOP, + # { (KECCAK256 0x00 0x2fffff) } + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + address=Address(0x094F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) (CALLCODE 10000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 0) (REVERT 0 32) } # noqa: E501 @@ -78,7 +66,7 @@ def test_create_oo_gafter_init_code_revert( + Op.POP( Op.CALLCODE( gas=0x2710, - address=0x94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -92,11 +80,23 @@ def test_create_oo_gafter_init_code_revert( address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll - # { (KECCAK256 0x00 0x2fffff) } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + # { (CALL (GAS) 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.CALL( + gas=Op.GAS, + address=contract_1, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x20, + ) + ) + + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) + + Op.STOP, nonce=0, - address=Address(0x094F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert2.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert2.py index 12894addc0a..d7a8fbcadff 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert2.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_init_code_revert2.py @@ -95,6 +95,16 @@ def test_create_oo_gafter_init_code_revert2( address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll + # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) (REVERT 0 32) } # noqa: E501 + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) + + Op.POP(Op.CREATE(value=0x0, offset=0x12, size=0xE)) + + Op.REVERT(offset=0x0, size=0x20) + + Op.STOP, + nonce=0, + address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + ) + # Source: lll # { (CALL 33000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0 32) [[ 1 ]] (MLOAD 0) } # noqa: E501 contract_1 = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -134,16 +144,6 @@ def test_create_oo_gafter_init_code_revert2( nonce=0, address=Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - # Source: lll - # { (MSTORE 0 0x6460016001556000526005601bf3) (CREATE 0 18 14) (REVERT 0 32) } # noqa: E501 - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x6460016001556000526005601BF3) - + Op.POP(Op.CREATE(value=0x0, offset=0x12, size=0xE)) - + Op.REVERT(offset=0x0, size=0x20) - + Op.STOP, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreateTest/test_create_oo_gafter_max_codesize.py b/tests/ported_static/stCreateTest/test_create_oo_gafter_max_codesize.py index e127e62553d..4cd22b226bc 100644 --- a/tests/ported_static/stCreateTest/test_create_oo_gafter_max_codesize.py +++ b/tests/ported_static/stCreateTest/test_create_oo_gafter_max_codesize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -90,9 +89,7 @@ def test_create_oo_gafter_max_codesize( contract_1 = Address(0x00000000000000000000000000000000000C0DE1) contract_2 = Address(0x00000000000000000000000000000000000C0DEB) contract_3 = Address(0x00000000000000000000000000000000000C0DEA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -315,9 +312,7 @@ def test_create_oo_gafter_max_codesize( + Op.JUMPDEST + Op.REVERT(offset=Op.DUP1, size=0x0), nonce=1, - address=Address(0x00000000000000000000000000000000000C0DEA), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stCreateTest/test_create_oog_from_call_refunds.py b/tests/ported_static/stCreateTest/test_create_oog_from_call_refunds.py index 2511550e8d8..f1ff087ac10 100644 --- a/tests/ported_static/stCreateTest/test_create_oog_from_call_refunds.py +++ b/tests/ported_static/stCreateTest/test_create_oog_from_call_refunds.py @@ -320,6 +320,114 @@ def test_create_oog_from_call_refunds( # berlin # { # sstore(0, 1) + # sstore(1, 1) + # sstore(1, 0) + # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 + # //let initcodelength := extcodesize(initcodeaddr) + # //extcodecopy(initcodeaddr, 0, 0, initcodelength) + # + # // protection from solc version changing init code + # let initcodelength := 15 + # mstore(0, 0x6001600055600060005560016000f30000000000000000000000000000000000) # noqa: E501 + # + # pop(create2(0, 0, initcodelength, 0)) + # return(add(initcodelength, 1), 1) + # } + contract_22 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x1] + + Op.PUSH1[0x0] + + Op.SSTORE(key=Op.DUP2, value=Op.DUP2) + + Op.SSTORE(key=Op.DUP3, value=Op.DUP1) + + Op.MSTORE( + offset=Op.DUP2, + value=0x6001600055600060005560016000F30000000000000000000000000000000000, # noqa: E501 + ) + + Op.DUP2 + + Op.SWAP1 + + Op.PUSH1[0xF] + + Op.SWAP1 + + Op.DUP2 * 2 + + Op.DUP1 + + Op.POP(Op.CREATE2) + + Op.ADD + + Op.RETURN, + nonce=0, + address=Address(0x000000000000000000000000000000000000008A), # noqa: E501 + ) + # Source: yul + # berlin + # { + # // Simple SSTORE to zero to get a refund + # sstore(1, 0) + # } + contract_25 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, + storage={1: 1}, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DEA), # noqa: E501 + ) + # Source: yul + # berlin + # { + # selfdestruct(origin()) + # } + contract_26 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=Op.ORIGIN), + storage={1: 1}, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DED), # noqa: E501 + ) + # Source: yul + # berlin + # { + # mstore(0, 0xff) + # log0(0, 32) + # log1(0, 32, 0xfa) + # log2(0, 32, 0xfa, 0xfb) + # log3(0, 32, 0xfa, 0xfb, 0xfc) + # log4(0, 32, 0xfa, 0xfb, 0xfc, 0xfd) + # } + contract_27 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0xFF) + + Op.LOG0(offset=0x0, size=0x20) + + Op.LOG1(offset=0x0, size=0x20, topic_1=0xFA) + + Op.LOG2(offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB) + + Op.LOG3( + offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB, topic_3=0xFC + ) + + Op.LOG4( + offset=0x0, + size=0x20, + topic_1=0xFA, + topic_2=0xFB, + topic_3=0xFC, + topic_4=0xFD, + ) + + Op.STOP, + storage={1: 1}, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DE0), # noqa: E501 + ) + # Source: yul + # berlin + # { + # sstore(0, 1) + # sstore(0, 0) + # return(0, 1) + # } + contract_28 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.SSTORE(key=Op.DUP1, value=Op.DUP1) + + Op.PUSH1[0x1] + + Op.SWAP1 + + Op.RETURN, + nonce=1, + address=Address(0x00000000000000000000000000000000000C0DE1), # noqa: E501 + ) + # Source: yul + # berlin + # { + # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 # return(0, 1) # } @@ -327,7 +435,7 @@ def test_create_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -349,7 +457,7 @@ def test_create_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -364,6 +472,31 @@ def test_create_oog_from_call_refunds( # berlin # { # sstore(0, 1) + # sstore(1, 1) + # pop(delegatecall(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0)) # noqa: E501 + # invalid() + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.SSTORE(key=Op.DUP1, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=Op.GAS, + address=contract_25, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=0x0, + ) + ) + + Op.INVALID, + nonce=0, + address=Address(0x000000000000000000000000000000000000003C), # noqa: E501 + ) + # Source: yul + # berlin + # { + # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 # invalid() # } @@ -372,7 +505,7 @@ def test_create_oog_from_call_refunds( + Op.POP( Op.CALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -397,7 +530,7 @@ def test_create_oog_from_call_refunds( + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.DELEGATECALL( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, @@ -412,15 +545,16 @@ def test_create_oog_from_call_refunds( # { # sstore(0, 1) # sstore(1, 1) - # pop(delegatecall(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0)) # noqa: E501 + # pop(callcode(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 # return(0, 5000) # } - contract_8 = pre.deploy_contract( # noqa: F841 + contract_11 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.DELEGATECALL( + + Op.CALLCODE( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, + value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, @@ -428,7 +562,7 @@ def test_create_oog_from_call_refunds( ) + Op.RETURN(offset=0x0, size=0x1388), nonce=0, - address=Address(0x000000000000000000000000000000000000003B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000004B), # noqa: E501 ) # Source: yul # berlin @@ -436,48 +570,22 @@ def test_create_oog_from_call_refunds( # sstore(0, 1) # sstore(1, 1) # pop(delegatecall(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0)) # noqa: E501 - # invalid() - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xC0DEA, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=0x0, - ) - ) - + Op.INVALID, - nonce=0, - address=Address(0x000000000000000000000000000000000000003C), # noqa: E501 - ) - # Source: yul - # berlin - # { - # sstore(0, 1) - # sstore(1, 1) - # pop(callcode(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 1) + # return(0, 5000) # } - contract_10 = pre.deploy_contract( # noqa: F841 + contract_8 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.CALLCODE( + + Op.DELEGATECALL( gas=Op.GAS, - address=0xC0DEA, - value=Op.DUP1, + address=contract_25, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1), + + Op.RETURN(offset=0x0, size=0x1388), nonce=0, - address=Address(0x000000000000000000000000000000000000004A), # noqa: E501 + address=Address(0x000000000000000000000000000000000000003B), # noqa: E501 ) # Source: yul # berlin @@ -485,23 +593,23 @@ def test_create_oog_from_call_refunds( # sstore(0, 1) # sstore(1, 1) # pop(callcode(gas(), 0x00000000000000000000000000000000000c0deA, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 5000) + # return(0, 1) # } - contract_11 = pre.deploy_contract( # noqa: F841 + contract_10 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.CALLCODE( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1388), + + Op.RETURN(offset=0x0, size=0x1), nonce=0, - address=Address(0x000000000000000000000000000000000000004B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000004A), # noqa: E501 ) # Source: yul # berlin @@ -517,7 +625,7 @@ def test_create_oog_from_call_refunds( + Op.POP( Op.CALLCODE( gas=Op.GAS, - address=0xC0DEA, + address=contract_25, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -534,44 +642,44 @@ def test_create_oog_from_call_refunds( # { # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deD, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 1) + # return(0, 5000) # } - contract_13 = pre.deploy_contract( # noqa: F841 + contract_14 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DED, + address=contract_26, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1), + + Op.RETURN(offset=0x0, size=0x1388), nonce=0, - address=Address(0x000000000000000000000000000000000000005A), # noqa: E501 + address=Address(0x000000000000000000000000000000000000005B), # noqa: E501 ) # Source: yul # berlin # { # sstore(0, 1) # pop(call(gas(), 0x00000000000000000000000000000000000c0deD, 0, 0, 0, 0, 0)) # noqa: E501 - # return(0, 5000) + # return(0, 1) # } - contract_14 = pre.deploy_contract( # noqa: F841 + contract_13 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DED, + address=contract_26, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, ret_offset=Op.DUP1, ret_size=0x0, ) - + Op.RETURN(offset=0x0, size=0x1388), + + Op.RETURN(offset=0x0, size=0x1), nonce=0, - address=Address(0x000000000000000000000000000000000000005B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000005A), # noqa: E501 ) # Source: yul # berlin @@ -585,7 +693,7 @@ def test_create_oog_from_call_refunds( + Op.POP( Op.CALL( gas=Op.GAS, - address=0xC0DED, + address=contract_26, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -608,7 +716,7 @@ def test_create_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DE0, + address=contract_27, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -630,7 +738,7 @@ def test_create_oog_from_call_refunds( code=Op.SSTORE(key=0x0, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xC0DE0, + address=contract_27, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -653,7 +761,7 @@ def test_create_oog_from_call_refunds( + Op.POP( Op.CALL( gas=Op.GAS, - address=0xC0DE0, + address=contract_27, value=Op.DUP1, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -674,43 +782,10 @@ def test_create_oog_from_call_refunds( # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create(0, 0, initcodelength)) - # return(add(initcodelength, 1), 1) - # } - contract_19 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x1] - + Op.PUSH1[0x0] - + Op.SSTORE(key=Op.DUP2, value=Op.DUP2) - + Op.SSTORE(key=Op.DUP3, value=Op.DUP1) - + Op.DUP2 - + Op.SWAP1 - + Op.PUSH3[0xC0DE1] - + Op.EXTCODESIZE(address=Op.DUP1) - + Op.SWAP2 - + Op.DUP3 - + Op.SWAP2 - + Op.DUP2 - + Op.SWAP1 - + Op.EXTCODECOPY - + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) - + Op.ADD - + Op.RETURN, - nonce=0, - address=Address(0x000000000000000000000000000000000000007A), # noqa: E501 - ) - # Source: yul - # berlin - # { - # sstore(0, 1) - # sstore(1, 1) - # sstore(1, 0) - # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 - # let initcodelength := extcodesize(initcodeaddr) - # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create(0, 0, initcodelength)) + # pop(create2(0, 0, initcodelength, 0)) # return(add(initcodelength, 1), 5000) # } - contract_20 = pre.deploy_contract( # noqa: F841 + contract_23 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) @@ -724,11 +799,13 @@ def test_create_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) + + Op.POP( + Op.CREATE2(value=Op.DUP1, offset=Op.DUP2, size=Op.DUP2, salt=0x0) + ) + Op.ADD + Op.RETURN, nonce=0, - address=Address(0x000000000000000000000000000000000000007B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000008B), # noqa: E501 ) # Source: yul # berlin @@ -739,14 +816,15 @@ def test_create_oog_from_call_refunds( # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create(0, 0, initcodelength)) + # pop(create2(0, 0, initcodelength, 0)) # invalid() # } - contract_21 = pre.deploy_contract( # noqa: F841 + contract_24 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) + Op.PUSH1[0x0] + + Op.DUP1 + Op.PUSH3[0xC0DE1] + Op.DUP2 + Op.EXTCODESIZE(address=Op.DUP2) @@ -754,50 +832,12 @@ def test_create_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.PUSH1[0x0] - + Op.DUP1 - + Op.POP(Op.CREATE) - + Op.INVALID, - nonce=0, - address=Address(0x000000000000000000000000000000000000007C), # noqa: E501 - ) - # Source: yul - # berlin - # { - # sstore(0, 1) - # sstore(1, 1) - # sstore(1, 0) - # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 - # //let initcodelength := extcodesize(initcodeaddr) - # //extcodecopy(initcodeaddr, 0, 0, initcodelength) - # - # // protection from solc version changing init code - # let initcodelength := 15 - # mstore(0, 0x6001600055600060005560016000f30000000000000000000000000000000000) # noqa: E501 - # - # pop(create2(0, 0, initcodelength, 0)) - # return(add(initcodelength, 1), 1) - # } - contract_22 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x1] - + Op.PUSH1[0x0] - + Op.SSTORE(key=Op.DUP2, value=Op.DUP2) - + Op.SSTORE(key=Op.DUP3, value=Op.DUP1) - + Op.MSTORE( - offset=Op.DUP2, - value=0x6001600055600060005560016000F30000000000000000000000000000000000, # noqa: E501 - ) + Op.DUP2 - + Op.SWAP1 - + Op.PUSH1[0xF] - + Op.SWAP1 - + Op.DUP2 * 2 + Op.DUP1 + Op.POP(Op.CREATE2) - + Op.ADD - + Op.RETURN, + + Op.INVALID, nonce=0, - address=Address(0x000000000000000000000000000000000000008A), # noqa: E501 + address=Address(0x000000000000000000000000000000000000008C), # noqa: E501 ) # Source: yul # berlin @@ -808,10 +848,10 @@ def test_create_oog_from_call_refunds( # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create2(0, 0, initcodelength, 0)) + # pop(create(0, 0, initcodelength)) # return(add(initcodelength, 1), 5000) # } - contract_23 = pre.deploy_contract( # noqa: F841 + contract_20 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) @@ -825,13 +865,11 @@ def test_create_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.POP( - Op.CREATE2(value=Op.DUP1, offset=Op.DUP2, size=Op.DUP2, salt=0x0) - ) + + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) + Op.ADD + Op.RETURN, nonce=0, - address=Address(0x000000000000000000000000000000000000008B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000007B), # noqa: E501 ) # Source: yul # berlin @@ -842,15 +880,14 @@ def test_create_oog_from_call_refunds( # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 # let initcodelength := extcodesize(initcodeaddr) # extcodecopy(initcodeaddr, 0, 0, initcodelength) - # pop(create2(0, 0, initcodelength, 0)) + # pop(create(0, 0, initcodelength)) # invalid() # } - contract_24 = pre.deploy_contract( # noqa: F841 + contract_21 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) + Op.SSTORE(key=Op.DUP1, value=0x1) + Op.SSTORE(key=0x1, value=0x0) + Op.PUSH1[0x0] - + Op.DUP1 + Op.PUSH3[0xC0DE1] + Op.DUP2 + Op.EXTCODESIZE(address=Op.DUP2) @@ -858,82 +895,45 @@ def test_create_oog_from_call_refunds( + Op.DUP4 + Op.SWAP3 + Op.EXTCODECOPY - + Op.DUP2 + + Op.PUSH1[0x0] + Op.DUP1 - + Op.POP(Op.CREATE2) + + Op.POP(Op.CREATE) + Op.INVALID, nonce=0, - address=Address(0x000000000000000000000000000000000000008C), # noqa: E501 - ) - # Source: yul - # berlin - # { - # // Simple SSTORE to zero to get a refund - # sstore(1, 0) - # } - contract_25 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, - storage={1: 1}, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DEA), # noqa: E501 - ) - # Source: yul - # berlin - # { - # selfdestruct(origin()) - # } - contract_26 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=Op.ORIGIN), - storage={1: 1}, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DED), # noqa: E501 - ) - # Source: yul - # berlin - # { - # mstore(0, 0xff) - # log0(0, 32) - # log1(0, 32, 0xfa) - # log2(0, 32, 0xfa, 0xfb) - # log3(0, 32, 0xfa, 0xfb, 0xfc) - # log4(0, 32, 0xfa, 0xfb, 0xfc, 0xfd) - # } - contract_27 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0xFF) - + Op.LOG0(offset=0x0, size=0x20) - + Op.LOG1(offset=0x0, size=0x20, topic_1=0xFA) - + Op.LOG2(offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB) - + Op.LOG3( - offset=0x0, size=0x20, topic_1=0xFA, topic_2=0xFB, topic_3=0xFC - ) - + Op.LOG4( - offset=0x0, - size=0x20, - topic_1=0xFA, - topic_2=0xFB, - topic_3=0xFC, - topic_4=0xFD, - ) - + Op.STOP, - storage={1: 1}, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DE0), # noqa: E501 + address=Address(0x000000000000000000000000000000000000007C), # noqa: E501 ) # Source: yul # berlin # { # sstore(0, 1) - # sstore(0, 0) - # return(0, 1) + # sstore(1, 1) + # sstore(1, 0) + # let initcodeaddr := 0x00000000000000000000000000000000000c0de1 + # let initcodelength := extcodesize(initcodeaddr) + # extcodecopy(initcodeaddr, 0, 0, initcodelength) + # pop(create(0, 0, initcodelength)) + # return(add(initcodelength, 1), 1) # } - contract_28 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.SSTORE(key=Op.DUP1, value=Op.DUP1) - + Op.PUSH1[0x1] + contract_19 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x1] + + Op.PUSH1[0x0] + + Op.SSTORE(key=Op.DUP2, value=Op.DUP2) + + Op.SSTORE(key=Op.DUP3, value=Op.DUP1) + + Op.DUP2 + + Op.SWAP1 + + Op.PUSH3[0xC0DE1] + + Op.EXTCODESIZE(address=Op.DUP1) + + Op.SWAP2 + + Op.DUP3 + + Op.SWAP2 + + Op.DUP2 + Op.SWAP1 + + Op.EXTCODECOPY + + Op.POP(Op.CREATE(value=Op.DUP1, offset=0x0, size=Op.DUP1)) + + Op.ADD + Op.RETURN, - nonce=1, - address=Address(0x00000000000000000000000000000000000C0DE1), # noqa: E501 + nonce=0, + address=Address(0x000000000000000000000000000000000000007A), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -1013,9 +1013,12 @@ def test_create_oog_from_call_refunds( compute_create_address(address=contract_0, nonce=1): Account( storage={0: 1}, code=bytes.fromhex("00"), nonce=2 ), - Address(0x522C2E1C5DA65010908EF9929E327FE8B6CC86DA): Account( - storage={}, code=bytes.fromhex("00"), nonce=1 - ), + compute_create_address( + address=compute_create_address( + address=contract_0, nonce=1 + ), + nonce=1, + ): Account(storage={}, code=bytes.fromhex("00"), nonce=1), }, }, { @@ -1026,8 +1029,11 @@ def test_create_oog_from_call_refunds( compute_create_address( address=contract_0, nonce=1 ): Account.NONEXISTENT, - Address( - 0x522C2E1C5DA65010908EF9929E327FE8B6CC86DA + compute_create_address( + address=compute_create_address( + address=contract_0, nonce=1 + ), + nonce=1, ): Account.NONEXISTENT, }, }, diff --git a/tests/ported_static/stCreateTest/test_create_results.py b/tests/ported_static/stCreateTest/test_create_results.py index e11d6b9cbee..67af6122a4d 100644 --- a/tests/ported_static/stCreateTest/test_create_results.py +++ b/tests/ported_static/stCreateTest/test_create_results.py @@ -218,6 +218,7 @@ def test_create_results( gas_limit=4294967296, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # ; Variables are 0x20 bytes (= 256 bits) apart, except for @@ -571,13 +572,13 @@ def test_create_results( ) + Op.STOP, storage={ - 16: 24743, - 18: 24743, - 19: 24743, - 20: 24743, - 21: 24743, - 32: 24743, - 33: 24743, + 16: contract_1, + 18: contract_1, + 19: contract_1, + 20: contract_1, + 21: contract_1, + 32: contract_1, + 33: contract_1, }, balance=0xBA1A9CE0BA1A9CE, nonce=0, @@ -593,7 +594,6 @@ def test_create_results( nonce=0, address=Address(0x00000000000000000000000000000000000060A7), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { @@ -601,7 +601,7 @@ def test_create_results( "network": [">=Cancun"], "result": { contract_0: Account(storage={32: 295, 33: 551}), - contract_1: Account(storage={0: 24743}), + contract_1: Account(storage={0: contract_1}), }, }, { @@ -621,8 +621,8 @@ def test_create_results( storage={ 18: 18, 19: 0x600060006000600060006160A761FFFFF1000000000000000000000000000000, # noqa: E501 - 20: 24743, - 21: 24743, + 20: contract_1, + 21: contract_1, 32: 295, 33: 551, }, @@ -636,11 +636,11 @@ def test_create_results( contract_0: Account( storage={ 16: 32, - 17: 24743, + 17: contract_1, 18: 18, 19: 0x600060006000600060006160A761FFFFF1000000000000000000000000000000, # noqa: E501 - 20: 24743, - 21: 24743, + 20: contract_1, + 21: contract_1, 32: 295, 33: 551, }, @@ -657,14 +657,14 @@ def test_create_results( "result": { contract_0: Account( storage={ - 16: 24743, + 16: contract_1, 17: 0, - 18: 24743, - 19: 24743, - 20: 24743, - 21: 24743, - 32: 24743, - 33: 24743, + 18: contract_1, + 19: contract_1, + 20: contract_1, + 21: contract_1, + 32: contract_1, + 33: contract_1, }, ), }, diff --git a/tests/ported_static/stCreateTest/test_create_transaction_call_data.py b/tests/ported_static/stCreateTest/test_create_transaction_call_data.py index c5b75faf700..e30600d6af6 100644 --- a/tests/ported_static/stCreateTest/test_create_transaction_call_data.py +++ b/tests/ported_static/stCreateTest/test_create_transaction_call_data.py @@ -9,7 +9,6 @@ import pytest from execution_testing import ( - EOA, Account, Alloc, Environment, @@ -64,9 +63,7 @@ def test_create_transaction_call_data( v: int, ) -> None: """Tests if CALLDATALOAD, CALLDATACOPY, CODECOPY and CODESIZE work...""" - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5AF3107A4000) env = Environment( fee_recipient=sender, @@ -77,8 +74,6 @@ def test_create_transaction_call_data( gas_limit=1000000, ) - pre[sender] = Account(balance=0x5AF3107A4000) - expect_entries_: list[dict] = [ { "indexes": {"data": [0, 1], "gas": -1, "value": -1}, diff --git a/tests/ported_static/stCreateTest/test_create_transaction_high_nonce.py b/tests/ported_static/stCreateTest/test_create_transaction_high_nonce.py index c7d88161164..6ba82dc452b 100644 --- a/tests/ported_static/stCreateTest/test_create_transaction_high_nonce.py +++ b/tests/ported_static/stCreateTest/test_create_transaction_high_nonce.py @@ -9,8 +9,6 @@ import pytest from execution_testing import ( - EOA, - Account, Alloc, Environment, StateTestFiller, @@ -60,9 +58,7 @@ def test_create_transaction_high_nonce( v: int, ) -> None: """The test check if the create transaction is reject if the origin's...""" - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5AF3107A4000, nonce=18446744073709551615) env = Environment( fee_recipient=sender, @@ -73,8 +69,6 @@ def test_create_transaction_high_nonce( gas_limit=1000000, ) - pre[sender] = Account(balance=0x5AF3107A4000, nonce=18446744073709551615) - expect_entries_: list[dict] = [ { "indexes": {"data": -1, "gas": -1, "value": -1}, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call1024_balance_too_low.py b/tests/ported_static/stDelegatecallTestHomestead/test_call1024_balance_too_low.py index 4aa2d08d313..ea046c78c62 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call1024_balance_too_low.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call1024_balance_too_low.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,10 +35,7 @@ def test_call1024_balance_too_low( ) -> None: """Test_call1024_balance_too_low.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -50,8 +46,7 @@ def test_call1024_balance_too_low( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (DELEGATECALL 0xfffffffffff 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call1024_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_call1024_oog.py index d2b7489c66b..2eb7e09753e 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call1024_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call1024_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,10 +57,7 @@ def test_call1024_oog( ) -> None: """Test_call1024_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -72,8 +68,7 @@ def test_call1024_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (DELEGATECALL (MUL (SUB (GAS) 10000) (SUB 1 (DIV @@0 1025))) 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_lose_gas_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_lose_gas_oog.py index ae2ab2786c4..6c3d024c7a4 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_lose_gas_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_lose_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_call_lose_gas_oog( ) -> None: """Test_call_lose_gas_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_call_lose_gas_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (DELEGATECALL (ADD 1(MUL @@0 100000)) 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_output1.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_output1.py index a34e21f9c05..e5ab00975ff 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_output1.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_output1.py @@ -46,6 +46,15 @@ def test_call_output1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (DELEGATECALL 50000 0 0 0 0) [[ 0 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output1( + Op.POP( Op.DELEGATECALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,15 +78,6 @@ def test_call_output1( nonce=0, address=Address(0x79ACCF3A3F2D0E87BEB2D0F72039A5AA27D46426), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_output2.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_output2.py index d50c8cfcb67..40d1f6758af 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_output2.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_output2.py @@ -46,6 +46,15 @@ def test_call_output2( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (DELEGATECALL 50000 0 32 0 0) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output2( + Op.POP( Op.DELEGATECALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x20, ret_offset=0x0, @@ -69,15 +78,6 @@ def test_call_output2( nonce=0, address=Address(0x6F04A8BA354531ECD357E2CD4DDB43140F1E5FC9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_output3.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_output3.py index 038fab4be3b..dd3cd83e332 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_output3.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_output3.py @@ -46,6 +46,15 @@ def test_call_output3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (DELEGATECALL 50000 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output3( + Op.POP( Op.DELEGATECALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,15 +78,6 @@ def test_call_output3( nonce=0, address=Address(0x4E40004DEDFDAD4927C60DE1289AB14535F5121A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial.py index 876cf5a8de2..2f4902b73d1 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial.py @@ -46,6 +46,15 @@ def test_call_output3partial( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (DELEGATECALL 50000 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_call_output3partial( + Op.POP( Op.DELEGATECALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,15 +78,6 @@ def test_call_output3partial( nonce=0, address=Address(0xEFB6356473F53E06A8627E7AC82AB3AB3D24E68A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial_fail.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial_fail.py index 2fd02853949..e7f0b8e4810 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial_fail.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_output3partial_fail.py @@ -48,6 +48,15 @@ def test_call_output3partial_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (DELEGATECALL 50000 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +67,7 @@ def test_call_output3partial_fail( + Op.POP( Op.DELEGATECALL( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -71,15 +80,6 @@ def test_call_output3partial_fail( nonce=0, address=Address(0xEFB6356473F53E06A8627E7AC82AB3AB3D24E68A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_recursive_bomb_pre_call.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_recursive_bomb_pre_call.py index eb37a533df6..6460d6ad306 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_recursive_bomb_pre_call.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_recursive_bomb_pre_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_call_recursive_bomb_pre_call( ) -> None: """Test_call_recursive_bomb_pre_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x77F65B71F1F16A75476F469F7106D1B60BFEC266AE25B8DA16A9091D223AA24A - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -97,7 +94,6 @@ def test_call_recursive_bomb_pre_call( nonce=0, address=Address(0x3046257C307A51F1A8AE73F6F6360937DD21138E), # noqa: E501 ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_call_with_high_value_and_gas_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_call_with_high_value_and_gas_oog.py index 52223519a53..10228549068 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_call_with_high_value_and_gas_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_call_with_high_value_and_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_with_high_value_and_gas_oog( ) -> None: """Test_call_with_high_value_and_gas_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_call_with_high_value_and_gas_oog( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (DELEGATECALL 0xffffffffffffffffffffffff 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +69,7 @@ def test_call_with_high_value_and_gas_oog( key=0x0, value=Op.DELEGATECALL( gas=0xFFFFFFFFFFFFFFFFFFFFFFFF, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -73,19 +79,7 @@ def test_call_with_high_value_and_gas_oog( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA7465A0005567E06FBAA3AE783E57F22419C5A0A), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_callcode_lose_gas_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_callcode_lose_gas_oog.py index c378f284126..37d33839061 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_callcode_lose_gas_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_callcode_lose_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,10 +63,7 @@ def test_callcode_lose_gas_oog( ) -> None: """Test_callcode_lose_gas_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -78,8 +74,7 @@ def test_callcode_lose_gas_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (DELEGATECALL (ADD 1(MUL @@0 100000)) 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_callcode_output3.py b/tests/ported_static/stDelegatecallTestHomestead/test_callcode_output3.py index ed42703b0fa..c90119c6d77 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_callcode_output3.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_callcode_output3.py @@ -46,6 +46,15 @@ def test_callcode_output3( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (DELEGATECALL 50000 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_callcode_output3( + Op.POP( Op.DELEGATECALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,15 +78,6 @@ def test_callcode_output3( nonce=0, address=Address(0x4E40004DEDFDAD4927C60DE1289AB14535F5121A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_callcode_with_high_value_and_gas_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_callcode_with_high_value_and_gas_oog.py index 842f5448d2e..3d9988dab1b 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_callcode_with_high_value_and_gas_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_callcode_with_high_value_and_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_with_high_value_and_gas_oog( ) -> None: """Test_callcode_with_high_value_and_gas_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_callcode_with_high_value_and_gas_oog( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (DELEGATECALL 0xffffffffffffffffffffffff 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +69,7 @@ def test_callcode_with_high_value_and_gas_oog( key=0x0, value=Op.DELEGATECALL( gas=0xFFFFFFFFFFFFFFFFFFFFFFFF, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -73,19 +79,7 @@ def test_callcode_with_high_value_and_gas_oog( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA7465A0005567E06FBAA3AE783E57F22419C5A0A), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_deleagate_call_after_value_transfer.py b/tests/ported_static/stDelegatecallTestHomestead/test_deleagate_call_after_value_transfer.py index d413b7f60ff..a17a34fd41e 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_deleagate_call_after_value_transfer.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_deleagate_call_after_value_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_deleagate_call_after_value_transfer( ) -> None: """Test_deleagate_call_after_value_transfer.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x3722FAAB4D25B944622D559EA4BCF38B4BCF3CAF07A6D2C6FD99321C1A66C974 - ) + sender = pre.fund_eoa(amount=0x2386F26FC10000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,22 @@ def test_deleagate_call_after_value_transfer( gas_limit=1000000, ) + # Source: lll + # { (SSTORE 0 (CALLVALUE)) (SSTORE 1 (CALLER)) (SSTORE 2 (CALLDATALOAD 0)) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.CALLVALUE) + + Op.SSTORE(key=0x1, value=Op.CALLER) + + Op.SSTORE(key=0x2, value=Op.CALLDATALOAD(offset=0x0)) + + Op.STOP, + nonce=0, + ) # Source: lll # { (MSTORE 0 0x01) (DELEGATECALL 100000 0 64 0 64) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=0x1) + Op.DELEGATECALL( gas=0x186A0, - address=0x346AA231CB52F55DDF201DC19CA469CC73E6495, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,19 +69,7 @@ def test_deleagate_call_after_value_transfer( + Op.STOP, balance=0x10C8E0, nonce=0, - address=Address(0xDD657898B318B3D967472EAA82BB75C4141B6735), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (CALLVALUE)) (SSTORE 1 (CALLER)) (SSTORE 2 (CALLDATALOAD 0)) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.CALLVALUE) - + Op.SSTORE(key=0x1, value=Op.CALLER) - + Op.SSTORE(key=0x2, value=Op.CALLDATALOAD(offset=0x0)) - + Op.STOP, - nonce=0, - address=Address(0x0346AA231CB52F55DDF201DC19CA469CC73E6495), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, @@ -85,13 +79,7 @@ def test_deleagate_call_after_value_transfer( ) post = { - target: Account( - storage={ - 0: 0, - 1: 0x6FDA566D1950D7E0A4DAC1DE87109B2CA7D12DA4, - 2: 1, - }, - ), + target: Account(storage={0: 0, 1: sender, 2: 1}), addr: Account(storage={0: 0, 1: 0, 2: 0}), } diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024.py index 21c52e64dd9..fc95b4c8ca8 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,10 +33,7 @@ def test_delegatecall1024( ) -> None: """Test_delegatecall1024.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,7 @@ def test_delegatecall1024( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (DELEGATECALL 0xfffffffffff 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024_oog.py index 8abb223e58d..42959c58111 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall1024_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_delegatecall1024_oog( ) -> None: """Test_delegatecall1024_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_delegatecall1024_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (DELEGATECALL (MUL (SUB (GAS) 10000) (SUB 1 (DIV @@0 1025))) 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_and_oo_gat_tx_level.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_and_oo_gat_tx_level.py index 6ccacffd7df..8b5a6413104 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_and_oo_gat_tx_level.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_and_oo_gat_tx_level.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_delegatecall_and_oo_gat_tx_level( ) -> None: """Test_delegatecall_and_oo_gat_tx_level.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_delegatecall_and_oo_gat_tx_level( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 3000001 0 0 0 0 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +61,7 @@ def test_delegatecall_and_oo_gat_tx_level( key=0x0, value=Op.DELEGATECALL( gas=0x2DC6C1, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -65,19 +71,7 @@ def test_delegatecall_and_oo_gat_tx_level( + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x830AB9AD91366BFB2BB745E4A637F97B25087928), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_basic.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_basic.py index 79d25d26e1b..9ff0b5b6fce 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_basic.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_basic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_delegatecall_basic( ) -> None: """Test_delegatecall_basic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_delegatecall_basic( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 500000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +59,7 @@ def test_delegatecall_basic( key=0x0, value=Op.DELEGATECALL( gas=0x7A120, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,19 +69,7 @@ def test_delegatecall_basic( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x55BB8A8658B848EBBBB73CBF6AC9D59D715AEC58), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_emptycontract.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_emptycontract.py index 1e09d014260..60b0410f6c4 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_emptycontract.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_emptycontract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_delegatecall_emptycontract( ) -> None: """Test_delegatecall_emptycontract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x11489F9B076D3F3185EBE5C6E2DBEDBE9E283A6CE75895780134252B3DD5DBCC - ) + sender = pre.fund_eoa(amount=0x10C8E0) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_delegatecall_emptycontract( + Op.STOP, balance=1000, nonce=0, - address=Address(0x4A88CF3B3F1DABDD27E62FCB5DF86D7D685E0044), # noqa: E501 ) - pre[sender] = Account(balance=0x10C8E0) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_empty_contract.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_empty_contract.py index 853a44901bd..1cac7ff8c76 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_empty_contract.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_empty_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_delegatecall_in_initcode_to_empty_contract( """Test_delegatecall_in_initcode_to_empty_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x2386F26FC10000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_delegatecall_in_initcode_to_empty_contract( + Op.STOP, balance=10000, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract.py index 2064cc786a3..e20c162ae59 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract.py @@ -52,6 +52,7 @@ def test_delegatecall_in_initcode_to_existing_contract( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (MSTORE 0 0x604060006040600073945304eb96065b2a98b57a48a06ae28d285a71b5620186) (MSTORE 32 0xa0f4600055336001550000000000000000000000000000000000000000000000) (CREATE 1 0 64) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -88,7 +89,6 @@ def test_delegatecall_in_initcode_to_existing_contract( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, @@ -99,12 +99,7 @@ def test_delegatecall_in_initcode_to_existing_contract( post = { compute_create_address(address=contract_0, nonce=0): Account( - storage={ - 0: 1, - 1: 0x1000000000000000000000000000000000000000, - 2: 1, - 11: 0x1000000000000000000000000000000000000000, - }, + storage={0: 1, 1: contract_0, 2: 1, 11: contract_0}, balance=1, ), } diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract_oog.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract_oog.py index a3bbd9709e6..b9d882a9583 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract_oog.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_in_initcode_to_existing_contract_oog.py @@ -51,6 +51,7 @@ def test_delegatecall_in_initcode_to_existing_contract_oog( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (MSTORE 0 0x604060006040600073945304eb96065b2a98b57a48a06ae28d285a71b5620186) (MSTORE 32 0xa0f4600a5533600b550000000000000000000000000000000000000000000000) (CREATE 5 0 64) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -75,7 +76,6 @@ def test_delegatecall_in_initcode_to_existing_contract_oog( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_oo_gin_call.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_oo_gin_call.py index 2e046ecfb4e..f56089b6c0a 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_oo_gin_call.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_oo_gin_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_delegatecall_oo_gin_call( ) -> None: """Test_delegatecall_oo_gin_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_delegatecall_oo_gin_call( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (ADD (DELEGATECALL 10000 0 0 0 0 ) 1) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +62,7 @@ def test_delegatecall_oo_gin_call( value=Op.ADD( Op.DELEGATECALL( gas=0x2710, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,19 +74,7 @@ def test_delegatecall_oo_gin_call( + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0xC0EEE677168D4ABE7E0974EF0A4284CCA6133B11), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_sender_check.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_sender_check.py index 24ad9900bc6..1a8518db75f 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_sender_check.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_sender_check.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_delegatecall_sender_check( ) -> None: """Test_delegatecall_sender_check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,13 @@ def test_delegatecall_sender_check( gas_limit=30000000, ) + # Source: lll + # {[[ 1 ]] (CALLER)} + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=Op.CALLER) + Op.STOP, + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 500000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +59,7 @@ def test_delegatecall_sender_check( key=0x0, value=Op.DELEGATECALL( gas=0x7A120, - address=0x7607CC240D38CCF9B55D1EEB1DF0C187F8EC28C1, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -65,17 +69,7 @@ def test_delegatecall_sender_check( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x55BB8A8658B848EBBBB73CBF6AC9D59D715AEC58), # noqa: E501 - ) - # Source: lll - # {[[ 1 ]] (CALLER)} - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=Op.CALLER) + Op.STOP, - balance=23, - nonce=0, - address=Address(0x7607CC240D38CCF9B55D1EEB1DF0C187F8EC28C1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -84,13 +78,6 @@ def test_delegatecall_sender_check( gas_limit=3000000, ) - post = { - target: Account( - storage={ - 0: 1, - 1: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), - } + post = {target: Account(storage={0: 1, 1: sender})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_value_check.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_value_check.py index 8c7005b3242..9d544dbdff8 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_value_check.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecall_value_check.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_delegatecall_value_check( ) -> None: """Test_delegatecall_value_check.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,13 @@ def test_delegatecall_value_check( gas_limit=30000000, ) + # Source: lll + # {[[ 1 ]] (CALLVALUE) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=Op.CALLVALUE) + Op.STOP, + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 500000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +59,7 @@ def test_delegatecall_value_check( key=0x0, value=Op.DELEGATECALL( gas=0x7A120, - address=0x5D25AD2A26F849E9400D6B65244F26F4EEA11ADF, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -65,17 +69,7 @@ def test_delegatecall_value_check( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x55BB8A8658B848EBBBB73CBF6AC9D59D715AEC58), # noqa: E501 - ) - # Source: lll - # {[[ 1 ]] (CALLVALUE) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=Op.CALLVALUE) + Op.STOP, - balance=23, - nonce=0, - address=Address(0x5D25AD2A26F849E9400D6B65244F26F4EEA11ADF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code.py index e1cda9b2948..13cf2e5404a 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code.py @@ -50,6 +50,7 @@ def test_delegatecode_dynamic_code( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # { (MSTORE 0 0x716860016000553360145560005260096017f36000526012600e6001f0600a55) (MSTORE 32 0x604060006040600073ffe4ebd2a68c02d9dcb0a17283d13346beb2d8b6620186) (MSTORE 64 0xa0f4600b55000000000000000000000000000000000000000000000000000000) (CREATE 1 0 96) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_delegatecode_dynamic_code( nonce=0, address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, @@ -81,8 +81,9 @@ def test_delegatecode_dynamic_code( ) post = { - Address( - 0xFFE4EBD2A68C02D9DCB0A17283D13346BEB2D8B6 + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=0, ): Account.NONEXISTENT, compute_create_address(address=contract_0, nonce=0): Account( storage={ diff --git a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code2_self_call.py b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code2_self_call.py index 9b084d3e8a5..dafe15bd0c0 100644 --- a/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code2_self_call.py +++ b/tests/ported_static/stDelegatecallTestHomestead/test_delegatecode_dynamic_code2_self_call.py @@ -50,6 +50,7 @@ def test_delegatecode_dynamic_code2_self_call( gas_limit=1000000, ) + pre[sender] = Account(balance=0x2386F26FC10000) # Source: lll # {(MSTORE 0 0x60406000604060007313136008b64ff592819b2fa6d43f2835c452020e620186) (MSTORE 32 0xa0f4600b5533600c550000000000000000000000000000000000000000000000) (CREATE 1 0 64) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_delegatecode_dynamic_code2_self_call( nonce=0, address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x2386F26FC10000) tx = Transaction( sender=sender, @@ -78,11 +78,7 @@ def test_delegatecode_dynamic_code2_self_call( post = { compute_create_address(address=contract_0, nonce=0): Account( - storage={ - 11: 1, - 12: 0x1000000000000000000000000000000000000000, - }, - balance=1, + storage={11: 1, 12: contract_0}, balance=1 ), } diff --git a/tests/ported_static/stEIP1153_transientStorage/test_10_revert_undoes_store_after_return.py b/tests/ported_static/stEIP1153_transientStorage/test_10_revert_undoes_store_after_return.py index c420133644f..888bace084d 100644 --- a/tests/ported_static/stEIP1153_transientStorage/test_10_revert_undoes_store_after_return.py +++ b/tests/ported_static/stEIP1153_transientStorage/test_10_revert_undoes_store_after_return.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_10_revert_undoes_store_after_return( ) -> None: """Revert undoes the transient storage writes after a successful call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xBE0E7D5FEA1604BF57E004B0B414DF8DE04816DBB1C8F8719B725D0D6619B531 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -136,9 +133,7 @@ def test_10_revert_undoes_store_after_return( storage={1: 65535}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE42B9E92D5348B0FC6353D40E3D220C316D3C685), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP1153_transientStorage/test_14_revert_after_nested_staticcall.py b/tests/ported_static/stEIP1153_transientStorage/test_14_revert_after_nested_staticcall.py index f54778b0312..c68b03a7c0c 100644 --- a/tests/ported_static/stEIP1153_transientStorage/test_14_revert_after_nested_staticcall.py +++ b/tests/ported_static/stEIP1153_transientStorage/test_14_revert_after_nested_staticcall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_14_revert_after_nested_staticcall( ) -> None: """Transient storage can't be manipulated from nested staticcall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xBE0E7D5FEA1604BF57E004B0B414DF8DE04816DBB1C8F8719B725D0D6619B531 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -134,9 +131,7 @@ def test_14_revert_after_nested_staticcall( storage={1: 65535}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1150BAFF55FDCEA5FD92B0995358EC0C416DEBE3), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_ok.py b/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_ok.py index c0dbd690ffd..818e6e4d756 100644 --- a/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_ok.py +++ b/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_ok.py @@ -168,6 +168,7 @@ def test_trans_storage_ok( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # { # // These two functions use transient storage. @@ -557,117 +558,6 @@ def test_trans_storage_ok( # verbatim_2i_0o(hex"5D", loc, val) # } # - # // If we are called by 0xca11bacc, this is part of the loop - # if eq(caller(), 0xca11bacc) { - # let counter := tload_temp(0) - # - # // If the counter is equal to zero, we're done - return. - # if eq(counter,0) { - # return(0,0) - # } - # - # // If counter isn't zero, add counter to Trans[1] and do recursion - # tstore_temp(1, add(tload_temp(1), counter)) - # - # // Change the loop variable and call 0xca11bacc, which calls us back. # noqa: E501 - # tstore_temp(0, sub(counter, 1)) - # let res := call(gas(), 0xca11bacc, 0, 0,0, 0,0) - # if iszero(res) { // If the call failed, fail too - # revert(0,0) - # } - # } - # - # // If called by a different address from 0xca11bacc, we are the first - # ... (12 more lines) - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI(pc=0x3F, condition=Op.EQ(Op.CALLER, 0xCA11BACC)) - + Op.JUMPDEST - + Op.JUMPI(pc=0x16, condition=Op.SUB(Op.CALLER, 0xCA11BACC)) - + Op.STOP - + Op.JUMPDEST - + Op.PUSH1[0x23] - + Op.CALLDATALOAD(offset=Op.PUSH0) - + Op.SSTORE(key=0x1, value=Op.DUP1) - + Op.PUSH0 - + Op.JUMP(pc=0x7F) - + Op.JUMPDEST - + Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=Op.GAS, - address=0xCA11BACC, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=Op.PUSH0, - ), - ) - + Op.PUSH1[0x3A] - + Op.PUSH1[0x1] - + Op.JUMP(pc=0x7B) - + Op.JUMPDEST - + Op.PUSH1[0x3] - + Op.SSTORE - + Op.STOP - + Op.JUMPDEST - + Op.PUSH1[0x46] - + Op.PUSH0 - + Op.JUMP(pc=0x7B) - + Op.JUMPDEST - + Op.JUMPI(pc=0x79, condition=Op.ISZERO(Op.DUP1)) - + Op.PUSH1[0x1] - + Op.DUP2 - + Op.PUSH1[0x60] - + Op.PUSH1[0x66] - + Op.SWAP4 - + Op.PUSH1[0x5A] - + Op.DUP5 - + Op.JUMP(pc=0x7B) - + Op.JUMPDEST - + Op.ADD - + Op.DUP4 - + Op.JUMP(pc=0x7F) - + Op.JUMPDEST - + Op.SUB - + Op.PUSH0 - + Op.JUMP(pc=0x7F) - + Op.JUMPDEST - + Op.JUMPI( - pc=0xA, - condition=Op.CALL( - gas=Op.GAS, - address=0xCA11BACC, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=Op.PUSH0, - ), - ) - + Op.REVERT(offset=Op.DUP1, size=Op.PUSH0) - + Op.JUMPDEST - + Op.STOP - + Op.JUMPDEST - + Op.TLOAD - + Op.SWAP1 - + Op.JUMP - + Op.JUMPDEST - + Op.TSTORE - + Op.JUMP, - nonce=1, - address=Address(0x000000000000000000000000000000005114E2C8), # noqa: E501 - ) - # Source: yul - # { - # function tload_temp(loc) -> val { - # val := verbatim_1i_1o(hex"5C", loc) - # } - # - # function tstore_temp(loc, val) { - # verbatim_2i_0o(hex"5D", loc, val) - # } - # # // We are inside the loop # if eq(caller(), address()) { # let counter := tload_temp(0) @@ -969,101 +859,6 @@ def test_trans_storage_ok( # verbatim_2i_0o(hex"5D", loc, val) # } # - # // The initial value of the counter is zero - # sstore(0, tload_temp(0)) - # - # // CALLCODE increments our Trans[0] - # sstore(0x11, callcode(gas(), 0xadd1, 0, 0,0, 0,0)) - # sstore(1, tload_temp(0)) - # - # // DELEGATECALL increments our Trans[0] - # sstore(0x12, delegatecall(gas(), 0xadd1, 0,0, 0,0)) - # sstore(2, tload_temp(0)) - # - # // CALL does not increment our Trans[0], it means a different - # // transient storage - # sstore(0x13, call(gas(), 0xadd1, 0, 0,0, 0,0)) - # sstore(3, tload_temp(0)) - # } - contract_8 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x6] - + Op.PUSH0 - + Op.JUMP(pc=0x4E) - + Op.JUMPDEST - + Op.PUSH0 - + Op.SSTORE - + Op.SSTORE( - key=0x11, - value=Op.CALLCODE( - gas=Op.GAS, - address=0xADD1, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=Op.PUSH0, - ), - ) - + Op.PUSH1[0x1C] - + Op.PUSH0 - + Op.JUMP(pc=0x4E) - + Op.JUMPDEST - + Op.PUSH1[0x1] - + Op.SSTORE - + Op.SSTORE( - key=0x12, - value=Op.DELEGATECALL( - gas=Op.GAS, - address=0xADD1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=Op.PUSH0, - ), - ) - + Op.PUSH1[0x32] - + Op.PUSH0 - + Op.JUMP(pc=0x4E) - + Op.JUMPDEST - + Op.PUSH1[0x2] - + Op.SSTORE - + Op.SSTORE( - key=0x13, - value=Op.CALL( - gas=Op.GAS, - address=0xADD1, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=Op.PUSH0, - ), - ) - + Op.PUSH1[0x49] - + Op.PUSH0 - + Op.JUMP(pc=0x4E) - + Op.JUMPDEST - + Op.PUSH1[0x3] - + Op.SSTORE - + Op.STOP - + Op.JUMPDEST - + Op.TLOAD - + Op.SWAP1 - + Op.JUMP, - storage={0: 24743}, - nonce=1, - address=Address(0x000000000000000000000000000000007F9317BD), # noqa: E501 - ) - # Source: yul - # { - # function tload_temp(loc) -> val { - # val := verbatim_1i_1o(hex"5C", loc) - # } - # - # function tstore_temp(loc, val) { - # verbatim_2i_0o(hex"5D", loc, val) - # } - # # // If we are at the bottom of the call stack, increment # // the counter and return # if eq(calldatasize(), 0) { @@ -1227,6 +1022,237 @@ def test_trans_storage_ok( ) # Source: yul # { + # let func := shr(224, calldataload(0)) + # let param := calldataload(4) + # sstore(0, func) + # mstore(0, param) + # sstore(1, call(gas(), func, 0, 0,32, 0,0)) + # } + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH0 + + Op.DUP1 + + Op.PUSH1[0x20] + + Op.DUP2 + + Op.DUP1 + + Op.SHR(0xE0, Op.CALLDATALOAD(offset=Op.DUP1)) + + Op.CALLDATALOAD(offset=0x4) + + Op.SSTORE(key=Op.DUP4, value=Op.DUP2) + + Op.DUP3 + + Op.MSTORE + + Op.GAS + + Op.SSTORE(key=0x1, value=Op.CALL) + + Op.STOP, + nonce=1, + address=Address(0xDD53B677A6FD4E871A6355F283B1BD7CEB95A95E), # noqa: E501 + ) + # Source: yul + # { + # function tload_temp(loc) -> val { + # val := verbatim_1i_1o(hex"5C", loc) + # } + # + # function tstore_temp(loc, val) { + # verbatim_2i_0o(hex"5D", loc, val) + # } + # + # // If we are called by 0xca11bacc, this is part of the loop + # if eq(caller(), 0xca11bacc) { + # let counter := tload_temp(0) + # + # // If the counter is equal to zero, we're done - return. + # if eq(counter,0) { + # return(0,0) + # } + # + # // If counter isn't zero, add counter to Trans[1] and do recursion + # tstore_temp(1, add(tload_temp(1), counter)) + # + # // Change the loop variable and call 0xca11bacc, which calls us back. # noqa: E501 + # tstore_temp(0, sub(counter, 1)) + # let res := call(gas(), 0xca11bacc, 0, 0,0, 0,0) + # if iszero(res) { // If the call failed, fail too + # revert(0,0) + # } + # } + # + # // If called by a different address from 0xca11bacc, we are the first + # ... (12 more lines) + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI(pc=0x3F, condition=Op.EQ(Op.CALLER, 0xCA11BACC)) + + Op.JUMPDEST + + Op.JUMPI(pc=0x16, condition=Op.SUB(Op.CALLER, 0xCA11BACC)) + + Op.STOP + + Op.JUMPDEST + + Op.PUSH1[0x23] + + Op.CALLDATALOAD(offset=Op.PUSH0) + + Op.SSTORE(key=0x1, value=Op.DUP1) + + Op.PUSH0 + + Op.JUMP(pc=0x7F) + + Op.JUMPDEST + + Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=Op.GAS, + address=0xCA11BACC, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=Op.PUSH0, + ), + ) + + Op.PUSH1[0x3A] + + Op.PUSH1[0x1] + + Op.JUMP(pc=0x7B) + + Op.JUMPDEST + + Op.PUSH1[0x3] + + Op.SSTORE + + Op.STOP + + Op.JUMPDEST + + Op.PUSH1[0x46] + + Op.PUSH0 + + Op.JUMP(pc=0x7B) + + Op.JUMPDEST + + Op.JUMPI(pc=0x79, condition=Op.ISZERO(Op.DUP1)) + + Op.PUSH1[0x1] + + Op.DUP2 + + Op.PUSH1[0x60] + + Op.PUSH1[0x66] + + Op.SWAP4 + + Op.PUSH1[0x5A] + + Op.DUP5 + + Op.JUMP(pc=0x7B) + + Op.JUMPDEST + + Op.ADD + + Op.DUP4 + + Op.JUMP(pc=0x7F) + + Op.JUMPDEST + + Op.SUB + + Op.PUSH0 + + Op.JUMP(pc=0x7F) + + Op.JUMPDEST + + Op.JUMPI( + pc=0xA, + condition=Op.CALL( + gas=Op.GAS, + address=0xCA11BACC, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=Op.PUSH0, + ), + ) + + Op.REVERT(offset=Op.DUP1, size=Op.PUSH0) + + Op.JUMPDEST + + Op.STOP + + Op.JUMPDEST + + Op.TLOAD + + Op.SWAP1 + + Op.JUMP + + Op.JUMPDEST + + Op.TSTORE + + Op.JUMP, + nonce=1, + address=Address(0x000000000000000000000000000000005114E2C8), # noqa: E501 + ) + # Source: yul + # { + # function tload_temp(loc) -> val { + # val := verbatim_1i_1o(hex"5C", loc) + # } + # + # function tstore_temp(loc, val) { + # verbatim_2i_0o(hex"5D", loc, val) + # } + # + # // The initial value of the counter is zero + # sstore(0, tload_temp(0)) + # + # // CALLCODE increments our Trans[0] + # sstore(0x11, callcode(gas(), 0xadd1, 0, 0,0, 0,0)) + # sstore(1, tload_temp(0)) + # + # // DELEGATECALL increments our Trans[0] + # sstore(0x12, delegatecall(gas(), 0xadd1, 0,0, 0,0)) + # sstore(2, tload_temp(0)) + # + # // CALL does not increment our Trans[0], it means a different + # // transient storage + # sstore(0x13, call(gas(), 0xadd1, 0, 0,0, 0,0)) + # sstore(3, tload_temp(0)) + # } + contract_8 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x6] + + Op.PUSH0 + + Op.JUMP(pc=0x4E) + + Op.JUMPDEST + + Op.PUSH0 + + Op.SSTORE + + Op.SSTORE( + key=0x11, + value=Op.CALLCODE( + gas=Op.GAS, + address=0xADD1, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=Op.PUSH0, + ), + ) + + Op.PUSH1[0x1C] + + Op.PUSH0 + + Op.JUMP(pc=0x4E) + + Op.JUMPDEST + + Op.PUSH1[0x1] + + Op.SSTORE + + Op.SSTORE( + key=0x12, + value=Op.DELEGATECALL( + gas=Op.GAS, + address=0xADD1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=Op.PUSH0, + ), + ) + + Op.PUSH1[0x32] + + Op.PUSH0 + + Op.JUMP(pc=0x4E) + + Op.JUMPDEST + + Op.PUSH1[0x2] + + Op.SSTORE + + Op.SSTORE( + key=0x13, + value=Op.CALL( + gas=Op.GAS, + address=0xADD1, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=Op.PUSH0, + ), + ) + + Op.PUSH1[0x49] + + Op.PUSH0 + + Op.JUMP(pc=0x4E) + + Op.JUMPDEST + + Op.PUSH1[0x3] + + Op.SSTORE + + Op.STOP + + Op.JUMPDEST + + Op.TLOAD + + Op.SWAP1 + + Op.JUMP, + storage={0: 24743}, + nonce=1, + address=Address(0x000000000000000000000000000000007F9317BD), # noqa: E501 + ) + # Source: yul + # { # // Set up Trans[0] with a regular call. # sstore(0x10,call(gas(), 0x57A7, 0, 0,1, 0,32)) # sstore(0, mload(0)) @@ -1286,39 +1312,13 @@ def test_trans_storage_ok( nonce=1, address=Address(0x000000000000000000000000000000005D7935DF), # noqa: E501 ) - # Source: yul - # { - # let func := shr(224, calldataload(0)) - # let param := calldataload(4) - # sstore(0, func) - # mstore(0, param) - # sstore(1, call(gas(), func, 0, 0,32, 0,0)) - # } - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH0 - + Op.DUP1 - + Op.PUSH1[0x20] - + Op.DUP2 - + Op.DUP1 - + Op.SHR(0xE0, Op.CALLDATALOAD(offset=Op.DUP1)) - + Op.CALLDATALOAD(offset=0x4) - + Op.SSTORE(key=Op.DUP4, value=Op.DUP2) - + Op.DUP3 - + Op.MSTORE - + Op.GAS - + Op.SSTORE(key=0x1, value=Op.CALL) - + Op.STOP, - nonce=1, - address=Address(0xDD53B677A6FD4E871A6355F283B1BD7CEB95A95E), # noqa: E501 - ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) expect_entries_: list[dict] = [ { "indexes": {"data": [0], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0xEBD141D5, 1: 1}), + target: Account(storage={0: contract_0, 1: 1}), contract_0: Account(storage={1: 16, 2: 1, 3: 136}), }, }, @@ -1326,7 +1326,7 @@ def test_trans_storage_ok( "indexes": {"data": [1], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x6E3A7204, 1: 1}), + target: Account(storage={0: contract_1, 1: 1}), contract_1: Account(storage={1: 16, 2: 1, 3: 136}), }, }, @@ -1334,7 +1334,7 @@ def test_trans_storage_ok( "indexes": {"data": [2], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0xC1C922F1, 1: 1}), + target: Account(storage={0: contract_2, 1: 1}), contract_2: Account(storage={1: 16, 2: 1, 3: 136}), }, }, @@ -1342,7 +1342,7 @@ def test_trans_storage_ok( "indexes": {"data": [3], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0xEBD141D5, 1: 1}), + target: Account(storage={0: contract_0, 1: 1}), contract_0: Account(storage={1: 256, 2: 1, 3: 32896}), }, }, @@ -1350,7 +1350,7 @@ def test_trans_storage_ok( "indexes": {"data": [4], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x5114E2C8, 1: 1}), + target: Account(storage={0: contract_4, 1: 1}), contract_4: Account(storage={1: 10, 2: 1, 3: 55}), contract_3: Account(storage={0: 0, 1: 0}), }, @@ -1359,7 +1359,7 @@ def test_trans_storage_ok( "indexes": {"data": [5], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x5114E2C8, 1: 1}), + target: Account(storage={0: contract_4, 1: 1}), contract_4: Account(storage={1: 50, 2: 1, 3: 1275}), contract_3: Account(storage={0: 0, 1: 0}), }, @@ -1368,7 +1368,7 @@ def test_trans_storage_ok( "indexes": {"data": [6], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x264BB86A, 1: 1}), + target: Account(storage={0: contract_5, 1: 1}), contract_5: Account(storage={1: 6, 2: 1, 3: 63}), }, }, @@ -1376,7 +1376,7 @@ def test_trans_storage_ok( "indexes": {"data": [7], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x7074A486, 1: 1}), + target: Account(storage={0: contract_6, 1: 1}), contract_6: Account(storage={1: 6, 2: 1, 3: 63}), }, }, @@ -1384,7 +1384,7 @@ def test_trans_storage_ok( "indexes": {"data": [8], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x7F9317BD, 1: 1}), + target: Account(storage={0: contract_8, 1: 1}), contract_8: Account( storage={0: 0, 1: 1, 2: 2, 3: 2, 17: 1, 18: 1, 19: 1}, ), @@ -1398,7 +1398,7 @@ def test_trans_storage_ok( }, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0xC54B5829, 1: 1}), + target: Account(storage={0: contract_9, 1: 1}), contract_9: Account(storage={0: 2}), }, }, @@ -1406,7 +1406,7 @@ def test_trans_storage_ok( "indexes": {"data": [15], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account(storage={0: 0x5D7935DF, 1: 1}), + target: Account(storage={0: contract_11, 1: 1}), contract_11: Account( storage={0: 24743, 1: 24743, 2: 0, 16: 1, 17: 1, 18: 0}, ), diff --git a/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_reset.py b/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_reset.py index 99415bedec2..de1ad618dd6 100644 --- a/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_reset.py +++ b/tests/ported_static/stEIP1153_transientStorage/test_trans_storage_reset.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -229,9 +228,7 @@ def test_trans_storage_reset( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x48DC5A9F099CAAAA557742CA3A990A94BE45B9969126A1BC74E5E8BE5A2B5B47 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE, nonce=1) env = Environment( fee_recipient=coinbase, @@ -359,7 +356,6 @@ def test_trans_storage_reset( + Op.JUMP, storage={16: 24743}, nonce=1, - address=Address(0xD1F046B080A87137C61A14BB81C2B6BBCEC17084), # noqa: E501 ) # Source: yul # { @@ -495,7 +491,6 @@ def test_trans_storage_reset( + Op.JUMP, storage={1: 24743}, nonce=1, - address=Address(0x9F075370EF41D4CD90151E731E33836E6F521669), # noqa: E501 ) # Source: yul # { @@ -528,21 +523,14 @@ def test_trans_storage_reset( + Op.SSTORE(key=0x1, value=Op.CALL) + Op.STOP, nonce=1, - address=Address(0x1679C7439EF325A99A6AFC54A8F7894C3DA35B16), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) expect_entries_: list[dict] = [ { "indexes": {"data": [0], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account( - storage={ - 0: 0x9F075370EF41D4CD90151E731E33836E6F521669, - 1: 1, - }, - ), + target: Account(storage={0: reverter, 1: 1}), reverter: Account(storage={0: 48879, 1: 1}), dead: Account(storage={16: 1}), }, @@ -551,12 +539,7 @@ def test_trans_storage_reset( "indexes": {"data": [3, 6, 9, 12, 15, 18], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account( - storage={ - 0: 0x9F075370EF41D4CD90151E731E33836E6F521669, - 1: 1, - }, - ), + target: Account(storage={0: reverter, 1: 1}), reverter: Account(storage={0: 48879, 1: 1, 16: 1}), }, }, @@ -564,12 +547,7 @@ def test_trans_storage_reset( "indexes": {"data": [24, 27], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account( - storage={ - 0: 0x9F075370EF41D4CD90151E731E33836E6F521669, - 1: 1, - }, - ), + target: Account(storage={0: reverter, 1: 1}), reverter: Account(storage={0: 0xBAD0BEEF, 1: 1, 16: 32343}), }, }, @@ -602,12 +580,7 @@ def test_trans_storage_reset( }, "network": [">=Cancun"], "result": { - target: Account( - storage={ - 0: 0x9F075370EF41D4CD90151E731E33836E6F521669, - 1: 1, - }, - ), + target: Account(storage={0: reverter, 1: 1}), reverter: Account(storage={0: 24743, 1: 0}), dead: Account(storage={16: 24743}), }, @@ -616,12 +589,7 @@ def test_trans_storage_reset( "indexes": {"data": [21], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - target: Account( - storage={ - 0: 0x9F075370EF41D4CD90151E731E33836E6F521669, - 1: 1, - }, - ), + target: Account(storage={0: reverter, 1: 1}), reverter: Account(storage={0: 24743, 1: 1}), dead: Account(storage={16: 32343}), }, diff --git a/tests/ported_static/stEIP150Specific/test_call_and_callcode_consume_more_gas_then_transaction_has.py b/tests/ported_static/stEIP150Specific/test_call_and_callcode_consume_more_gas_then_transaction_has.py index 4861b94c7b0..aa6ecf33493 100644 --- a/tests/ported_static/stEIP150Specific/test_call_and_callcode_consume_more_gas_then_transaction_has.py +++ b/tests/ported_static/stEIP150Specific/test_call_and_callcode_consume_more_gas_then_transaction_has.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has( ) -> None: """Test_call_and_callcode_consume_more_gas_then_transaction_has.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,12 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (SSTORE 0 0x12) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x12) + Op.STOP, + nonce=0, + ) # Source: lll # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) (SSTORE 10 (CALLCODE 600000 0 0 0 0 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +59,7 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has( key=0x9, value=Op.CALL( gas=0x927C0, - address=0xFD59ABAE521384B5731AC657616680219FBC423D, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,7 +71,7 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has( key=0xA, value=Op.CALLCODE( gas=0x927C0, - address=0xFD59ABAE521384B5731AC657616680219FBC423D, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -79,14 +81,6 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0x9BDB308C9B567E1DBC906D9D592A8464A05FFD44), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 0x12) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x12) + Op.STOP, - nonce=0, - address=Address(0xFD59ABAE521384B5731AC657616680219FBC423D), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_call_ask_more_gas_on_depth2_then_transaction_has.py b/tests/ported_static/stEIP150Specific/test_call_ask_more_gas_on_depth2_then_transaction_has.py index 36b738a1a77..61fd1052dec 100644 --- a/tests/ported_static/stEIP150Specific/test_call_ask_more_gas_on_depth2_then_transaction_has.py +++ b/tests/ported_static/stEIP150Specific/test_call_ask_more_gas_on_depth2_then_transaction_has.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has( ) -> None: """Test_call_ask_more_gas_on_depth2_then_transaction_has.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,16 +45,21 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 200000 0 0 0 0 0)) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 (GAS))} + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( - gas=0x30D40, - address=0x25C370B55EC8467127BC4E13404915901D689098, + gas=0x927C0, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -67,17 +69,16 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0x8553D06001D46F3B0B18A938ACF8C552D87C5837), # noqa: E501 ) # Source: lll - # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 200000 0 0 0 0 0)) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( - gas=0x927C0, - address=0xF39D40EACB6D2C685AC10664E759D1CF8F775DFF, + gas=0x30D40, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -87,14 +88,6 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0x25C370B55EC8467127BC4E13404915901D689098), # noqa: E501 - ) - # Source: lll - # { (SSTORE 8 (GAS))} - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.STOP, - nonce=0, - address=Address(0xF39D40EACB6D2C685AC10664E759D1CF8F775DFF), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level.py b/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level.py index aae0948831b..ce3ec8f7f19 100644 --- a/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level.py +++ b/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_goes_oog_on_second_level( ) -> None: """Test_call_goes_oog_on_second_level.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,16 +43,25 @@ def test_call_goes_oog_on_second_level( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 (GAS)) (KECCAK256 0x00 0x2fffff) (SSTORE 9 (GAS)) (SSTORE 10 (GAS)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=Op.GAS) + + Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) + + Op.SSTORE(key=0x9, value=Op.GAS) + + Op.SSTORE(key=0xA, value=Op.GAS) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 300000 0 0 0 0 0)) [[12]] 1} # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( - gas=0x927C0, - address=0x66F77B181E0E662E17D427C7320267ADF2FD624, + gas=0x493E0, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -63,19 +69,19 @@ def test_call_goes_oog_on_second_level( ret_size=0x0, ), ) + + Op.SSTORE(key=0xC, value=0x1) + Op.STOP, nonce=0, - address=Address(0x3C6DCA5471C6305D0642C6210D39D4613B5EA30B), # noqa: E501 ) # Source: lll - # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 300000 0 0 0 0 0)) [[12]] 1} # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( - gas=0x493E0, - address=0xCCC0159BD2EF7118B5E7B8D958E72237F02493FE, + gas=0x927C0, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -83,21 +89,8 @@ def test_call_goes_oog_on_second_level( ret_size=0x0, ), ) - + Op.SSTORE(key=0xC, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x066F77B181E0E662E17D427C7320267ADF2FD624), # noqa: E501 - ) - # Source: lll - # { (SSTORE 8 (GAS)) (KECCAK256 0x00 0x2fffff) (SSTORE 9 (GAS)) (SSTORE 10 (GAS)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=Op.GAS) - + Op.POP(Op.SHA3(offset=0x0, size=0x2FFFFF)) - + Op.SSTORE(key=0x9, value=Op.GAS) - + Op.SSTORE(key=0xA, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xCCC0159BD2EF7118B5E7B8D958E72237F02493FE), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level2.py b/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level2.py index d4824a14a6b..186b2ad0636 100644 --- a/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level2.py +++ b/tests/ported_static/stEIP150Specific/test_call_goes_oog_on_second_level2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_goes_oog_on_second_level2( ) -> None: """Test_call_goes_oog_on_second_level2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,16 +43,23 @@ def test_call_goes_oog_on_second_level2( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 (GAS)) (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=Op.GAS) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( gas=0x927C0, - address=0xE1D370A0538366EAFFBC9FCD571AF7B1E80D377C, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -65,17 +69,16 @@ def test_call_goes_oog_on_second_level2( ) + Op.STOP, nonce=0, - address=Address(0x171742E7809E3B571E899F0D4D9D35CD5DEEACF1), # noqa: E501 ) # Source: lll - # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 (GAS)) (SSTORE 9 (CALL 600000 0 0 0 0 0)) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( gas=0x927C0, - address=0xBFB2B65E4EF26A144A185B32C7BAF39EF8E40B4B, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -85,16 +88,6 @@ def test_call_goes_oog_on_second_level2( ) + Op.STOP, nonce=0, - address=Address(0xE1D370A0538366EAFFBC9FCD571AF7B1E80D377C), # noqa: E501 - ) - # Source: lll - # { (SSTORE 8 (GAS)) (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=Op.GAS) - + Op.SHA3(offset=0x0, size=0x2FFFFF) - + Op.STOP, - nonce=0, - address=Address(0xBFB2B65E4EF26A144A185B32C7BAF39EF8E40B4B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_create_and_gas_inside_create.py b/tests/ported_static/stEIP150Specific/test_create_and_gas_inside_create.py index f86550f6574..0bcf52c7d85 100644 --- a/tests/ported_static/stEIP150Specific/test_create_and_gas_inside_create.py +++ b/tests/ported_static/stEIP150Specific/test_create_and_gas_inside_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_and_gas_inside_create( """Test_create_and_gas_inside_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create_and_gas_inside_create( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [100] (GAS) (MSTORE 0 0x5a60fd55) (SSTORE 11 (CREATE 0 28 4)) (SSTORE 9 (SUB @100 (GAS))) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,6 @@ def test_create_and_gas_inside_create( + Op.SSTORE(key=0x9, value=Op.SUB(Op.MLOAD(offset=0x64), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( @@ -72,7 +67,7 @@ def test_create_and_gas_inside_create( contract_0: Account( storage={ 9: 0x129DB, - 11: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 11: compute_create_address(address=contract_0, nonce=0), }, ), compute_create_address(address=contract_0, nonce=0): Account( diff --git a/tests/ported_static/stEIP150Specific/test_delegate_call_on_eip.py b/tests/ported_static/stEIP150Specific/test_delegate_call_on_eip.py index 820af2c8af5..5156516411b 100644 --- a/tests/ported_static/stEIP150Specific/test_delegate_call_on_eip.py +++ b/tests/ported_static/stEIP150Specific/test_delegate_call_on_eip.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_delegate_call_on_eip( ) -> None: """Test_delegate_call_on_eip.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,12 @@ def test_delegate_call_on_eip( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (SSTORE 0 0x12) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x12) + Op.STOP, + nonce=0, + ) # Source: lll # { [8] (GAS) (SSTORE 9 (DELEGATECALL 600000 0 0 0 0)) [[8]] (SUB @8 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +57,7 @@ def test_delegate_call_on_eip( key=0x9, value=Op.DELEGATECALL( gas=0x927C0, - address=0xFD59ABAE521384B5731AC657616680219FBC423D, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -65,14 +67,6 @@ def test_delegate_call_on_eip( + Op.SSTORE(key=0x8, value=Op.SUB(Op.MLOAD(offset=0x8), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x90BC108216940A7DDAF3BA6624F2FDBE4C5E83DC), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 0x12) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x12) + Op.STOP, - nonce=0, - address=Address(0xFD59ABAE521384B5731AC657616680219FBC423D), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_execute_call_that_ask_fore_gas_then_trabsaction_has.py b/tests/ported_static/stEIP150Specific/test_execute_call_that_ask_fore_gas_then_trabsaction_has.py index e88bb9138e6..4e96ff618dd 100644 --- a/tests/ported_static/stEIP150Specific/test_execute_call_that_ask_fore_gas_then_trabsaction_has.py +++ b/tests/ported_static/stEIP150Specific/test_execute_call_that_ask_fore_gas_then_trabsaction_has.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_execute_call_that_ask_fore_gas_then_trabsaction_has( ) -> None: """Test_execute_call_that_ask_fore_gas_then_trabsaction_has.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,13 @@ def test_execute_call_that_ask_fore_gas_then_trabsaction_has( gas_limit=10000000, ) - pre[sender] = Account(balance=0x5F5E100) + # Source: lll + # { [[1]] 12 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, + balance=0x186A0, + nonce=0, + ) # Source: lll # { [[1]] (CALL 600000 0 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +59,7 @@ def test_execute_call_that_ask_fore_gas_then_trabsaction_has( key=0x1, value=Op.CALL( gas=0x927C0, - address=0xBFDD294028701B119D416C68EFF7DD9F7EFFD249, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,15 +69,6 @@ def test_execute_call_that_ask_fore_gas_then_trabsaction_has( ) + Op.STOP, nonce=0, - address=Address(0x1819CF5BFF62F0D379F146B85BAAF9BD18239832), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xBFDD294028701B119D416C68EFF7DD9F7EFFD249), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_new_gas_price_for_codes.py b/tests/ported_static/stEIP150Specific/test_new_gas_price_for_codes.py index 7ee910014d6..0be45107816 100644 --- a/tests/ported_static/stEIP150Specific/test_new_gas_price_for_codes.py +++ b/tests/ported_static/stEIP150Specific/test_new_gas_price_for_codes.py @@ -68,25 +68,15 @@ def test_new_gas_price_for_codes( # { [999] (GAS) (SSTORE 1 (EXTCODESIZE )) (EXTCODECOPY 0 0 20) (SSTORE 2 (MLOAD 0)) (SSTORE 4 (SLOAD 0)) (SSTORE 5 (CALL 30000 1 0 0 0 0)) (SSTORE 6 (CALLCODE 30000 1 0 0 0 0)) (SSTORE 7 (DELEGATECALL 30000 0 0 0 0)) (SSTORE 8 (CALL 30000 0x1000000000000000000000000000000000000013 0 0 0 0 0)) (SSTORE 3 (BALANCE )) (SSTORE 10 (SUB (MLOAD 999) (GAS))) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3E7, value=Op.GAS) - + Op.SSTORE( - key=0x1, - value=Op.EXTCODESIZE( - address=0xC572A70AFAAB9D01D0A2AFB855BFBAFB47C8211B - ), - ) - + Op.EXTCODECOPY( - address=0xC572A70AFAAB9D01D0A2AFB855BFBAFB47C8211B, - dest_offset=0x0, - offset=0x0, - size=0x14, - ) + + Op.SSTORE(key=0x1, value=Op.EXTCODESIZE(address=addr)) + + Op.EXTCODECOPY(address=addr, dest_offset=0x0, offset=0x0, size=0x14) + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x0)) + Op.SSTORE(key=0x4, value=Op.SLOAD(key=0x0)) + Op.SSTORE( key=0x5, value=Op.CALL( gas=0x7530, - address=0xAD9D325B811CB0701839C07C6F139F3799476798, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x0, @@ -98,7 +88,7 @@ def test_new_gas_price_for_codes( key=0x6, value=Op.CALLCODE( gas=0x7530, - address=0xAD9D325B811CB0701839C07C6F139F3799476798, + address=addr_2, value=0x1, args_offset=0x0, args_size=0x0, @@ -110,7 +100,7 @@ def test_new_gas_price_for_codes( key=0x7, value=Op.DELEGATECALL( gas=0x7530, - address=0xAD9D325B811CB0701839C07C6F139F3799476798, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -129,12 +119,7 @@ def test_new_gas_price_for_codes( ret_size=0x0, ), ) - + Op.SSTORE( - key=0x3, - value=Op.BALANCE( - address=0xFAA10B404AB607779993C016CD5DA73AE1F29D7E - ), - ) + + Op.SSTORE(key=0x3, value=Op.BALANCE(address=sender)) + Op.SSTORE(key=0xA, value=Op.SUB(Op.MLOAD(offset=0x3E7), Op.GAS)) + Op.STOP, storage={0: 18}, diff --git a/tests/ported_static/stEIP150Specific/test_suicide_to_existing_contract.py b/tests/ported_static/stEIP150Specific/test_suicide_to_existing_contract.py index 3c0025042ba..f8cea302098 100644 --- a/tests/ported_static/stEIP150Specific/test_suicide_to_existing_contract.py +++ b/tests/ported_static/stEIP150Specific/test_suicide_to_existing_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_suicide_to_existing_contract( ) -> None: """Test_suicide_to_existing_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_suicide_to_existing_contract( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 60000 0 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stEIP150Specific/test_suicide_to_not_existing_contract.py b/tests/ported_static/stEIP150Specific/test_suicide_to_not_existing_contract.py index cf820a6d31f..5a3ff77c96f 100644 --- a/tests/ported_static/stEIP150Specific/test_suicide_to_not_existing_contract.py +++ b/tests/ported_static/stEIP150Specific/test_suicide_to_not_existing_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_suicide_to_not_existing_contract( ) -> None: """Test_suicide_to_not_existing_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,15 @@ def test_suicide_to_not_existing_contract( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (SELFDESTRUCT 0x2000000000000000000000000000000000000115) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT( + address=0x2000000000000000000000000000000000000115 + ) + + Op.STOP, + nonce=0, + ) # Source: lll # { [0] (GAS) (CALL 60000 0 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +59,7 @@ def test_suicide_to_not_existing_contract( + Op.POP( Op.CALL( gas=0xEA60, - address=0x9D6D7885D3D58A49C8352635776C205F722501C, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -65,17 +70,6 @@ def test_suicide_to_not_existing_contract( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xBABAE893BEE69E2141E0E92F2251664AC445EA2A), # noqa: E501 - ) - # Source: lll - # { (SELFDESTRUCT 0x2000000000000000000000000000000000000115) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x2000000000000000000000000000000000000115 - ) - + Op.STOP, - nonce=0, - address=Address(0x09D6D7885D3D58A49C8352635776C205F722501C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64e0.py b/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64e0.py index 45a32d3f9d0..256cf7ea0bb 100644 --- a/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64e0.py +++ b/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64e0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_transaction64_rule_d64e0( ) -> None: """Test_transaction64_rule_d64e0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,12 @@ def test_transaction64_rule_d64e0( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { [[1]] 12 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, + nonce=0, + ) # Source: lll # { [0] (GAS) (CALL 160000 0 0 0 0 0) [[2]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +56,7 @@ def test_transaction64_rule_d64e0( + Op.POP( Op.CALL( gas=0x27100, - address=0x6B7466044211F090B767199794F6F7041829BA85, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -65,14 +67,6 @@ def test_transaction64_rule_d64e0( + Op.SSTORE(key=0x2, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x4CBC458D12C7F73A3B12EF4515C3EB1BB7430798), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, - nonce=0, - address=Address(0x6B7466044211F090B767199794F6F7041829BA85), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64m1.py b/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64m1.py index a8267666f7a..dd89bd167ec 100644 --- a/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64m1.py +++ b/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64m1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_transaction64_rule_d64m1( ) -> None: """Test_transaction64_rule_d64m1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,12 @@ def test_transaction64_rule_d64m1( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { [[1]] 12 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, + nonce=0, + ) # Source: lll # { [0] (GAS) (CALL 160000 0 0 0 0 0) [[2]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +56,7 @@ def test_transaction64_rule_d64m1( + Op.POP( Op.CALL( gas=0x27100, - address=0x6B7466044211F090B767199794F6F7041829BA85, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -65,14 +67,6 @@ def test_transaction64_rule_d64m1( + Op.SSTORE(key=0x2, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x4CBC458D12C7F73A3B12EF4515C3EB1BB7430798), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, - nonce=0, - address=Address(0x6B7466044211F090B767199794F6F7041829BA85), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64p1.py b/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64p1.py index 0b7fa472d71..2dead5d9e1a 100644 --- a/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64p1.py +++ b/tests/ported_static/stEIP150Specific/test_transaction64_rule_d64p1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_transaction64_rule_d64p1( ) -> None: """Test_transaction64_rule_d64p1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,12 @@ def test_transaction64_rule_d64p1( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { [[1]] 12 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, + nonce=0, + ) # Source: lll # { [0] (GAS) (CALL 160000 0 0 0 0 0) [[2]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +56,7 @@ def test_transaction64_rule_d64p1( + Op.POP( Op.CALL( gas=0x27100, - address=0x6B7466044211F090B767199794F6F7041829BA85, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -65,14 +67,6 @@ def test_transaction64_rule_d64p1( + Op.SSTORE(key=0x2, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x4CBC458D12C7F73A3B12EF4515C3EB1BB7430798), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, - nonce=0, - address=Address(0x6B7466044211F090B767199794F6F7041829BA85), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150Specific/test_transaction64_rule_integer_boundaries.py b/tests/ported_static/stEIP150Specific/test_transaction64_rule_integer_boundaries.py index 9be75cc4ce8..0940f507d26 100644 --- a/tests/ported_static/stEIP150Specific/test_transaction64_rule_integer_boundaries.py +++ b/tests/ported_static/stEIP150Specific/test_transaction64_rule_integer_boundaries.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -119,9 +118,7 @@ def test_transaction64_rule_integer_boundaries( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0000000000000000000000000000000000001000) contract_1 = Address(0x000000000000000000000000000000000000C0DE) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x10000000000000000) env = Environment( fee_recipient=coinbase, @@ -206,9 +203,7 @@ def test_transaction64_rule_integer_boundaries( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x000000000000000000000000000000000000C0DE), # noqa: E501 ) - pre[sender] = Account(balance=0x10000000000000000) tx_data = [ Hash(0x7F), diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929.py index 639742dc60d..c62a6e1859a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -279,9 +278,7 @@ def test_eip2929( contract_1 = Address(0x000000000000000000000000000000CA1100CA11) contract_2 = Address(0x00000000000000000000000000000000CA110100) contract_3 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -302,23 +299,23 @@ def test_eip2929( ) # Source: lll # { - # (balance 0xca11) + # @@0x100 # } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.BALANCE(address=0xCA11) + Op.STOP, + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.SLOAD(key=0x100) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x000000000000000000000000000000CA1100CA11), # noqa: E501 + address=Address(0x00000000000000000000000000000000CA110100), # noqa: E501 ) # Source: lll # { - # @@0x100 + # (balance 0xca11) # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.SLOAD(key=0x100) + Op.STOP, + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.BALANCE(address=0xCA11) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x00000000000000000000000000000000CA110100), # noqa: E501 + address=Address(0x000000000000000000000000000000CA1100CA11), # noqa: E501 ) # Source: lll # { @@ -355,8 +352,8 @@ def test_eip2929( contract_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=Op.GAS) + Op.MSTORE(offset=0x20, value=Op.GAS) - + Op.POP(Op.BALANCE(address=0xCA1100CA11)) - + Op.POP(Op.BALANCE(address=0xCA110100)) + + Op.POP(Op.BALANCE(address=contract_1)) + + Op.POP(Op.BALANCE(address=contract_2)) + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + Op.MSTORE(offset=0x0, value=Op.GAS) + Op.JUMPI( @@ -382,7 +379,7 @@ def test_eip2929( + Op.PUSH1[0x0] + Op.JUMP(pc=Op.PUSH2[0x66]) + Op.JUMPDEST - + Op.BALANCE(address=0xCA11) + + Op.BALANCE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI( @@ -391,7 +388,7 @@ def test_eip2929( + Op.PUSH1[0x0] + Op.JUMP(pc=Op.PUSH2[0x7D]) + Op.JUMPDEST - + Op.EXTCODESIZE(address=0xCA11) + + Op.EXTCODESIZE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI( @@ -400,7 +397,9 @@ def test_eip2929( + Op.POP(0x0) + Op.JUMP(pc=Op.PUSH2[0x9B]) + Op.JUMPDEST - + Op.EXTCODECOPY(address=0xCA11, dest_offset=0x0, offset=0x0, size=0x0) + + Op.EXTCODECOPY( + address=contract_0, dest_offset=0x0, offset=0x0, size=0x0 + ) + Op.JUMPDEST + Op.JUMPI( pc=Op.PUSH2[0xAC], condition=Op.EQ(Op.MLOAD(offset=0x40), 0xE) @@ -408,7 +407,7 @@ def test_eip2929( + Op.PUSH1[0x0] + Op.JUMP(pc=Op.PUSH2[0xB1]) + Op.JUMPDEST - + Op.EXTCODEHASH(address=0xCA11) + + Op.EXTCODEHASH(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI( @@ -419,7 +418,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xCA11, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -436,7 +435,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xCA11, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -451,7 +450,7 @@ def test_eip2929( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x1000, - address=0xCA11, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -465,7 +464,7 @@ def test_eip2929( + Op.JUMPDEST + Op.STATICCALL( gas=0x1000, - address=0xCA11, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -479,7 +478,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xCA1100CA11, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -494,7 +493,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xCA110100, + address=contract_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -509,7 +508,7 @@ def test_eip2929( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x1000, - address=0xCA110100, + address=contract_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -543,27 +542,29 @@ def test_eip2929( + Op.PUSH1[0x0] + Op.JUMP(pc=0x211) + Op.JUMPDEST - + Op.BALANCE(address=0xCA11) + + Op.BALANCE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI(pc=0x223, condition=Op.EQ(Op.MLOAD(offset=0x40), 0xC)) + Op.PUSH1[0x0] + Op.JUMP(pc=0x228) + Op.JUMPDEST - + Op.EXTCODESIZE(address=0xCA11) + + Op.EXTCODESIZE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI(pc=0x23B, condition=Op.EQ(Op.MLOAD(offset=0x40), 0xD)) + Op.POP(0x0) + Op.JUMP(pc=0x246) + Op.JUMPDEST - + Op.EXTCODECOPY(address=0xCA11, dest_offset=0x0, offset=0x0, size=0x0) + + Op.EXTCODECOPY( + address=contract_0, dest_offset=0x0, offset=0x0, size=0x0 + ) + Op.JUMPDEST + Op.JUMPI(pc=0x257, condition=Op.EQ(Op.MLOAD(offset=0x40), 0xE)) + Op.PUSH1[0x0] + Op.JUMP(pc=0x25C) + Op.JUMPDEST - + Op.EXTCODEHASH(address=0xCA11) + + Op.EXTCODEHASH(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI(pc=0x26E, condition=Op.EQ(Op.MLOAD(offset=0x40), 0x15)) @@ -572,7 +573,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xCA11, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -587,7 +588,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xCA11, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -602,7 +603,7 @@ def test_eip2929( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x1000, - address=0xCA11, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -616,7 +617,7 @@ def test_eip2929( + Op.JUMPDEST + Op.STATICCALL( gas=0x1000, - address=0xCA11, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -630,7 +631,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xCA1100CA11, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -645,7 +646,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xCA110100, + address=contract_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -660,7 +661,7 @@ def test_eip2929( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x1000, - address=0xCA110100, + address=contract_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -694,27 +695,29 @@ def test_eip2929( + Op.PUSH1[0x0] + Op.JUMP(pc=0x3BC) + Op.JUMPDEST - + Op.BALANCE(address=0xCA11) + + Op.BALANCE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI(pc=0x3CE, condition=Op.EQ(Op.MLOAD(offset=0x40), 0xC)) + Op.PUSH1[0x0] + Op.JUMP(pc=0x3D3) + Op.JUMPDEST - + Op.EXTCODESIZE(address=0xCA11) + + Op.EXTCODESIZE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI(pc=0x3E6, condition=Op.EQ(Op.MLOAD(offset=0x40), 0xD)) + Op.POP(0x0) + Op.JUMP(pc=0x3F1) + Op.JUMPDEST - + Op.EXTCODECOPY(address=0xCA11, dest_offset=0x0, offset=0x0, size=0x0) + + Op.EXTCODECOPY( + address=contract_0, dest_offset=0x0, offset=0x0, size=0x0 + ) + Op.JUMPDEST + Op.JUMPI(pc=0x402, condition=Op.EQ(Op.MLOAD(offset=0x40), 0xE)) + Op.PUSH1[0x0] + Op.JUMP(pc=0x407) + Op.JUMPDEST - + Op.EXTCODEHASH(address=0xCA11) + + Op.EXTCODEHASH(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI(pc=0x419, condition=Op.EQ(Op.MLOAD(offset=0x40), 0x15)) @@ -723,7 +726,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xCA11, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -738,7 +741,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xCA11, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -753,7 +756,7 @@ def test_eip2929( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x1000, - address=0xCA11, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -767,7 +770,7 @@ def test_eip2929( + Op.JUMPDEST + Op.STATICCALL( gas=0x1000, - address=0xCA11, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -781,7 +784,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xCA1100CA11, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -796,7 +799,7 @@ def test_eip2929( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xCA110100, + address=contract_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -811,7 +814,7 @@ def test_eip2929( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x1000, - address=0xCA110100, + address=contract_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -831,9 +834,7 @@ def test_eip2929( storage={256: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_minus_ff.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_minus_ff.py index 8d977b8653d..0e9ecf78d46 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_minus_ff.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_minus_ff.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -104,9 +103,7 @@ def test_eip2929_minus_ff( contract_0 = Address(0x000000000000000000000000000000000000DE57) contract_1 = Address(0x000000000000000000000000000000000000CA11) contract_2 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -169,7 +166,7 @@ def test_eip2929_minus_ff( contract_2 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x100, value=0xFF) + Op.MSTORE(offset=0x120, value=0xFF) - + Op.POP(Op.BALANCE(address=0xCA11)) + + Op.POP(Op.BALANCE(address=contract_1)) + Op.JUMPI( pc=Op.PUSH2[0x21], condition=Op.EQ(Op.CALLDATALOAD(offset=0x4), 0x31), @@ -177,7 +174,7 @@ def test_eip2929_minus_ff( + Op.PUSH1[0x0] + Op.JUMP(pc=Op.PUSH2[0x26]) + Op.JUMPDEST - + Op.BALANCE(address=0xDE57) + + Op.BALANCE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI( @@ -187,7 +184,7 @@ def test_eip2929_minus_ff( + Op.PUSH1[0x0] + Op.JUMP(pc=Op.PUSH2[0x3D]) + Op.JUMPDEST - + Op.EXTCODESIZE(address=0xDE57) + + Op.EXTCODESIZE(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI( @@ -197,7 +194,9 @@ def test_eip2929_minus_ff( + Op.POP(0x0) + Op.JUMP(pc=Op.PUSH2[0x5B]) + Op.JUMPDEST - + Op.EXTCODECOPY(address=0xDE57, dest_offset=0x0, offset=0x0, size=0x1) + + Op.EXTCODECOPY( + address=contract_0, dest_offset=0x0, offset=0x0, size=0x1 + ) + Op.JUMPDEST + Op.JUMPI( pc=Op.PUSH2[0x6C], @@ -206,7 +205,7 @@ def test_eip2929_minus_ff( + Op.PUSH1[0x0] + Op.JUMP(pc=Op.PUSH2[0x71]) + Op.JUMPDEST - + Op.EXTCODEHASH(address=0xDE57) + + Op.EXTCODEHASH(address=contract_0) + Op.JUMPDEST + Op.POP + Op.JUMPI( @@ -218,7 +217,7 @@ def test_eip2929_minus_ff( + Op.JUMPDEST + Op.CALL( gas=0x10000, - address=0xDE57, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -236,7 +235,7 @@ def test_eip2929_minus_ff( + Op.JUMPDEST + Op.CALLCODE( gas=0x10000, - address=0xDE57, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -254,7 +253,7 @@ def test_eip2929_minus_ff( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x10000, - address=0xDE57, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -271,7 +270,7 @@ def test_eip2929_minus_ff( + Op.JUMPDEST + Op.STATICCALL( gas=0x10000, - address=0xDE57, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -283,7 +282,7 @@ def test_eip2929_minus_ff( + Op.POP( Op.CALL( gas=0x1000000, - address=0xCA11, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -299,7 +298,7 @@ def test_eip2929_minus_ff( ), ) + Op.MSTORE(offset=0x100, value=Op.GAS) - + Op.POP(Op.BALANCE(address=0xDE57)) + + Op.POP(Op.BALANCE(address=contract_0)) + Op.MSTORE(offset=0x120, value=Op.GAS) + Op.SSTORE( key=0x1, @@ -310,9 +309,7 @@ def test_eip2929_minus_ff( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_oog.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_oog.py index 7d8b9723062..c1624aa5866 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_oog.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_eip2929_oog.py @@ -129,6 +129,7 @@ def test_eip2929_oog( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: lll # { # @@0 @@ -151,46 +152,49 @@ def test_eip2929_oog( ) # Source: lll # { - # (balance 0xACC7) - # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.BALANCE(address=0xACC7) + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0000000000000000000000000000000000001031), # noqa: E501 - ) - # Source: lll - # { - # (extcodesize 0x1031) + # (return 0 0) # } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.EXTCODESIZE(address=0x1031) + Op.STOP, + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x000000000000000000000000000000000000103B), # noqa: E501 + address=Address(0x000000000000000000000000000000000000ACC7), # noqa: E501 ) # Source: lll # { - # (extcodecopy 0x1031 0 0 0x20) + # (def 'addr $4) ; the address to call + # (def 'callGas $36) ; the amount of gas to give it + # + # [[0]] (call callGas addr 0 0 0 0 0) # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.EXTCODECOPY( - address=0x1031, dest_offset=0x0, offset=0x0, size=0x20 + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=Op.CALLDATALOAD(offset=0x24), + address=Op.CALLDATALOAD(offset=0x4), + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), ) + Op.STOP, + storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x000000000000000000000000000000000000103C), # noqa: E501 + address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) # Source: lll # { - # (extcodehash 0x1031) + # (balance 0xACC7) # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.EXTCODEHASH(address=0x1031) + Op.STOP, + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.BALANCE(address=0xACC7) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x000000000000000000000000000000000000103F), # noqa: E501 + address=Address(0x0000000000000000000000000000000000001031), # noqa: E501 ) # Source: lll # { @@ -213,6 +217,24 @@ def test_eip2929_oog( ) # Source: lll # { + # (staticcall 0x06A5 0xACC7 0 0 0 0) + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x6A5, + address=0xACC7, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x00000000000000000000000000000000000010FA), # noqa: E501 + ) + # Source: lll + # { # (callcode 0x06A5 0xACC7 0 0 0 0 0) # } contract_7 = pre.deploy_contract( # noqa: F841 @@ -250,59 +272,37 @@ def test_eip2929_oog( ) # Source: lll # { - # (staticcall 0x06A5 0xACC7 0 0 0 0) + # (extcodecopy 0x1031 0 0 0x20) # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x6A5, - address=0xACC7, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.EXTCODECOPY( + address=0x1031, dest_offset=0x0, offset=0x0, size=0x20 ) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x00000000000000000000000000000000000010FA), # noqa: E501 + address=Address(0x000000000000000000000000000000000000103C), # noqa: E501 ) # Source: lll # { - # (return 0 0) + # (extcodesize 0x1031) # } - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.EXTCODESIZE(address=0x1031) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x000000000000000000000000000000000000ACC7), # noqa: E501 + address=Address(0x000000000000000000000000000000000000103B), # noqa: E501 ) # Source: lll # { - # (def 'addr $4) ; the address to call - # (def 'callGas $36) ; the amount of gas to give it - # - # [[0]] (call callGas addr 0 0 0 0 0) + # (extcodehash 0x1031) # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=Op.CALLDATALOAD(offset=0x24), - address=Op.CALLDATALOAD(offset=0x4), - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - storage={0: 24743}, + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.EXTCODEHASH(address=0x1031) + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 + address=Address(0x000000000000000000000000000000000000103F), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) tx_data = [ Bytes("1a8451e6") + Hash(contract_0, left_padding=True) + Hash(0x7D0), diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost.py index 31b6e7693b0..98b4497269a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost.py @@ -728,6 +728,7 @@ def test_gas_cost( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { ; LLL doesn't let us call arbitrary code, so we craft # ; a new contract with the opcode and then call it to see @@ -851,7 +852,6 @@ def test_gas_cost( nonce=0, address=Address(0xCCDCF3FF42C8382ABEEF05BB8949F975A6BC345C), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_berlin.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_berlin.py index a11595f8ea4..c122aab7d30 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_berlin.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_berlin.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -712,9 +711,7 @@ def test_gas_cost_berlin( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -848,7 +845,6 @@ def test_gas_cost_berlin( nonce=0, address=Address(0x2F170B2347023BB6BF3EEC84B53259B96E0268C3), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("000000"), diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_exp.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_exp.py index ef775c738b1..6b9f898a757 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_exp.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_exp.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -98,9 +97,7 @@ def test_gas_cost_exp( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -158,9 +155,7 @@ def test_gas_cost_exp( storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x087AAB8070088FBBE4F60141CF79032D28528B89), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("c5b5a1ae") + Hash(0x0) + Hash(0x20), diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_jump.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_jump.py index 48f7047d708..e176e90fd86 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_jump.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_jump.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -67,9 +66,7 @@ def test_gas_cost_jump( contract_2 = Address(0x0000000000000000000000000000000000003000) contract_3 = Address(0x0000000000000000000000000000000000004000) contract_4 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -149,7 +146,7 @@ def test_gas_cost_jump( + Op.POP( Op.CALL( gas=0x10000, - address=0x1000, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -166,7 +163,7 @@ def test_gas_cost_jump( + Op.POP( Op.CALL( gas=0x10000, - address=0x2000, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -184,7 +181,7 @@ def test_gas_cost_jump( + Op.POP( Op.CALL( gas=0x10000, - address=0x3000, + address=contract_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -202,7 +199,7 @@ def test_gas_cost_jump( + Op.POP( Op.CALL( gas=0x10000, - address=0x4000, + address=contract_3, value=0x0, args_offset=0x0, args_size=0x0, @@ -223,9 +220,7 @@ def test_gas_cost_jump( storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("c5b5a1ae") + Hash(0x1) + Hash(0x4), diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_mem_seg.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_mem_seg.py index b9e08d5bb92..1b37685b220 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_mem_seg.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_mem_seg.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -374,9 +373,7 @@ def test_gas_cost_mem_seg( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -540,9 +537,7 @@ def test_gas_cost_mem_seg( storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x727437E50AF8535411157A4ACA154C81D72BAAD4), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("98eed7a4") diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_memory.py index de51a40f163..aad4a36436a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -501,9 +500,7 @@ def test_gas_cost_memory( contract_1 = Address(0x000000000000000000000000000000000010BA5E) contract_2 = Address(0x000000000000000000000000000000000011BA5E) contract_3 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -633,7 +630,7 @@ def test_gas_cost_memory( + Op.POP( Op.CALL( gas=0x10000, - address=0xBA5E, + address=contract_0, value=0x0, args_offset=0x20, args_size=0x20, @@ -657,7 +654,7 @@ def test_gas_cost_memory( + Op.POP( Op.CALL( gas=0x10000, - address=0xBA5E, + address=contract_0, value=0x0, args_offset=0x20, args_size=0x20, @@ -674,7 +671,7 @@ def test_gas_cost_memory( + Op.POP( Op.CALL( gas=0x10000, - address=0x10BA5E, + address=contract_1, value=0x0, args_offset=0x20, args_size=0x20, @@ -696,7 +693,7 @@ def test_gas_cost_memory( + Op.POP( Op.CALL( gas=0x10000, - address=0xBA5E, + address=contract_0, value=0x0, args_offset=0x20, args_size=0x20, @@ -713,7 +710,7 @@ def test_gas_cost_memory( + Op.POP( Op.CALL( gas=0x10000, - address=0x11BA5E, + address=contract_2, value=0x0, args_offset=0x20, args_size=0x20, @@ -767,9 +764,7 @@ def test_gas_cost_memory( storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_return.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_return.py index 4d9a218a2b2..cebe282fc29 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_return.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_gas_cost_return.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_gas_cost_return( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_gas_cost_return( code=Op.PUSH1[0x0] + Op.PUSH1[0xFF] + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xEB0E68B88A12FC84AD4A1EEB07B289638C4D9F3C), # noqa: E501 ) # Source: raw # 0x600060FFF3 @@ -60,7 +56,6 @@ def test_gas_cost_return( code=Op.RETURN(offset=0xFF, size=0x0), balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x35CD99E56B0F9AC243172A86BEF4D042DFDBC166), # noqa: E501 ) # Source: lll # { @@ -131,9 +126,7 @@ def test_gas_cost_return( storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x155665FB22995BB5B9DC1D8D9D57A00AC64DC1E0), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_balance_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_balance_gas.py index 1245ad40bcd..9b410ce9fb9 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_balance_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_balance_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_balance_gas( ) -> None: """Test_raw_balance_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,18 +43,14 @@ def test_raw_balance_gas( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (BALANCE ) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.POP( - Op.BALANCE(address=0xFAA10B404AB607779993C016CD5DA73AE1F29D7E) - ) + + Op.POP(Op.BALANCE(address=sender)) + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xDFDE2D07C7829A62D244D6B9791742B2921AF7C0), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas.py index f0df76fdf2e..ce267ffe0b9 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_call_code_gas( ) -> None: """Test_raw_call_code_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_call_code_gas( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 30000 0 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_call_code_gas( + Op.POP( Op.CALLCODE( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,7 +67,6 @@ def test_raw_call_code_gas( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x2368FC9631CC2861D8E253341F166876337E12B0), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_ask.py index 338862b55c4..4850de47a79 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_call_code_gas_ask( ) -> None: """Test_raw_call_code_gas_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_call_code_gas_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 3000000 0 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_call_code_gas_ask( + Op.POP( Op.CALLCODE( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,7 +67,6 @@ def test_raw_call_code_gas_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x971FAD0EE9240291BBA0691A5C8DB57FCB9A6A22), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory.py index f2763a748c0..d5eecdff81e 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_code_gas_memory( ) -> None: """Test_raw_call_code_gas_memory.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_code_gas_memory( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 30000 0 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_code_gas_memory( + Op.POP( Op.CALLCODE( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x1F40, @@ -74,7 +69,6 @@ def test_raw_call_code_gas_memory( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xEFBB83CB8BB5ED4F8CBCE07972C071D88020EA1F), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory_ask.py index 6d6dea998e7..dbed9f97250 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_memory_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_code_gas_memory_ask( ) -> None: """Test_raw_call_code_gas_memory_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_code_gas_memory_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 3000000 0 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_code_gas_memory_ask( + Op.POP( Op.CALLCODE( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x1F40, @@ -74,7 +69,6 @@ def test_raw_call_code_gas_memory_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x71A0BCD4587FB3C57B8066A375518DADA2A8ECDB), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer.py index b61fa486d90..8082a69671c 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_code_gas_value_transfer( ) -> None: """Test_raw_call_code_gas_value_transfer.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_code_gas_value_transfer( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 30000 10 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_code_gas_value_transfer( + Op.POP( Op.CALLCODE( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x0, @@ -74,7 +69,6 @@ def test_raw_call_code_gas_value_transfer( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x52AA4AAF09161CCB2C2FDBDD1F646420A6B96087), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_ask.py index 9c32ba75b58..d69e9eec044 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_code_gas_value_transfer_ask( ) -> None: """Test_raw_call_code_gas_value_transfer_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_code_gas_value_transfer_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 3000000 10 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_code_gas_value_transfer_ask( + Op.POP( Op.CALLCODE( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x0, @@ -74,7 +69,6 @@ def test_raw_call_code_gas_value_transfer_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x956D6BBD9F4F04F26A090166E43C641B1C5C2EDE), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory.py index 730ba366c62..adc2b040768 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_code_gas_value_transfer_memory( ) -> None: """Test_raw_call_code_gas_value_transfer_memory.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_code_gas_value_transfer_memory( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 30000 10 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_code_gas_value_transfer_memory( + Op.POP( Op.CALLCODE( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x1F40, @@ -74,7 +69,6 @@ def test_raw_call_code_gas_value_transfer_memory( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xF1F3A9AF4253BD7852A915ED5DCAA2360DE438F6), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory_ask.py index efd24139352..db089d6d3fc 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_code_gas_value_transfer_memory_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_code_gas_value_transfer_memory_ask( ) -> None: """Test_raw_call_code_gas_value_transfer_memory_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_code_gas_value_transfer_memory_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALLCODE 3000000 10 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_code_gas_value_transfer_memory_ask( + Op.POP( Op.CALLCODE( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x1F40, @@ -74,7 +69,6 @@ def test_raw_call_code_gas_value_transfer_memory_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x2A2CF91E47A7D53E3AA1D443454EF6AFAC34E2C8), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas.py index d8102a1447c..97bc8524d66 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_call_gas( ) -> None: """Test_raw_call_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_call_gas( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 30000 0 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_call_gas( + Op.POP( Op.CALL( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,7 +67,6 @@ def test_raw_call_gas( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x7541FD15B3CBF59FFE4C9FA7303C5A98C7C2AEFD), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_ask.py index 25c81635957..6935ff2a0d7 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_call_gas_ask( ) -> None: """Test_raw_call_gas_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_call_gas_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 3000000 0 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_call_gas_ask( + Op.POP( Op.CALL( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,7 +67,6 @@ def test_raw_call_gas_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x18817869E5F5B3F55F57BB7791EA8EE6F62604C8), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer.py index fdd367c3445..c94dd98e65a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_gas_value_transfer( ) -> None: """Test_raw_call_gas_value_transfer.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_gas_value_transfer( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 30000 10 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_gas_value_transfer( + Op.POP( Op.CALL( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x0, @@ -74,7 +69,6 @@ def test_raw_call_gas_value_transfer( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xC2955AF3F56C0D3150BE7ABBD80A01914337D211), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_ask.py index 2348ff7e697..46240d39693 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_gas_value_transfer_ask( ) -> None: """Test_raw_call_gas_value_transfer_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_gas_value_transfer_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 3000000 10 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_gas_value_transfer_ask( + Op.POP( Op.CALL( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x0, @@ -74,7 +69,6 @@ def test_raw_call_gas_value_transfer_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x75DA17BE9A3B7768A69E918C1574A320A6F9E59F), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory.py index e6eb2dcadbd..cd1f9f68c18 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_gas_value_transfer_memory( ) -> None: """Test_raw_call_gas_value_transfer_memory.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_gas_value_transfer_memory( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 30000 10 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_gas_value_transfer_memory( + Op.POP( Op.CALL( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x1F40, @@ -74,7 +69,6 @@ def test_raw_call_gas_value_transfer_memory( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xAD8277A2165D713AF6E54A1CEFB7E5E29022B8A5), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory_ask.py index f94defb8e02..0939cc07c2a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_gas_value_transfer_memory_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_call_gas_value_transfer_memory_ask( ) -> None: """Test_raw_call_gas_value_transfer_memory_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_call_gas_value_transfer_memory_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 3000000 10 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_call_gas_value_transfer_memory_ask( + Op.POP( Op.CALL( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0xA, args_offset=0x0, args_size=0x1F40, @@ -74,7 +69,6 @@ def test_raw_call_gas_value_transfer_memory_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x29902EA04A72CBB6F877F6D27471A102E0700F20), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas.py index 07c5589ce86..2626ed1afa2 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_call_memory_gas( ) -> None: """Test_raw_call_memory_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_call_memory_gas( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 30000 0 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_call_memory_gas( + Op.POP( Op.CALL( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x1F40, @@ -72,7 +67,6 @@ def test_raw_call_memory_gas( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x590B5B415A9A5F546BDB1A7781B31B91C53902ED), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas_ask.py index 085e8cb7954..1ea4c6eab02 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_call_memory_gas_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_call_memory_gas_ask( ) -> None: """Test_raw_call_memory_gas_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_call_memory_gas_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CALL 3000000 0 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_call_memory_gas_ask( + Op.POP( Op.CALL( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, value=0x0, args_offset=0x0, args_size=0x1F40, @@ -72,7 +67,6 @@ def test_raw_call_memory_gas_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x708C831C65C2FB3B3CE85A39A273B30726324A8A), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer.py index 3cc3b49047b..b1926166116 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_raw_create_fail_gas_value_transfer( """Test_raw_create_fail_gas_value_transfer.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_raw_create_fail_gas_value_transfer( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CREATE 11 0 0) [[1]] (SUB @0 (GAS)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +55,6 @@ def test_raw_create_fail_gas_value_transfer( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer2.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer2.py index c32cdafc4a3..cff6a4c875c 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer2.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_fail_gas_value_transfer2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_raw_create_fail_gas_value_transfer2( """Test_raw_create_fail_gas_value_transfer2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_raw_create_fail_gas_value_transfer2( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CREATE 11 0 8000) [[1]] (SUB @0 (GAS)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +55,6 @@ def test_raw_create_fail_gas_value_transfer2( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas.py index 73306bf1d30..cfcdaf8e86f 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_create_gas( """Test_raw_create_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_raw_create_gas( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CREATE 0 0 0) [[1]] (SUB @0 (GAS)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -57,7 +53,6 @@ def test_raw_create_gas( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_memory.py index 057fb26f5ab..78b9d6682e6 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_create_gas_memory( """Test_raw_create_gas_memory.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_raw_create_gas_memory( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CREATE 0 0 8000) [[1]] (SUB @0 (GAS)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -57,7 +53,6 @@ def test_raw_create_gas_memory( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer.py index 326573abc02..355d74d1dfd 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_raw_create_gas_value_transfer( """Test_raw_create_gas_value_transfer.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_raw_create_gas_value_transfer( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CREATE 10 0 0) [[1]] (SUB @0 (GAS)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +55,6 @@ def test_raw_create_gas_value_transfer( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer_memory.py index 376eeeb408f..52578c5b4b9 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_create_gas_value_transfer_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_raw_create_gas_value_transfer_memory( """Test_raw_create_gas_value_transfer_memory.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_raw_create_gas_value_transfer_memory( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (CREATE 10 0 8000) [[1]] (SUB @0 (GAS)) } contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +55,6 @@ def test_raw_create_gas_value_transfer_memory( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas.py index 47fda58f764..9ff87ffdc2a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_delegate_call_gas( ) -> None: """Test_raw_delegate_call_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,9 +48,7 @@ def test_raw_delegate_call_gas( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (DELEGATECALL 30000 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +56,7 @@ def test_raw_delegate_call_gas( + Op.POP( Op.DELEGATECALL( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -71,7 +66,6 @@ def test_raw_delegate_call_gas( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x8DFC4F381EEE03447D510A61A1266821A480BD85), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_ask.py index b58dbe0a593..64eeacabb25 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_delegate_call_gas_ask( ) -> None: """Test_raw_delegate_call_gas_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_delegate_call_gas_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (DELEGATECALL 3000000 0 0 0 0) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_delegate_call_gas_ask( + Op.POP( Op.DELEGATECALL( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -73,7 +68,6 @@ def test_raw_delegate_call_gas_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xDC20EAF593590F91C2439B61F29CF075006750FF), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory.py index b49b1a0c366..3db2620bb5a 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_delegate_call_gas_memory( ) -> None: """Test_raw_delegate_call_gas_memory.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_delegate_call_gas_memory( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (DELEGATECALL 30000 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_delegate_call_gas_memory( + Op.POP( Op.DELEGATECALL( gas=0x7530, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, args_offset=0x0, args_size=0x1F40, ret_offset=0x0, @@ -73,7 +68,6 @@ def test_raw_delegate_call_gas_memory( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x2DA2093C616EE035CC42F6A9297B0C3838D01605), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory_ask.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory_ask.py index 7f8d9d66a8a..37333476bf2 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory_ask.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_delegate_call_gas_memory_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_delegate_call_gas_memory_ask( ) -> None: """Test_raw_delegate_call_gas_memory_ask.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_raw_delegate_call_gas_memory_ask( addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (DELEGATECALL 3000000 0 8000 0 8000) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +58,7 @@ def test_raw_delegate_call_gas_memory_ask( + Op.POP( Op.DELEGATECALL( gas=0x2DC6C0, - address=0xE497CD0909C3691E0B6D2A42E26F36696FC27BA5, + address=addr, args_offset=0x0, args_size=0x1F40, ret_offset=0x0, @@ -73,7 +68,6 @@ def test_raw_delegate_call_gas_memory_ask( + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x8759CFBF878E9FF3CD4D3D7413FC8A44B7935CEC), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_gas.py index 53f904f24e1..c75b732ee35 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_ext_code_copy_gas( ) -> None: """Test_raw_ext_code_copy_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,23 +50,15 @@ def test_raw_ext_code_copy_gas( "0112233445566778899101112131415161718191202122232425" ), nonce=0, - address=Address(0x4A84C43FBA78AE75CBC15C5B63CAA15DA55F4464), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (EXTCODECOPY 32 0 20) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.EXTCODECOPY( - address=0x4A84C43FBA78AE75CBC15C5B63CAA15DA55F4464, - dest_offset=0x20, - offset=0x0, - size=0x14, - ) + + Op.EXTCODECOPY(address=addr, dest_offset=0x20, offset=0x0, size=0x14) + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x3D74E06FE0AF85E65C8B2F5DCFF3FA076F5B5BB8), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_memory_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_memory_gas.py index 83af5181cb5..a03431f4f6c 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_memory_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_copy_memory_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_raw_ext_code_copy_memory_gas( ) -> None: """Test_raw_ext_code_copy_memory_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -55,23 +52,17 @@ def test_raw_ext_code_copy_memory_gas( "0112233445566778899101112131415161718191202122232425" ), nonce=0, - address=Address(0x4A84C43FBA78AE75CBC15C5B63CAA15DA55F4464), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (EXTCODECOPY 32 0 11120) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=Op.GAS) + Op.EXTCODECOPY( - address=0x4A84C43FBA78AE75CBC15C5B63CAA15DA55F4464, - dest_offset=0x20, - offset=0x0, - size=0x2B70, + address=addr, dest_offset=0x20, offset=0x0, size=0x2B70 ) + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x792ED227B10FCD174ACC9E5A69C1F1471A138C5D), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_size_gas.py b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_size_gas.py index fe08562662f..4da7798cbdc 100644 --- a/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_size_gas.py +++ b/tests/ported_static/stEIP150singleCodeGasPrices/test_raw_ext_code_size_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_raw_ext_code_size_gas( ) -> None: """Test_raw_ext_code_size_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -53,20 +50,15 @@ def test_raw_ext_code_size_gas( "0112233445566778899101112131415161718191202122232425" ), nonce=0, - address=Address(0x4A84C43FBA78AE75CBC15C5B63CAA15DA55F4464), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0] (GAS) (EXTCODESIZE ) [[1]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.POP( - Op.EXTCODESIZE(address=0x4A84C43FBA78AE75CBC15C5B63CAA15DA55F4464) - ) + + Op.POP(Op.EXTCODESIZE(address=addr)) + Op.SSTORE(key=0x1, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x585F8515632DD8B3ACCE933A4C2DE8BA66A09A36), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP1559/test_base_fee_diff_places.py b/tests/ported_static/stEIP1559/test_base_fee_diff_places.py index 5699d94c79f..51016abbbae 100644 --- a/tests/ported_static/stEIP1559/test_base_fee_diff_places.py +++ b/tests/ported_static/stEIP1559/test_base_fee_diff_places.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -268,9 +267,7 @@ def test_base_fee_diff_places( contract_10 = Address(0x000000000000000000000000000000000060BACC) contract_11 = Address(0x00000000000000000000000000000000DEADDEAD) contract_12 = Address(0x00000000000000000000000000000060BACCFA57) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -329,6 +326,73 @@ def test_base_fee_diff_places( ) # Source: yul # berlin { + # // basefee is still not supported in Yul 0.8.5 + # + # + # mstore(0, verbatim_0i_1o(hex"48")) + # + # + # return(0, 0x20) // return the result as our return value + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) + + Op.RETURN(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 + ) + # Source: yul + # berlin { + # // basefee is still not supported in Yul 0.8.5 + # + # + # mstore(0, verbatim_0i_1o(hex"48")) + # + # + # sstore(0,mload(0)) + # invalid() + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.INVALID, + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 + ) + # Source: yul + # berlin { + # // basefee is still not supported in Yul 0.8.5 + # + # + # mstore(0, verbatim_0i_1o(hex"48")) + # + # + # sstore(0,mload(0)) + # revert(0,0x20) + # } + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.REVERT(offset=0x0, size=0x20), + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 + ) + # Source: yul + # berlin { + # selfdestruct(0) + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=0x0), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 + ) + # Source: yul + # berlin { # let addr := 0x20C0DE # let length := extcodesize(addr) # @@ -355,6 +419,120 @@ def test_base_fee_diff_places( ) # Source: yul # berlin { + # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALLCODE( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALL( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_8 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.STATICCALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.DELEGATECALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 + ) + # Source: yul + # berlin { # let action := calldataload(4) # let res := 1 // If the result of a call is revert, revert here too # let addr := 1 // If the result of CREATE[2] is zero, it reverted @@ -986,187 +1164,6 @@ def test_base_fee_diff_places( ) # Source: yul # berlin { - # // basefee is still not supported in Yul 0.8.5 - # - # - # mstore(0, verbatim_0i_1o(hex"48")) - # - # - # return(0, 0x20) // return the result as our return value - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) - + Op.RETURN(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALL( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALLCODE( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_8 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.STATICCALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 - ) - # Source: yul - # berlin { - # // basefee is still not supported in Yul 0.8.5 - # - # - # mstore(0, verbatim_0i_1o(hex"48")) - # - # - # sstore(0,mload(0)) - # invalid() - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.INVALID, - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 - ) - # Source: yul - # berlin { - # // basefee is still not supported in Yul 0.8.5 - # - # - # mstore(0, verbatim_0i_1o(hex"48")) - # - # - # sstore(0,mload(0)) - # revert(0,0x20) - # } - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.REVERT(offset=0x0, size=0x20), - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 - ) - # Source: yul - # berlin { - # selfdestruct(0) - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=0x0), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 - ) - # Source: yul - # berlin { # let depth := calldataload(0) # # if eq(depth,0) { @@ -1221,7 +1218,6 @@ def test_base_fee_diff_places( nonce=1, address=Address(0x00000000000000000000000000000060BACCFA57), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/stEIP1559/test_base_fee_diff_places_osaka.py b/tests/ported_static/stEIP1559/test_base_fee_diff_places_osaka.py index 0594b630629..8eb133b8c6e 100644 --- a/tests/ported_static/stEIP1559/test_base_fee_diff_places_osaka.py +++ b/tests/ported_static/stEIP1559/test_base_fee_diff_places_osaka.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -261,9 +260,7 @@ def test_base_fee_diff_places( contract_10 = Address(0x000000000000000000000000000000000060BACC) contract_11 = Address(0x00000000000000000000000000000000DEADDEAD) contract_12 = Address(0x00000000000000000000000000000060BACCFA57) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -322,6 +319,73 @@ def test_base_fee_diff_places( ) # Source: yul # berlin { + # // basefee is still not supported in Yul 0.8.5 + # + # + # mstore(0, verbatim_0i_1o(hex"48")) + # + # + # return(0, 0x20) // return the result as our return value + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) + + Op.RETURN(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 + ) + # Source: yul + # berlin { + # // basefee is still not supported in Yul 0.8.5 + # + # + # mstore(0, verbatim_0i_1o(hex"48")) + # + # + # sstore(0,mload(0)) + # invalid() + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.INVALID, + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 + ) + # Source: yul + # berlin { + # // basefee is still not supported in Yul 0.8.5 + # + # + # mstore(0, verbatim_0i_1o(hex"48")) + # + # + # sstore(0,mload(0)) + # revert(0,0x20) + # } + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.REVERT(offset=0x0, size=0x20), + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 + ) + # Source: yul + # berlin { + # selfdestruct(0) + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=0x0), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 + ) + # Source: yul + # berlin { # let addr := 0x20C0DE # let length := extcodesize(addr) # @@ -348,6 +412,120 @@ def test_base_fee_diff_places( ) # Source: yul # berlin { + # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALLCODE( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALL( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_8 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.STATICCALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.DELEGATECALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 + ) + # Source: yul + # berlin { # let action := calldataload(4) # let res := 1 // If the result of a call is revert, revert here too # let addr := 1 // If the result of CREATE[2] is zero, it reverted @@ -979,187 +1157,6 @@ def test_base_fee_diff_places( ) # Source: yul # berlin { - # // basefee is still not supported in Yul 0.8.5 - # - # - # mstore(0, verbatim_0i_1o(hex"48")) - # - # - # return(0, 0x20) // return the result as our return value - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) - + Op.RETURN(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALL( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALLCODE( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_8 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.STATICCALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 - ) - # Source: yul - # berlin { - # // basefee is still not supported in Yul 0.8.5 - # - # - # mstore(0, verbatim_0i_1o(hex"48")) - # - # - # sstore(0,mload(0)) - # invalid() - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.INVALID, - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 - ) - # Source: yul - # berlin { - # // basefee is still not supported in Yul 0.8.5 - # - # - # mstore(0, verbatim_0i_1o(hex"48")) - # - # - # sstore(0,mload(0)) - # revert(0,0x20) - # } - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.BASEFEE) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.REVERT(offset=0x0, size=0x20), - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 - ) - # Source: yul - # berlin { - # selfdestruct(0) - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=0x0), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 - ) - # Source: yul - # berlin { # let depth := calldataload(0) # # if eq(depth,0) { @@ -1214,7 +1211,6 @@ def test_base_fee_diff_places( nonce=1, address=Address(0x00000000000000000000000000000060BACCFA57), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/stEIP1559/test_gas_price_diff_places.py b/tests/ported_static/stEIP1559/test_gas_price_diff_places.py index e291c7968eb..40115726f8a 100644 --- a/tests/ported_static/stEIP1559/test_gas_price_diff_places.py +++ b/tests/ported_static/stEIP1559/test_gas_price_diff_places.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -268,9 +267,7 @@ def test_gas_price_diff_places( contract_10 = Address(0x000000000000000000000000000000000060BACC) contract_11 = Address(0x00000000000000000000000000000000DEADDEAD) contract_12 = Address(0x00000000000000000000000000000060BACCFA57) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -323,6 +320,66 @@ def test_gas_price_diff_places( ) # Source: yul # berlin { + # mstore(0, gasprice()) + # + # + # return(0, 0x20) // return the result as our return value + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) + + Op.RETURN(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 + ) + # Source: yul + # berlin { + # mstore(0, gasprice()) + # + # + # sstore(0,mload(0)) + # invalid() + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.GASPRICE + + Op.PUSH1[0x0] + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.SSTORE + + Op.INVALID, + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 + ) + # Source: yul + # berlin { + # mstore(0, gasprice()) + # + # + # sstore(0,mload(0)) + # revert(0,0x20) + # } + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.REVERT(offset=0x0, size=0x20), + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 + ) + # Source: yul + # berlin { + # selfdestruct(0) + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=0x0), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 + ) + # Source: yul + # berlin { # let addr := 0x20C0DE # let length := extcodesize(addr) # @@ -349,6 +406,120 @@ def test_gas_price_diff_places( ) # Source: yul # berlin { + # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALLCODE( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALL( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_8 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.STATICCALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.DELEGATECALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 + ) + # Source: yul + # berlin { # let action := calldataload(4) # let res := 1 // If the result of a call is revert, revert here too # let addr := 1 // If the result of CREATE[2] is zero, it reverted @@ -983,180 +1154,6 @@ def test_gas_price_diff_places( ) # Source: yul # berlin { - # mstore(0, gasprice()) - # - # - # return(0, 0x20) // return the result as our return value - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) - + Op.RETURN(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALL( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALLCODE( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_8 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.STATICCALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 - ) - # Source: yul - # berlin { - # mstore(0, gasprice()) - # - # - # sstore(0,mload(0)) - # invalid() - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.GASPRICE - + Op.PUSH1[0x0] - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.SSTORE - + Op.INVALID, - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 - ) - # Source: yul - # berlin { - # mstore(0, gasprice()) - # - # - # sstore(0,mload(0)) - # revert(0,0x20) - # } - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.REVERT(offset=0x0, size=0x20), - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 - ) - # Source: yul - # berlin { - # selfdestruct(0) - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=0x0), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 - ) - # Source: yul - # berlin { # let depth := calldataload(0) # # if eq(depth,0) { @@ -1208,7 +1205,6 @@ def test_gas_price_diff_places( nonce=1, address=Address(0x00000000000000000000000000000060BACCFA57), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/stEIP1559/test_gas_price_diff_places_osaka.py b/tests/ported_static/stEIP1559/test_gas_price_diff_places_osaka.py index 09c943cc425..873dae98658 100644 --- a/tests/ported_static/stEIP1559/test_gas_price_diff_places_osaka.py +++ b/tests/ported_static/stEIP1559/test_gas_price_diff_places_osaka.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -261,9 +260,7 @@ def test_gas_price_diff_places( contract_10 = Address(0x000000000000000000000000000000000060BACC) contract_11 = Address(0x00000000000000000000000000000000DEADDEAD) contract_12 = Address(0x00000000000000000000000000000060BACCFA57) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -316,6 +313,66 @@ def test_gas_price_diff_places( ) # Source: yul # berlin { + # mstore(0, gasprice()) + # + # + # return(0, 0x20) // return the result as our return value + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) + + Op.RETURN(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 + ) + # Source: yul + # berlin { + # mstore(0, gasprice()) + # + # + # sstore(0,mload(0)) + # invalid() + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.GASPRICE + + Op.PUSH1[0x0] + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.SSTORE + + Op.INVALID, + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 + ) + # Source: yul + # berlin { + # mstore(0, gasprice()) + # + # + # sstore(0,mload(0)) + # revert(0,0x20) + # } + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.REVERT(offset=0x0, size=0x20), + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 + ) + # Source: yul + # berlin { + # selfdestruct(0) + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=0x0), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 + ) + # Source: yul + # berlin { # let addr := 0x20C0DE # let length := extcodesize(addr) # @@ -342,6 +399,120 @@ def test_gas_price_diff_places( ) # Source: yul # berlin { + # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALLCODE( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x15, + condition=Op.ISZERO( + Op.CALL( + gas=Op.GAS, + address=0xCA11, + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_8 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.STATICCALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 + ) + # Source: yul + # berlin { + # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) + # { revert(0,0x20) } + # + # return(0, 0x20) // return the result as our return value + # } + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x14, + condition=Op.ISZERO( + Op.DELEGATECALL( + gas=Op.GAS, + address=0xCA11, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=0x0, + ret_size=0x20, + ) + ), + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.JUMPDEST + + Op.REVERT(offset=0x0, size=0x20), + balance=0xDE0B6B3A7640000, + nonce=1, + address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 + ) + # Source: yul + # berlin { # let action := calldataload(4) # let res := 1 // If the result of a call is revert, revert here too # let addr := 1 // If the result of CREATE[2] is zero, it reverted @@ -976,180 +1147,6 @@ def test_gas_price_diff_places( ) # Source: yul # berlin { - # mstore(0, gasprice()) - # - # - # return(0, 0x20) // return the result as our return value - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) - + Op.RETURN(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000000CA11), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(call(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALL( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F1), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(callcode(gas(), 0xca11, 0, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x15, - condition=Op.ISZERO( - Op.CALLCODE( - gas=Op.GAS, - address=0xCA11, - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F2), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(delegatecall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.DELEGATECALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100F4), # noqa: E501 - ) - # Source: yul - # berlin { - # if iszero(staticcall(gas(), 0xca11, 0, 0, 0, 0x20)) - # { revert(0,0x20) } - # - # return(0, 0x20) // return the result as our return value - # } - contract_8 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x14, - condition=Op.ISZERO( - Op.STATICCALL( - gas=Op.GAS, - address=0xCA11, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=0x0, - ret_size=0x20, - ) - ), - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.JUMPDEST - + Op.REVERT(offset=0x0, size=0x20), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000CA1100FA), # noqa: E501 - ) - # Source: yul - # berlin { - # mstore(0, gasprice()) - # - # - # sstore(0,mload(0)) - # invalid() - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.GASPRICE - + Op.PUSH1[0x0] - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.SSTORE - + Op.INVALID, - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x0000000000000000000000000000000000060006), # noqa: E501 - ) - # Source: yul - # berlin { - # mstore(0, gasprice()) - # - # - # sstore(0,mload(0)) - # revert(0,0x20) - # } - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GASPRICE) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.REVERT(offset=0x0, size=0x20), - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x000000000000000000000000000000000060BACC), # noqa: E501 - ) - # Source: yul - # berlin { - # selfdestruct(0) - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=0x0), - balance=0xDE0B6B3A7640000, - nonce=1, - address=Address(0x00000000000000000000000000000000DEADDEAD), # noqa: E501 - ) - # Source: yul - # berlin { # let depth := calldataload(0) # # if eq(depth,0) { @@ -1201,7 +1198,6 @@ def test_gas_price_diff_places( nonce=1, address=Address(0x00000000000000000000000000000060BACCFA57), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/stEIP1559/test_low_fee_cap.py b/tests/ported_static/stEIP1559/test_low_fee_cap.py index 3d4f4f31f76..82deed00eff 100644 --- a/tests/ported_static/stEIP1559/test_low_fee_cap.py +++ b/tests/ported_static/stEIP1559/test_low_fee_cap.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -35,9 +33,7 @@ def test_low_fee_cap( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -56,9 +52,7 @@ def test_low_fee_cap( code=Op.SSTORE(key=0x0, value=0x2) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD71B14C239FC39327F25764DD784C85EF0285FDA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP1559/test_low_gas_limit.py b/tests/ported_static/stEIP1559/test_low_gas_limit.py index 302f0728e2d..d2baa131eae 100644 --- a/tests/ported_static/stEIP1559/test_low_gas_limit.py +++ b/tests/ported_static/stEIP1559/test_low_gas_limit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -73,9 +72,7 @@ def test_low_gas_limit( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -96,9 +93,7 @@ def test_low_gas_limit( storage={0: 24743}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEF0454D0376D1921B9A83868282725853C293AB5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP1559/test_low_gas_price_old_types.py b/tests/ported_static/stEIP1559/test_low_gas_price_old_types.py index 580ee63f8a7..48974cd0123 100644 --- a/tests/ported_static/stEIP1559/test_low_gas_price_old_types.py +++ b/tests/ported_static/stEIP1559/test_low_gas_price_old_types.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -61,9 +59,7 @@ def test_low_gas_price_old_types( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -82,9 +78,7 @@ def test_low_gas_price_old_types( code=Op.SSTORE(key=0x0, value=0x2) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD71B14C239FC39327F25764DD784C85EF0285FDA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP1559/test_out_of_funds.py b/tests/ported_static/stEIP1559/test_out_of_funds.py index de865a0fce1..8684ccdbf0d 100644 --- a/tests/ported_static/stEIP1559/test_out_of_funds.py +++ b/tests/ported_static/stEIP1559/test_out_of_funds.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -74,9 +72,7 @@ def test_out_of_funds( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -95,9 +91,7 @@ def test_out_of_funds( code=Op.SSTORE(key=0x0, value=0x2) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD71B14C239FC39327F25764DD784C85EF0285FDA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP1559/test_out_of_funds_old_types.py b/tests/ported_static/stEIP1559/test_out_of_funds_old_types.py index 466316f9880..faa5538f101 100644 --- a/tests/ported_static/stEIP1559/test_out_of_funds_old_types.py +++ b/tests/ported_static/stEIP1559/test_out_of_funds_old_types.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -101,9 +99,7 @@ def test_out_of_funds_old_types( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -122,9 +118,7 @@ def test_out_of_funds_old_types( code=Op.SSTORE(key=0x0, value=0x2) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD71B14C239FC39327F25764DD784C85EF0285FDA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP1559/test_sender_balance.py b/tests/ported_static/stEIP1559/test_sender_balance.py index 4e1428d6048..c248718b4df 100644 --- a/tests/ported_static/stEIP1559/test_sender_balance.py +++ b/tests/ported_static/stEIP1559/test_sender_balance.py @@ -50,6 +50,7 @@ def test_sender_balance( gas_limit=30000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: yul # london # { @@ -60,7 +61,6 @@ def test_sender_balance( nonce=0, address=Address(0x420132F96200BA8E5C98298A85633C35C4F052EF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP1559/test_tip_too_high.py b/tests/ported_static/stEIP1559/test_tip_too_high.py index eab3dd91b22..5a019d933c0 100644 --- a/tests/ported_static/stEIP1559/test_tip_too_high.py +++ b/tests/ported_static/stEIP1559/test_tip_too_high.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -35,9 +33,7 @@ def test_tip_too_high( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -57,9 +53,7 @@ def test_tip_too_high( code=Op.SSTORE(key=0x0, value=0x2) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEC75F5D282F63DA54CB0DAD4FF8EAAA070D2DA2B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP1559/test_transaction_intinsic_bug_paris.py b/tests/ported_static/stEIP1559/test_transaction_intinsic_bug_paris.py index 19d8a6a9e78..46e0c57138f 100644 --- a/tests/ported_static/stEIP1559/test_transaction_intinsic_bug_paris.py +++ b/tests/ported_static/stEIP1559/test_transaction_intinsic_bug_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,10 +33,7 @@ def test_transaction_intinsic_bug_paris( ) -> None: """Bug discovered on ropsten https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x85B89DB0E2AEF2A23F50801209A3DE4C65C58D9D) - sender = EOA( - key=0x91E0C3C68D9DE64B3299188625BEBD08C8B66D1C7E853E155F997C465E8F5F47 - ) + sender = pre.fund_eoa(amount=0x2FAF094, nonce=1) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,7 @@ def test_transaction_intinsic_bug_paris( gas_limit=71794957647893862, ) - pre[addr] = Account(balance=10) - pre[sender] = Account(balance=0x2FAF094, nonce=1) + addr = pre.fund_eoa(amount=10) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP1559/test_val_causes_oof.py b/tests/ported_static/stEIP1559/test_val_causes_oof.py index da081c1728b..dfbb5a3e162 100644 --- a/tests/ported_static/stEIP1559/test_val_causes_oof.py +++ b/tests/ported_static/stEIP1559/test_val_causes_oof.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -126,9 +124,7 @@ def test_val_causes_oof( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7608AB0A661408930040C5E3EB5B0C6520ACBB6CE5B28DDBE53676109E8EA24B - ) + sender = pre.fund_eoa(amount=0x5F5E100, nonce=1) env = Environment( fee_recipient=coinbase, @@ -160,9 +156,7 @@ def test_val_causes_oof( + Op.JUMP(pc=0x3), balance=0x5AF3107A4000, nonce=0, - address=Address(0x71E12B76AB6BE1EFBC98AC17EBFE5FAF488DA45E), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide.py b/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide.py index bde6b6d42f0..d99dcdf7185 100644 --- a/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide.py +++ b/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_one_v_call_suicide( ) -> None: """Test_call_one_v_call_suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_call_one_v_call_suicide( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0](GAS) (CALL 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide2.py b/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide2.py index 32da5c2a438..2c222ca68f4 100644 --- a/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide2.py +++ b/tests/ported_static/stEIP158Specific/test_call_one_v_call_suicide2.py @@ -48,6 +48,17 @@ def test_call_one_v_call_suicide2( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr_2] = Account(balance=0, nonce=1) + # Source: lll + # { (SELFDESTRUCT ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT( + address=0xEB201D2887816E041F6E807E804F64F3A7A226FE + ) + + Op.STOP, + nonce=0, + address=Address(0x99378E0DB04E57AE174AD69770E1B7A0AA805930), # noqa: E501 + ) # Source: lll # { [0](GAS) (CALL 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,17 +80,6 @@ def test_call_one_v_call_suicide2( nonce=0, address=Address(0xEA04224539257FBE043981AA6058FBC1D5E21B1A), # noqa: E501 ) - # Source: lll - # { (SELFDESTRUCT ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0xEB201D2887816E041F6E807E804F64F3A7A226FE - ) - + Op.STOP, - nonce=0, - address=Address(0x99378E0DB04E57AE174AD69770E1B7A0AA805930), # noqa: E501 - ) - pre[addr_2] = Account(balance=0, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP158Specific/test_call_to_empty_then_call_error_paris.py b/tests/ported_static/stEIP158Specific/test_call_to_empty_then_call_error_paris.py index a53da088e68..c0efd41acce 100644 --- a/tests/ported_static/stEIP158Specific/test_call_to_empty_then_call_error_paris.py +++ b/tests/ported_static/stEIP158Specific/test_call_to_empty_then_call_error_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_call_to_empty_then_call_error_paris( ) -> None: """Test_call_to_empty_then_call_error_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr_2 = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,14 +43,20 @@ def test_call_to_empty_then_call_error_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr_2 = pre.fund_eoa(amount=10) # noqa: F841 + # Source: lll + # { (GAS) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.GAS + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 0 0 0 0 0 0) (CALL 0 0 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -64,7 +66,7 @@ def test_call_to_empty_then_call_error_paris( ) + Op.CALL( gas=0x0, - address=0xAB4CDAE660B629C6F7BE5A12139558E6296AD0B5, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -73,16 +75,7 @@ def test_call_to_empty_then_call_error_paris( ) + Op.STOP, nonce=0, - address=Address(0x2FD4E62119E6702B1B340B14AAB503AF144D0DA4), # noqa: E501 - ) - # Source: lll - # { (GAS) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.GAS + Op.STOP, - nonce=0, - address=Address(0xAB4CDAE660B629C6F7BE5A12139558E6296AD0B5), # noqa: E501 ) - pre[addr_2] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP158Specific/test_call_zero_v_call_suicide.py b/tests/ported_static/stEIP158Specific/test_call_zero_v_call_suicide.py index f632140f042..901902b9a5b 100644 --- a/tests/ported_static/stEIP158Specific/test_call_zero_v_call_suicide.py +++ b/tests/ported_static/stEIP158Specific/test_call_zero_v_call_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_zero_v_call_suicide( ) -> None: """Test_call_zero_v_call_suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_call_zero_v_call_suicide( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0](GAS) (CALL 60000 0 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stEIP158Specific/test_exp_empty.py b/tests/ported_static/stEIP158Specific/test_exp_empty.py index d748a2036c4..9b7b323744c 100644 --- a/tests/ported_static/stEIP158Specific/test_exp_empty.py +++ b/tests/ported_static/stEIP158Specific/test_exp_empty.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_exp_empty( ) -> None: """Test_exp_empty.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_exp_empty( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [0](GAS) [[1]](EXP 0 12) [[2]](SUB @0 (GAS)) [0](GAS) [[3]](EXP 12 0) [[4]](SUB @0 (GAS)) [0](GAS) [[5]](EXP 0 0xffffffffffffffff) [[6]](SUB @0 (GAS)) [0](GAS) [[7]](EXP 0 0xffffffffffffffffffffffffffffffff) [[8]](SUB @0 (GAS)) [0](GAS) [[9]](EXP 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[10]](SUB @0 (GAS)) [0](GAS) [[11]](EXP 0xffffffffffffffff 0) [[12]](SUB @0 (GAS)) [0](GAS) [[13]](EXP 0xffffffffffffffffffffffffffffffff 0) [[14]](SUB @0 (GAS)) [0] (GAS) [[15]](EXP 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -92,7 +88,6 @@ def test_exp_empty( + Op.SSTORE(key=0x64, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x8A3C9879FC69C8C45C1201C27DA63312E9E9F6FE), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP158Specific/test_extcodesize_to_epmty_paris.py b/tests/ported_static/stEIP158Specific/test_extcodesize_to_epmty_paris.py index fa7b6f50122..35e01d26d30 100644 --- a/tests/ported_static/stEIP158Specific/test_extcodesize_to_epmty_paris.py +++ b/tests/ported_static/stEIP158Specific/test_extcodesize_to_epmty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_extcodesize_to_epmty_paris( ) -> None: """Test_extcodesize_to_epmty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,24 +43,17 @@ def test_extcodesize_to_epmty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (EXTCODESIZE ) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.SSTORE( - key=0x1, - value=Op.EXTCODESIZE( - address=0x76FAE819612A29489A1A43208613D8F8557B8898 - ), - ) + + Op.SSTORE(key=0x1, value=Op.EXTCODESIZE(address=addr)) + Op.SSTORE(key=0x64, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, storage={1: 1536}, nonce=0, - address=Address(0x6A7CA130BA6213231C23332FA5FCAB8CCB85C04B), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stEIP158Specific/test_vitalik_transaction_test_paris.py b/tests/ported_static/stEIP158Specific/test_vitalik_transaction_test_paris.py index b11681ea432..0dd5b77613a 100644 --- a/tests/ported_static/stEIP158Specific/test_vitalik_transaction_test_paris.py +++ b/tests/ported_static/stEIP158Specific/test_vitalik_transaction_test_paris.py @@ -14,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -155,7 +156,7 @@ def test_vitalik_transaction_test_paris( post = { coinbase: Account(storage={}, code=b"", nonce=1), sender: Account(storage={}, code=b"", nonce=336), - Address(0x1BC78AE0E5EC5CB439F1D5355D6F90D38343E109): Account( + compute_create_address(address=sender, nonce=335): Account( storage={}, code=b"", nonce=3 ), Address(0x51F9D7F98E997BDD6BEBDE4C2DD27BE8C99303AA): Account( diff --git a/tests/ported_static/stEIP2930/test_address_opcodes.py b/tests/ported_static/stEIP2930/test_address_opcodes.py index 83b7d261aa3..2461399d90c 100644 --- a/tests/ported_static/stEIP2930/test_address_opcodes.py +++ b/tests/ported_static/stEIP2930/test_address_opcodes.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -338,9 +337,7 @@ def test_address_opcodes( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0000000000000000000000000000000000001000) contract_1 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -548,7 +545,6 @@ def test_address_opcodes( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { @@ -702,7 +698,7 @@ def test_address_opcodes( ], 4: [ AccessList( - address=Address(0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), + address=sender, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -716,7 +712,7 @@ def test_address_opcodes( 5: [], 6: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -730,7 +726,7 @@ def test_address_opcodes( 7: [], 8: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -791,7 +787,7 @@ def test_address_opcodes( ], 16: [ AccessList( - address=Address(0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), + address=sender, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -805,7 +801,7 @@ def test_address_opcodes( 17: [], 18: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -819,7 +815,7 @@ def test_address_opcodes( 19: [], 20: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -880,7 +876,7 @@ def test_address_opcodes( ], 28: [ AccessList( - address=Address(0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), + address=sender, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -894,7 +890,7 @@ def test_address_opcodes( 29: [], 30: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -908,7 +904,7 @@ def test_address_opcodes( 31: [], 32: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -969,7 +965,7 @@ def test_address_opcodes( ], 40: [ AccessList( - address=Address(0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), + address=sender, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -983,7 +979,7 @@ def test_address_opcodes( 41: [], 42: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -997,7 +993,7 @@ def test_address_opcodes( 43: [], 44: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stEIP2930/test_coinbase_t01.py b/tests/ported_static/stEIP2930/test_coinbase_t01.py index 53fa5e76425..62e00904240 100644 --- a/tests/ported_static/stEIP2930/test_coinbase_t01.py +++ b/tests/ported_static/stEIP2930/test_coinbase_t01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -66,9 +65,7 @@ def test_coinbase_t01( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -79,6 +76,7 @@ def test_coinbase_t01( gas_limit=71794957647893862, ) + pre[coinbase] = Account(balance=0, nonce=1) # Source: yul # berlin # { @@ -94,7 +92,7 @@ def test_coinbase_t01( + Op.POP( Op.CALL( gas=Op.GAS, - address=0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3, + address=coinbase, value=0xF4240, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -112,10 +110,7 @@ def test_coinbase_t01( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=1, - address=Address(0x30873F83C35401E315E6E5994C012F1EE8119585), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[coinbase] = Account(balance=0, nonce=1) expect_entries_: list[dict] = [ { @@ -141,7 +136,7 @@ def test_coinbase_t01( tx_access_lists: dict[int, list] = { 1: [ AccessList( - address=Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3), + address=coinbase, storage_keys=[], ), ], diff --git a/tests/ported_static/stEIP2930/test_coinbase_t2.py b/tests/ported_static/stEIP2930/test_coinbase_t2.py index 2e575455aa8..22716cfa65b 100644 --- a/tests/ported_static/stEIP2930/test_coinbase_t2.py +++ b/tests/ported_static/stEIP2930/test_coinbase_t2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -60,9 +59,7 @@ def test_coinbase_t2( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -73,6 +70,7 @@ def test_coinbase_t2( gas_limit=71794957647893862, ) + pre[coinbase] = Account(balance=0, nonce=1) # Source: yul # berlin # { @@ -88,7 +86,7 @@ def test_coinbase_t2( + Op.POP( Op.CALL( gas=Op.GAS, - address=0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3, + address=coinbase, value=0xF4240, args_offset=Op.DUP1, args_size=Op.DUP1, @@ -106,10 +104,7 @@ def test_coinbase_t2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=1, - address=Address(0x30873F83C35401E315E6E5994C012F1EE8119585), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[coinbase] = Account(balance=0, nonce=1) expect_entries_: list[dict] = [ { @@ -134,7 +129,7 @@ def test_coinbase_t2( tx_access_lists: dict[int, list] = { 0: [ AccessList( - address=Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3), + address=coinbase, storage_keys=[], ), ], diff --git a/tests/ported_static/stEIP2930/test_storage_costs.py b/tests/ported_static/stEIP2930/test_storage_costs.py index ddb2359c4f7..2c5f0f91686 100644 --- a/tests/ported_static/stEIP2930/test_storage_costs.py +++ b/tests/ported_static/stEIP2930/test_storage_costs.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -275,9 +274,7 @@ def test_storage_costs( contract_8 = Address(0x0000000000000000000000000000000000001020) contract_9 = Address(0x0000000000000000000000000000000000001021) contract_10 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -650,7 +647,6 @@ def test_storage_costs( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { @@ -798,7 +794,7 @@ def test_storage_costs( tx_access_lists: dict[int, list] = { 0: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -808,7 +804,7 @@ def test_storage_costs( ], 1: [ AccessList( - address=Address(0x0000000000000000000000000000000000001001), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -818,7 +814,7 @@ def test_storage_costs( ], 2: [ AccessList( - address=Address(0x0000000000000000000000000000000000001002), + address=contract_2, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -828,7 +824,7 @@ def test_storage_costs( ], 3: [ AccessList( - address=Address(0x0000000000000000000000000000000000001003), + address=contract_3, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -838,7 +834,7 @@ def test_storage_costs( ], 4: [ AccessList( - address=Address(0x0000000000000000000000000000000000001004), + address=contract_4, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -848,7 +844,7 @@ def test_storage_costs( ], 5: [ AccessList( - address=Address(0x0000000000000000000000000000000000001005), + address=contract_5, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -858,7 +854,7 @@ def test_storage_costs( ], 6: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -868,7 +864,7 @@ def test_storage_costs( ], 7: [ AccessList( - address=Address(0x0000000000000000000000000000000000001001), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -878,7 +874,7 @@ def test_storage_costs( ], 8: [ AccessList( - address=Address(0x0000000000000000000000000000000000001002), + address=contract_2, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -888,7 +884,7 @@ def test_storage_costs( ], 9: [ AccessList( - address=Address(0x0000000000000000000000000000000000001003), + address=contract_3, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -898,7 +894,7 @@ def test_storage_costs( ], 10: [ AccessList( - address=Address(0x0000000000000000000000000000000000001004), + address=contract_4, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -908,7 +904,7 @@ def test_storage_costs( ], 11: [ AccessList( - address=Address(0x0000000000000000000000000000000000001005), + address=contract_5, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -978,7 +974,7 @@ def test_storage_costs( ], 24: [ AccessList( - address=Address(0x0000000000000000000000000000000000001010), + address=contract_6, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -988,7 +984,7 @@ def test_storage_costs( ], 25: [ AccessList( - address=Address(0x0000000000000000000000000000000000001010), + address=contract_6, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -998,7 +994,7 @@ def test_storage_costs( ], 26: [ AccessList( - address=Address(0x0000000000000000000000000000000000001011), + address=contract_7, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1008,7 +1004,7 @@ def test_storage_costs( ], 27: [ AccessList( - address=Address(0x0000000000000000000000000000000000001011), + address=contract_7, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -1018,7 +1014,7 @@ def test_storage_costs( ], 28: [ AccessList( - address=Address(0x0000000000000000000000000000000000001020), + address=contract_8, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1028,7 +1024,7 @@ def test_storage_costs( ], 29: [ AccessList( - address=Address(0x0000000000000000000000000000000000001020), + address=contract_8, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -1038,7 +1034,7 @@ def test_storage_costs( ], 30: [ AccessList( - address=Address(0x0000000000000000000000000000000000001021), + address=contract_9, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1048,7 +1044,7 @@ def test_storage_costs( ], 31: [ AccessList( - address=Address(0x0000000000000000000000000000000000001021), + address=contract_9, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000010" # noqa: E501 @@ -1058,7 +1054,7 @@ def test_storage_costs( ], 32: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_10, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1096,7 +1092,7 @@ def test_storage_costs( ], 34: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_10, storage_keys=[ Hash( "0x000000000000000000000000000000000000000000000000000000000000f000" # noqa: E501 @@ -1132,7 +1128,7 @@ def test_storage_costs( ], ), AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x00000000000000000000000000000000000000000000000000000000000fffff" # noqa: E501 diff --git a/tests/ported_static/stEIP2930/test_transaction_costs.py b/tests/ported_static/stEIP2930/test_transaction_costs.py index 65245a0c468..3695bf9a542 100644 --- a/tests/ported_static/stEIP2930/test_transaction_costs.py +++ b/tests/ported_static/stEIP2930/test_transaction_costs.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -120,9 +119,7 @@ def test_transaction_costs( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7778A3B885EA30938725C6E00831943A454477163CDBC252DEBEB9612B4FA5F7 - ) + sender = pre.fund_eoa(amount=0x5FA9C18) env = Environment( fee_recipient=coinbase, @@ -139,9 +136,7 @@ def test_transaction_costs( code=Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x1BF4BD50BBDA0F09948556F87D37F86F2E19E84A), # noqa: E501 ) - pre[sender] = Account(balance=0x5FA9C18) expect_entries: list[dict] = [ # EIP-7981 changes access list costs in Amsterdam+. Balance is a diff --git a/tests/ported_static/stEIP2930/test_varied_context.py b/tests/ported_static/stEIP2930/test_varied_context.py index 0f2cf613ad7..20f3bd03c20 100644 --- a/tests/ported_static/stEIP2930/test_varied_context.py +++ b/tests/ported_static/stEIP2930/test_varied_context.py @@ -305,66 +305,7 @@ def test_varied_context( gas_limit=71794957647893862, ) - # Source: lll - # { - # ; DELEGATE_VALID DELEGATE_INVALID - # - # (delegatecall (gas) 0xC057 0 0 0 0) - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=Op.GAS, - address=0xC057, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001000), # noqa: E501 - ) - # Source: lll - # { - # ; CALL_VALID CALL_INVALID - # (call (gas) 0xC057 0 0 0 0 0) - # } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=Op.GAS, - address=0xC057, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001001), # noqa: E501 - ) - # Source: lll - # { - # ; CALLCODE_VALID CALLCODE_INVALID - # (callcode (gas) 0xC057 0 0 0 0 0) - # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=Op.GAS, - address=0xC057, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001002), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ; 0xC057: DELEGATE_VALID DELEGATE_INVALID @@ -416,31 +357,6 @@ def test_varied_context( ) # Source: lll # { - # ; STATICCALL_VALID STATICCALL_INVALID - # - # ; Need to store the result here, because static call is, well, static - # (staticcall (gas) 0xEAD0C057 0 0 0 0x20) - # [[0]] @0 - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xEAD0C057, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x20, - ) - ) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001003), # noqa: E501 - ) - # Source: lll - # { # ; STATICCALL_VALID STATICCALL_INVALID # # @@ -517,34 +433,6 @@ def test_varied_context( # Source: lll # { # ; CALL_WRITE_SUICIDE_VALID CALL_WRITE_SUICIDE_INVALID - # [0] (gas) - # (call (gas) 0xDEAD0111 0 0 0 0 0) - # [[0]] (- @0 (gas) 0x7fe8) - # } - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.POP( - Op.CALL( - gas=Op.GAS, - address=0xDEAD0111, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - ) - + Op.SSTORE( - key=0x0, value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x0), Op.GAS), 0x7FE8) - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001011), # noqa: E501 - ) - # Source: lll - # { - # ; CALL_WRITE_SUICIDE_VALID CALL_WRITE_SUICIDE_INVALID # [[0]] 0xDEAD # # (selfdestruct 0) @@ -560,34 +448,6 @@ def test_varied_context( # Source: lll # { # ; CALL_READ_SUICIDE_VALID CALL_READ_SUICIDE_INVALID - # [0] (gas) - # (call (gas) 0xDEAD0112 0 0 0 0 0) - # [[0]] (- @0 (gas) 0x7fe8) - # } - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.POP( - Op.CALL( - gas=Op.GAS, - address=0xDEAD0112, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - ) - + Op.SSTORE( - key=0x0, value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x0), Op.GAS), 0x7FE8) - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001012), # noqa: E501 - ) - # Source: lll - # { - # ; CALL_READ_SUICIDE_VALID CALL_READ_SUICIDE_INVALID # @@0 # # (selfdestruct 0) @@ -603,35 +463,6 @@ def test_varied_context( ) # Source: lll # { ; STATIC_WRITE_VALID STATIC_WRITE_INVALID - # - # [0x00] 0x0BAD - # - # ; If the call is successful @0 becomes 0x600D - # (staticcall (gas) 0xF113 0 0 0 0x20) - # - # [[0]] @0x00 - # } - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0xBAD) - + Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xF113, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x20, - ) - ) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.STOP, - storage={0: 24743}, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001013), # noqa: E501 - ) - # Source: lll - # { ; STATIC_WRITE_VALID STATIC_WRITE_INVALID # [[0]] 0xDEAD60A7 # # ; If we get here, GOOD @@ -649,25 +480,6 @@ def test_varied_context( ) # Source: lll # { ; WRITE_INVALID_OOG WRITE_VALID_NO_OOG - # (call 0x0B65 0xF114 0 0 0 0 0x20) - # } - contract_13 = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=0xB65, - address=0xF114, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x20, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001014), # noqa: E501 - ) - # Source: lll - # { ; WRITE_INVALID_OOG WRITE_VALID_NO_OOG # # [[0]] 0x600D # } @@ -680,25 +492,6 @@ def test_varied_context( ) # Source: lll # { ; READ_INVALID_OOG READ_VALID_NO_OOG - # (call 0x1800 0xF115 0 0 0 0 0x20) - # } - contract_15 = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=0x1800, - address=0xF115, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x20, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001015), # noqa: E501 - ) - # Source: lll - # { ; READ_INVALID_OOG READ_VALID_NO_OOG # [0] @@0x60A7 # [[0]] 0x600D # } @@ -712,117 +505,26 @@ def test_varied_context( address=Address(0x000000000000000000000000000000000000F115), # noqa: E501 ) # Source: lll - # { ; RECURSE_VALID RECURSE_INVALID - # (def 'NOP 0) - # - # ; Read storage cell zero, so the first time we read it to won't - # ; be added to the cost - # @@0 - # - # ; Write to [[0xBEEF]], and see how much gas that cost. It should - # ; cost more when it is not declared storage - # [0] (gas) - # [[0xBEEF]] 0x02 - # [0] (- @0 (gas) 17) - # - # ; Read [[0x60A7]], and see how much gas that cost. It should - # ; cost more when it is not declared storage - # [0x20] (gas) - # [0xA0] @@0x60A7 - # [0x20] (- @0x20 (gas) 35) + # { + # ; CREATE_VALID CREATE_INVALID # - # ; Write to a different cell each time - # [0x40] (gas) - # [[(+ 0xF000 @@0)]] 0xBEEF - # [0x40] (- @0x40 (gas) 0x78) + # ; Variables are 0x20 bytes (= 256 bits) apart, except for + # ; code buffers that get 0x100 (256 bytes) + # (def 'constructorCode 0x000) + # (def 'contractCode 0x100) + # (def 'contractLength 0x200) + # (def 'constructorLength 0x220) + # (def 'addr 0x240) # - # ; Read from a different cell each time - # [0x60] (gas) - # @@(+ 0xF010 @@0) - # [0x60] (- @0x60 (gas) 0x7a) + # (def 'bufLength 0x100) # - # - # ... (13 more lines) - contract_17 = pre.deploy_contract( # noqa: F841 - code=Op.POP(Op.SLOAD(key=0x0)) - + Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.SSTORE(key=0xBEEF, value=0x2) - + Op.MSTORE( - offset=0x0, - value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x0), Op.GAS), 0x11), - ) - + Op.MSTORE(offset=0x20, value=Op.GAS) - + Op.MSTORE(offset=0xA0, value=Op.SLOAD(key=0x60A7)) - + Op.MSTORE( - offset=0x20, - value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x20), Op.GAS), 0x23), - ) - + Op.MSTORE(offset=0x40, value=Op.GAS) - + Op.SSTORE(key=Op.ADD(0xF000, Op.SLOAD(key=0x0)), value=0xBEEF) - + Op.MSTORE( - offset=0x40, - value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x40), Op.GAS), 0x78), - ) - + Op.MSTORE(offset=0x60, value=Op.GAS) - + Op.POP(Op.SLOAD(key=Op.ADD(0xF010, Op.SLOAD(key=0x0)))) - + Op.MSTORE( - offset=0x60, - value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x60), Op.GAS), 0x7A), - ) - + Op.SSTORE( - key=Op.ADD(0x100, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x0) - ) - + Op.SSTORE( - key=Op.ADD(0x200, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x20) - ) - + Op.SSTORE( - key=Op.ADD(0x300, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x40) - ) - + Op.SSTORE( - key=Op.ADD(0x400, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x60) - ) - + Op.JUMPI(pc=0x9B, condition=Op.GT(Op.SLOAD(key=0x0), 0x0)) - + Op.PUSH1[0x0] - + Op.JUMP(pc=0xB4) - + Op.JUMPDEST - + Op.SSTORE(key=0x0, value=Op.SUB(Op.SLOAD(key=0x0), 0x1)) - + Op.CALL( - gas=Op.GAS, - address=0x1016, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.JUMPDEST - + Op.STOP, - storage={0: 15, 24743: 57005}, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x0000000000000000000000000000000000001016), # noqa: E501 - ) - # Source: lll - # { - # ; CREATE_VALID CREATE_INVALID - # - # ; Variables are 0x20 bytes (= 256 bits) apart, except for - # ; code buffers that get 0x100 (256 bytes) - # (def 'constructorCode 0x000) - # (def 'contractCode 0x100) - # (def 'contractLength 0x200) - # (def 'constructorLength 0x220) - # (def 'addr 0x240) - # - # (def 'bufLength 0x100) - # - # ; Create the contract code - # [contractLength] - # (lll - # { - # [[0]] 0xFF - # } contractCode - # ) ; contract lll + # ; Create the contract code + # [contractLength] + # (lll + # { + # [[0]] 0xFF + # } contractCode + # ) ; contract lll # # ; Create the constructor code, which runs with the contract address # ; of the newly created contract. If we declare that address in the @@ -1238,6 +940,240 @@ def test_varied_context( # Source: lll # { # ; CALL_TWICE_VALID CALL_TWICE_INVALID + # [0] (gas) + # [[0x00]] 0x60A7 + # [0] (- @0 (gas)) + # + # ; If @@1 is empty, write to it. Otherwise, write to @@2 + # (if (= @@1 0) {[[1]] @0} {[[2]] @0}) + # + # } + contract_25 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GAS) + + Op.SSTORE(key=0x0, value=0x60A7) + + Op.MSTORE(offset=0x0, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + + Op.JUMPI(pc=0x24, condition=Op.EQ(Op.SLOAD(key=0x1), 0x0)) + + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x0)) + + Op.JUMP(pc=0x2B) + + Op.JUMPDEST + + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) + + Op.JUMPDEST + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x000000000000000000000000000000000000F126), # noqa: E501 + ) + # Source: lll + # { + # ; DELEGATE_VALID DELEGATE_INVALID + # + # (delegatecall (gas) 0xC057 0 0 0 0) + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=Op.GAS, + address=0xC057, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001000), # noqa: E501 + ) + # Source: lll + # { + # ; CALLCODE_VALID CALLCODE_INVALID + # (callcode (gas) 0xC057 0 0 0 0 0) + # } + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=Op.GAS, + address=0xC057, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001002), # noqa: E501 + ) + # Source: lll + # { + # ; CALL_VALID CALL_INVALID + # (call (gas) 0xC057 0 0 0 0 0) + # } + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=Op.GAS, + address=0xC057, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001001), # noqa: E501 + ) + # Source: lll + # { + # ; STATICCALL_VALID STATICCALL_INVALID + # + # ; Need to store the result here, because static call is, well, static + # (staticcall (gas) 0xEAD0C057 0 0 0 0x20) + # [[0]] @0 + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=0xEAD0C057, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x20, + ) + ) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001003), # noqa: E501 + ) + # Source: lll + # { + # ; CALL_WRITE_SUICIDE_VALID CALL_WRITE_SUICIDE_INVALID + # [0] (gas) + # (call (gas) 0xDEAD0111 0 0 0 0 0) + # [[0]] (- @0 (gas) 0x7fe8) + # } + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GAS) + + Op.POP( + Op.CALL( + gas=Op.GAS, + address=0xDEAD0111, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + ) + + Op.SSTORE( + key=0x0, value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x0), Op.GAS), 0x7FE8) + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001011), # noqa: E501 + ) + # Source: lll + # { + # ; CALL_READ_SUICIDE_VALID CALL_READ_SUICIDE_INVALID + # [0] (gas) + # (call (gas) 0xDEAD0112 0 0 0 0 0) + # [[0]] (- @0 (gas) 0x7fe8) + # } + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GAS) + + Op.POP( + Op.CALL( + gas=Op.GAS, + address=0xDEAD0112, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + ) + + Op.SSTORE( + key=0x0, value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x0), Op.GAS), 0x7FE8) + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001012), # noqa: E501 + ) + # Source: lll + # { ; STATIC_WRITE_VALID STATIC_WRITE_INVALID + # + # [0x00] 0x0BAD + # + # ; If the call is successful @0 becomes 0x600D + # (staticcall (gas) 0xF113 0 0 0 0x20) + # + # [[0]] @0x00 + # } + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0xBAD) + + Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=0xF113, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x20, + ) + ) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.STOP, + storage={0: 24743}, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001013), # noqa: E501 + ) + # Source: lll + # { ; WRITE_INVALID_OOG WRITE_VALID_NO_OOG + # (call 0x0B65 0xF114 0 0 0 0 0x20) + # } + contract_13 = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=0xB65, + address=0xF114, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x20, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001014), # noqa: E501 + ) + # Source: lll + # { ; READ_INVALID_OOG READ_VALID_NO_OOG + # (call 0x1800 0xF115 0 0 0 0 0x20) + # } + contract_15 = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=0x1800, + address=0xF115, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x20, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001015), # noqa: E501 + ) + # Source: lll + # { + # ; CALL_TWICE_VALID CALL_TWICE_INVALID # (call (gas) 0xF126 0 0 0 0 0) # (call (gas) 0xF126 0 0 0 0 0) # } @@ -1269,32 +1205,6 @@ def test_varied_context( ) # Source: lll # { - # ; CALL_TWICE_VALID CALL_TWICE_INVALID - # [0] (gas) - # [[0x00]] 0x60A7 - # [0] (- @0 (gas)) - # - # ; If @@1 is empty, write to it. Otherwise, write to @@2 - # (if (= @@1 0) {[[1]] @0} {[[2]] @0}) - # - # } - contract_25 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.SSTORE(key=0x0, value=0x60A7) - + Op.MSTORE(offset=0x0, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) - + Op.JUMPI(pc=0x24, condition=Op.EQ(Op.SLOAD(key=0x1), 0x0)) - + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x0)) - + Op.JUMP(pc=0x2B) - + Op.JUMPDEST - + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) - + Op.JUMPDEST - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x000000000000000000000000000000000000F126), # noqa: E501 - ) - # Source: lll - # { # ; ccc...ccc revert and suicide contract # (call (gas) (+ 0x1000 $4) 0 0 0 0 0x40) # @@ -1320,7 +1230,97 @@ def test_varied_context( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { ; RECURSE_VALID RECURSE_INVALID + # (def 'NOP 0) + # + # ; Read storage cell zero, so the first time we read it to won't + # ; be added to the cost + # @@0 + # + # ; Write to [[0xBEEF]], and see how much gas that cost. It should + # ; cost more when it is not declared storage + # [0] (gas) + # [[0xBEEF]] 0x02 + # [0] (- @0 (gas) 17) + # + # ; Read [[0x60A7]], and see how much gas that cost. It should + # ; cost more when it is not declared storage + # [0x20] (gas) + # [0xA0] @@0x60A7 + # [0x20] (- @0x20 (gas) 35) + # + # ; Write to a different cell each time + # [0x40] (gas) + # [[(+ 0xF000 @@0)]] 0xBEEF + # [0x40] (- @0x40 (gas) 0x78) + # + # ; Read from a different cell each time + # [0x60] (gas) + # @@(+ 0xF010 @@0) + # [0x60] (- @0x60 (gas) 0x7a) + # + # + # ... (13 more lines) + contract_17 = pre.deploy_contract( # noqa: F841 + code=Op.POP(Op.SLOAD(key=0x0)) + + Op.MSTORE(offset=0x0, value=Op.GAS) + + Op.SSTORE(key=0xBEEF, value=0x2) + + Op.MSTORE( + offset=0x0, + value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x0), Op.GAS), 0x11), + ) + + Op.MSTORE(offset=0x20, value=Op.GAS) + + Op.MSTORE(offset=0xA0, value=Op.SLOAD(key=0x60A7)) + + Op.MSTORE( + offset=0x20, + value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x20), Op.GAS), 0x23), + ) + + Op.MSTORE(offset=0x40, value=Op.GAS) + + Op.SSTORE(key=Op.ADD(0xF000, Op.SLOAD(key=0x0)), value=0xBEEF) + + Op.MSTORE( + offset=0x40, + value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x40), Op.GAS), 0x78), + ) + + Op.MSTORE(offset=0x60, value=Op.GAS) + + Op.POP(Op.SLOAD(key=Op.ADD(0xF010, Op.SLOAD(key=0x0)))) + + Op.MSTORE( + offset=0x60, + value=Op.SUB(Op.SUB(Op.MLOAD(offset=0x60), Op.GAS), 0x7A), + ) + + Op.SSTORE( + key=Op.ADD(0x100, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x0) + ) + + Op.SSTORE( + key=Op.ADD(0x200, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x20) + ) + + Op.SSTORE( + key=Op.ADD(0x300, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x40) + ) + + Op.SSTORE( + key=Op.ADD(0x400, Op.SLOAD(key=0x0)), value=Op.MLOAD(offset=0x60) + ) + + Op.JUMPI(pc=0x9B, condition=Op.GT(Op.SLOAD(key=0x0), 0x0)) + + Op.PUSH1[0x0] + + Op.JUMP(pc=0xB4) + + Op.JUMPDEST + + Op.SSTORE(key=0x0, value=Op.SUB(Op.SLOAD(key=0x0), 0x1)) + + Op.CALL( + gas=Op.GAS, + address=0x1016, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.JUMPDEST + + Op.STOP, + storage={0: 15, 24743: 57005}, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x0000000000000000000000000000000000001016), # noqa: E501 + ) expect_entries_: list[dict] = [ { @@ -1781,7 +1781,7 @@ def test_varied_context( tx_access_lists: dict[int, list] = { 0: [ AccessList( - address=Address(0x0000000000000000000000000000000000001000), + address=contract_0, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1794,7 +1794,7 @@ def test_varied_context( ], 1: [ AccessList( - address=Address(0x000000000000000000000000000000000000C057), + address=contract_3, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1807,7 +1807,7 @@ def test_varied_context( ], 2: [ AccessList( - address=Address(0x0000000000000000000000000000000000001002), + address=contract_2, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1820,7 +1820,7 @@ def test_varied_context( ], 3: [ AccessList( - address=Address(0x000000000000000000000000000000000000C057), + address=contract_3, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1833,7 +1833,7 @@ def test_varied_context( ], 4: [ AccessList( - address=Address(0x0000000000000000000000000000000000001001), + address=contract_1, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1846,7 +1846,7 @@ def test_varied_context( ], 5: [ AccessList( - address=Address(0x000000000000000000000000000000000000C057), + address=contract_3, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1859,7 +1859,7 @@ def test_varied_context( ], 6: [ AccessList( - address=Address(0x0000000000000000000000000000000000001003), + address=contract_4, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1872,7 +1872,7 @@ def test_varied_context( ], 7: [ AccessList( - address=Address(0x00000000000000000000000000000000EAD0C057), + address=contract_5, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1885,7 +1885,7 @@ def test_varied_context( ], 8: [ AccessList( - address=Address(0x0000000000000000000000000000000000001010), + address=contract_6, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1898,7 +1898,7 @@ def test_varied_context( ], 9: [ AccessList( - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), + address=contract_26, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1911,7 +1911,7 @@ def test_varied_context( ], 10: [ AccessList( - address=Address(0x00000000000000000000000000000000DEAD0111), + address=contract_8, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1921,7 +1921,7 @@ def test_varied_context( ], 11: [ AccessList( - address=Address(0x0000000000000000000000000000000000001011), + address=contract_7, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1931,7 +1931,7 @@ def test_varied_context( ], 12: [ AccessList( - address=Address(0x00000000000000000000000000000000DEAD0112), + address=contract_10, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1941,7 +1941,7 @@ def test_varied_context( ], 13: [ AccessList( - address=Address(0x0000000000000000000000000000000000001012), + address=contract_9, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1961,7 +1961,7 @@ def test_varied_context( ], 15: [ AccessList( - address=Address(0x000000000000000000000000000000000000F113), + address=contract_12, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1971,7 +1971,7 @@ def test_varied_context( ], 16: [ AccessList( - address=Address(0x000000000000000000000000000000000000F114), + address=contract_14, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1981,7 +1981,7 @@ def test_varied_context( ], 17: [ AccessList( - address=Address(0x0000000000000000000000000000000000001014), + address=contract_13, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -1991,7 +1991,7 @@ def test_varied_context( ], 18: [ AccessList( - address=Address(0x000000000000000000000000000000000000F115), + address=contract_16, storage_keys=[ Hash( "0x00000000000000000000000000000000000000000000000000000000000060a7" # noqa: E501 @@ -2001,7 +2001,7 @@ def test_varied_context( ], 19: [ AccessList( - address=Address(0x0000000000000000000000000000000000001015), + address=contract_15, storage_keys=[ Hash( "0x00000000000000000000000000000000000000000000000000000000000060a7" # noqa: E501 @@ -2011,7 +2011,7 @@ def test_varied_context( ], 20: [ AccessList( - address=Address(0x0000000000000000000000000000000000001016), + address=contract_17, storage_keys=[ Hash( "0x00000000000000000000000000000000000000000000000000000000000060a7" # noqa: E501 @@ -2253,7 +2253,7 @@ def test_varied_context( ], 34: [ AccessList( - address=Address(0x000000000000000000000000000000000000F126), + address=contract_25, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 @@ -2263,7 +2263,7 @@ def test_varied_context( ], 35: [ AccessList( - address=Address(0x000000000000000000000000000000000000F126), + address=contract_25, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000020" # noqa: E501 diff --git a/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas.py b/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas.py index a07f84bf4e4..6bdb6c49c1a 100644 --- a/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas.py +++ b/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas.py @@ -107,6 +107,8 @@ def test_coinbase_warm_account_call_gas( gas_limit=100000000, ) + pre[coinbase] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # berlin # { @@ -257,8 +259,6 @@ def test_coinbase_warm_account_call_gas( nonce=1, address=Address(0xA4A48FC5F3526A9BC06A0136AB0BA1D9574D15BA), # noqa: E501 ) - pre[coinbase] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas_fail.py b/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas_fail.py index 39144c983eb..cc58c53e55a 100644 --- a/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas_fail.py +++ b/tests/ported_static/stEIP3651_warmcoinbase/test_coinbase_warm_account_call_gas_fail.py @@ -83,83 +83,8 @@ def test_coinbase_warm_account_call_gas_fail( gas_limit=100000000, ) - # Source: yul - # berlin - # { - # // Depending on the called contract here, the subcall will perform - # // another call/delegatecall/staticcall/callcode that will only succeed # noqa: E501 - # // if coinbase is considered warm by default (post-Shanghai). - # let calladdr := calldataload(4) - # - # let callgas := 100 - # switch calladdr - # case { - # // Extra: COINBASE + 6xPUSH1 + DUP6 + 2xPOP - # callgas := add(callgas, 27) - # } - # case { - # // Extra: COINBASE + 6xPUSH1 + DUP6 + 2xPOP - # callgas := add(callgas, 27) - # } - # case { - # // Extra: COINBASE + 5xPUSH1 + DUP6 + 2xPOP - # callgas := add(callgas, 24) - # } - # case { - # // Extra: COINBASE + 5xPUSH1 + DUP6 + 2xPOP - # callgas := add(callgas, 24) - # } - # // Call and save result - # sstore(0, call(callgas, calladdr, 0, 0, 0, 0, 0)) - # - # } - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH1[0x0] - + Op.DUP1 * 4 - + Op.CALLDATALOAD(offset=0x4) - + Op.PUSH1[0x64] - + Op.DUP2 - + Op.JUMPI( - pc=0x88, - condition=Op.EQ( - 0x8DDF5D9A5251C41EFD2949F53DB0A464116C7C6E, Op.DUP1 - ), - ) - + Op.JUMPI( - pc=0x88, - condition=Op.EQ( - 0x498516B6B2F25CB6A8E011A7C37A617B77E7D500, Op.DUP1 - ), - ) - + Op.JUMPI( - pc=0x80, - condition=Op.EQ( - 0x8873820BB96DAA39DB93AE64A9D6397E4C6A48D7, Op.DUP1 - ), - ) - + Op.PUSH20[0x303B6790D019874A107418EB549E4E7766A64728] - + Op.JUMPI(pc=0x79, condition=Op.EQ) - + Op.JUMPDEST - + Op.SSTORE(key=0x0, value=Op.CALL) - + Op.STOP - + Op.JUMPDEST - + Op.PUSH1[0x18] - + Op.ADD - + Op.JUMP(pc=0x73) - + Op.JUMPDEST - + Op.POP - + Op.PUSH1[0x18] - + Op.ADD - + Op.JUMP(pc=0x73) - + Op.JUMPDEST - + Op.POP - + Op.PUSH1[0x1B] - + Op.ADD - + Op.JUMP(pc=0x73), - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x0A92FC97BB4C47B3D5E9E96FBB1C3FC2F07DBA81), # noqa: E501 - ) + pre[coinbase] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # berlin # { @@ -242,8 +167,83 @@ def test_coinbase_warm_account_call_gas_fail( nonce=1, address=Address(0x303B6790D019874A107418EB549E4E7766A64728), # noqa: E501 ) - pre[coinbase] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) + # Source: yul + # berlin + # { + # // Depending on the called contract here, the subcall will perform + # // another call/delegatecall/staticcall/callcode that will only succeed # noqa: E501 + # // if coinbase is considered warm by default (post-Shanghai). + # let calladdr := calldataload(4) + # + # let callgas := 100 + # switch calladdr + # case { + # // Extra: COINBASE + 6xPUSH1 + DUP6 + 2xPOP + # callgas := add(callgas, 27) + # } + # case { + # // Extra: COINBASE + 6xPUSH1 + DUP6 + 2xPOP + # callgas := add(callgas, 27) + # } + # case { + # // Extra: COINBASE + 5xPUSH1 + DUP6 + 2xPOP + # callgas := add(callgas, 24) + # } + # case { + # // Extra: COINBASE + 5xPUSH1 + DUP6 + 2xPOP + # callgas := add(callgas, 24) + # } + # // Call and save result + # sstore(0, call(callgas, calladdr, 0, 0, 0, 0, 0)) + # + # } + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH1[0x0] + + Op.DUP1 * 4 + + Op.CALLDATALOAD(offset=0x4) + + Op.PUSH1[0x64] + + Op.DUP2 + + Op.JUMPI( + pc=0x88, + condition=Op.EQ( + 0x8DDF5D9A5251C41EFD2949F53DB0A464116C7C6E, Op.DUP1 + ), + ) + + Op.JUMPI( + pc=0x88, + condition=Op.EQ( + 0x498516B6B2F25CB6A8E011A7C37A617B77E7D500, Op.DUP1 + ), + ) + + Op.JUMPI( + pc=0x80, + condition=Op.EQ( + 0x8873820BB96DAA39DB93AE64A9D6397E4C6A48D7, Op.DUP1 + ), + ) + + Op.PUSH20[0x303B6790D019874A107418EB549E4E7766A64728] + + Op.JUMPI(pc=0x79, condition=Op.EQ) + + Op.JUMPDEST + + Op.SSTORE(key=0x0, value=Op.CALL) + + Op.STOP + + Op.JUMPDEST + + Op.PUSH1[0x18] + + Op.ADD + + Op.JUMP(pc=0x73) + + Op.JUMPDEST + + Op.POP + + Op.PUSH1[0x18] + + Op.ADD + + Op.JUMP(pc=0x73) + + Op.JUMPDEST + + Op.POP + + Op.PUSH1[0x1B] + + Op.ADD + + Op.JUMP(pc=0x73), + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x0A92FC97BB4C47B3D5E9E96FBB1C3FC2F07DBA81), # noqa: E501 + ) tx_data = [ Bytes("693c6139") + Hash(addr, left_padding=True), diff --git a/tests/ported_static/stEIP3855_push0/test_push0.py b/tests/ported_static/stEIP3855_push0/test_push0.py index 06c9b25f0ae..82a91325613 100644 --- a/tests/ported_static/stEIP3855_push0/test_push0.py +++ b/tests/ported_static/stEIP3855_push0/test_push0.py @@ -159,6 +159,25 @@ def test_push0( nonce=0, address=Address(0x0000000000000000000000000000000000000400), # noqa: E501 ) + # Source: raw + # 0x60ff5f5360016000f3 + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=Op.PUSH0, value=0xFF) + + Op.RETURN(offset=0x0, size=0x1), + nonce=0, + address=Address(0x0000000000000000000000000000000000000600), # noqa: E501 + ) + # Source: raw + # 0x6004565f5b60015f5500 + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.JUMP(pc=0x4) + + Op.PUSH0 + + Op.JUMPDEST + + Op.SSTORE(key=Op.PUSH0, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x0000000000000000000000000000000000000700), # noqa: E501 + ) # Source: yul # berlin # { @@ -187,25 +206,6 @@ def test_push0( nonce=0, address=Address(0x0000000000000000000000000000000000000500), # noqa: E501 ) - # Source: raw - # 0x60ff5f5360016000f3 - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=Op.PUSH0, value=0xFF) - + Op.RETURN(offset=0x0, size=0x1), - nonce=0, - address=Address(0x0000000000000000000000000000000000000600), # noqa: E501 - ) - # Source: raw - # 0x6004565f5b60015f5500 - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.JUMP(pc=0x4) - + Op.PUSH0 - + Op.JUMPDEST - + Op.SSTORE(key=Op.PUSH0, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x0000000000000000000000000000000000000700), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP3855_push0/test_push0_gas.py b/tests/ported_static/stEIP3855_push0/test_push0_gas.py index 8ca1722597c..e9a870b6600 100644 --- a/tests/ported_static/stEIP3855_push0/test_push0_gas.py +++ b/tests/ported_static/stEIP3855_push0/test_push0_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_push0_gas( ) -> None: """Test_push0_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDC4EFA209AECDD4C2D5201A419EA27506151B4EC687F14A613229E310932491B - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_push0_gas( gas_limit=89128960, ) - pre[sender] = Account(balance=0x989680) # Source: raw # 0x5a6000555f5a6000540360015500 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +51,6 @@ def test_push0_gas( + Op.SSTORE(key=0x1, value=Op.SUB(Op.SLOAD(key=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0xC1ACA9DA71F5EA8DB94B3428D8CBE5D544472FF7), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py index d1c6d456398..02b8f8dd203 100644 --- a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py +++ b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py @@ -79,33 +79,6 @@ def test_create2_init_code_size_limit( # Source: yul # berlin # { - # mstore(0, calldataload(0)) - # let call_result := call(10000000, 0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b, 0, 0, calldatasize(), 0, 0) # noqa: E501 - # sstore(0, call_result) - # sstore(1, 1) - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x989680, - address=0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.CALLDATASIZE, - ret_offset=Op.DUP1, - ret_size=0x0, - ), - ) - + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - # Source: yul - # berlin - # { # // :yul { codecopy(0x00, 0x00, 0x0a) return(0x00, 0x0a) } # mstore(0, 0x600a80600080396000f300000000000000000000000000000000000000000000) # noqa: E501 # // get initcode size from calldata @@ -138,6 +111,33 @@ def test_create2_init_code_size_limit( nonce=0, address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) + # Source: yul + # berlin + # { + # mstore(0, calldataload(0)) + # let call_result := call(10000000, 0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b, 0, 0, calldatasize(), 0, 0) # noqa: E501 + # sstore(0, call_result) + # sstore(1, 1) + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x989680, + address=contract_1, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.CALLDATASIZE, + ret_offset=Op.DUP1, + ret_size=0x0, + ), + ) + + Op.SSTORE(key=Op.DUP1, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 + ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py index 0c8d60ecd47..dc9500e9b45 100644 --- a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py +++ b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py @@ -80,33 +80,6 @@ def test_create_init_code_size_limit( # Source: yul # berlin # { - # mstore(0, calldataload(0)) - # let call_result := call(10000000, 0xc0de, 0, 0, calldatasize(), 0, 0) - # sstore(0, call_result) - # sstore(1, 1) - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x989680, - address=0xC0DE, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.CALLDATASIZE, - ret_offset=Op.DUP1, - ret_size=0x0, - ), - ) - + Op.SSTORE(key=Op.DUP1, value=0x1) - + Op.STOP, - nonce=1, - address=Address(0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB), # noqa: E501 - ) - # Source: yul - # berlin - # { # // :yul { codecopy(0x00, 0x00, 0x0a) return(0x00, 0x0a) } # mstore(0, 0x600a80600080396000f300000000000000000000000000000000000000000000) # noqa: E501 # // get initcode size from calldata @@ -138,6 +111,33 @@ def test_create_init_code_size_limit( nonce=1, address=Address(0x000000000000000000000000000000000000C0DE), # noqa: E501 ) + # Source: yul + # berlin + # { + # mstore(0, calldataload(0)) + # let call_result := call(10000000, 0xc0de, 0, 0, calldatasize(), 0, 0) + # sstore(0, call_result) + # sstore(1, 1) + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x989680, + address=contract_1, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.CALLDATASIZE, + ret_offset=Op.DUP1, + ret_size=0x0, + ), + ) + + Op.SSTORE(key=Op.DUP1, value=0x1) + + Op.STOP, + nonce=1, + address=Address(0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB), # noqa: E501 + ) expect_entries_: list[dict] = [ { @@ -148,7 +148,7 @@ def test_create_init_code_size_limit( contract_0: Account(storage={0: 1, 1: 1}), contract_1: Account( storage={ - 0: 0x5F6BAAEB5B7C97725F84D1569C4ABC85135F4716, + 0: compute_create_address(address=contract_1, nonce=1), 10: 46323, }, ), diff --git a/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py b/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py index 5b2b0b9a600..ff9a504ca81 100644 --- a/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py +++ b/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -52,7 +51,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_creation_tx_init_code_size_limit( state_test: StateTestFiller, pre: Alloc, @@ -63,9 +61,7 @@ def test_creation_tx_init_code_size_limit( ) -> None: """Test_creation_tx_init_code_size_limit.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBEBC200) env = Environment( fee_recipient=coinbase, @@ -76,8 +72,6 @@ def test_creation_tx_init_code_size_limit( gas_limit=20000000, ) - pre[sender] = Account(balance=0xBEBC200) - expect_entries_: list[dict] = [ { "indexes": {"data": [0], "gas": -1, "value": -1}, diff --git a/tests/ported_static/stEIP4844_blobtransactions/test_create_blobhash_tx.py b/tests/ported_static/stEIP4844_blobtransactions/test_create_blobhash_tx.py index e236d084a7b..d11cc789e44 100644 --- a/tests/ported_static/stEIP4844_blobtransactions/test_create_blobhash_tx.py +++ b/tests/ported_static/stEIP4844_blobtransactions/test_create_blobhash_tx.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -38,9 +37,7 @@ def test_create_blobhash_tx( ) -> None: """BLOB002.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,9 +58,7 @@ def test_create_blobhash_tx( code=Op.SSTORE(key=0x0, value=Op.BLOBHASH(index=0x0)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC4DCF66BD4CDEFE4CE7FBA4951BE4E9F580122C5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -81,7 +76,7 @@ def test_create_blobhash_tx( ], access_list=[ AccessList( - address=Address(0xC4DCF66BD4CDEFE4CE7FBA4951BE4E9F580122C5), + address=addr, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stEIP4844_blobtransactions/test_empty_blobhash_list.py b/tests/ported_static/stEIP4844_blobtransactions/test_empty_blobhash_list.py index bb690f34429..e97a3c33320 100644 --- a/tests/ported_static/stEIP4844_blobtransactions/test_empty_blobhash_list.py +++ b/tests/ported_static/stEIP4844_blobtransactions/test_empty_blobhash_list.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -39,9 +38,7 @@ def test_empty_blobhash_list( ) -> None: """BLOB000.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,9 +59,7 @@ def test_empty_blobhash_list( code=Op.SSTORE(key=0x0, value=Op.BLOBHASH(index=0x0)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC4DCF66BD4CDEFE4CE7FBA4951BE4E9F580122C5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -78,7 +73,7 @@ def test_empty_blobhash_list( blob_versioned_hashes=[], access_list=[ AccessList( - address=Address(0xC4DCF66BD4CDEFE4CE7FBA4951BE4E9F580122C5), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobh_bounds.py b/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobh_bounds.py index 133cbc915d7..dadd17acd8c 100644 --- a/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobh_bounds.py +++ b/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobh_bounds.py @@ -51,6 +51,7 @@ def test_opcode_blobh_bounds( gas_limit=68719476736, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ; Can also add lll style comments here @@ -82,7 +83,6 @@ def test_opcode_blobh_bounds( nonce=0, address=Address(0xC8126E943C569C35DF09619F8E1E67460ACFF695), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -103,7 +103,7 @@ def test_opcode_blobh_bounds( ], access_list=[ AccessList( - address=Address(0xC8126E943C569C35DF09619F8E1E67460ACFF695), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobhash_out_of_range.py b/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobhash_out_of_range.py index 826156302d4..39c73145913 100644 --- a/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobhash_out_of_range.py +++ b/tests/ported_static/stEIP4844_blobtransactions/test_opcode_blobhash_out_of_range.py @@ -51,6 +51,7 @@ def test_opcode_blobhash_out_of_range( gas_limit=68719476736, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ; Can also add lll style comments here @@ -66,7 +67,6 @@ def test_opcode_blobhash_out_of_range( nonce=0, address=Address(0x0C4D6F62D3C85069CEA2411284BD520AC87FB7EB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -87,7 +87,7 @@ def test_opcode_blobhash_out_of_range( ], access_list=[ AccessList( - address=Address(0x0C4D6F62D3C85069CEA2411284BD520AC87FB7EB), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stEIP4844_blobtransactions/test_wrong_blobhash_version.py b/tests/ported_static/stEIP4844_blobtransactions/test_wrong_blobhash_version.py index eedcbcc90d4..33ae23f221a 100644 --- a/tests/ported_static/stEIP4844_blobtransactions/test_wrong_blobhash_version.py +++ b/tests/ported_static/stEIP4844_blobtransactions/test_wrong_blobhash_version.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -39,9 +38,7 @@ def test_wrong_blobhash_version( ) -> None: """BLOB001.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,9 +59,7 @@ def test_wrong_blobhash_version( code=Op.SSTORE(key=0x0, value=Op.BLOBHASH(index=0x0)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC4DCF66BD4CDEFE4CE7FBA4951BE4E9F580122C5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -85,7 +80,7 @@ def test_wrong_blobhash_version( ], access_list=[ AccessList( - address=Address(0xC4DCF66BD4CDEFE4CE7FBA4951BE4E9F580122C5), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stEIP5656_MCOPY/test_mcopy.py b/tests/ported_static/stEIP5656_MCOPY/test_mcopy.py index 7104590b343..acae638389f 100644 --- a/tests/ported_static/stEIP5656_MCOPY/test_mcopy.py +++ b/tests/ported_static/stEIP5656_MCOPY/test_mcopy.py @@ -179,6 +179,7 @@ def test_mcopy( gas_limit=1000000, ) + pre[sender] = Account(balance=0x3B9ACA00) # Source: yul # cancun { # // Fill memory at [0-96] (3x32) with the pattern of unique bytes. @@ -219,7 +220,6 @@ def test_mcopy( nonce=1, address=Address(0xBFD584EC9DC8FBADCEA812C707E1765B4DF8FA6C), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP5656_MCOPY/test_mcopy_copy_cost.py b/tests/ported_static/stEIP5656_MCOPY/test_mcopy_copy_cost.py index cb768f45489..92430e5fbce 100644 --- a/tests/ported_static/stEIP5656_MCOPY/test_mcopy_copy_cost.py +++ b/tests/ported_static/stEIP5656_MCOPY/test_mcopy_copy_cost.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -419,7 +418,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_mcopy_copy_cost( state_test: StateTestFiller, pre: Alloc, @@ -430,9 +428,7 @@ def test_mcopy_copy_cost( ) -> None: """Test cases for the cost of memory copy in the MCOPY instruction.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -473,9 +469,7 @@ def test_mcopy_copy_cost( + Op.JUMP(pc=0x3) + Op.JUMPDEST, nonce=1, - address=Address(0x9F1A7B52BB2D016223285964CB0876DFF8C9C9F8), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stEIP5656_MCOPY/test_mcopy_memory_expansion_cost.py b/tests/ported_static/stEIP5656_MCOPY/test_mcopy_memory_expansion_cost.py index 0cd3770cd3a..c6b1b90837d 100644 --- a/tests/ported_static/stEIP5656_MCOPY/test_mcopy_memory_expansion_cost.py +++ b/tests/ported_static/stEIP5656_MCOPY/test_mcopy_memory_expansion_cost.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -169,7 +168,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_mcopy_memory_expansion_cost( state_test: StateTestFiller, pre: Alloc, @@ -180,9 +178,7 @@ def test_mcopy_memory_expansion_cost( ) -> None: """Test cases for the memory expansion cost in the MCOPY instruction.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -215,9 +211,7 @@ def test_mcopy_memory_expansion_cost( + Op.STOP, storage={0: 0xFA11ED}, nonce=1, - address=Address(0x147DAECF943FA4FB48D1B7287571525B0BAEFEB9), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stExample/test_add11.py b/tests/ported_static/stExample/test_add11.py index 1e3e8e2f503..5d6769f2d7a 100644 --- a/tests/ported_static/stExample/test_add11.py +++ b/tests/ported_static/stExample/test_add11.py @@ -47,6 +47,7 @@ def test_add11( gas_limit=71794957647893862, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: hex # 0x coinbase = pre.deploy_contract( # noqa: F841 @@ -62,7 +63,6 @@ def test_add11( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stExample/test_add11_yml.py b/tests/ported_static/stExample/test_add11_yml.py index 6953ecc03c5..bf7cbfdba7d 100644 --- a/tests/ported_static/stExample/test_add11_yml.py +++ b/tests/ported_static/stExample/test_add11_yml.py @@ -48,6 +48,7 @@ def test_add11_yml( ) pre[coinbase] = Account(balance=0, nonce=1) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ; Can also add lll style comments here @@ -59,7 +60,6 @@ def test_add11_yml( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stExample/test_basefee_example.py b/tests/ported_static/stExample/test_basefee_example.py index ef1a0573572..047f10ea622 100644 --- a/tests/ported_static/stExample/test_basefee_example.py +++ b/tests/ported_static/stExample/test_basefee_example.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -35,9 +34,7 @@ def test_basefee_example( ) -> None: """A test shows basefee transaction example.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -57,9 +54,7 @@ def test_basefee_example( code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAD21EB96C7A254C810474F7B1E1E66CA449A3426), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -71,7 +66,7 @@ def test_basefee_example( max_priority_fee_per_gas=2, access_list=[ AccessList( - address=Address(0xAD21EB96C7A254C810474F7B1E1E66CA449A3426), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stExample/test_eip1559.py b/tests/ported_static/stExample/test_eip1559.py index 91874978154..7b107d1f969 100644 --- a/tests/ported_static/stExample/test_eip1559.py +++ b/tests/ported_static/stExample/test_eip1559.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, AccessList, Account, Address, @@ -35,9 +34,7 @@ def test_eip1559( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDE0C95357363DA5C1C5A73BD7C2781CA5C9FECC1014103B5E1D1E990AE8208EC - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_eip1559( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=1, - address=Address(0x38DC047054D46298A5BB7ED3A0BAD84BF69090D4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) tx = Transaction( sender=sender, @@ -73,7 +68,7 @@ def test_eip1559( nonce=1, access_list=[ AccessList( - address=Address(0x38DC047054D46298A5BB7ED3A0BAD84BF69090D4), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stExample/test_indexes_omit_example.py b/tests/ported_static/stExample/test_indexes_omit_example.py index 1ef6e8e0012..71c4aec9f8d 100644 --- a/tests/ported_static/stExample/test_indexes_omit_example.py +++ b/tests/ported_static/stExample/test_indexes_omit_example.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_indexes_omit_example( ) -> None: """Expect section set -indexes field by default equal to -1.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,9 +53,7 @@ def test_indexes_omit_example( code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAD21EB96C7A254C810474F7B1E1E66CA449A3426), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stExample/test_invalid_tr.py b/tests/ported_static/stExample/test_invalid_tr.py index cb30f1f7e18..c55aa6717b0 100644 --- a/tests/ported_static/stExample/test_invalid_tr.py +++ b/tests/ported_static/stExample/test_invalid_tr.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_invalid_tr( ) -> None: """A state test with invalid transaction example filler.""" coinbase = Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_invalid_tr( code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4567F627ABB612A28ED0A355E3FA9BF1E455677A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stExample/test_labels_example.py b/tests/ported_static/stExample/test_labels_example.py index 229f449668a..9a8208197ee 100644 --- a/tests/ported_static/stExample/test_labels_example.py +++ b/tests/ported_static/stExample/test_labels_example.py @@ -83,6 +83,7 @@ def test_labels_example( gas_limit=71794957647893862, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # [[0]] (CALLDATALOAD 0) @@ -93,7 +94,6 @@ def test_labels_example( nonce=0, address=Address(0xA054BC58F204030CBC0EC558A5B88AC9BD5ADED2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stExample/test_merge_test.py b/tests/ported_static/stExample/test_merge_test.py index e494566df93..a15fb3a5cc0 100644 --- a/tests/ported_static/stExample/test_merge_test.py +++ b/tests/ported_static/stExample/test_merge_test.py @@ -48,6 +48,7 @@ def test_merge_test( gas_limit=16777216, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) # Source: lll # { # (sstore 0 (gasprice)) @@ -63,7 +64,6 @@ def test_merge_test( nonce=1, address=Address(0x49A0FE79E28D1D65E16CDF53ACAFEAE7BACCAC0E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) tx = Transaction( sender=sender, @@ -75,7 +75,7 @@ def test_merge_test( nonce=1, access_list=[ AccessList( - address=Address(0x49A0FE79E28D1D65E16CDF53ACAFEAE7BACCAC0E), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stExample/test_ranges_example.py b/tests/ported_static/stExample/test_ranges_example.py index bd18ff3b028..2a1990456f4 100644 --- a/tests/ported_static/stExample/test_ranges_example.py +++ b/tests/ported_static/stExample/test_ranges_example.py @@ -203,6 +203,7 @@ def test_ranges_example( gas_limit=71794957647893862, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # [[0]] (CALLDATALOAD 0) @@ -213,7 +214,6 @@ def test_ranges_example( nonce=0, address=Address(0xA054BC58F204030CBC0EC558A5B88AC9BD5ADED2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stExample/test_yul_example.py b/tests/ported_static/stExample/test_yul_example.py index b942b283782..710c01076b7 100644 --- a/tests/ported_static/stExample/test_yul_example.py +++ b/tests/ported_static/stExample/test_yul_example.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_yul_example( ) -> None: """An example test for using simple yul contracts in the test.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -60,9 +57,7 @@ def test_yul_example( code=Op.SSTORE(key=0x0, value=0x3) + Op.RETURN(offset=0x0, size=0x20), balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xF30C160326A04ECB32E7651C0A8F373468BEA269), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract.py b/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract.py index 90ca11896e0..dce50fa3f12 100644 --- a/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract.py +++ b/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_contract_creation_oo_gdont_leave_empty_contract( """Test_contract_creation_oo_gdont_leave_empty_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000001) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_contract_creation_oo_gdont_leave_empty_contract( gas_limit=1000000, ) - pre[sender] = Account(balance=0xF4240) # Source: lll # { (SSTORE 1 0x10) (MSTORE 0 0x6001600155601080600c6000396000f3006000355415600957005b6020356000 ) (CREATE 0 0 32)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -62,7 +58,6 @@ def test_contract_creation_oo_gdont_leave_empty_contract( + Op.CREATE(value=0x0, offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py b/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py index 2c3ffd26dc8..82d92551fc3 100644 --- a/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py +++ b/tests/ported_static/stHomesteadSpecific/test_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py @@ -52,6 +52,13 @@ def test_contract_creation_oo_gdont_leave_empty_contract_via_transaction( pre[sender] = Account(balance=0x10C8E0) # Source: lll + # {(SSTORE 1 1)} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: lll # {(CALL 50000 0x1000000000000000000000000000000000000001 0 0 64 0 64)} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.CALL( @@ -68,13 +75,6 @@ def test_contract_creation_oo_gdont_leave_empty_contract_via_transaction( nonce=0, address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - # Source: lll - # {(SSTORE 1 1)} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract.py b/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract.py index 1311ab5ae55..1989648a8b1 100644 --- a/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract.py +++ b/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_create_contract_via_contract( """Test_create_contract_via_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000001) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,11 @@ def test_create_contract_via_contract( gas_limit=1000000, ) - pre[sender] = Account(balance=0xF4240) # Source: lll # { (CREATE 0 0 0)} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.CREATE(value=0x0, offset=0x0, size=0x0) + Op.STOP, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract_oog_init_code.py b/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract_oog_init_code.py index f29201b4c80..7b3e101416a 100644 --- a/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract_oog_init_code.py +++ b/tests/ported_static/stHomesteadSpecific/test_create_contract_via_contract_oog_init_code.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -36,9 +36,7 @@ def test_create_contract_via_contract_oog_init_code( """Test_create_contract_via_contract_oog_init_code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000001) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x10C8E0) env = Environment( fee_recipient=coinbase, @@ -49,7 +47,6 @@ def test_create_contract_via_contract_oog_init_code( gas_limit=1000000, ) - pre[sender] = Account(balance=0x10C8E0) # Source: lll # { (MSTORE 0 0x602060406000f0600c600055)(CREATE 0 20 12)} contract_0 = pre.deploy_contract( # noqa: F841 @@ -57,7 +54,6 @@ def test_create_contract_via_contract_oog_init_code( + Op.CREATE(value=0x0, offset=0x14, size=0xC) + Op.STOP, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) tx = Transaction( @@ -68,8 +64,9 @@ def test_create_contract_via_contract_oog_init_code( ) post = { - Address( - 0x4FF884BFFC83E888AE11B32B1D94BF9BC8D1732F + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=0, ): Account.NONEXISTENT, } diff --git a/tests/ported_static/stHomesteadSpecific/test_create_contract_via_transaction_cost53000.py b/tests/ported_static/stHomesteadSpecific/test_create_contract_via_transaction_cost53000.py index 2a3844b3d4f..aaa0ab8e85f 100644 --- a/tests/ported_static/stHomesteadSpecific/test_create_contract_via_transaction_cost53000.py +++ b/tests/ported_static/stHomesteadSpecific/test_create_contract_via_transaction_cost53000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -27,16 +26,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_contract_via_transaction_cost53000( state_test: StateTestFiller, pre: Alloc, ) -> None: """Trigger transaction creating gasPrice in the state.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,6 @@ def test_create_contract_via_transaction_cost53000( gas_limit=1000000, ) - pre[sender] = Account(balance=0xF4240) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_and_call_it_oog.py b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_and_call_it_oog.py index 52e65943d83..e5dde4f4373 100644 --- a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_and_call_it_oog.py +++ b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_and_call_it_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_call_contract_to_create_contract_and_call_it_oog( """Test_call_contract_to_create_contract_and_call_it_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -71,7 +68,6 @@ def test_call_contract_to_create_contract_and_call_it_oog( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, @@ -82,7 +78,9 @@ def test_call_contract_to_create_contract_and_call_it_oog( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), sender: Account(nonce=1), diff --git a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_no_cash.py b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_no_cash.py index 16dde5285eb..4298cd98ba6 100644 --- a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_no_cash.py +++ b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_no_cash.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_contract_to_create_contract_no_cash( ) -> None: """Test_call_contract_to_create_contract_no_cash.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -60,9 +57,7 @@ def test_call_contract_to_create_contract_no_cash( + Op.STOP, balance=10000, nonce=0, - address=Address(0x985ACA92559C5B1B9CD7897FEC0F7C7993AD0D60), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog.py b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog.py index e62d3575c99..32bd64fd55a 100644 --- a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog.py +++ b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_contract_to_create_contract_oog( ) -> None: """Test_call_contract_to_create_contract_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -66,7 +63,6 @@ def test_call_contract_to_create_contract_oog( nonce=0, address=Address(0x1BC6342E077E772B0F4CC48116BC171F9A35D09E), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog_bonus_gas.py b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog_bonus_gas.py index dd64b3173ee..11a0f3780e7 100644 --- a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog_bonus_gas.py +++ b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_oog_bonus_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_call_contract_to_create_contract_oog_bonus_gas( """Test_call_contract_to_create_contract_oog_bonus_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -71,7 +68,6 @@ def test_call_contract_to_create_contract_oog_bonus_gas( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) tx = Transaction( sender=sender, @@ -82,7 +78,9 @@ def test_call_contract_to_create_contract_oog_bonus_gas( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), sender: Account(nonce=1), diff --git a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_if_called.py b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_if_called.py index 0f968466a78..16fb7d6b4df 100644 --- a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_if_called.py +++ b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_if_called.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_call_contract_to_create_contract_which_would_create_contract_if_called( """Test_call_contract_to_create_contract_which_would_create_contract_i...""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -71,7 +68,6 @@ def test_call_contract_to_create_contract_which_would_create_contract_if_called( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) tx = Transaction( sender=sender, @@ -82,11 +78,14 @@ def test_call_contract_to_create_contract_which_would_create_contract_if_called( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), - Address( - 0x62C01474F089B07DAE603491675DC5B5748F7049 + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=0, ): Account.NONEXISTENT, sender: Account(nonce=1), compute_create_address(address=contract_0, nonce=0): Account( diff --git a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_in_init_code.py b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_in_init_code.py index 57f2c8b40b6..b1dabf644aa 100644 --- a/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_in_init_code.py +++ b/tests/ported_static/stInitCodeTest/test_call_contract_to_create_contract_which_would_create_contract_in_init_code.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_call_contract_to_create_contract_which_would_create_contract_in_init_co """Test_call_contract_to_create_contract_which_would_create_contract_i...""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -58,9 +55,7 @@ def test_call_contract_to_create_contract_which_would_create_contract_in_init_co + Op.STOP, balance=1, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) tx = Transaction( sender=sender, @@ -71,8 +66,9 @@ def test_call_contract_to_create_contract_which_would_create_contract_in_init_co post = { contract_0: Account(balance=1, nonce=1), - Address( - 0x62C01474F089B07DAE603491675DC5B5748F7049 + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=0, ): Account.NONEXISTENT, sender: Account(nonce=1), compute_create_address(address=contract_0, nonce=0): Account( diff --git a/tests/ported_static/stInitCodeTest/test_call_recursive_contract.py b/tests/ported_static/stInitCodeTest/test_call_recursive_contract.py index 3735404acc9..971bc2d4760 100644 --- a/tests/ported_static/stInitCodeTest/test_call_recursive_contract.py +++ b/tests/ported_static/stInitCodeTest/test_call_recursive_contract.py @@ -47,6 +47,7 @@ def test_call_recursive_contract( gas_limit=100000000, ) + pre[sender] = Account(balance=0x989680) # Source: lll # {[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)} contract_0 = pre.deploy_contract( # noqa: F841 @@ -57,7 +58,6 @@ def test_call_recursive_contract( nonce=40, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x989680) tx = Transaction( sender=sender, @@ -68,11 +68,7 @@ def test_call_recursive_contract( ) post = { - contract_0: Account( - storage={2: 0x95E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87}, - balance=1, - nonce=41, - ), + contract_0: Account(storage={2: contract_0}, balance=1, nonce=41), Address( 0x1A4C83E1A9834CDC7E4A905FF7F0CF44AED73180 ): Account.NONEXISTENT, diff --git a/tests/ported_static/stInitCodeTest/test_call_the_contract_to_create_empty_contract.py b/tests/ported_static/stInitCodeTest/test_call_the_contract_to_create_empty_contract.py index dfb3de3012d..08cb3cc54f5 100644 --- a/tests/ported_static/stInitCodeTest/test_call_the_contract_to_create_empty_contract.py +++ b/tests/ported_static/stInitCodeTest/test_call_the_contract_to_create_empty_contract.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_call_the_contract_to_create_empty_contract( """Test_call_the_contract_to_create_empty_contract.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_call_the_contract_to_create_empty_contract( contract_0 = pre.deploy_contract( # noqa: F841 code=Op.CREATE(value=0x0, offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x989680) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stInitCodeTest/test_out_of_gas_contract_creation.py b/tests/ported_static/stInitCodeTest/test_out_of_gas_contract_creation.py index 2911e3a4d69..9525495cff9 100644 --- a/tests/ported_static/stInitCodeTest/test_out_of_gas_contract_creation.py +++ b/tests/ported_static/stInitCodeTest/test_out_of_gas_contract_creation.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,7 +58,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_out_of_gas_contract_creation( state_test: StateTestFiller, pre: Alloc, @@ -70,8 +68,8 @@ def test_out_of_gas_contract_creation( ) -> None: """Test_out_of_gas_contract_creation.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -83,10 +81,6 @@ def test_out_of_gas_contract_creation( gas_limit=100000000000000, ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 - ) - expect_entries_: list[dict] = [ { "indexes": {"data": 0, "gas": 1, "value": -1}, diff --git a/tests/ported_static/stInitCodeTest/test_return_test.py b/tests/ported_static/stInitCodeTest/test_return_test.py index ec66c49dd59..63721b3fe3b 100644 --- a/tests/ported_static/stInitCodeTest/test_return_test.py +++ b/tests/ported_static/stInitCodeTest/test_return_test.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_return_test( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,22 @@ def test_return_test( gas_limit=10000000, ) + # Source: lll + # {(MSTORE 0 0x15) (RETURN 31 1)} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x15) + + Op.RETURN(offset=0x1F, size=0x1) + + Op.STOP, + balance=0x186A0, + nonce=0, + ) # Source: lll # {(CALL 2000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 30 1 31 1) [[0]](MLOAD 0) (RETURN 30 2)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x7D0, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x0, args_offset=0x1E, args_size=0x1, @@ -66,18 +72,6 @@ def test_return_test( + Op.RETURN(offset=0x1E, size=0x2) + Op.STOP, nonce=0, - address=Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - pre[sender] = Account(balance=0x989680) - # Source: lll - # {(MSTORE 0 0x15) (RETURN 31 1)} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x15) - + Op.RETURN(offset=0x1F, size=0x1) - + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stInitCodeTest/test_return_test2.py b/tests/ported_static/stInitCodeTest/test_return_test2.py index fc4b408d63a..44212cd0b15 100644 --- a/tests/ported_static/stInitCodeTest/test_return_test2.py +++ b/tests/ported_static/stInitCodeTest/test_return_test2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_return_test2( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,17 @@ def test_return_test2( gas_limit=1000000000, ) + # Source: lll + # {(MSTORE 0 (MUL 3 (CALLDATALOAD 0)))(RETURN 0 32)} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, value=Op.MUL(0x3, Op.CALLDATALOAD(offset=0x0)) + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=0x186A0, + nonce=0, + ) # Source: lll # {(MSTORE 0 0x15)(CALL 7000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 32 32 32) [[0]](MLOAD 0) [[1]](MLOAD 32) (RETURN 0 64)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -55,7 +63,7 @@ def test_return_test2( + Op.POP( Op.CALL( gas=0x1B58, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x20, @@ -68,20 +76,6 @@ def test_return_test2( + Op.RETURN(offset=0x0, size=0x40) + Op.STOP, nonce=0, - address=Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - pre[sender] = Account(balance=0x989680) - # Source: lll - # {(MSTORE 0 (MUL 3 (CALLDATALOAD 0)))(RETURN 0 32)} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, value=Op.MUL(0x3, Op.CALLDATALOAD(offset=0x0)) - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stInitCodeTest/test_stack_under_flow_contract_creation.py b/tests/ported_static/stInitCodeTest/test_stack_under_flow_contract_creation.py index 60af424269a..6648c3ae81d 100644 --- a/tests/ported_static/stInitCodeTest/test_stack_under_flow_contract_creation.py +++ b/tests/ported_static/stInitCodeTest/test_stack_under_flow_contract_creation.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_under_flow_contract_creation( ) -> None: """Test_stack_under_flow_contract_creation.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xAE9F7BCC00) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_stack_under_flow_contract_creation( ) pre[coinbase] = Account(balance=0, nonce=1) - pre[sender] = Account(balance=0xAE9F7BCC00) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stInitCodeTest/test_transaction_create_random_init_code.py b/tests/ported_static/stInitCodeTest/test_transaction_create_random_init_code.py index 860a00e375d..2924e4d01ee 100644 --- a/tests/ported_static/stInitCodeTest/test_transaction_create_random_init_code.py +++ b/tests/ported_static/stInitCodeTest/test_transaction_create_random_init_code.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_transaction_create_random_init_code( ) -> None: """Stack underflow in init code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_transaction_create_random_init_code( ) pre[coinbase] = Account(balance=0, nonce=1) - pre[sender] = Account(balance=0x2540BE400) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stInitCodeTest/test_transaction_create_stop_in_initcode.py b/tests/ported_static/stInitCodeTest/test_transaction_create_stop_in_initcode.py index e4e8f335ae2..15156479273 100644 --- a/tests/ported_static/stInitCodeTest/test_transaction_create_stop_in_initcode.py +++ b/tests/ported_static/stInitCodeTest/test_transaction_create_stop_in_initcode.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stInitCodeTest/TransactionCreateStopInInitcodeFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_transaction_create_stop_in_initcode( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_transaction_create_stop_in_initcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_transaction_create_stop_in_initcode( gas_limit=1000000, ) - pre[sender] = Account(balance=0xF4240) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stInitCodeTest/test_transaction_create_suicide_in_initcode.py b/tests/ported_static/stInitCodeTest/test_transaction_create_suicide_in_initcode.py index dd53ae55822..59214c2f5d8 100644 --- a/tests/ported_static/stInitCodeTest/test_transaction_create_suicide_in_initcode.py +++ b/tests/ported_static/stInitCodeTest/test_transaction_create_suicide_in_initcode.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_transaction_create_suicide_in_initcode( ) -> None: """Test_transaction_create_suicide_in_initcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -49,7 +46,6 @@ def test_transaction_create_suicide_in_initcode( ) pre[coinbase] = Account(balance=0, nonce=1) - pre[sender] = Account(balance=0x3B9ACA00) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_empty_mem.py b/tests/ported_static/stLogTests/test_log0_empty_mem.py index 9fb9491d611..8569ed72148 100644 --- a/tests/ported_static/stLogTests/test_log0_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log0_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log0_empty_mem( ) -> None: """Test_log0_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,13 @@ def test_log0_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG0(offset=0x0, size=0x0) + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +57,7 @@ def test_log0_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xC2A943E837808399D9C1B946C6188739D4D4475E, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,17 +68,7 @@ def test_log0_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (LOG0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG0(offset=0x0, size=0x0) + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC2A943E837808399D9C1B946C6188739D4D4475E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_log_mem_start_too_high.py b/tests/ported_static/stLogTests/test_log0_log_mem_start_too_high.py index 836c248590b..cddabdb16d0 100644 --- a/tests/ported_static/stLogTests/test_log0_log_mem_start_too_high.py +++ b/tests/ported_static/stLogTests/test_log0_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log0_log_mem_start_too_high( ) -> None: """Test_log0_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,21 @@ def test_log0_log_mem_start_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x1, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +65,7 @@ def test_log0_log_mem_start_too_high( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x4E46DD6CCD823BBE05D8CEAF0CA778101F8D8E6B, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,25 +76,7 @@ def test_log0_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x1, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x4E46DD6CCD823BBE05D8CEAF0CA778101F8D8E6B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_log_memsize_too_high.py b/tests/ported_static/stLogTests/test_log0_log_memsize_too_high.py index 3ae97a5aa54..1a45b8be972 100644 --- a/tests/ported_static/stLogTests/test_log0_log_memsize_too_high.py +++ b/tests/ported_static/stLogTests/test_log0_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log0_log_memsize_too_high( ) -> None: """Test_log0_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,21 @@ def test_log0_log_memsize_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0( + offset=0x1, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +65,7 @@ def test_log0_log_memsize_too_high( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x6573BB447199FC94C98AD0F26068653C70DA4044, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,25 +76,7 @@ def test_log0_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0( - offset=0x1, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x6573BB447199FC94C98AD0F26068653C70DA4044), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_log_memsize_zero.py b/tests/ported_static/stLogTests/test_log0_log_memsize_zero.py index 84c0ed789bf..c65a16813a5 100644 --- a/tests/ported_static/stLogTests/test_log0_log_memsize_zero.py +++ b/tests/ported_static/stLogTests/test_log0_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log0_log_memsize_zero( ) -> None: """Test_log0_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log0_log_memsize_zero( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0(offset=0x1, size=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log0_log_memsize_zero( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x2F70A6BCEE18358A07F12FF4630E0A802D8C293A, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log0_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0(offset=0x1, size=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x2F70A6BCEE18358A07F12FF4630E0A802D8C293A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_non_empty_mem.py b/tests/ported_static/stLogTests/test_log0_non_empty_mem.py index b4bbb933d39..ade885f9145 100644 --- a/tests/ported_static/stLogTests/test_log0_non_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log0_non_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log0_non_empty_mem( ) -> None: """Test_log0_non_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log0_non_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.LOG0(offset=0x0, size=0x20) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log0_non_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x86BB6680BEC59591FA113B66365D1BF87A4C6910, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log0_non_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.LOG0(offset=0x0, size=0x20) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x86BB6680BEC59591FA113B66365D1BF87A4C6910), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1.py b/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1.py index 84e1cb5e27e..30dbc528cf9 100644 --- a/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1.py +++ b/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log0_non_empty_mem_log_mem_size1( ) -> None: """Test_log0_non_empty_mem_log_mem_size1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log0_non_empty_mem_log_mem_size1( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0(offset=0x0, size=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log0_non_empty_mem_log_mem_size1( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x2DA68E115CD98F7D70E0B7CFABE76581FD2D667, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log0_non_empty_mem_log_mem_size1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0(offset=0x0, size=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x02DA68E115CD98F7D70E0B7CFABE76581FD2D667), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1_log_mem_start31.py b/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1_log_mem_start31.py index 0a97323c3b7..588dc0232c1 100644 --- a/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1_log_mem_start31.py +++ b/tests/ported_static/stLogTests/test_log0_non_empty_mem_log_mem_size1_log_mem_start31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_log0_non_empty_mem_log_mem_size1_log_mem_start31( ) -> None: """Test_log0_non_empty_mem_log_mem_size1_log_mem_start31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,18 @@ def test_log0_non_empty_mem_log_mem_size1_log_mem_start31( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 31 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0(offset=0x1F, size=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +64,7 @@ def test_log0_non_empty_mem_log_mem_size1_log_mem_start31( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x897FEE72AFB437BE678EE00C486726DA08ADB887, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -66,22 +75,7 @@ def test_log0_non_empty_mem_log_mem_size1_log_mem_start31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 31 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0(offset=0x1F, size=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x897FEE72AFB437BE678EE00C486726DA08ADB887), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_caller.py b/tests/ported_static/stLogTests/test_log1_caller.py index 28c4c58fe0d..1047550d155 100644 --- a/tests/ported_static/stLogTests/test_log1_caller.py +++ b/tests/ported_static/stLogTests/test_log1_caller.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_caller( ) -> None: """Test_log1_caller.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_log1_caller( gas_limit=1000000, ) + # Source: lll + # { (MSTORE8 0 0xff) (LOG1 0 32 (CALLER)) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xFF) + + Op.LOG1(offset=0x0, size=0x20, topic_1=Op.CALLER) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +59,7 @@ def test_log1_caller( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x488E90E8584A9B411FD53CFBB85544DE674BB24F, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,19 +70,7 @@ def test_log1_caller( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE8 0 0xff) (LOG1 0 32 (CALLER)) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xFF) - + Op.LOG1(offset=0x0, size=0x20, topic_1=Op.CALLER) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x488E90E8584A9B411FD53CFBB85544DE674BB24F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_empty_mem.py b/tests/ported_static/stLogTests/test_log1_empty_mem.py index 09d975a868f..c4a3eac61c4 100644 --- a/tests/ported_static/stLogTests/test_log1_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log1_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_empty_mem( ) -> None: """Test_log1_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,13 @@ def test_log1_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG1 0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG1(offset=0x0, size=0x0, topic_1=0x0) + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +57,7 @@ def test_log1_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xA86CBC14A38774A22B21CC067FF70DD74CC18E7F, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,17 +68,7 @@ def test_log1_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (LOG1 0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG1(offset=0x0, size=0x0, topic_1=0x0) + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xA86CBC14A38774A22B21CC067FF70DD74CC18E7F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_log_mem_start_too_high.py b/tests/ported_static/stLogTests/test_log1_log_mem_start_too_high.py index 480acfd7a72..cc40876e27e 100644 --- a/tests/ported_static/stLogTests/test_log1_log_mem_start_too_high.py +++ b/tests/ported_static/stLogTests/test_log1_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_log_mem_start_too_high( ) -> None: """Test_log1_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_log1_log_mem_start_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x1, + topic_1=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +66,7 @@ def test_log1_log_mem_start_too_high( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x2884BD4A36D3BF28249C493EEFC971380A638684, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,26 +77,7 @@ def test_log1_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x1, - topic_1=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x2884BD4A36D3BF28249C493EEFC971380A638684), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_log_memsize_too_high.py b/tests/ported_static/stLogTests/test_log1_log_memsize_too_high.py index 5a65ba8f2fa..22c8d411255 100644 --- a/tests/ported_static/stLogTests/test_log1_log_memsize_too_high.py +++ b/tests/ported_static/stLogTests/test_log1_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_log_memsize_too_high( ) -> None: """Test_log1_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_log1_log_memsize_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1( + offset=0x1, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + topic_1=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +66,7 @@ def test_log1_log_memsize_too_high( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x232172C10FC2B2CB5CCBC4349B5D177EB640EDC0, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,26 +77,7 @@ def test_log1_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1( - offset=0x1, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - topic_1=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x232172C10FC2B2CB5CCBC4349B5D177EB640EDC0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_log_memsize_zero.py b/tests/ported_static/stLogTests/test_log1_log_memsize_zero.py index f325df6918c..1c69477bcff 100644 --- a/tests/ported_static/stLogTests/test_log1_log_memsize_zero.py +++ b/tests/ported_static/stLogTests/test_log1_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_log_memsize_zero( ) -> None: """Test_log1_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log1_log_memsize_zero( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1(offset=0x1, size=0x0, topic_1=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log1_log_memsize_zero( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xC1F290174E61D4F7F40C5E11677591C31E0F63C7, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log1_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1(offset=0x1, size=0x0, topic_1=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC1F290174E61D4F7F40C5E11677591C31E0F63C7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_max_topic.py b/tests/ported_static/stLogTests/test_log1_max_topic.py index e029f52403d..c53b2d36149 100644 --- a/tests/ported_static/stLogTests/test_log1_max_topic.py +++ b/tests/ported_static/stLogTests/test_log1_max_topic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_max_topic( ) -> None: """Test_log1_max_topic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_log1_max_topic( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1( + offset=0x0, + size=0x20, + topic_1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +66,7 @@ def test_log1_max_topic( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xFAA3ACCE157A3DEDD9D750DD925F6067D252752E, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,26 +77,7 @@ def test_log1_max_topic( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1( - offset=0x0, - size=0x20, - topic_1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xFAA3ACCE157A3DEDD9D750DD925F6067D252752E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_non_empty_mem.py b/tests/ported_static/stLogTests/test_log1_non_empty_mem.py index 9a34219bd54..87119697c9c 100644 --- a/tests/ported_static/stLogTests/test_log1_non_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log1_non_empty_mem.py @@ -46,6 +46,20 @@ def test_log1_non_empty_mem( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.LOG1(offset=0x0, size=0x20, topic_1=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x6727EA02222B905F7708C2B4CB20898F34DFF1DD), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,20 +80,6 @@ def test_log1_non_empty_mem( nonce=0, address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 ) - # Source: lll - # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG1 0 32 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.LOG1(offset=0x0, size=0x20, topic_1=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x6727EA02222B905F7708C2B4CB20898F34DFF1DD), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1.py b/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1.py index 1ca4825fbb6..415c2cf396f 100644 --- a/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1.py +++ b/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_non_empty_mem_log_mem_size1( ) -> None: """Test_log1_non_empty_mem_log_mem_size1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log1_non_empty_mem_log_mem_size1( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 1 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1(offset=0x0, size=0x1, topic_1=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log1_non_empty_mem_log_mem_size1( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xAA71C9D8F626B8430A90ADE1BC39F086C51A2E13, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log1_non_empty_mem_log_mem_size1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 1 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1(offset=0x0, size=0x1, topic_1=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xAA71C9D8F626B8430A90ADE1BC39F086C51A2E13), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1_log_mem_start31.py b/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1_log_mem_start31.py index abf92753a06..d459d004d50 100644 --- a/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1_log_mem_start31.py +++ b/tests/ported_static/stLogTests/test_log1_non_empty_mem_log_mem_size1_log_mem_start31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_log1_non_empty_mem_log_mem_size1_log_mem_start31( ) -> None: """Test_log1_non_empty_mem_log_mem_size1_log_mem_start31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,18 @@ def test_log1_non_empty_mem_log_mem_size1_log_mem_start31( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 31 1 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1(offset=0x1F, size=0x1, topic_1=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +64,7 @@ def test_log1_non_empty_mem_log_mem_size1_log_mem_start31( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xB0C981060788593ED6C8A538DE7CBDC696D8D76C, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -66,22 +75,7 @@ def test_log1_non_empty_mem_log_mem_size1_log_mem_start31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 31 1 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1(offset=0x1F, size=0x1, topic_1=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xB0C981060788593ED6C8A538DE7CBDC696D8D76C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_caller.py b/tests/ported_static/stLogTests/test_log2_caller.py index a953a227c99..f719f43f081 100644 --- a/tests/ported_static/stLogTests/test_log2_caller.py +++ b/tests/ported_static/stLogTests/test_log2_caller.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_caller( ) -> None: """Test_log2_caller.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_log2_caller( gas_limit=1000000, ) + # Source: lll + # { (MSTORE8 0 0xff) (LOG2 0 32 0 (CALLER) ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xFF) + + Op.LOG2(offset=0x0, size=0x20, topic_1=0x0, topic_2=Op.CALLER) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +59,7 @@ def test_log2_caller( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x861CCCBD560D81A33AAC05190E986540663C6BBA, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,19 +70,7 @@ def test_log2_caller( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE8 0 0xff) (LOG2 0 32 0 (CALLER) ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xFF) - + Op.LOG2(offset=0x0, size=0x20, topic_1=0x0, topic_2=Op.CALLER) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x861CCCBD560D81A33AAC05190E986540663C6BBA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_empty_mem.py b/tests/ported_static/stLogTests/test_log2_empty_mem.py index b2f67b628b0..1413a36e56d 100644 --- a/tests/ported_static/stLogTests/test_log2_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log2_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_empty_mem( ) -> None: """Test_log2_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,13 @@ def test_log2_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG2 0 0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG2(offset=0x0, size=0x0, topic_1=0x0, topic_2=0x0) + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +57,7 @@ def test_log2_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xE0A9386910935A6148822DDB2A8361DF15EF268F, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,17 +68,7 @@ def test_log2_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (LOG2 0 0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG2(offset=0x0, size=0x0, topic_1=0x0, topic_2=0x0) + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xE0A9386910935A6148822DDB2A8361DF15EF268F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_log_mem_start_too_high.py b/tests/ported_static/stLogTests/test_log2_log_mem_start_too_high.py index 67855b705af..b3e9f3ea501 100644 --- a/tests/ported_static/stLogTests/test_log2_log_mem_start_too_high.py +++ b/tests/ported_static/stLogTests/test_log2_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_log_mem_start_too_high( ) -> None: """Test_log2_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,23 @@ def test_log2_log_mem_start_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG2( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x1, + topic_1=0x0, + topic_2=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +67,7 @@ def test_log2_log_mem_start_too_high( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x9C6A28DAEC9E2AF2FA5C362EEDC028ACD207E63B, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,27 +78,7 @@ def test_log2_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG2( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x1, - topic_1=0x0, - topic_2=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x9C6A28DAEC9E2AF2FA5C362EEDC028ACD207E63B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_log_memsize_too_high.py b/tests/ported_static/stLogTests/test_log2_log_memsize_too_high.py index 4a2ef34539d..2e03f0322f3 100644 --- a/tests/ported_static/stLogTests/test_log2_log_memsize_too_high.py +++ b/tests/ported_static/stLogTests/test_log2_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_log_memsize_too_high( ) -> None: """Test_log2_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,23 @@ def test_log2_log_memsize_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG2( + offset=0x1, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + topic_1=0x0, + topic_2=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +67,7 @@ def test_log2_log_memsize_too_high( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x3BAD71F49AD0CABDA27D388877A6CF157E9A3471, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,27 +78,7 @@ def test_log2_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG2( - offset=0x1, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - topic_1=0x0, - topic_2=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x3BAD71F49AD0CABDA27D388877A6CF157E9A3471), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_log_memsize_zero.py b/tests/ported_static/stLogTests/test_log2_log_memsize_zero.py index e59a0f8f026..e8dcfaf31d4 100644 --- a/tests/ported_static/stLogTests/test_log2_log_memsize_zero.py +++ b/tests/ported_static/stLogTests/test_log2_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_log_memsize_zero( ) -> None: """Test_log2_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log2_log_memsize_zero( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG2(offset=0x1, size=0x0, topic_1=0x0, topic_2=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log2_log_memsize_zero( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x5FE859FD0650FAB879E19018F55B76BE2E4C6391, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log2_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 1 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG2(offset=0x1, size=0x0, topic_1=0x0, topic_2=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x5FE859FD0650FAB879E19018F55B76BE2E4C6391), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_max_topic.py b/tests/ported_static/stLogTests/test_log2_max_topic.py index 53adc2e753f..b75f87756b4 100644 --- a/tests/ported_static/stLogTests/test_log2_max_topic.py +++ b/tests/ported_static/stLogTests/test_log2_max_topic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_max_topic( ) -> None: """Test_log2_max_topic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,23 @@ def test_log2_max_topic( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG2( + offset=0x0, + size=0x20, + topic_1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + topic_2=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +67,7 @@ def test_log2_max_topic( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x317504258A7AACAC178DA9B86E047C40C8A0A15B, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,27 +78,7 @@ def test_log2_max_topic( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG2( - offset=0x0, - size=0x20, - topic_1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - topic_2=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x317504258A7AACAC178DA9B86E047C40C8A0A15B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_non_empty_mem.py b/tests/ported_static/stLogTests/test_log2_non_empty_mem.py index b92d47ce8aa..2f1e7cd061b 100644 --- a/tests/ported_static/stLogTests/test_log2_non_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log2_non_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_non_empty_mem( ) -> None: """Test_log2_non_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log2_non_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG2 0 32 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.LOG2(offset=0x0, size=0x20, topic_1=0x0, topic_2=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log2_non_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xFD7C64173AC47172BBAED3CC40C7ECCEE3BBE114, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log2_non_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG2 0 32 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.LOG2(offset=0x0, size=0x20, topic_1=0x0, topic_2=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xFD7C64173AC47172BBAED3CC40C7ECCEE3BBE114), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1.py b/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1.py index 509c5c59fd9..21c251780cd 100644 --- a/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1.py +++ b/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_non_empty_mem_log_mem_size1( ) -> None: """Test_log2_non_empty_mem_log_mem_size1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log2_non_empty_mem_log_mem_size1( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 1 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG2(offset=0x0, size=0x1, topic_1=0x0, topic_2=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log2_non_empty_mem_log_mem_size1( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x9B06D70A66BB79592EDCFA38DA878F8610EBC1A8, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log2_non_empty_mem_log_mem_size1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 0 1 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG2(offset=0x0, size=0x1, topic_1=0x0, topic_2=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x9B06D70A66BB79592EDCFA38DA878F8610EBC1A8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1_log_mem_start31.py b/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1_log_mem_start31.py index cc8cc5478a2..d717f6e86ee 100644 --- a/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1_log_mem_start31.py +++ b/tests/ported_static/stLogTests/test_log2_non_empty_mem_log_mem_size1_log_mem_start31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_log2_non_empty_mem_log_mem_size1_log_mem_start31( ) -> None: """Test_log2_non_empty_mem_log_mem_size1_log_mem_start31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,18 @@ def test_log2_non_empty_mem_log_mem_size1_log_mem_start31( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 31 1 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG2(offset=0x1F, size=0x1, topic_1=0x0, topic_2=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +64,7 @@ def test_log2_non_empty_mem_log_mem_size1_log_mem_start31( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x54972C7257A6C4CDC7C3C144E8CCB3D8EB7AFE19, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -66,22 +75,7 @@ def test_log2_non_empty_mem_log_mem_size1_log_mem_start31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG2 31 1 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG2(offset=0x1F, size=0x1, topic_1=0x0, topic_2=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x54972C7257A6C4CDC7C3C144E8CCB3D8EB7AFE19), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_caller.py b/tests/ported_static/stLogTests/test_log3_caller.py index 60eb43c854c..8c7d121b848 100644 --- a/tests/ported_static/stLogTests/test_log3_caller.py +++ b/tests/ported_static/stLogTests/test_log3_caller.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_caller( ) -> None: """Test_log3_caller.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,17 @@ def test_log3_caller( gas_limit=1000000, ) + # Source: lll + # { (MSTORE8 0 0xff) (LOG3 0 32 0 0 (CALLER) ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xFF) + + Op.LOG3( + offset=0x0, size=0x20, topic_1=0x0, topic_2=0x0, topic_3=Op.CALLER + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +61,7 @@ def test_log3_caller( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x6C5DA6457F756A77C392C72FE884F7F650428AEF, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,21 +72,7 @@ def test_log3_caller( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE8 0 0xff) (LOG3 0 32 0 0 (CALLER) ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xFF) - + Op.LOG3( - offset=0x0, size=0x20, topic_1=0x0, topic_2=0x0, topic_3=Op.CALLER - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x6C5DA6457F756A77C392C72FE884F7F650428AEF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_empty_mem.py b/tests/ported_static/stLogTests/test_log3_empty_mem.py index 6553322b8ff..9f8d986475d 100644 --- a/tests/ported_static/stLogTests/test_log3_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log3_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_empty_mem( ) -> None: """Test_log3_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,16 @@ def test_log3_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG3 0 0 0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG3( + offset=0x0, size=0x0, topic_1=0x0, topic_2=0x0, topic_3=0x0 + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +60,7 @@ def test_log3_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x7314CC13D5F8CF58DB63F7C590A16C8CA956B249, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,20 +71,7 @@ def test_log3_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (LOG3 0 0 0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG3( - offset=0x0, size=0x0, topic_1=0x0, topic_2=0x0, topic_3=0x0 - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x7314CC13D5F8CF58DB63F7C590A16C8CA956B249), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_log_mem_start_too_high.py b/tests/ported_static/stLogTests/test_log3_log_mem_start_too_high.py index cd4ea28c61b..c0b58437f75 100644 --- a/tests/ported_static/stLogTests/test_log3_log_mem_start_too_high.py +++ b/tests/ported_static/stLogTests/test_log3_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_log_mem_start_too_high( ) -> None: """Test_log3_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log3_log_mem_start_too_high( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0x1034F91C93DA34534EFF3F8EFA3A807A417E2496, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -83,9 +60,26 @@ def test_log3_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1034F91C93DA34534EFF3F8EFA3A807A417E2496), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_log_memsize_too_high.py b/tests/ported_static/stLogTests/test_log3_log_memsize_too_high.py index cc560713c0e..b41f6cb0b79 100644 --- a/tests/ported_static/stLogTests/test_log3_log_memsize_too_high.py +++ b/tests/ported_static/stLogTests/test_log3_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_log_memsize_too_high( ) -> None: """Test_log3_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log3_log_memsize_too_high( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0x9C9665291C53FC348FC97C4ACA92EA13459C8367, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -83,9 +60,26 @@ def test_log3_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9C9665291C53FC348FC97C4ACA92EA13459C8367), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_log_memsize_zero.py b/tests/ported_static/stLogTests/test_log3_log_memsize_zero.py index ff468b4db18..55ea2718000 100644 --- a/tests/ported_static/stLogTests/test_log3_log_memsize_zero.py +++ b/tests/ported_static/stLogTests/test_log3_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_log_memsize_zero( ) -> None: """Test_log3_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log3_log_memsize_zero( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG3(offset=0x1, size=0x0, topic_1=0x0, topic_2=0x0, topic_3=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log3_log_memsize_zero( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x561CEB099A0D44D31649D7270095033C4003881F, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log3_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 1 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG3(offset=0x1, size=0x0, topic_1=0x0, topic_2=0x0, topic_3=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x561CEB099A0D44D31649D7270095033C4003881F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_max_topic.py b/tests/ported_static/stLogTests/test_log3_max_topic.py index 62ca782a779..4b3acca45b9 100644 --- a/tests/ported_static/stLogTests/test_log3_max_topic.py +++ b/tests/ported_static/stLogTests/test_log3_max_topic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_max_topic( ) -> None: """Test_log3_max_topic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log3_max_topic( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0x3105241BE1236A8BD2D48B82BDD4DA7C7FCEC2D7, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -83,9 +60,26 @@ def test_log3_max_topic( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3105241BE1236A8BD2D48B82BDD4DA7C7FCEC2D7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_non_empty_mem.py b/tests/ported_static/stLogTests/test_log3_non_empty_mem.py index 1572af57abc..3310575f7e3 100644 --- a/tests/ported_static/stLogTests/test_log3_non_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log3_non_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_non_empty_mem( ) -> None: """Test_log3_non_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log3_non_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG3 0 32 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.LOG3(offset=0x0, size=0x20, topic_1=0x0, topic_2=0x0, topic_3=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log3_non_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xF9578A6384BFFF36932A673BB3B0A9B92290E65C, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log3_non_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG3 0 32 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.LOG3(offset=0x0, size=0x20, topic_1=0x0, topic_2=0x0, topic_3=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xF9578A6384BFFF36932A673BB3B0A9B92290E65C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1.py b/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1.py index 69099c0d2f5..76f639fe3f2 100644 --- a/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1.py +++ b/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_non_empty_mem_log_mem_size1( ) -> None: """Test_log3_non_empty_mem_log_mem_size1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,18 @@ def test_log3_non_empty_mem_log_mem_size1( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 1 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG3(offset=0x0, size=0x1, topic_1=0x0, topic_2=0x0, topic_3=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +62,7 @@ def test_log3_non_empty_mem_log_mem_size1( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xE0885D29735CC94D2CF68DA45B9EC5079C7102CC, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,22 +73,7 @@ def test_log3_non_empty_mem_log_mem_size1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 0 1 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG3(offset=0x0, size=0x1, topic_1=0x0, topic_2=0x0, topic_3=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xE0885D29735CC94D2CF68DA45B9EC5079C7102CC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1_log_mem_start31.py b/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1_log_mem_start31.py index 80181418fc2..42ce8374089 100644 --- a/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1_log_mem_start31.py +++ b/tests/ported_static/stLogTests/test_log3_non_empty_mem_log_mem_size1_log_mem_start31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_log3_non_empty_mem_log_mem_size1_log_mem_start31( ) -> None: """Test_log3_non_empty_mem_log_mem_size1_log_mem_start31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,18 @@ def test_log3_non_empty_mem_log_mem_size1_log_mem_start31( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 31 1 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG3(offset=0x1F, size=0x1, topic_1=0x0, topic_2=0x0, topic_3=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +64,7 @@ def test_log3_non_empty_mem_log_mem_size1_log_mem_start31( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x14FA8BBD322A53AD4DAB974AEF0DF9EAA219F627, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -66,22 +75,7 @@ def test_log3_non_empty_mem_log_mem_size1_log_mem_start31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG3 31 1 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG3(offset=0x1F, size=0x1, topic_1=0x0, topic_2=0x0, topic_3=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x14FA8BBD322A53AD4DAB974AEF0DF9EAA219F627), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log3_pc.py b/tests/ported_static/stLogTests/test_log3_pc.py index c3c0a87b4b0..7b62c047c5d 100644 --- a/tests/ported_static/stLogTests/test_log3_pc.py +++ b/tests/ported_static/stLogTests/test_log3_pc.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_pc( ) -> None: """Test_log3_pc.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,17 @@ def test_log3_pc( gas_limit=1000000, ) + # Source: lll + # { (MSTORE8 0 0xff) (LOG3 0 32 (PC) (PC) (PC) ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xFF) + + Op.LOG3( + offset=0x0, size=0x20, topic_1=Op.PC, topic_2=Op.PC, topic_3=Op.PC + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +61,7 @@ def test_log3_pc( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x2D74CBAE3F7951CF201441F09537705A05E5290C, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,21 +72,7 @@ def test_log3_pc( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE8 0 0xff) (LOG3 0 32 (PC) (PC) (PC) ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xFF) - + Op.LOG3( - offset=0x0, size=0x20, topic_1=Op.PC, topic_2=Op.PC, topic_3=Op.PC - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x2D74CBAE3F7951CF201441F09537705A05E5290C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_caller.py b/tests/ported_static/stLogTests/test_log4_caller.py index 9480c345aa9..60556c375ad 100644 --- a/tests/ported_static/stLogTests/test_log4_caller.py +++ b/tests/ported_static/stLogTests/test_log4_caller.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_caller( ) -> None: """Test_log4_caller.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_log4_caller( gas_limit=1000000, ) + # Source: lll + # { (MSTORE8 0 0xff) (LOG4 0 32 0 0 0 (CALLER) ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xFF) + + Op.LOG4( + offset=0x0, + size=0x20, + topic_1=0x0, + topic_2=0x0, + topic_3=0x0, + topic_4=Op.CALLER, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +66,7 @@ def test_log4_caller( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x3AAC40E63F4E85B4F222671FB5691C8A4FDFB3DE, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,26 +77,7 @@ def test_log4_caller( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE8 0 0xff) (LOG4 0 32 0 0 0 (CALLER) ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xFF) - + Op.LOG4( - offset=0x0, - size=0x20, - topic_1=0x0, - topic_2=0x0, - topic_3=0x0, - topic_4=Op.CALLER, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x3AAC40E63F4E85B4F222671FB5691C8A4FDFB3DE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_empty_mem.py b/tests/ported_static/stLogTests/test_log4_empty_mem.py index a110aeb8fd2..d1b6ecc5d10 100644 --- a/tests/ported_static/stLogTests/test_log4_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log4_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_empty_mem( ) -> None: """Test_log4_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,21 @@ def test_log4_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG4 0 0 0 0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG4( + offset=0x0, + size=0x0, + topic_1=0x0, + topic_2=0x0, + topic_3=0x0, + topic_4=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +65,7 @@ def test_log4_empty_mem( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x4D1560AF4D4E7F6B2B987D349D4B631048EBB581, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,25 +76,7 @@ def test_log4_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (LOG4 0 0 0 0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG4( - offset=0x0, - size=0x0, - topic_1=0x0, - topic_2=0x0, - topic_3=0x0, - topic_4=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x4D1560AF4D4E7F6B2B987D349D4B631048EBB581), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_log_mem_start_too_high.py b/tests/ported_static/stLogTests/test_log4_log_mem_start_too_high.py index b98f38fcc27..ecb1fe7f51d 100644 --- a/tests/ported_static/stLogTests/test_log4_log_mem_start_too_high.py +++ b/tests/ported_static/stLogTests/test_log4_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_log_mem_start_too_high( ) -> None: """Test_log4_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log4_log_mem_start_too_high( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0x57D85807540DA11B345D5909E74550D27E116302, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -84,9 +61,26 @@ def test_log4_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x57D85807540DA11B345D5909E74550D27E116302), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_log_memsize_too_high.py b/tests/ported_static/stLogTests/test_log4_log_memsize_too_high.py index c2696841314..78ac2beb50b 100644 --- a/tests/ported_static/stLogTests/test_log4_log_memsize_too_high.py +++ b/tests/ported_static/stLogTests/test_log4_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_log_memsize_too_high( ) -> None: """Test_log4_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log4_log_memsize_too_high( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0x59E2F8FDF907D6E627FCAFD97606824CE1FE1E2A, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -84,9 +61,26 @@ def test_log4_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x59E2F8FDF907D6E627FCAFD97606824CE1FE1E2A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_log_memsize_zero.py b/tests/ported_static/stLogTests/test_log4_log_memsize_zero.py index 2ab42b2d386..4049b43cc09 100644 --- a/tests/ported_static/stLogTests/test_log4_log_memsize_zero.py +++ b/tests/ported_static/stLogTests/test_log4_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_log_memsize_zero( ) -> None: """Test_log4_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log4_log_memsize_zero( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0xB03FD6E714A14074A17E2ECFD412E35B1DDB21E5, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 1 0 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -84,9 +61,26 @@ def test_log4_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB03FD6E714A14074A17E2ECFD412E35B1DDB21E5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_max_topic.py b/tests/ported_static/stLogTests/test_log4_max_topic.py index 45f2eadd24c..b8efc373d81 100644 --- a/tests/ported_static/stLogTests/test_log4_max_topic.py +++ b/tests/ported_static/stLogTests/test_log4_max_topic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_max_topic( ) -> None: """Test_log4_max_topic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log4_max_topic( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0xCCB217083DF3658F7F5BB3325D2368AC932ED83B, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -84,9 +61,26 @@ def test_log4_max_topic( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCCB217083DF3658F7F5BB3325D2368AC932ED83B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_non_empty_mem.py b/tests/ported_static/stLogTests/test_log4_non_empty_mem.py index 89e93ff070e..542de72a9fe 100644 --- a/tests/ported_static/stLogTests/test_log4_non_empty_mem.py +++ b/tests/ported_static/stLogTests/test_log4_non_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_non_empty_mem( ) -> None: """Test_log4_non_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log4_non_empty_mem( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0xD78CA74FB91DC10B6315B23141F23FCE8317AB9A, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG4 0 32 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -84,9 +61,26 @@ def test_log4_non_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD78CA74FB91DC10B6315B23141F23FCE8317AB9A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1.py b/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1.py index bdb4fdf5dea..63933ed45ad 100644 --- a/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1.py +++ b/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_non_empty_mem_log_mem_size1( ) -> None: """Test_log4_non_empty_mem_log_mem_size1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,26 +43,6 @@ def test_log4_non_empty_mem_log_mem_size1( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0xA1BA9EDCB02902136B7A79A5C49409E244BC01C5, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 0 1 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -84,9 +61,26 @@ def test_log4_non_empty_mem_log_mem_size1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA1BA9EDCB02902136B7A79A5C49409E244BC01C5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1_log_mem_start31.py b/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1_log_mem_start31.py index 4ca21e7a71c..5d25ff48d5a 100644 --- a/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1_log_mem_start31.py +++ b/tests/ported_static/stLogTests/test_log4_non_empty_mem_log_mem_size1_log_mem_start31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_log4_non_empty_mem_log_mem_size1_log_mem_start31( ) -> None: """Test_log4_non_empty_mem_log_mem_size1_log_mem_start31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,26 +45,6 @@ def test_log4_non_empty_mem_log_mem_size1_log_mem_start31( gas_limit=1000000, ) - # Source: lll - # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=0x3E8, - address=0x23886789BD30D62944A3475276B774A785CB3329, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG4 31 1 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -86,9 +63,26 @@ def test_log4_non_empty_mem_log_mem_size1_log_mem_start31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x23886789BD30D62944A3475276B774A785CB3329), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=0x3E8, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log4_pc.py b/tests/ported_static/stLogTests/test_log4_pc.py index 6448e008a77..958493ee98a 100644 --- a/tests/ported_static/stLogTests/test_log4_pc.py +++ b/tests/ported_static/stLogTests/test_log4_pc.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_pc( ) -> None: """Test_log4_pc.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_log4_pc( gas_limit=1000000, ) + # Source: lll + # { (MSTORE8 0 0xff) (LOG4 0 32 (PC) (PC) (PC) (PC) ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0xFF) + + Op.LOG4( + offset=0x0, + size=0x20, + topic_1=Op.PC, + topic_2=Op.PC, + topic_3=Op.PC, + topic_4=Op.PC, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +66,7 @@ def test_log4_pc( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x84861F45AE3E1AA4792A50F336696EFA9902C95B, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,26 +77,7 @@ def test_log4_pc( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1E5597B6168FE79952CB2DE7AF91C3449BC95BD4), # noqa: E501 - ) - # Source: lll - # { (MSTORE8 0 0xff) (LOG4 0 32 (PC) (PC) (PC) (PC) ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0xFF) - + Op.LOG4( - offset=0x0, - size=0x20, - topic_1=Op.PC, - topic_2=Op.PC, - topic_3=Op.PC, - topic_4=Op.PC, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x84861F45AE3E1AA4792A50F336696EFA9902C95B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stLogTests/test_log_in_oog_call.py b/tests/ported_static/stLogTests/test_log_in_oog_call.py index 28be25e5bb7..577c60f1347 100644 --- a/tests/ported_static/stLogTests/test_log_in_oog_call.py +++ b/tests/ported_static/stLogTests/test_log_in_oog_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log_in_oog_call( ) -> None: """Test_log_in_oog_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_log_in_oog_call( gas_limit=1000000, ) + # Source: lll + # { (LOG0 0 32) (MLOAD 0xffffffffffffffff) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG0(offset=0x0, size=0x20) + + Op.MLOAD(offset=0xFFFFFFFFFFFFFFFF) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 100000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +59,7 @@ def test_log_in_oog_call( key=0x0, value=Op.CALL( gas=0x186A0, - address=0x69B6134B97E638B919A7089DF82AF74961E71FF8, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -64,19 +70,7 @@ def test_log_in_oog_call( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x825DCC9FBF5CFF44E688BAE15B79E8E11951BE2A), # noqa: E501 - ) - # Source: lll - # { (LOG0 0 32) (MLOAD 0xffffffffffffffff) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG0(offset=0x0, size=0x20) - + Op.MLOAD(offset=0xFFFFFFFFFFFFFFFF) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x69B6134B97E638B919A7089DF82AF74961E71FF8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expanding_calls.py index e40f6d2ceb0..ff44e5b435b 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expand ) -> None: """Test_call_and_callcode_consume_more_gas_then_transaction_has_with_m...""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x8D19F2B0D2F5689C1771FBCA70476CA6E877A81EE15C3733DE87FAE38E5ABCEF - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,11 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expand gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: hex # 0x6012600055 addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x12), nonce=0, - address=Address(0xA1F6E75A455896613053D45331763A07F4718969), # noqa: E501 ) # Source: hex # 0x5a60085560ff60ff60ff60ff600073620927c0f160095560ff60ff60ff60ff600073620927c0f2600a55 # noqa: E501 @@ -64,7 +59,7 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expand key=0x9, value=Op.CALL( gas=0x927C0, - address=0xA1F6E75A455896613053D45331763A07F4718969, + address=addr, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -76,7 +71,7 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expand key=0xA, value=Op.CALLCODE( gas=0x927C0, - address=0xA1F6E75A455896613053D45331763A07F4718969, + address=addr, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -85,7 +80,6 @@ def test_call_and_callcode_consume_more_gas_then_transaction_has_with_mem_expand ), ), nonce=0, - address=Address(0x346E4C3E54A808E0CAD66173DE0D81FF4D06BABF), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_calls.py index 549f63f546d..e181c5c7f03 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_cal ) -> None: """Test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expa...""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x8D19F2B0D2F5689C1771FBCA70476CA6E877A81EE15C3733DE87FAE38E5ABCEF - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,16 +45,21 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_cal gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: hex - # 0x5a60085560ff60ff60ff60ff60007362030d40f1600955 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # 0x5a600855 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=Op.GAS), + nonce=0, + ) + # Source: hex + # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( - gas=0x30D40, - address=0xA229D9EFD075227ED1E0EA0427045B5EE24DC40A, + gas=0x927C0, + address=addr, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -66,24 +68,16 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_cal ), ), nonce=0, - address=Address(0x97442DA68A5F2B1BE1728C655C0F395CFFB999CF), # noqa: E501 ) # Source: hex - # 0x5a600855 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=Op.GAS), - nonce=0, - address=Address(0x9EDEFDFB5A11A6B30DBA1BFF8726F94F9D9E1232), # noqa: E501 - ) - # Source: hex - # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # 0x5a60085560ff60ff60ff60ff60007362030d40f1600955 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( - gas=0x927C0, - address=0x9EDEFDFB5A11A6B30DBA1BFF8726F94F9D9E1232, + gas=0x30D40, + address=addr_2, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -92,7 +86,6 @@ def test_call_ask_more_gas_on_depth2_then_transaction_has_with_mem_expanding_cal ), ), nonce=0, - address=Address(0xA229D9EFD075227ED1E0EA0427045B5EE24DC40A), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level2_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level2_with_mem_expanding_calls.py index a80c621df0b..03fba477f8e 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level2_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level2_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( ) -> None: """Test_call_goes_oog_on_second_level2_with_mem_expanding_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB51075BB33D347A23B516E327E1B71C54F63FAA192D1D94B62C76E0C26CF98A - ) + sender = pre.fund_eoa(amount=0xE8D4A510000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( gas_limit=100000000, ) - pre[sender] = Account(balance=0xE8D4A510000) # Source: hex # 0x5a6008555a6009555a600a55 addr = pre.deploy_contract( # noqa: F841 @@ -56,7 +52,6 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( + Op.SSTORE(key=0x9, value=Op.GAS) + Op.SSTORE(key=0xA, value=Op.GAS), nonce=0, - address=Address(0x96983DE02BFBCB5D0F4E0EE98FDDE6D6F0C75FE0), # noqa: E501 ) # Source: hex # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 @@ -66,7 +61,7 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( key=0x9, value=Op.CALL( gas=0x927C0, - address=0x96983DE02BFBCB5D0F4E0EE98FDDE6D6F0C75FE0, + address=addr, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -75,7 +70,6 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( ), ), nonce=0, - address=Address(0xC10A98222464B07008CEB5A0EC44ED49920ADDDA), # noqa: E501 ) # Source: hex # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 @@ -85,7 +79,7 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( key=0x9, value=Op.CALL( gas=0x927C0, - address=0xC10A98222464B07008CEB5A0EC44ED49920ADDDA, + address=addr_2, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -94,7 +88,6 @@ def test_call_goes_oog_on_second_level2_with_mem_expanding_calls( ), ), nonce=0, - address=Address(0x0700BB425D7D4C412AC658014015BD6C98652DC4), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level_with_mem_expanding_calls.py index c8a6b1d87ad..3c9a3facb41 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_call_goes_oog_on_second_level_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_goes_oog_on_second_level_with_mem_expanding_calls( ) -> None: """Test_call_goes_oog_on_second_level_with_mem_expanding_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x8D19F2B0D2F5689C1771FBCA70476CA6E877A81EE15C3733DE87FAE38E5ABCEF - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,16 +45,24 @@ def test_call_goes_oog_on_second_level_with_mem_expanding_calls( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: hex - # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # 0x5a600855600060006000f050600060006000f0505a6009555a600a55 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=Op.GAS) + + Op.POP(Op.CREATE(value=0x0, offset=0x0, size=0x0)) * 2 + + Op.SSTORE(key=0x9, value=Op.GAS) + + Op.SSTORE(key=0xA, value=Op.GAS), + nonce=0, + ) + # Source: hex + # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( gas=0x927C0, - address=0xA27E20572430916B3D6772B27329CC460224904D, + address=addr, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -66,27 +71,16 @@ def test_call_goes_oog_on_second_level_with_mem_expanding_calls( ), ), nonce=0, - address=Address(0xAF229807016A538DFCDAB92A53337DE38178D40F), # noqa: E501 ) # Source: hex - # 0x5a600855600060006000f050600060006000f0505a6009555a600a55 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=Op.GAS) - + Op.POP(Op.CREATE(value=0x0, offset=0x0, size=0x0)) * 2 - + Op.SSTORE(key=0x9, value=Op.GAS) - + Op.SSTORE(key=0xA, value=Op.GAS), - nonce=0, - address=Address(0x2EF686162BEBF2542147767D5BE471976860CCEB), # noqa: E501 - ) - # Source: hex - # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # 0x5a60085560ff60ff60ff60ff600073620927c0f1600955 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=Op.GAS) + Op.SSTORE( key=0x9, value=Op.CALL( gas=0x927C0, - address=0x2EF686162BEBF2542147767D5BE471976860CCEB, + address=addr_2, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -95,7 +89,6 @@ def test_call_goes_oog_on_second_level_with_mem_expanding_calls( ), ), nonce=0, - address=Address(0xA27E20572430916B3D6772B27329CC460224904D), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_create_and_gas_inside_create_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_create_and_gas_inside_create_with_mem_expanding_calls.py index 2b549a7bac4..705e9e760f9 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_create_and_gas_inside_create_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_create_and_gas_inside_create_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_create_and_gas_inside_create_with_mem_expanding_calls( """Test_create_and_gas_inside_create_with_mem_expanding_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_create_and_gas_inside_create_with_mem_expanding_calls( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: hex # 0x5a600a55635a60fd556000526004601c6000f0600b555a600955 contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +55,6 @@ def test_create_and_gas_inside_create_with_mem_expanding_calls( + Op.SSTORE(key=0xB, value=Op.CREATE(value=0x0, offset=0x1C, size=0x4)) + Op.SSTORE(key=0x9, value=Op.GAS), nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( @@ -75,7 +70,7 @@ def test_create_and_gas_inside_create_with_mem_expanding_calls( storage={ 9: 0x75596, 10: 0x8D5B6, - 11: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 11: compute_create_address(address=contract_0, nonce=0), }, nonce=1, ), diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_delegate_call_on_eip_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_delegate_call_on_eip_with_mem_expanding_calls.py index b68c050df27..dec68916fab 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_delegate_call_on_eip_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_delegate_call_on_eip_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_delegate_call_on_eip_with_mem_expanding_calls( ) -> None: """Test_delegate_call_on_eip_with_mem_expanding_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x8D19F2B0D2F5689C1771FBCA70476CA6E877A81EE15C3733DE87FAE38E5ABCEF - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,12 @@ def test_delegate_call_on_eip_with_mem_expanding_calls( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: hex + # 0x6012600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x12), + nonce=0, + ) # Source: hex # 0x5a60085560ff60ff60ff60ff73620927c0f4600955 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +59,7 @@ def test_delegate_call_on_eip_with_mem_expanding_calls( key=0x9, value=Op.DELEGATECALL( gas=0x927C0, - address=0xA1F6E75A455896613053D45331763A07F4718969, + address=addr, args_offset=0xFF, args_size=0xFF, ret_offset=0xFF, @@ -65,14 +67,6 @@ def test_delegate_call_on_eip_with_mem_expanding_calls( ), ), nonce=0, - address=Address(0x3FC906A124D4054023BE5DD8666CE29AA3712CCB), # noqa: E501 - ) - # Source: hex - # 0x6012600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x12), - nonce=0, - address=Address(0xA1F6E75A455896613053D45331763A07F4718969), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_calls.py index 34fffbc11f2..0779b06c87b 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_ ) -> None: """Test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_e...""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x6A3A7E4100E459734759453F3AEBB7F5FE9B806BAA83232CD5C42FE0A359CA67 - ) + sender = pre.fund_eoa(amount=0x186A000) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,13 @@ def test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_ gas_limit=10000000, ) - pre[sender] = Account(balance=0x186A000) + # Source: hex + # 0x600c600155 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC), + balance=0x186A0, + nonce=0, + ) # Source: hex # 0x60ff60ff60ff60ff600073620927c0f1600155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +59,7 @@ def test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_ key=0x1, value=Op.CALL( gas=0x927C0, - address=0x73D01F7D28C5A55520CD80D2C3F0938C1834CCFF, + address=addr, value=0x0, args_offset=0xFF, args_size=0xFF, @@ -65,15 +68,6 @@ def test_execute_call_that_ask_more_gas_then_transaction_has_with_mem_expanding_ ), ), nonce=0, - address=Address(0xBDBACB5FB8222511832EB176B990CD8AD511C271), # noqa: E501 - ) - # Source: hex - # 0x600c600155 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC), - balance=0x186A0, - nonce=0, - address=Address(0x73D01F7D28C5A55520CD80D2C3F0938C1834CCFF), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_new_gas_price_for_codes_with_mem_expanding_calls.py b/tests/ported_static/stMemExpandingEIP150Calls/test_new_gas_price_for_codes_with_mem_expanding_calls.py index 005c5297574..47aed815167 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_new_gas_price_for_codes_with_mem_expanding_calls.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_new_gas_price_for_codes_with_mem_expanding_calls.py @@ -48,6 +48,7 @@ def test_new_gas_price_for_codes_with_mem_expanding_calls( gas_limit=10000000, ) + pre[sender] = Account(balance=0xE8D4A5100000) # Source: hex # 0x1122334455667788991011121314151617181920212223242526272829303132 addr = pre.deploy_contract( # noqa: F841 @@ -65,29 +66,18 @@ def test_new_gas_price_for_codes_with_mem_expanding_calls( nonce=0, address=Address(0x7B8C83E74CC8DFADB03138C2743C70588ACE4222), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A5100000) # Source: hex # 0x733b600155601460006000733c60005160025560005460045560ff60ff60ff60ff600173617530f160055560ff60ff60ff60ff600173617530f260065560ff60ff60ff60ff73617530f460075560ff60ff60ff60ff6000731000000000000000000000000000000000000013617530f160085573316003555a600a55 # noqa: E501 target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x1, - value=Op.EXTCODESIZE( - address=0x6B6AF3C6E1714081C8C3085ACBAC8C2B21FADF0B - ), - ) - + Op.EXTCODECOPY( - address=0x6B6AF3C6E1714081C8C3085ACBAC8C2B21FADF0B, - dest_offset=0x0, - offset=0x0, - size=0x14, - ) + code=Op.SSTORE(key=0x1, value=Op.EXTCODESIZE(address=addr)) + + Op.EXTCODECOPY(address=addr, dest_offset=0x0, offset=0x0, size=0x14) + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x0)) + Op.SSTORE(key=0x4, value=Op.SLOAD(key=0x0)) + Op.SSTORE( key=0x5, value=Op.CALL( gas=0x7530, - address=0x7B8C83E74CC8DFADB03138C2743C70588ACE4222, + address=addr_2, value=0x1, args_offset=0xFF, args_size=0xFF, @@ -99,7 +89,7 @@ def test_new_gas_price_for_codes_with_mem_expanding_calls( key=0x6, value=Op.CALLCODE( gas=0x7530, - address=0x7B8C83E74CC8DFADB03138C2743C70588ACE4222, + address=addr_2, value=0x1, args_offset=0xFF, args_size=0xFF, @@ -111,7 +101,7 @@ def test_new_gas_price_for_codes_with_mem_expanding_calls( key=0x7, value=Op.DELEGATECALL( gas=0x7530, - address=0x7B8C83E74CC8DFADB03138C2743C70588ACE4222, + address=addr_2, args_offset=0xFF, args_size=0xFF, ret_offset=0xFF, @@ -130,12 +120,7 @@ def test_new_gas_price_for_codes_with_mem_expanding_calls( ret_size=0xFF, ), ) - + Op.SSTORE( - key=0x3, - value=Op.BALANCE( - address=0xF1100237A29F570CBF8B107BA3CB5BF2DB42BD3F - ), - ) + + Op.SSTORE(key=0x3, value=Op.BALANCE(address=sender)) + Op.SSTORE(key=0xA, value=Op.GAS), storage={0: 18}, nonce=0, diff --git a/tests/ported_static/stMemExpandingEIP150Calls/test_oo_gin_return.py b/tests/ported_static/stMemExpandingEIP150Calls/test_oo_gin_return.py index fdc89fe7e7d..145e2b341e1 100644 --- a/tests/ported_static/stMemExpandingEIP150Calls/test_oo_gin_return.py +++ b/tests/ported_static/stMemExpandingEIP150Calls/test_oo_gin_return.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -83,9 +82,7 @@ def test_oo_gin_return( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -175,7 +172,6 @@ def test_oo_gin_return( nonce=0, address=Address(0xEBD3191DD8150F47E30F87927DB4592163EE9224), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryStressTest/test_call_bounds.py b/tests/ported_static/stMemoryStressTest/test_call_bounds.py index 4b1122057f9..49a2518ece9 100644 --- a/tests/ported_static/stMemoryStressTest/test_call_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_call_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_call_bounds( ) -> None: """Test_call_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,13 +67,20 @@ def test_call_bounds( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 0x7ffffffffffffff 0 0 0 0 0) (CALL 0x7ffffffffffffff 0 0 0xfffffff 0 0xfffffff) (CALL 0x7ffffffffffffff 0 0 0xffffffff 0 0xffffffff) (CALL 0x7ffffffffffffff 0 0xfffffff 0 0xfffffff 0) (CALL 0x7ffffffffffffff 0 0xffffffff 0 0xffffffff 0) (CALL 0x7ffffffffffffff 0 0xffffffffffffffff 0 0xffffffffffffffff 0) (CALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0) (CALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -85,7 +91,7 @@ def test_call_bounds( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFF, @@ -96,7 +102,7 @@ def test_call_bounds( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFF, @@ -107,7 +113,7 @@ def test_call_bounds( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFF, args_size=0x0, @@ -118,7 +124,7 @@ def test_call_bounds( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFF, args_size=0x0, @@ -129,7 +135,7 @@ def test_call_bounds( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0x0, @@ -140,7 +146,7 @@ def test_call_bounds( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0x0, @@ -150,7 +156,7 @@ def test_call_bounds( ) + Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0x0, @@ -159,18 +165,6 @@ def test_call_bounds( ) + Op.STOP, nonce=0, - address=Address(0x5F620F2EA7307FD66700749255ADE959893706FF), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_call_bounds2.py b/tests/ported_static/stMemoryStressTest/test_call_bounds2.py index d3014037e9a..3638beda9b6 100644 --- a/tests/ported_static/stMemoryStressTest/test_call_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_call_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_call_bounds2( ) -> None: """Test_call_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,12 +67,19 @@ def test_call_bounds2( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 0x7ffffffffffffff 0 0xfffffff 0xfffffff 0xfffffff 0xfffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFF, args_size=0xFFFFFFF, @@ -82,18 +88,6 @@ def test_call_bounds2( ) + Op.STOP, nonce=0, - address=Address(0xB6055EE15F692591C71B50A7BDA55180B78F6EF9), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_call_bounds2a.py b/tests/ported_static/stMemoryStressTest/test_call_bounds2a.py index 4824d8563f1..1065f6cec49 100644 --- a/tests/ported_static/stMemoryStressTest/test_call_bounds2a.py +++ b/tests/ported_static/stMemoryStressTest/test_call_bounds2a.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_call_bounds2a( ) -> None: """Test_call_bounds2a.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,12 +67,19 @@ def test_call_bounds2a( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 0x7ffffffffffffff 0 0xffffffff 0xffffffff 0xffffffff 0xffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFF, args_size=0xFFFFFFFF, @@ -82,18 +88,6 @@ def test_call_bounds2a( ) + Op.STOP, nonce=0, - address=Address(0x6C184E7E792470E474B189A511B48F06F0643D4B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_call_bounds3.py b/tests/ported_static/stMemoryStressTest/test_call_bounds3.py index 85af0b5ba31..81ccd53caf4 100644 --- a/tests/ported_static/stMemoryStressTest/test_call_bounds3.py +++ b/tests/ported_static/stMemoryStressTest/test_call_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,8 +60,8 @@ def test_call_bounds3( ) -> None: """Test_call_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -74,13 +73,20 @@ def test_call_bounds3( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 0x7ffffffffffffff 0 0 0xffffffffffffffff 0 0xffffffffffffffff) (CALL 0x7ffffffffffffff 0 0 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff) (CALL 0x7ffffffffffffff 0 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 0x7ffffffffffffff 0 0xffffffff 0xffffffff 0xffffffff 0xffffffff) (CALL 0x7ffffffffffffff 0 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff) (CALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff) (CALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFF, @@ -91,7 +97,7 @@ def test_call_bounds3( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -102,7 +108,7 @@ def test_call_bounds3( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -113,7 +119,7 @@ def test_call_bounds3( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFF, args_size=0xFFFFFFFF, @@ -124,7 +130,7 @@ def test_call_bounds3( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFF, @@ -135,7 +141,7 @@ def test_call_bounds3( + Op.POP( Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -145,7 +151,7 @@ def test_call_bounds3( ) + Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -154,18 +160,6 @@ def test_call_bounds3( ) + Op.STOP, nonce=0, - address=Address(0x82475C10FEA2425B322D1F97FCEF265C5DC7C8C9), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_callcode_bounds.py b/tests/ported_static/stMemoryStressTest/test_callcode_bounds.py index e39eb09e713..3a7a1cd03ea 100644 --- a/tests/ported_static/stMemoryStressTest/test_callcode_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_callcode_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_callcode_bounds( ) -> None: """Test_callcode_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -68,13 +67,20 @@ def test_callcode_bounds( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALLCODE 0x7ffffffffffffff 0 0 0 0 0) (CALLCODE 0x7ffffffffffffff 0 0 0xfffffff 0 0xfffffff) (CALLCODE 0x7ffffffffffffff 0 0 0xffffffff 0 0xffffffff) (CALLCODE 0x7ffffffffffffff 0 0xfffffff 0 0xfffffff 0) (CALLCODE 0x7ffffffffffffff 0 0xffffffff 0 0xffffffff 0) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffff 0 0xffffffffffffffff 0) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -85,7 +91,7 @@ def test_callcode_bounds( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFF, @@ -96,7 +102,7 @@ def test_callcode_bounds( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFF, @@ -107,7 +113,7 @@ def test_callcode_bounds( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFF, args_size=0x0, @@ -118,7 +124,7 @@ def test_callcode_bounds( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFF, args_size=0x0, @@ -129,7 +135,7 @@ def test_callcode_bounds( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0x0, @@ -140,7 +146,7 @@ def test_callcode_bounds( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0x0, @@ -150,7 +156,7 @@ def test_callcode_bounds( ) + Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0x0, @@ -159,18 +165,6 @@ def test_callcode_bounds( ) + Op.STOP, nonce=0, - address=Address(0x3F4ED7C54CD8A44E2D6B4D967E8E070A8C4A4F34), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_callcode_bounds2.py b/tests/ported_static/stMemoryStressTest/test_callcode_bounds2.py index df3ea69f7d7..5496732ba6d 100644 --- a/tests/ported_static/stMemoryStressTest/test_callcode_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_callcode_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_callcode_bounds2( ) -> None: """Test_callcode_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -68,12 +67,19 @@ def test_callcode_bounds2( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALLCODE 0x7ffffffffffffff 0 0xfffffff 0xfffffff 0xfffffff 0xfffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFF, args_size=0xFFFFFFF, @@ -82,18 +88,6 @@ def test_callcode_bounds2( ) + Op.STOP, nonce=0, - address=Address(0x814CC86EB9CAA0E43CFEA934FBB77C7917F5CC0E), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_callcode_bounds3.py b/tests/ported_static/stMemoryStressTest/test_callcode_bounds3.py index 6a2ea1945e0..9bddda9e3be 100644 --- a/tests/ported_static/stMemoryStressTest/test_callcode_bounds3.py +++ b/tests/ported_static/stMemoryStressTest/test_callcode_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_callcode_bounds3( ) -> None: """Test_callcode_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -68,12 +67,19 @@ def test_callcode_bounds3( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALLCODE 0x7ffffffffffffff 0 0xffffffff 0xffffffff 0xffffffff 0xffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFF, args_size=0xFFFFFFFF, @@ -82,18 +88,6 @@ def test_callcode_bounds3( ) + Op.STOP, nonce=0, - address=Address(0x206C40E47A57C530785338BCD7F38A6197BEE97B), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_callcode_bounds4.py b/tests/ported_static/stMemoryStressTest/test_callcode_bounds4.py index 9607bc07420..fc8373060be 100644 --- a/tests/ported_static/stMemoryStressTest/test_callcode_bounds4.py +++ b/tests/ported_static/stMemoryStressTest/test_callcode_bounds4.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,8 +60,8 @@ def test_callcode_bounds4( ) -> None: """Test_callcode_bounds4.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -74,13 +73,20 @@ def test_callcode_bounds4( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (CALLCODE 0x7ffffffffffffff 0 0 0xffffffffffffffff 0 0xffffffffffffffff) (CALLCODE 0x7ffffffffffffff 0 0 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff) (CALLCODE 0x7ffffffffffffff 0 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALLCODE 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFF, @@ -91,7 +97,7 @@ def test_callcode_bounds4( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -102,7 +108,7 @@ def test_callcode_bounds4( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -113,7 +119,7 @@ def test_callcode_bounds4( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFF, @@ -125,7 +131,7 @@ def test_callcode_bounds4( + Op.POP( Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -135,7 +141,7 @@ def test_callcode_bounds4( ) + Op.CALLCODE( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, value=0x0, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -144,18 +150,6 @@ def test_callcode_bounds4( ) + Op.STOP, nonce=0, - address=Address(0xC0479FBAC15CB575E66DED014FD60CEB98749B04), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_create_bounds.py b/tests/ported_static/stMemoryStressTest/test_create_bounds.py index 82eceb0f60e..992a097d01c 100644 --- a/tests/ported_static/stMemoryStressTest/test_create_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_create_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,8 +56,8 @@ def test_create_bounds( """Test_create_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -84,10 +83,6 @@ def test_create_bounds( + Op.STOP, balance=100, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_create_bounds2.py b/tests/ported_static/stMemoryStressTest/test_create_bounds2.py index 23c78763d23..d136a0b2ed3 100644 --- a/tests/ported_static/stMemoryStressTest/test_create_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_create_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,8 +56,8 @@ def test_create_bounds2( """Test_create_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -83,10 +82,6 @@ def test_create_bounds2( + Op.STOP, balance=100, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_create_bounds3.py b/tests/ported_static/stMemoryStressTest/test_create_bounds3.py index db1768045c0..d78ccc430d7 100644 --- a/tests/ported_static/stMemoryStressTest/test_create_bounds3.py +++ b/tests/ported_static/stMemoryStressTest/test_create_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -63,8 +62,8 @@ def test_create_bounds3( """Test_create_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -135,10 +134,6 @@ def test_create_bounds3( + Op.STOP, balance=100, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds.py b/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds.py index e4a4356ae1e..bdc3e3a6b0d 100644 --- a/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_delegatecall_bounds( ) -> None: """Test_delegatecall_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -68,13 +67,20 @@ def test_delegatecall_bounds( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # {(DELEGATECALL 0x7ffffffffffffff 0 0 0 0) (DELEGATECALL 0x7ffffffffffffff 0 0xfffffff 0 0xfffffff) (DELEGATECALL 0x7ffffffffffffff 0 0xffffffff 0 0xffffffff) (DELEGATECALL 0x7ffffffffffffff 0xfffffff 0 0xfffffff 0) (DELEGATECALL 0x7ffffffffffffff 0xffffffff 0 0xffffffff 0) (DELEGATECALL 0x7ffffffffffffff 0xffffffffffffffff 0 0xffffffffffffffff 0) (DELEGATECALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0) (DELEGATECALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) (DELEGATECALL 0x7ffffffffffffff 0xfffffff 0xfffffff 0xfffffff 0xfffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -84,7 +90,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0x0, args_size=0xFFFFFFF, ret_offset=0x0, @@ -94,7 +100,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0x0, args_size=0xFFFFFFFF, ret_offset=0x0, @@ -104,7 +110,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFF, @@ -114,7 +120,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFFF, @@ -124,7 +130,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFFFFFFFFFFF, @@ -134,7 +140,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -144,7 +150,7 @@ def test_delegatecall_bounds( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0x0, ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -153,7 +159,7 @@ def test_delegatecall_bounds( ) + Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFF, args_size=0xFFFFFFF, ret_offset=0xFFFFFFF, @@ -161,18 +167,6 @@ def test_delegatecall_bounds( ) + Op.STOP, nonce=0, - address=Address(0x75BC6DCEF9BDDA4E2EB511E92ED4815699F32B4F), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds2.py b/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds2.py index 7d35a713b94..4dde13d2569 100644 --- a/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_delegatecall_bounds2( ) -> None: """Test_delegatecall_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -68,12 +67,19 @@ def test_delegatecall_bounds2( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (DELEGATECALL 0x7ffffffffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFF, args_size=0xFFFFFFFF, ret_offset=0xFFFFFFFF, @@ -81,18 +87,6 @@ def test_delegatecall_bounds2( ) + Op.STOP, nonce=0, - address=Address(0x7B7E1FED40D6CB2420C7F2718725BADB76616D4D), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds3.py b/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds3.py index cf48a071112..804fc02744b 100644 --- a/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds3.py +++ b/tests/ported_static/stMemoryStressTest/test_delegatecall_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,8 +60,8 @@ def test_delegatecall_bounds3( ) -> None: """Test_delegatecall_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -74,13 +73,20 @@ def test_delegatecall_bounds3( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (DELEGATECALL 0x7ffffffffffffff 0 0xffffffffffffffff 0 0xffffffffffffffff) (DELEGATECALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff) (DELEGATECALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (DELEGATECALL 0x7ffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff) (DELEGATECALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff) (DELEGATECALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFF, ret_offset=0x0, @@ -90,7 +96,7 @@ def test_delegatecall_bounds3( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ret_offset=0x0, @@ -100,7 +106,7 @@ def test_delegatecall_bounds3( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 ret_offset=0x0, @@ -110,7 +116,7 @@ def test_delegatecall_bounds3( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFF, ret_offset=0xFFFFFFFFFFFFFFFF, @@ -120,7 +126,7 @@ def test_delegatecall_bounds3( + Op.POP( Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -129,7 +135,7 @@ def test_delegatecall_bounds3( ) + Op.DELEGATECALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -137,18 +143,6 @@ def test_delegatecall_bounds3( ) + Op.STOP, nonce=0, - address=Address(0x5A6CC254B318BB5F7539FCC10CFB01C517154C5C), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_dup_bounds.py b/tests/ported_static/stMemoryStressTest/test_dup_bounds.py index 1996ca05c2e..8f413ec636b 100644 --- a/tests/ported_static/stMemoryStressTest/test_dup_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_dup_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_dup_bounds( ) -> None: """Test_dup_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x31B5AF02B012484AE954B3A43943242EDE546A2E76FC0A6ACC17435107C385EB - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -220,9 +217,7 @@ def test_dup_bounds( * 8 + Op.DUP8, nonce=0, - address=Address(0xE860BD7BF0474923E526CBE86FA5B5F76AEE36ED), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_fill_stack.py b/tests/ported_static/stMemoryStressTest/test_fill_stack.py index 1813133b035..ecb5ba40c04 100644 --- a/tests/ported_static/stMemoryStressTest/test_fill_stack.py +++ b/tests/ported_static/stMemoryStressTest/test_fill_stack.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_fill_stack( ) -> None: """Test_fill_stack.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0x23000FE3D08CDEBA75EB2E2E2909F842DBF48AA0C566F49101E8285C8DEC62D6 - ) + sender = pre.fund_eoa(amount=0x152D02C7E14AF6800000) env = Environment( fee_recipient=coinbase, @@ -95,7 +92,6 @@ def test_fill_stack( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x709EE68118AB00CE0BAB659C9AA89744B35703FA), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -113,7 +109,6 @@ def test_fill_stack( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0x152D02C7E14AF6800000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryStressTest/test_jump_bounds.py b/tests/ported_static/stMemoryStressTest/test_jump_bounds.py index 8a89ac36082..2a1a55e636a 100644 --- a/tests/ported_static/stMemoryStressTest/test_jump_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_jump_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_jump_bounds( ) -> None: """Test_jump_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x31B5AF02B012484AE954B3A43943242EDE546A2E76FC0A6ACC17435107C385EB - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,9 +70,7 @@ def test_jump_bounds( target = pre.deploy_contract( # noqa: F841 code=Op.JUMP(pc=0x0) + Op.STOP, nonce=0, - address=Address(0xB2448DEB71E9FD31ED854E3B856F729ADBC0C288), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_jump_bounds2.py b/tests/ported_static/stMemoryStressTest/test_jump_bounds2.py index 1e39ba7a289..eaaebf34d20 100644 --- a/tests/ported_static/stMemoryStressTest/test_jump_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_jump_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_jump_bounds2( ) -> None: """Test_jump_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x31B5AF02B012484AE954B3A43943242EDE546A2E76FC0A6ACC17435107C385EB - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -78,9 +75,7 @@ def test_jump_bounds2( pc=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ), nonce=0, - address=Address(0xDE573D26B8C4A55FD9DAA17E8F93347C269EE4F6), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_jumpi_bounds.py b/tests/ported_static/stMemoryStressTest/test_jumpi_bounds.py index a29444e3f49..fcb17d5633e 100644 --- a/tests/ported_static/stMemoryStressTest/test_jumpi_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_jumpi_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_jumpi_bounds( ) -> None: """Test_jumpi_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x31B5AF02B012484AE954B3A43943242EDE546A2E76FC0A6ACC17435107C385EB - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -80,9 +77,7 @@ def test_jumpi_bounds( ) + Op.STOP, nonce=0, - address=Address(0x147F3300E29F2F09880E97B81F7B3EBCF78863E9), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound.py b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound.py index 629438d5d7b..5763dad5154 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound.py +++ b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mload32bit_bound( ) -> None: """Test_mload32bit_bound.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA3A3360EDACC183E5D6D28657FC0A09CD4819B2C73A02881B04471F81BE35A5A - ) + sender = pre.fund_eoa(amount=0x3E801F4FA93760) env = Environment( fee_recipient=coinbase, @@ -77,9 +74,7 @@ def test_mload32bit_bound( code=Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x100000000)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74639ACDFE345F749D595381961DAC48C3C5E56A), # noqa: E501 ) - pre[sender] = Account(balance=0x3E801F4FA93760) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound2.py b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound2.py index c166e7919da..322e11428e8 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound2.py +++ b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mload32bit_bound2( ) -> None: """Test_mload32bit_bound2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xD566533F0CCAB46749AC8725E15DA8CE513758257002A8B481F6F5F96484C5ED - ) + sender = pre.fund_eoa(amount=0x157B5373E07CA) env = Environment( fee_recipient=coinbase, @@ -77,9 +74,7 @@ def test_mload32bit_bound2( code=Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x177359400)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC287E277D2163771E55D630BDD96C6405A6FE251), # noqa: E501 ) - pre[sender] = Account(balance=0x157B5373E07CA) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_msize.py b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_msize.py index 87978c1736d..ccff8e7bdf2 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_msize.py +++ b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_msize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_mload32bit_bound_msize( ) -> None: """Test_mload32bit_bound_msize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD14755C573E37C1F649B0C53B9815F76AEBD636DF7CCFA97F4579F33BA59A0 - ) + sender = pre.fund_eoa(amount=0x186A0C3B1E19A180) env = Environment( fee_recipient=coinbase, @@ -79,9 +76,7 @@ def test_mload32bit_bound_msize( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x15D5A32351458FF3DCA214BD202C21F066031AE1), # noqa: E501 ) - pre[sender] = Account(balance=0x186A0C3B1E19A180) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return.py b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return.py index ce5d14212ed..26035b812b3 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return.py +++ b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_mload32bit_bound_return( ) -> None: """Test_mload32bit_bound_return.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD14755C573E37C1F649B0C53B9815F76AEBD636DF7CCFA97F4579F33BA59A0 - ) + sender = pre.fund_eoa(amount=0x186A0C3B1E19A180) env = Environment( fee_recipient=coinbase, @@ -74,9 +71,7 @@ def test_mload32bit_bound_return( code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD9CBA08B7A9695800F57E226045176CF420CA0C1), # noqa: E501 ) - pre[sender] = Account(balance=0x186A0C3B1E19A180) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return2.py b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return2.py index 7dfd0fd7b2c..a6ff16bdf72 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return2.py +++ b/tests/ported_static/stMemoryStressTest/test_mload32bit_bound_return2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_mload32bit_bound_return2( ) -> None: """Test_mload32bit_bound_return2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD14755C573E37C1F649B0C53B9815F76AEBD636DF7CCFA97F4579F33BA59A0 - ) + sender = pre.fund_eoa(amount=0x186A0C3B1E19A180) env = Environment( fee_recipient=coinbase, @@ -76,9 +73,7 @@ def test_mload32bit_bound_return2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x48C46C265C6883F765EEA264F561FE7637968B4E), # noqa: E501 ) - pre[sender] = Account(balance=0x186A0C3B1E19A180) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_mload_bounds.py b/tests/ported_static/stMemoryStressTest/test_mload_bounds.py index 576951a18c8..4a0eff0c7e6 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_mload_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_mload_bounds( ) -> None: """Test_mload_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xFE5BE118AD5955E30E0FFC4E1F1BBDCAA7F5A67CB1426C4AC19E32C80ECCDC06 - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -75,9 +72,7 @@ def test_mload_bounds( + Op.MLOAD(offset=0xFFFFFFFF) + Op.STOP, nonce=0, - address=Address(0x8B0647E983082E6923F7B20E38972690FCE91E9B), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_mload_bounds2.py b/tests/ported_static/stMemoryStressTest/test_mload_bounds2.py index cca60078e35..e35d61df04c 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_mload_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_mload_bounds2( ) -> None: """Test_mload_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xFE5BE118AD5955E30E0FFC4E1F1BBDCAA7F5A67CB1426C4AC19E32C80ECCDC06 - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -78,9 +75,7 @@ def test_mload_bounds2( ) + Op.STOP, nonce=0, - address=Address(0xB581F1A0F5810AD50A1F96713DF63EB8CB0EBF8A), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_mload_bounds3.py b/tests/ported_static/stMemoryStressTest/test_mload_bounds3.py index b34def49c4f..adef7836ab7 100644 --- a/tests/ported_static/stMemoryStressTest/test_mload_bounds3.py +++ b/tests/ported_static/stMemoryStressTest/test_mload_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_mload_bounds3( ) -> None: """Test_mload_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xFE5BE118AD5955E30E0FFC4E1F1BBDCAA7F5A67CB1426C4AC19E32C80ECCDC06 - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,9 +71,7 @@ def test_mload_bounds3( target = pre.deploy_contract( # noqa: F841 code=Op.MLOAD(offset=0x400000) + Op.STOP, nonce=0, - address=Address(0xB4B66EEF4A593BFD61289EC192AF659C68266259), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_mstore_bounds.py b/tests/ported_static/stMemoryStressTest/test_mstore_bounds.py index c764c3a97d7..49713f67bc8 100644 --- a/tests/ported_static/stMemoryStressTest/test_mstore_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_mstore_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_mstore_bounds( ) -> None: """Test_mstore_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -73,10 +72,6 @@ def test_mstore_bounds( target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0xFFFFFFFFFFFFFFFF, value=0x1) + Op.STOP, nonce=0, - address=Address(0x3634C48093587D5DAB61C69EE815D8E8752E9312), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_mstore_bounds2.py b/tests/ported_static/stMemoryStressTest/test_mstore_bounds2.py index 1f8ff32dd6f..93358c7451f 100644 --- a/tests/ported_static/stMemoryStressTest/test_mstore_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_mstore_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_mstore_bounds2( ) -> None: """Test_mstore_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -73,10 +72,6 @@ def test_mstore_bounds2( target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0xFFFFFFFFFF, value=0x1) + Op.STOP, nonce=0, - address=Address(0xDD1868B8341812C23C84DA08446BC70919A815DF), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_mstore_bounds2a.py b/tests/ported_static/stMemoryStressTest/test_mstore_bounds2a.py index 001c9bb8b43..82cbcebb094 100644 --- a/tests/ported_static/stMemoryStressTest/test_mstore_bounds2a.py +++ b/tests/ported_static/stMemoryStressTest/test_mstore_bounds2a.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,8 +58,8 @@ def test_mstore_bounds2a( ) -> None: """Test_mstore_bounds2a.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -77,10 +76,6 @@ def test_mstore_bounds2a( target = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3FFFFF, value=0x1) + Op.STOP, nonce=0, - address=Address(0x10DA52CBD00939AEBE8218A1DD2EDA0BFFE93F30), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stMemoryStressTest/test_pop_bounds.py b/tests/ported_static/stMemoryStressTest/test_pop_bounds.py index 8ac24f68b76..70870df24b0 100644 --- a/tests/ported_static/stMemoryStressTest/test_pop_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_pop_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_pop_bounds( ) -> None: """Test_pop_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xFE5BE118AD5955E30E0FFC4E1F1BBDCAA7F5A67CB1426C4AC19E32C80ECCDC06 - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -80,9 +77,7 @@ def test_pop_bounds( ) + Op.STOP, nonce=0, - address=Address(0x5BD3610AFCEC3B0C20466CA011B505497B0009F0), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_return_bounds.py b/tests/ported_static/stMemoryStressTest/test_return_bounds.py index 9a65ef00795..8014fe56cb0 100644 --- a/tests/ported_static/stMemoryStressTest/test_return_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_return_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,8 +63,8 @@ def test_return_bounds( ) -> None: """Test_return_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -77,6 +76,121 @@ def test_return_bounds( gas_limit=9223372036854775807, ) + # Source: lll + # { (RETURN 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffff 0) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffff 0) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffff 0) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffffffffffffffffffffffff 0) } + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, size=0x0) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x0, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xfffffff) } + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffff) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffffffffffff) } + addr_9 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xfffffffffffffffffffffffffff) } + addr_10 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr_11 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0x0, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffff 0xfffffff) } + addr_12 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFF, size=0xFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffff 0xffffffff) } + addr_13 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFF, size=0xFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffff 0xffffffffffffffff) } + addr_14 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0xFFFFFFFFFFFFFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffffffffffffffffffffffff 0xfffffffffffffffffffffffffff) } + addr_15 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr_16 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + nonce=0, + ) # Source: lll # { [[1]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[2]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[3]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[4]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[5]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[6]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[7]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[8]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[9]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[10]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[11]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[12]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[13]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[14]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[15]] (CALL 0x7ffffffffffffff 0 0 0 0 0) [[16]] (CALL 0x7ffffffffffffff 0 0 0 0 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +198,7 @@ def test_return_bounds( key=0x1, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x5EFBF04D8E1CC5B6B3719B16B5744A09BACFC18B, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -96,7 +210,7 @@ def test_return_bounds( key=0x2, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0xC7AA750FE05C7E38475A49FE98A301024D0C1D54, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -108,7 +222,7 @@ def test_return_bounds( key=0x3, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0xFF6B6D23BE161344E86EB7B174ACEDD4B1DC6DC7, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x0, @@ -120,7 +234,7 @@ def test_return_bounds( key=0x4, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x7BBCF24C83493C4E733CB54079B51873D3211AD2, + address=addr_4, value=0x0, args_offset=0x0, args_size=0x0, @@ -132,7 +246,7 @@ def test_return_bounds( key=0x5, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x7A4461AC9F9CD13F40F9514A7C60E23A71C1DFF3, + address=addr_5, value=0x0, args_offset=0x0, args_size=0x0, @@ -144,7 +258,7 @@ def test_return_bounds( key=0x6, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -156,7 +270,7 @@ def test_return_bounds( key=0x7, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -168,7 +282,7 @@ def test_return_bounds( key=0x8, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -180,7 +294,7 @@ def test_return_bounds( key=0x9, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -192,7 +306,7 @@ def test_return_bounds( key=0xA, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -204,7 +318,7 @@ def test_return_bounds( key=0xB, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -216,7 +330,7 @@ def test_return_bounds( key=0xC, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -228,7 +342,7 @@ def test_return_bounds( key=0xD, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -240,7 +354,7 @@ def test_return_bounds( key=0xE, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -252,7 +366,7 @@ def test_return_bounds( key=0xF, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -264,7 +378,7 @@ def test_return_bounds( key=0x10, value=Op.CALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -274,141 +388,6 @@ def test_return_bounds( ) + Op.STOP, nonce=0, - address=Address(0xD66A0237EE5D25106FC05BC767734BDDBA1FAB35), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x5EFBF04D8E1CC5B6B3719B16B5744A09BACFC18B), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffff 0) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0xC7AA750FE05C7E38475A49FE98A301024D0C1D54), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffff 0) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0xFF6B6D23BE161344E86EB7B174ACEDD4B1DC6DC7), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffff 0) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x7BBCF24C83493C4E733CB54079B51873D3211AD2), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffffffffffffffffffffffff 0) } - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, size=0x0) - + Op.STOP, - nonce=0, - address=Address(0x7A4461AC9F9CD13F40F9514A7C60E23A71C1DFF3), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x0, - ) - + Op.STOP, - nonce=0, - address=Address(0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xfffffff) } - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x7266F1C07958D55CE36DE0592604F1A915BDF1C2), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffff) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x2CEB88D6C420E5C65593D9EBED9A25600AB9E113), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffffffffffff) } - addr_9 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x0B09CA4308585F026B8D02BE147FEA0739EC463A), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xfffffffffffffffffffffffffff) } - addr_10 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF) - + Op.STOP, - nonce=0, - address=Address(0xF519DE4DCB9AAA53F8F0DB9B18C715C928CAADE8), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr_11 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0x0, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - nonce=0, - address=Address(0x28463490948D21EFC49949B4D394989BF52C57F1), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffff 0xfffffff) } - addr_12 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFF, size=0xFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x07084994C5891B1467D74BEDB0477DA4909E4C0E), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffff 0xffffffff) } - addr_13 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFF, size=0xFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0xAD7754A8A56CC5AD4E319FA94194E435628DEE67), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffff 0xffffffffffffffff) } - addr_14 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0xFFFFFFFFFFFFFFFF) - + Op.STOP, - nonce=0, - address=Address(0x416408C1D7FDA274DDEB45FFE4817068808121CA), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffffffffffffffffffffffff 0xfffffffffffffffffffffffffff) } - addr_15 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, - ) - + Op.STOP, - nonce=0, - address=Address(0x2548BDA95A3831ABCD613F4D24E4634615A71CCA), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr_16 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - nonce=0, - address=Address(0x76006C948F3A0529479C6D18A6F95908426E8092), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stMemoryStressTest/test_sload_bounds.py b/tests/ported_static/stMemoryStressTest/test_sload_bounds.py index 9681a7f4ba1..1c04ca420b1 100644 --- a/tests/ported_static/stMemoryStressTest/test_sload_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_sload_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_sload_bounds( ) -> None: """Test_sload_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xFE5BE118AD5955E30E0FFC4E1F1BBDCAA7F5A67CB1426C4AC19E32C80ECCDC06 - ) + sender = pre.fund_eoa(amount=0x7FFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -80,9 +77,7 @@ def test_sload_bounds( ) + Op.STOP, nonce=0, - address=Address(0x1B71C198EA09541AFB8301905A0A80D026EBFA17), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stMemoryStressTest/test_sstore_bounds.py b/tests/ported_static/stMemoryStressTest/test_sstore_bounds.py index 6f7fd2d5bb3..3aee2e858ab 100644 --- a/tests/ported_static/stMemoryStressTest/test_sstore_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_sstore_bounds.py @@ -71,6 +71,7 @@ def test_sstore_bounds( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) # Source: lll # { (SSTORE 0xffffffff 1) (SSTORE 0xffffffffffffffff 1) (SSTORE 0xffffffffffffffffffffffffffffffff 1) (SSTORE 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) (SSTORE 32 0xffffffff) (SSTORE 64 0xffffffffffffffff) (SSTORE 128 0xffffffffffffffffffffffffffffffff) (SSTORE 256 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -92,7 +93,6 @@ def test_sstore_bounds( nonce=0, address=Address(0x1F2AEE312C3C47BDEB27FF5275FDDB33C543E394), # noqa: E501 ) - pre[sender] = Account(balance=0x7FFFFFFFFFFFFFFFFFF) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryStressTest/test_static_call_bounds.py b/tests/ported_static/stMemoryStressTest/test_static_call_bounds.py index 63e769b4b73..c6a2e86cb91 100644 --- a/tests/ported_static/stMemoryStressTest/test_static_call_bounds.py +++ b/tests/ported_static/stMemoryStressTest/test_static_call_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_static_call_bounds( ) -> None: """Test_static_call_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,13 +67,20 @@ def test_static_call_bounds( gas_limit=9223372036854775807, ) + # Source: lll + # { (MSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (STATICCALL 0x7ffffffffffffff 0 0 0 0) (STATICCALL 0x7ffffffffffffff 0 0xfffffff 0 0xfffffff) (STATICCALL 0x7ffffffffffffff 0 0xffffffff 0 0xffffffff) (STATICCALL 0x7ffffffffffffff 0xfffffff 0 0xfffffff 0) (STATICCALL 0x7ffffffffffffff 0xffffffff 0 0xffffffff 0) (STATICCALL 0x7ffffffffffffff 0xffffffffffffffff 0 0xffffffffffffffff 0) (STATICCALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0) (STATICCALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -84,7 +90,7 @@ def test_static_call_bounds( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0x0, args_size=0xFFFFFFF, ret_offset=0x0, @@ -94,7 +100,7 @@ def test_static_call_bounds( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0x0, args_size=0xFFFFFFFF, ret_offset=0x0, @@ -104,7 +110,7 @@ def test_static_call_bounds( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFF, @@ -114,7 +120,7 @@ def test_static_call_bounds( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFFF, @@ -124,7 +130,7 @@ def test_static_call_bounds( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFFFFFFFFFFF, @@ -134,7 +140,7 @@ def test_static_call_bounds( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0x0, ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -143,7 +149,7 @@ def test_static_call_bounds( ) + Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0x0, ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -151,18 +157,6 @@ def test_static_call_bounds( ) + Op.STOP, nonce=0, - address=Address(0x7F91C742985AC295DA40F3771A1BE98F99F6A357), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0xCC704D60C46B9C08AAB4D15281184441AC7ED35C), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_static_call_bounds2.py b/tests/ported_static/stMemoryStressTest/test_static_call_bounds2.py index d9c6d90404b..b4d70c3de24 100644 --- a/tests/ported_static/stMemoryStressTest/test_static_call_bounds2.py +++ b/tests/ported_static/stMemoryStressTest/test_static_call_bounds2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_static_call_bounds2( ) -> None: """Test_static_call_bounds2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,12 +67,19 @@ def test_static_call_bounds2( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (STATICCALL 0x7ffffffffffffff 0xfffffff 0xfffffff 0xfffffff 0xfffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFF, args_size=0xFFFFFFF, ret_offset=0xFFFFFFF, @@ -81,18 +87,6 @@ def test_static_call_bounds2( ) + Op.STOP, nonce=0, - address=Address(0x897C36DFFCE5CC08EB13170A6C308AB09FA72E65), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_static_call_bounds2a.py b/tests/ported_static/stMemoryStressTest/test_static_call_bounds2a.py index 1247a29948e..c27269691ae 100644 --- a/tests/ported_static/stMemoryStressTest/test_static_call_bounds2a.py +++ b/tests/ported_static/stMemoryStressTest/test_static_call_bounds2a.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_static_call_bounds2a( ) -> None: """Test_static_call_bounds2a.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,12 +67,19 @@ def test_static_call_bounds2a( gas_limit=9223372036854775807, ) + # Source: lll + # { (SSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (STATICCALL 0x7ffffffffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x849F53126ADE5F72469029537296F2B6644D4D41, + address=addr, args_offset=0xFFFFFFFF, args_size=0xFFFFFFFF, ret_offset=0xFFFFFFFF, @@ -81,18 +87,6 @@ def test_static_call_bounds2a( ) + Op.STOP, nonce=0, - address=Address(0x9EDF5834C8B457164C7D203E17DF72D92D384DBA), # noqa: E501 - ) - # Source: lll - # { (SSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0x849F53126ADE5F72469029537296F2B6644D4D41), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryStressTest/test_static_call_bounds3.py b/tests/ported_static/stMemoryStressTest/test_static_call_bounds3.py index 8a2b2e5a3e5..fe5980fd434 100644 --- a/tests/ported_static/stMemoryStressTest/test_static_call_bounds3.py +++ b/tests/ported_static/stMemoryStressTest/test_static_call_bounds3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,8 +54,8 @@ def test_static_call_bounds3( ) -> None: """Test_static_call_bounds3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xEF111BBDAB3A1622936AFDFC9BBEC4B5BC05B4FA4B1EF0CE2A55CEF552F7650E + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) env = Environment( @@ -68,13 +67,20 @@ def test_static_call_bounds3( gas_limit=9223372036854775807, ) + # Source: lll + # { (MSTORE 0 (ADD 1 (SLOAD 0))) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: lll # { (STATICCALL 0x7ffffffffffffff 0 0xffffffffffffffff 0 0xffffffffffffffff) (STATICCALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffff) (STATICCALL 0x7ffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (STATICCALL 0x7ffffffffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff) (STATICCALL 0x7ffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff) (STATICCALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffff) (STATICCALL 0x7ffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFF, ret_offset=0x0, @@ -84,7 +90,7 @@ def test_static_call_bounds3( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ret_offset=0x0, @@ -94,7 +100,7 @@ def test_static_call_bounds3( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0x0, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 ret_offset=0x0, @@ -104,7 +110,7 @@ def test_static_call_bounds3( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFF, args_size=0xFFFFFFFF, ret_offset=0xFFFFFFFF, @@ -114,7 +120,7 @@ def test_static_call_bounds3( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFF, ret_offset=0xFFFFFFFFFFFFFFFF, @@ -124,7 +130,7 @@ def test_static_call_bounds3( + Op.POP( Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, @@ -133,7 +139,7 @@ def test_static_call_bounds3( ) + Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xCC704D60C46B9C08AAB4D15281184441AC7ED35C, + address=addr, args_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 args_size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 ret_offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 @@ -141,18 +147,6 @@ def test_static_call_bounds3( ) + Op.STOP, nonce=0, - address=Address(0x83143406093D1F3560DD269416596D3406F1C991), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (ADD 1 (SLOAD 0))) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0xCC704D60C46B9C08AAB4D15281184441AC7ED35C), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) tx_data = [ diff --git a/tests/ported_static/stMemoryTest/test_buffer.py b/tests/ported_static/stMemoryTest/test_buffer.py index 52ded431cbb..e8eb1086eaf 100644 --- a/tests/ported_static/stMemoryTest/test_buffer.py +++ b/tests/ported_static/stMemoryTest/test_buffer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -2139,9 +2138,7 @@ def test_buffer( contract_1 = Address(0x000000000000000000000000000000000F30C0DE) contract_2 = Address(0x000000000000000000000000000000000FF0C0DE) contract_3 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -2435,7 +2432,7 @@ def test_buffer( + Op.JUMP(pc=0x2C0) + Op.JUMPDEST + Op.EXTCODECOPY( - address=0xC0DE, + address=contract_0, dest_offset=Op.MLOAD(offset=0x2040), offset=0x0, size=Op.MLOAD(offset=0x2020), @@ -2536,7 +2533,7 @@ def test_buffer( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xC0DE, + address=contract_0, value=0x0, args_offset=Op.MLOAD(offset=0x2040), args_size=Op.MLOAD(offset=0x2020), @@ -2553,7 +2550,7 @@ def test_buffer( + Op.JUMPDEST + Op.CALL( gas=0x1000, - address=0xC0DE, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -2570,7 +2567,7 @@ def test_buffer( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xC0DE, + address=contract_0, value=0x0, args_offset=Op.MLOAD(offset=0x2040), args_size=Op.MLOAD(offset=0x2020), @@ -2587,7 +2584,7 @@ def test_buffer( + Op.JUMPDEST + Op.CALLCODE( gas=0x1000, - address=0xC0DE, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -2604,7 +2601,7 @@ def test_buffer( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x100000, - address=0xC0DE, + address=contract_0, args_offset=Op.MLOAD(offset=0x2040), args_size=Op.MLOAD(offset=0x2020), ret_offset=0x0, @@ -2620,7 +2617,7 @@ def test_buffer( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x100000, - address=0xC0DE, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=Op.MLOAD(offset=0x2040), @@ -2650,7 +2647,7 @@ def test_buffer( + Op.JUMPDEST + Op.STATICCALL( gas=0x100000, - address=0xC0DE, + address=contract_0, args_offset=Op.MLOAD(offset=0x2040), args_size=Op.MLOAD(offset=0x2020), ret_offset=0x0, @@ -2666,7 +2663,7 @@ def test_buffer( + Op.JUMPDEST + Op.STATICCALL( gas=0x100000, - address=0xC0DE, + address=contract_0, args_offset=0x0, args_size=0x0, ret_offset=Op.MLOAD(offset=0x2040), @@ -2683,7 +2680,7 @@ def test_buffer( + Op.POP( Op.CALL( gas=0x1000, - address=0xC0DE, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -2705,7 +2702,7 @@ def test_buffer( + Op.JUMPDEST + Op.CALL( gas=0x100000, - address=0xF30C0DE, + address=contract_1, value=0x0, args_offset=0x2020, args_size=0x40, @@ -2723,7 +2720,7 @@ def test_buffer( + Op.POP( Op.CALL( gas=0x100000, - address=0xFF0C0DE, + address=contract_2, value=0x0, args_offset=0x2020, args_size=0x40, @@ -2738,9 +2735,7 @@ def test_buffer( storage={256: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryTest/test_buffer_src_offset.py b/tests/ported_static/stMemoryTest/test_buffer_src_offset.py index c95f7c6c8e8..1a644f966f1 100644 --- a/tests/ported_static/stMemoryTest/test_buffer_src_offset.py +++ b/tests/ported_static/stMemoryTest/test_buffer_src_offset.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -769,9 +768,7 @@ def test_buffer_src_offset( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x000000000000000000000000000000000000C0DE) contract_1 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -994,7 +991,7 @@ def test_buffer_src_offset( + Op.JUMP(pc=0x22A) + Op.JUMPDEST + Op.EXTCODECOPY( - address=0xC0DE, + address=contract_0, dest_offset=Op.MLOAD(offset=0x2040), offset=Op.MLOAD(offset=0x2020), size=Op.MLOAD(offset=0x2060), @@ -1021,7 +1018,7 @@ def test_buffer_src_offset( + Op.POP( Op.CALL( gas=0x1000, - address=0xC0DE, + address=contract_0, value=0x0, args_offset=0x0, args_size=0x0, @@ -1050,9 +1047,7 @@ def test_buffer_src_offset( storage={256: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryTest/test_call_data_copy_offset.py b/tests/ported_static/stMemoryTest/test_call_data_copy_offset.py index 808fb053b47..2cd7a467e4b 100644 --- a/tests/ported_static/stMemoryTest/test_call_data_copy_offset.py +++ b/tests/ported_static/stMemoryTest/test_call_data_copy_offset.py @@ -48,6 +48,7 @@ def test_call_data_copy_offset( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0x00 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALLDATACOPY 0x00 0xffff 0x10) (SSTORE 0x00 (MLOAD 0x00)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,7 @@ def test_call_data_copy_offset( code=Op.MSTORE(offset=0x0, value=0x123456789ABCDEF) + Op.CALL( gas=0xFFFF, - address=0xEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP2, args_size=0xF, @@ -80,7 +81,6 @@ def test_call_data_copy_offset( nonce=1, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu.py b/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu.py index bc80056ad0e..362489d30fb 100644 --- a/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_calldatacopy_dejavu( ) -> None: """Test_calldatacopy_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_calldatacopy_dejavu( + Op.CALLDATACOPY(dest_offset=0xFFFFFFF, offset=0xFFFFFFF, size=0xFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCB76EF53A4EB6CCF604DAED675E91DF8A0B544F8), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu2.py b/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu2.py index e2652c917cc..f1b4ce171f7 100644 --- a/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu2.py +++ b/tests/ported_static/stMemoryTest/test_calldatacopy_dejavu2.py @@ -46,6 +46,7 @@ def test_calldatacopy_dejavu2( gas_limit=52949672960, ) + pre[sender] = Account(balance=0x271000000000) # Source: yul # berlin { mstore8(0x1f, 0x42) calldatacopy(0x1f, 0, 0x0103) let mem := mload(0) if eq(mem,0x60) { stop() } sstore(0xff, 0x0badc0ffee) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -59,7 +60,6 @@ def test_calldatacopy_dejavu2( nonce=0, address=Address(0xD6A7F80046F7576FA76EE5198426097F149E60FF), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_code_copy_offset.py b/tests/ported_static/stMemoryTest/test_code_copy_offset.py index 4157cc3c343..36b096523aa 100644 --- a/tests/ported_static/stMemoryTest/test_code_copy_offset.py +++ b/tests/ported_static/stMemoryTest/test_code_copy_offset.py @@ -46,6 +46,7 @@ def test_code_copy_offset( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0x00 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CODECOPY 0x00 0xffff 0x10) (SSTORE 0x00 (MLOAD 0x00)) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -66,7 +67,7 @@ def test_code_copy_offset( code=Op.MSTORE(offset=0x0, value=0x123456789ABCDEF) + Op.CALL( gas=0xFFFF, - address=0x27D16E1D3CC862149F1E7162E612635FCAEF9FF4, + address=addr, value=Op.DUP1, args_offset=Op.DUP2, args_size=0xF, @@ -78,7 +79,6 @@ def test_code_copy_offset( nonce=1, address=Address(0xAF89A7504341A87E1CFDFFD483A00A4688469B3D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_codecopy_dejavu.py b/tests/ported_static/stMemoryTest/test_codecopy_dejavu.py index ed7f3b2985a..0d5a8167151 100644 --- a/tests/ported_static/stMemoryTest/test_codecopy_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_codecopy_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_codecopy_dejavu( ) -> None: """Test_codecopy_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_codecopy_dejavu( + Op.CODECOPY(dest_offset=0xFFFFFFF, offset=0xFFFFFFF, size=0xFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8719757D888E6B73B95B8873672380186FF72D55), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_codecopy_dejavu2.py b/tests/ported_static/stMemoryTest/test_codecopy_dejavu2.py index ce6082b30e3..0899770f06b 100644 --- a/tests/ported_static/stMemoryTest/test_codecopy_dejavu2.py +++ b/tests/ported_static/stMemoryTest/test_codecopy_dejavu2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_codecopy_dejavu2( ) -> None: """Test_codecopy_dejavu2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_codecopy_dejavu2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC165257D26F9435CBD00D8E2825FF173393D3B31), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_extcodecopy_dejavu.py b/tests/ported_static/stMemoryTest/test_extcodecopy_dejavu.py index 31a783644ec..2b3503f4af9 100644 --- a/tests/ported_static/stMemoryTest/test_extcodecopy_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_extcodecopy_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_extcodecopy_dejavu( ) -> None: """Test_extcodecopy_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_extcodecopy_dejavu( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE15245403DDC4D3674436CF955358A73D67E226A), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_log1_dejavu.py b/tests/ported_static/stMemoryTest/test_log1_dejavu.py index 835aeab49ca..179a5c1a3ca 100644 --- a/tests/ported_static/stMemoryTest/test_log1_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_log1_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log1_dejavu( ) -> None: """Test_log1_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_log1_dejavu( code=Op.LOG1(offset=0xFFFFFFF, size=0xFF, topic_1=0xFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2E5DD28ACE62CB4FC05FC800DED494A6275107AC), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_log2_dejavu.py b/tests/ported_static/stMemoryTest/test_log2_dejavu.py index 76ed2629490..5d6f925646d 100644 --- a/tests/ported_static/stMemoryTest/test_log2_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_log2_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log2_dejavu( ) -> None: """Test_log2_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_log2_dejavu( code=Op.PUSH1[0xFF] * 2 + Op.PUSH4[0xFFFFFFF] + Op.LOG2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x38AC6CCFFB48040475CF67E7040ADEBB1DD11DEC), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_log3_dejavu.py b/tests/ported_static/stMemoryTest/test_log3_dejavu.py index fc1d2fae01e..c51230ca359 100644 --- a/tests/ported_static/stMemoryTest/test_log3_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_log3_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log3_dejavu( ) -> None: """Test_log3_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_log3_dejavu( code=Op.LOG2(offset=0xFFFFFFF, size=0xFF, topic_1=0xFF, topic_2=0xFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD1D57042B5AF54C18E8AD98B2756C1C30C08D5C1), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_log4_dejavu.py b/tests/ported_static/stMemoryTest/test_log4_dejavu.py index 844f5bf40ff..8b6757fc42b 100644 --- a/tests/ported_static/stMemoryTest/test_log4_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_log4_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_log4_dejavu( ) -> None: """Test_log4_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_log4_dejavu( code=Op.LOG2(offset=0xFFFFFFF, size=0xFF, topic_1=0xFF, topic_2=0xFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD1D57042B5AF54C18E8AD98B2756C1C30C08D5C1), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem0b_single_byte.py b/tests/ported_static/stMemoryTest/test_mem0b_single_byte.py index 73200b18818..843515cd61a 100644 --- a/tests/ported_static/stMemoryTest/test_mem0b_single_byte.py +++ b/tests/ported_static/stMemoryTest/test_mem0b_single_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem0b_single_byte( ) -> None: """Test_mem0b_single_byte.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem0b_single_byte( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1C10357A4309C879B65E6A761586A2D2762F4510), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem31b_single_byte.py b/tests/ported_static/stMemoryTest/test_mem31b_single_byte.py index c05ccf2b724..bfcb48d6313 100644 --- a/tests/ported_static/stMemoryTest/test_mem31b_single_byte.py +++ b/tests/ported_static/stMemoryTest/test_mem31b_single_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem31b_single_byte( ) -> None: """Test_mem31b_single_byte.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem31b_single_byte( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAB348FDB607AE2689A4738D1161DDE14F01B206B), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32b_single_byte.py b/tests/ported_static/stMemoryTest/test_mem32b_single_byte.py index 8d346a01797..10a1a44be41 100644 --- a/tests/ported_static/stMemoryTest/test_mem32b_single_byte.py +++ b/tests/ported_static/stMemoryTest/test_mem32b_single_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32b_single_byte( ) -> None: """Test_mem32b_single_byte.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32b_single_byte( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5F920D21D87930A31D9F34E893E46F9D24AE98BF), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb.py b/tests/ported_static/stMemoryTest/test_mem32kb.py index 59af8049672..6abb8684567 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb( ) -> None: """Test_mem32kb.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x61EE8FDB26DDFD9F99F1089A4196985009F1C2B5), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_minus_1.py b/tests/ported_static/stMemoryTest/test_mem32kb_minus_1.py index 417ad97e39f..d33ac793bf9 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_minus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_minus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_minus_1( ) -> None: """Test_mem32kb_minus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_minus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCDB6A2DB045D5F57D702F7F2B31B763A48E93012), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_minus_31.py b/tests/ported_static/stMemoryTest/test_mem32kb_minus_31.py index 578163a878a..d02c97eac67 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_minus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_minus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_minus_31( ) -> None: """Test_mem32kb_minus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_minus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB46476112BE03A9D0EA0E5C2D87FD734EE2C2687), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_minus_32.py b/tests/ported_static/stMemoryTest/test_mem32kb_minus_32.py index c03ea765aef..1093a4f54f6 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_minus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_minus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_minus_32( ) -> None: """Test_mem32kb_minus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_minus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6486AA041FF3591199AC99568935ECAEE0B3ACFA), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_minus_33.py b/tests/ported_static/stMemoryTest/test_mem32kb_minus_33.py index 11f30ef4685..64cbdd9afc7 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_minus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_minus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_minus_33( ) -> None: """Test_mem32kb_minus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_minus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4FD3D54F0B8734358798F93F9206E3D2CA5642A5), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_plus_1.py b/tests/ported_static/stMemoryTest/test_mem32kb_plus_1.py index a2157ea5d05..dafcda655e8 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_plus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_plus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_plus_1( ) -> None: """Test_mem32kb_plus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_plus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x458BB38FF5220DB011D56827C1346B799C1C409D), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_plus_31.py b/tests/ported_static/stMemoryTest/test_mem32kb_plus_31.py index f42a12f4a21..e7485db550c 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_plus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_plus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_plus_31( ) -> None: """Test_mem32kb_plus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_plus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAC6D4CB03FBB766035268AAF36604A5BF6EB5D04), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_plus_32.py b/tests/ported_static/stMemoryTest/test_mem32kb_plus_32.py index 08b768dbecd..729337fa8ea 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_plus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_plus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_plus_32( ) -> None: """Test_mem32kb_plus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_plus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB73F7199EF3863783B117A38DBD30D67E44F29E7), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_plus_33.py b/tests/ported_static/stMemoryTest/test_mem32kb_plus_33.py index 34d100d09a9..f571510af1e 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_plus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_plus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_plus_33( ) -> None: """Test_mem32kb_plus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem32kb_plus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x06B8C6BBDA80245D64A2D903E0D864A6EE862270), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte.py index cc9a9cebc71..c44e45cc506 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte( ) -> None: """Test_mem32kb_single_byte.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x341D86929D1B27823501662866E6233246F72ECC), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_1.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_1.py index 4790033d442..27b8314fe8a 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_minus_1( ) -> None: """Test_mem32kb_single_byte_minus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_minus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4310553BBFDF1433D24739581D21601557C480F6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_31.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_31.py index b169fee89d2..f66669a5a5c 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_minus_31( ) -> None: """Test_mem32kb_single_byte_minus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_minus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA66B4A1CC854F0B1AC130E79071CA4D277ABB87D), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_32.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_32.py index 6f015e7922b..8750a2af20d 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_minus_32( ) -> None: """Test_mem32kb_single_byte_minus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_minus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3EFC5CDD351CC21217FA684A05526F34B6D79729), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_33.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_33.py index 50d006c3125..da15d33663d 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_minus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_minus_33( ) -> None: """Test_mem32kb_single_byte_minus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_minus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6D7E35221D9D5F6E4A2B09ED59E10F64CA3C2257), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_1.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_1.py index 0649d3951a1..34345e79be7 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_plus_1( ) -> None: """Test_mem32kb_single_byte_plus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_plus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA6D38BB472A2B1A04CBCBD484EE16EDC3F4062DE), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_31.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_31.py index 605c285179c..583fc5f103a 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_plus_31( ) -> None: """Test_mem32kb_single_byte_plus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_plus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x924A0400505752C6DAC9F040C259A232D60E5BB4), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_32.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_32.py index e4bf57c7438..a2bd740ed36 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_plus_32( ) -> None: """Test_mem32kb_single_byte_plus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_plus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC7DA3537800028DF78D2869D4DB3100E84387ED4), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_33.py b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_33.py index ab196e3db2a..556f398db04 100644 --- a/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem32kb_single_byte_plus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem32kb_single_byte_plus_33( ) -> None: """Test_mem32kb_single_byte_plus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem32kb_single_byte_plus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8C60EAE101B125F477522D98DE262B98AC2786F9), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem33b_single_byte.py b/tests/ported_static/stMemoryTest/test_mem33b_single_byte.py index 09525b3a82f..46c75434094 100644 --- a/tests/ported_static/stMemoryTest/test_mem33b_single_byte.py +++ b/tests/ported_static/stMemoryTest/test_mem33b_single_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem33b_single_byte( ) -> None: """Test_mem33b_single_byte.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem33b_single_byte( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3F4D3ABB658B6063FAAE1D1515CFF8A434104677), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb.py b/tests/ported_static/stMemoryTest/test_mem64kb.py index c89e8c120c9..e21071e1249 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb( ) -> None: """Test_mem64kb.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x723656B1F4A75E4C7E382335E836D393D8A9E8CF), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_minus_1.py b/tests/ported_static/stMemoryTest/test_mem64kb_minus_1.py index f9880640c9d..22383d2a177 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_minus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_minus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_minus_1( ) -> None: """Test_mem64kb_minus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_minus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1AADC0C1DBDA9E85F5829FDCA5FDA372982164B0), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_minus_31.py b/tests/ported_static/stMemoryTest/test_mem64kb_minus_31.py index b302ef9fa93..98293337bae 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_minus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_minus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_minus_31( ) -> None: """Test_mem64kb_minus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_minus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC500D8B6A0AC6A677DBB818B03D5D596DA40C315), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_minus_32.py b/tests/ported_static/stMemoryTest/test_mem64kb_minus_32.py index a7417aa3e97..2b119c33641 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_minus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_minus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_minus_32( ) -> None: """Test_mem64kb_minus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_minus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x243CB187EA7A138CC5A6344C376D789C066A89C8), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_minus_33.py b/tests/ported_static/stMemoryTest/test_mem64kb_minus_33.py index 59589fd43c3..67241de1f79 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_minus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_minus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_minus_33( ) -> None: """Test_mem64kb_minus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_minus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3D7B73D4373952117FD84E96937007F34F914DAD), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_plus_1.py b/tests/ported_static/stMemoryTest/test_mem64kb_plus_1.py index d2d317a222f..5991bb0989d 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_plus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_plus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_plus_1( ) -> None: """Test_mem64kb_plus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_plus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x079111606E69DD3101AC45527BCDE41FB2C251E2), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_plus_31.py b/tests/ported_static/stMemoryTest/test_mem64kb_plus_31.py index 7a71faaf8f8..8d556ff6c7f 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_plus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_plus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_plus_31( ) -> None: """Test_mem64kb_plus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_plus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF3C68586EE37CB1C2D59DA9BA004DBEEF51F5CA6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_plus_32.py b/tests/ported_static/stMemoryTest/test_mem64kb_plus_32.py index c3e690395d8..465babad461 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_plus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_plus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_plus_32( ) -> None: """Test_mem64kb_plus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_plus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x72A9FFC9E1EA4E32148240CCB6816EC75795C3E2), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_plus_33.py b/tests/ported_static/stMemoryTest/test_mem64kb_plus_33.py index 1c63e52731b..4c63e0333b9 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_plus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_plus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_plus_33( ) -> None: """Test_mem64kb_plus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -55,9 +52,7 @@ def test_mem64kb_plus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6DFF7C00A64065EF56EB10F2E51EA77EAFC75BA3), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte.py index 73c1ee4d9ad..e095fa5ded9 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte( ) -> None: """Test_mem64kb_single_byte.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6C0CF9E7FBA0563117DBF01F9126777D60BC54B4), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_1.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_1.py index b18bd0e5826..6bf456d288f 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_minus_1( ) -> None: """Test_mem64kb_single_byte_minus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_minus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE6E541EED2E0E281FCD02D4130C5FBEB077E1147), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_31.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_31.py index 8ea3ed36850..b211c18b6f7 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_minus_31( ) -> None: """Test_mem64kb_single_byte_minus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_minus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4926E43CCE3C8681C244E6E6768D3E74995A5FAF), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_32.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_32.py index d97e0c82175..e79769c8d96 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_minus_32( ) -> None: """Test_mem64kb_single_byte_minus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_minus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x901876228E9BA4F968788B6E9EBA80E7EC7D91F9), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_33.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_33.py index 9acd0ff2274..00a4b9e6adf 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_minus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_minus_33( ) -> None: """Test_mem64kb_single_byte_minus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_minus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFB3508C998CC4F73516F89AF816422663EE3C87A), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_1.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_1.py index d83c54ab8e4..9f92d0fea32 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_1.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_plus_1( ) -> None: """Test_mem64kb_single_byte_plus_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_plus_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9C7B05F885F77026B10380EA29D2214B1A0DADDB), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_31.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_31.py index bd6b0b75629..434a6dda64e 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_31.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_plus_31( ) -> None: """Test_mem64kb_single_byte_plus_31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_plus_31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAE623ECFAFD38D21B0994049C19F434543C942C7), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_32.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_32.py index 460afe8beb5..f8b36bbe824 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_32.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_32.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_plus_32( ) -> None: """Test_mem64kb_single_byte_plus_32.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_plus_32( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDB97D5421507F0363F22C3E3F307D51D0D6D0DB0), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_33.py b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_33.py index f882f465dc2..89d78adcb29 100644 --- a/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_33.py +++ b/tests/ported_static/stMemoryTest/test_mem64kb_single_byte_plus_33.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem64kb_single_byte_plus_33( ) -> None: """Test_mem64kb_single_byte_plus_33.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem64kb_single_byte_plus_33( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA251D3C4B8E301CC8690335BFB85C771220191C6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem_copy_self.py b/tests/ported_static/stMemoryTest/test_mem_copy_self.py index 1f8656c59e0..6db803aed00 100644 --- a/tests/ported_static/stMemoryTest/test_mem_copy_self.py +++ b/tests/ported_static/stMemoryTest/test_mem_copy_self.py @@ -46,6 +46,7 @@ def test_mem_copy_self( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) # Source: yul # berlin # { @@ -105,7 +106,6 @@ def test_mem_copy_self( nonce=1, address=Address(0xB595300AC049B84C5277C7CA68A96D74AE377B85), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mem_return.py b/tests/ported_static/stMemoryTest/test_mem_return.py index 2230c7b0776..458c2148704 100644 --- a/tests/ported_static/stMemoryTest/test_mem_return.py +++ b/tests/ported_static/stMemoryTest/test_mem_return.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mem_return( ) -> None: """Test_mem_return.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_mem_return( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x80349881D6A01127FFE2A32D172EE0599D94C87E), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mload16bit_bound.py b/tests/ported_static/stMemoryTest/test_mload16bit_bound.py index 65e59615f5a..fb8e930d5df 100644 --- a/tests/ported_static/stMemoryTest/test_mload16bit_bound.py +++ b/tests/ported_static/stMemoryTest/test_mload16bit_bound.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mload16bit_bound( ) -> None: """Test_mload16bit_bound.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA9DF11BD92FC8535FFCA3AE0A2133C80D5F4ECC5D31D100B94FF03E63F7E74FF - ) + sender = pre.fund_eoa(amount=0xA00050281798) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_mload16bit_bound( code=Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x10000)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x85EAA01AC6288C06360D431D62CD865C92B74A28), # noqa: E501 ) - pre[sender] = Account(balance=0xA00050281798) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mload8bit_bound.py b/tests/ported_static/stMemoryTest/test_mload8bit_bound.py index 24054d9d614..8c3f579959f 100644 --- a/tests/ported_static/stMemoryTest/test_mload8bit_bound.py +++ b/tests/ported_static/stMemoryTest/test_mload8bit_bound.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mload8bit_bound( ) -> None: """Test_mload8bit_bound.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_mload8bit_bound( code=Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x100)) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xADEA3CDF2C1F0EFD3DB876810AA68CBCD58D7693), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mload_dejavu.py b/tests/ported_static/stMemoryTest/test_mload_dejavu.py index bfd2ef385bc..ae1d9c0d283 100644 --- a/tests/ported_static/stMemoryTest/test_mload_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_mload_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mload_dejavu( ) -> None: """Test_mload_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_mload_dejavu( code=Op.MLOAD(offset=0xFFFFFFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEA3899B6A7DB8734111AF8B25F6D873E1D14870D), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mstore_dejavu.py b/tests/ported_static/stMemoryTest/test_mstore_dejavu.py index 63430d68a1d..4c99760786c 100644 --- a/tests/ported_static/stMemoryTest/test_mstore_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_mstore_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mstore_dejavu( ) -> None: """Test_mstore_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_mstore_dejavu( code=Op.MSTORE(offset=0xFFFFFFF, value=0xF1), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x31FE53A538F8D289FA848C04EDC3664468340362), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_mstroe8_dejavu.py b/tests/ported_static/stMemoryTest/test_mstroe8_dejavu.py index 45645a89e6a..98f8977abc4 100644 --- a/tests/ported_static/stMemoryTest/test_mstroe8_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_mstroe8_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_mstroe8_dejavu( ) -> None: """Test_mstroe8_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_mstroe8_dejavu( code=Op.MSTORE8(offset=0xFFFFFFF, value=0xF1), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xABF77E5B1365493306A9A197D08677715B84CA69), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_oog.py b/tests/ported_static/stMemoryTest/test_oog.py index 47be00cab5c..5c2f1cc4f01 100644 --- a/tests/ported_static/stMemoryTest/test_oog.py +++ b/tests/ported_static/stMemoryTest/test_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -322,9 +321,7 @@ def test_oog( contract_20 = Address(0x00000000000000000000000000000000000100FA) contract_21 = Address(0x00000000000000000000000000000000000111F1) contract_22 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE, nonce=1) env = Environment( fee_recipient=coinbase, @@ -389,32 +386,6 @@ def test_oog( # Source: yul # berlin # { - # // Make sure there is return data to be copied - # pop(call(gas(), 0x1113e, 0, 0, 0x20, 0, 0x20)) - # - # returndatacopy(0x1000,0,0x10) - # } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.CALL( - gas=Op.GAS, - address=0x1113E, - value=Op.DUP1, - args_offset=Op.DUP2, - args_size=Op.DUP2, - ret_offset=0x0, - ret_size=0x20, - ) - ) - + Op.RETURNDATACOPY(dest_offset=0x1000, offset=0x0, size=0x10) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x000000000000000000000000000000000001003E), # noqa: E501 - ) - # Source: yul - # berlin - # { # mstore(0, 0x0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20) # noqa: E501 # return(0,0x20) # } @@ -565,6 +536,70 @@ def test_oog( # Source: yul # berlin # { + # stop() + # } + contract_21 = pre.deploy_contract( # noqa: F841 + code=Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x00000000000000000000000000000000000111F1), # noqa: E501 + ) + # Source: yul + # berlin + # { + # let op := calldataload(0x04) + # let gasAmt := calldataload(0x24) + # + # // Call the function that actually goes OOG (or not) + # sstore(0, call(gasAmt, add(0x10000,op), 0, 0, 0, 0, 0)) + # } + contract_22 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=Op.CALLDATALOAD(offset=0x24), + address=Op.ADD(Op.CALLDATALOAD(offset=0x4), 0x10000), + value=Op.DUP1, + args_offset=Op.DUP1, + args_size=Op.DUP1, + ret_offset=Op.DUP1, + ret_size=0x0, + ), + ) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 + ) + # Source: yul + # berlin + # { + # // Make sure there is return data to be copied + # pop(call(gas(), 0x1113e, 0, 0, 0x20, 0, 0x20)) + # + # returndatacopy(0x1000,0,0x10) + # } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.CALL( + gas=Op.GAS, + address=0x1113E, + value=Op.DUP1, + args_offset=Op.DUP2, + args_size=Op.DUP2, + ret_offset=0x0, + ret_size=0x20, + ) + ) + + Op.RETURNDATACOPY(dest_offset=0x1000, offset=0x0, size=0x10) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=1, + address=Address(0x000000000000000000000000000000000001003E), # noqa: E501 + ) + # Source: yul + # berlin + # { # pop(call(gas(), 0x111f1, 0, 0x10000, 0, 0, 0)) # } contract_17 = pre.deploy_contract( # noqa: F841 @@ -585,13 +620,12 @@ def test_oog( # Source: yul # berlin # { - # pop(callcode(gas(), 0x111f1, 0, 0x10000, 0, 0, 0)) + # pop(staticcall(gas(), 0x111f1, 0x10000, 0, 0, 0)) # } - contract_18 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( + contract_20 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( gas=Op.GAS, address=0x111F1, - value=Op.DUP2, args_offset=0x10000, args_size=Op.DUP1, ret_offset=Op.DUP1, @@ -600,7 +634,7 @@ def test_oog( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x00000000000000000000000000000000000100F2), # noqa: E501 + address=Address(0x00000000000000000000000000000000000100FA), # noqa: E501 ) # Source: yul # berlin @@ -624,12 +658,13 @@ def test_oog( # Source: yul # berlin # { - # pop(staticcall(gas(), 0x111f1, 0x10000, 0, 0, 0)) + # pop(callcode(gas(), 0x111f1, 0, 0x10000, 0, 0, 0)) # } - contract_20 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( + contract_18 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( gas=Op.GAS, address=0x111F1, + value=Op.DUP2, args_offset=0x10000, args_size=Op.DUP1, ret_offset=Op.DUP1, @@ -638,47 +673,8 @@ def test_oog( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x00000000000000000000000000000000000100FA), # noqa: E501 - ) - # Source: yul - # berlin - # { - # stop() - # } - contract_21 = pre.deploy_contract( # noqa: F841 - code=Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0x00000000000000000000000000000000000111F1), # noqa: E501 - ) - # Source: yul - # berlin - # { - # let op := calldataload(0x04) - # let gasAmt := calldataload(0x24) - # - # // Call the function that actually goes OOG (or not) - # sstore(0, call(gasAmt, add(0x10000,op), 0, 0, 0, 0, 0)) - # } - contract_22 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=Op.CALLDATALOAD(offset=0x24), - address=Op.ADD(Op.CALLDATALOAD(offset=0x4), 0x10000), - value=Op.DUP1, - args_offset=Op.DUP1, - args_size=Op.DUP1, - ret_offset=Op.DUP1, - ret_size=0x0, - ), - ) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=1, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 + address=Address(0x00000000000000000000000000000000000100F2), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stMemoryTest/test_sha3_dejavu.py b/tests/ported_static/stMemoryTest/test_sha3_dejavu.py index 31969392158..71ea3d8f864 100644 --- a/tests/ported_static/stMemoryTest/test_sha3_dejavu.py +++ b/tests/ported_static/stMemoryTest/test_sha3_dejavu.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sha3_dejavu( ) -> None: """Test_sha3_dejavu.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x7DD1D0EC78FE936B0E88F8C21226F51F048579915C7BAFF1C5D7FD84B2139BF1 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_sha3_dejavu( code=Op.SHA3(offset=0xFFFFFFF, size=0xFF), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA9B85B894D15D75175CE20CC2D6810154894110C), # noqa: E501 ) - pre[sender] = Account(balance=0x271000000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_gas_1023.py b/tests/ported_static/stMemoryTest/test_stack_limit_gas_1023.py index 2c8c21b2e1c..b00ed4ee67b 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_gas_1023.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_gas_1023.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_gas_1023( ) -> None: """Test_stack_limit_gas_1023.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -57,9 +54,7 @@ def test_stack_limit_gas_1023( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEE5DE953F398CD2615E0067F1071541730357EBF), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_gas_1024.py b/tests/ported_static/stMemoryTest/test_stack_limit_gas_1024.py index 78ec7171a20..7ce6abe11e0 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_gas_1024.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_gas_1024.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_gas_1024( ) -> None: """Test_stack_limit_gas_1024.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -57,9 +54,7 @@ def test_stack_limit_gas_1024( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB2B4442B80EDD3930F9D8A8696794672FBEEBFD0), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_gas_1025.py b/tests/ported_static/stMemoryTest/test_stack_limit_gas_1025.py index 76007c44876..29ee60d63d2 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_gas_1025.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_gas_1025.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_gas_1025( ) -> None: """Test_stack_limit_gas_1025.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -57,9 +54,7 @@ def test_stack_limit_gas_1025( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6498D2DA4FC198B991F2214160A3CE0E5438F3E4), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_push31_1023.py b/tests/ported_static/stMemoryTest/test_stack_limit_push31_1023.py index 54666231af9..c021f1a041e 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_push31_1023.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_push31_1023.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_push31_1023( ) -> None: """Test_stack_limit_push31_1023.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_stack_limit_push31_1023( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x887FE5A55A7BE422CAF5816B6721C8BB9F8ABBCB), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_push31_1024.py b/tests/ported_static/stMemoryTest/test_stack_limit_push31_1024.py index 9e8c2657854..e3b1790cc4e 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_push31_1024.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_push31_1024.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_push31_1024( ) -> None: """Test_stack_limit_push31_1024.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_stack_limit_push31_1024( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBCC7FF917E8EDB8DCB3F445B38E466370C684661), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_push31_1025.py b/tests/ported_static/stMemoryTest/test_stack_limit_push31_1025.py index ce5a47f2480..e1927888e80 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_push31_1025.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_push31_1025.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_push31_1025( ) -> None: """Test_stack_limit_push31_1025.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_stack_limit_push31_1025( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x176570409B578ECDAC49079AAE3F1C743FE50853), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_push32_1023.py b/tests/ported_static/stMemoryTest/test_stack_limit_push32_1023.py index cd7ef1c2d56..64916cb0e05 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_push32_1023.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_push32_1023.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_push32_1023( ) -> None: """Test_stack_limit_push32_1023.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_stack_limit_push32_1023( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x34B65BADF9EFCA4FEBC588C255DCFBF8D256E1F0), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_push32_1024.py b/tests/ported_static/stMemoryTest/test_stack_limit_push32_1024.py index f5162482b22..c75f16d85e3 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_push32_1024.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_push32_1024.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_push32_1024( ) -> None: """Test_stack_limit_push32_1024.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_stack_limit_push32_1024( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6ACB6452D5C01D94259FCC0138D1CB14977B5E7E), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stMemoryTest/test_stack_limit_push32_1025.py b/tests/ported_static/stMemoryTest/test_stack_limit_push32_1025.py index ad03979b9a1..5d72f2a638c 100644 --- a/tests/ported_static/stMemoryTest/test_stack_limit_push32_1025.py +++ b/tests/ported_static/stMemoryTest/test_stack_limit_push32_1025.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_stack_limit_push32_1025( ) -> None: """Test_stack_limit_push32_1025.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_stack_limit_push32_1025( + Op.STOP * 2, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3A584DFB85485C7DA4F7F6203D4AA78E8C40295A), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_empty_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_empty_paris.py index c0a9490e04a..fcfb431e5b8 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_empty_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_non_zero_value_call_to_empty_paris( ) -> None: """Test_non_zero_value_call_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_non_zero_value_call_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (CALL 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_non_zero_value_call_to_empty_paris( key=0x1, value=Op.CALL( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -70,9 +66,7 @@ def test_non_zero_value_call_to_empty_paris( + Op.STOP, balance=1000, nonce=0, - address=Address(0xF6029618CF51CA5236AFC14EAD1FBE0739573C23), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_non_non_zero_balance.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_non_non_zero_balance.py index 2e76021f28b..462c93ae2ae 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_non_non_zero_balance.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_non_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_non_zero_value_call_to_non_non_zero_balance( ) -> None: """Test_non_zero_value_call_to_non_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_non_zero_value_call_to_non_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (CALL 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_non_zero_value_call_to_non_non_zero_balance( key=0x1, value=Op.CALL( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -69,9 +65,7 @@ def test_non_zero_value_call_to_non_non_zero_balance( + Op.SSTORE(key=0x64, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x4ABD26A4E64C75F89EF76DE6649D66B4929919EC), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_one_storage_key_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_one_storage_key_paris.py index 5bf5653c0c8..76dd7cdb2ba 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_one_storage_key_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_call_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_non_zero_value_call_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [0](GAS) [[1]] (CALL 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -72,7 +73,6 @@ def test_non_zero_value_call_to_one_storage_key_paris( nonce=0, address=Address(0xF6029618CF51CA5236AFC14EAD1FBE0739573C23), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_empty_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_empty_paris.py index 71778a04ec9..36f7f5f9c28 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_empty_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_non_zero_value_callcode_to_empty_paris( ) -> None: """Test_non_zero_value_callcode_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x85B89DB0E2AEF2A23F50801209A3DE4C65C58D9D) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_non_zero_value_callcode_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (CALLCODE 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_non_zero_value_callcode_to_empty_paris( key=0x1, value=Op.CALLCODE( gas=0xEA60, - address=0x85B89DB0E2AEF2A23F50801209A3DE4C65C58D9D, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -70,9 +66,7 @@ def test_non_zero_value_callcode_to_empty_paris( + Op.STOP, balance=100, nonce=0, - address=Address(0x6DCDA83CA878DEC588C8CC2ADF0DEFBFF1C589B9), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_non_non_zero_balance.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_non_non_zero_balance.py index 32f170670e3..20ecf378e6b 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_non_non_zero_balance.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_non_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_non_zero_value_callcode_to_non_non_zero_balance( ) -> None: """Test_non_zero_value_callcode_to_non_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_non_zero_value_callcode_to_non_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (CALLCODE 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_non_zero_value_callcode_to_non_non_zero_balance( key=0x1, value=Op.CALLCODE( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -69,9 +65,7 @@ def test_non_zero_value_callcode_to_non_non_zero_balance( + Op.SSTORE(key=0x64, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x082A0810DA3F7A5B41A2D8291511FE800D7A021C), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_one_storage_key_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_one_storage_key_paris.py index c4a9e058a2c..24406f1746d 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_one_storage_key_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_callcode_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_non_zero_value_callcode_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [0](GAS) [[1]] (CALLCODE 60000 1 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -72,7 +73,6 @@ def test_non_zero_value_callcode_to_one_storage_key_paris( nonce=0, address=Address(0xB7BB61C75BE691459CEF9A8FD7EC074933FA1D1F), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_empty_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_empty_paris.py index be9986768fb..1c2a832d499 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_empty_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_non_zero_value_delegatecall_to_empty_paris( ) -> None: """Test_non_zero_value_delegatecall_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_non_zero_value_delegatecall_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_non_zero_value_delegatecall_to_empty_paris( key=0x1, value=Op.DELEGATECALL( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,9 +64,7 @@ def test_non_zero_value_delegatecall_to_empty_paris( + Op.SSTORE(key=0x64, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x9C1470E9F035F5D8F34D7C0FF2650F9F89DE43FE), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_non_non_zero_balance.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_non_non_zero_balance.py index 197f0ddb7e9..f4716bb2707 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_non_non_zero_balance.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_non_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_non_zero_value_delegatecall_to_non_non_zero_balance( ) -> None: """Test_non_zero_value_delegatecall_to_non_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_non_zero_value_delegatecall_to_non_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [0](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_non_zero_value_delegatecall_to_non_non_zero_balance( key=0x1, value=Op.DELEGATECALL( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,9 +64,7 @@ def test_non_zero_value_delegatecall_to_non_non_zero_balance( + Op.SSTORE(key=0x64, value=Op.SUB(Op.MLOAD(offset=0x0), Op.GAS)) + Op.STOP, nonce=0, - address=Address(0x9C1470E9F035F5D8F34D7C0FF2650F9F89DE43FE), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_one_storage_key_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_one_storage_key_paris.py index 022c431b1e6..59f545e4ace 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_one_storage_key_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_delegatecall_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_non_zero_value_delegatecall_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [0](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[100]] (SUB @0 (GAS)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_non_zero_value_delegatecall_to_one_storage_key_paris( nonce=0, address=Address(0x9C1470E9F035F5D8F34D7C0FF2650F9F89DE43FE), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_empty_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_empty_paris.py index 75df7269787..10199a820db 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_empty_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_empty_paris.py @@ -50,6 +50,7 @@ def test_non_zero_value_suicide_to_empty_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10) # Source: lll # { (SELFDESTRUCT ) } target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_non_zero_value_suicide_to_empty_paris( nonce=0, address=Address(0xEB9A4C7A191790631D13FC4927446F5EF9D201FC), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_non_non_zero_balance.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_non_non_zero_balance.py index ba77faa7fbc..3ba10da6dfc 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_non_non_zero_balance.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_non_non_zero_balance.py @@ -50,6 +50,7 @@ def test_non_zero_value_suicide_to_non_non_zero_balance( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=100) # Source: lll # { (SELFDESTRUCT ) } target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_non_zero_value_suicide_to_non_non_zero_balance( nonce=0, address=Address(0xEB9A4C7A191790631D13FC4927446F5EF9D201FC), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_one_storage_key_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_one_storage_key_paris.py index 4ca8cbba6e0..ee3e06ea5e1 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_one_storage_key_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_suicide_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_non_zero_value_suicide_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { (SELFDESTRUCT ) } target = pre.deploy_contract( # noqa: F841 @@ -62,7 +63,6 @@ def test_non_zero_value_suicide_to_one_storage_key_paris( nonce=0, address=Address(0xCF0486CE2ACF393729249BA0F9B3CFBE450DF9C3), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_empty_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_empty_paris.py index e3db6728ce0..14ca33fffcf 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_empty_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,17 +25,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_non_zero_value_transaction_cal_lwith_data_to_empty_paris( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_non_zero_value_transaction_cal_lwith_data_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +42,7 @@ def test_non_zero_value_transaction_cal_lwith_data_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance.py index f82893cc030..cb790534638 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,17 +25,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance.""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +42,7 @@ def test_non_zero_value_transaction_cal_lwith_data_to_non_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=100) + addr = pre.fund_eoa(amount=100) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_empty_paris.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_empty_paris.py index 095040893c2..66d1d845ec1 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_empty_paris.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -27,17 +26,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_non_zero_value_transaction_call_to_empty_paris( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_non_zero_value_transaction_call_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,8 +43,7 @@ def test_non_zero_value_transaction_call_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_non_non_zero_balance.py b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_non_non_zero_balance.py index 219911b6d67..91d139dce97 100644 --- a/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_non_non_zero_balance.py +++ b/tests/ported_static/stNonZeroCallsTest/test_non_zero_value_transaction_call_to_non_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -27,17 +26,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_non_zero_value_transaction_call_to_non_non_zero_balance( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_non_zero_value_transaction_call_to_non_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,8 +43,7 @@ def test_non_zero_value_transaction_call_to_non_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=100) + addr = pre.fund_eoa(amount=100) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts/test_modexp.py b/tests/ported_static/stPreCompiledContracts/test_modexp.py index a4c9a100a7b..982a98231e2 100644 --- a/tests/ported_static/stPreCompiledContracts/test_modexp.py +++ b/tests/ported_static/stPreCompiledContracts/test_modexp.py @@ -973,6 +973,7 @@ def test_modexp( gas_limit=10000000000, ) + pre[sender] = Account(balance=0x3635C9ADC5DEA00000) # Source: lll # { (CALLDATACOPY 0 0 (CALLDATASIZE)) [[1]] (CALLCODE (GAS) 5 0 0 (CALLDATASIZE) 1000 32) [[2]](MLOAD 1000) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -994,7 +995,6 @@ def test_modexp( nonce=0, address=Address(0x2D06AD61919840E4E00F80782DEDCE12ADA1E859), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stPreCompiledContracts/test_modexp_tests.py b/tests/ported_static/stPreCompiledContracts/test_modexp_tests.py index b8675dabb75..487eb639575 100644 --- a/tests/ported_static/stPreCompiledContracts/test_modexp_tests.py +++ b/tests/ported_static/stPreCompiledContracts/test_modexp_tests.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -810,9 +809,7 @@ def test_modexp_tests( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x48DC5A9F099CAAAA557742CA3A990A94BE45B9969126A1BC74E5E8BE5A2B5B47 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE, nonce=1) env = Environment( fee_recipient=coinbase, @@ -882,9 +879,7 @@ def test_modexp_tests( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x6082A22DBF403B1AF4FE03A0CCBD9BB78DEFB44A), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stPreCompiledContracts/test_precomps_eip2929_cancun.py b/tests/ported_static/stPreCompiledContracts/test_precomps_eip2929_cancun.py index 56378befc76..6bc03947432 100644 --- a/tests/ported_static/stPreCompiledContracts/test_precomps_eip2929_cancun.py +++ b/tests/ported_static/stPreCompiledContracts/test_precomps_eip2929_cancun.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -2808,7 +2807,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_precomps_eip2929_cancun( state_test: StateTestFiller, pre: Alloc, @@ -2819,9 +2817,7 @@ def test_precomps_eip2929_cancun( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -2832,6 +2828,24 @@ def test_precomps_eip2929_cancun( gas_limit=71794957647893862, ) + # Source: yul + # berlin + # { + # mstore(0,add(1,2)) + # } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x3) + Op.STOP, + nonce=1, + ) + # Source: yul + # berlin + # { + # mstore(0,add(1,2)) + # } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x3) + Op.STOP, + nonce=1, + ) # Source: yul # berlin optimise # { @@ -2876,7 +2890,7 @@ def test_precomps_eip2929_cancun( + Op.POP( Op.CALL( gas=0x100000, - address=0x7BE86FFAB69B0AF1ED862AE6D8E1EFA3E8438B79, + address=addr_2, value=0x1, args_offset=Op.DUP1, args_size=0x0, @@ -3565,29 +3579,7 @@ def test_precomps_eip2929_cancun( + Op.POP * 9, storage={0: 24743, 1: 24743}, nonce=1, - address=Address(0x858295015AFF9CFDB96C3C2EC19F7AC654871B6C), # noqa: E501 - ) - # Source: yul - # berlin - # { - # mstore(0,add(1,2)) - # } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x3) + Op.STOP, - nonce=1, - address=Address(0x1338F76642A7A19CC50BDFF45172CB6C2A7D20C0), # noqa: E501 - ) - # Source: yul - # berlin - # { - # mstore(0,add(1,2)) - # } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x3) + Op.STOP, - nonce=1, - address=Address(0x7BE86FFAB69B0AF1ED862AE6D8E1EFA3E8438B79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stPreCompiledContracts/test_sec80.py b/tests/ported_static/stPreCompiledContracts/test_sec80.py index b0a5de2af25..7f08f0420c8 100644 --- a/tests/ported_static/stPreCompiledContracts/test_sec80.py +++ b/tests/ported_static/stPreCompiledContracts/test_sec80.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sec80( ) -> None: """Test_sec80.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -95,9 +92,7 @@ def test_sec80( + Op.JUMP(pc=0x9), balance=0x1312D00, nonce=0, - address=Address(0x39C2FBD2D4E46FA75775649472DDB79E836160B0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0.py index de149aa5a2c..96a35affc1a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0.py @@ -47,6 +47,7 @@ def test_call_ecrecover0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_call_ecrecover0( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,14 +94,6 @@ def test_call_ecrecover0( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_0input.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_0input.py index 0f2b601cce9..5116b30b570 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_0input.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_0input.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_ecrecover0_0input( ) -> None: """Test_call_ecrecover0_0input.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -67,9 +64,7 @@ def test_call_ecrecover0_0input( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x6988D3CD2C65677341D1E302439627344DFB1C82), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_complete_return_value.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_complete_return_value.py index 90a04e42c17..6f44a02596c 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_complete_return_value.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_complete_return_value.py @@ -49,6 +49,7 @@ def test_call_ecrecover0_complete_return_value( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_call_ecrecover0_complete_return_value( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -93,13 +93,6 @@ def test_call_ecrecover0_complete_return_value( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas2999.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas2999.py index b58b7e89146..7252f2e85fb 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas2999.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas2999.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_ecrecover0_gas2999( ) -> None: """Test_call_ecrecover0_gas2999.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_call_ecrecover0_gas2999( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x34BC8D999C6FFD2DF1999D36424D37AA91286FA3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas3000.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas3000.py index d95b758fde6..d030a8f189e 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas3000.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_gas3000.py @@ -47,6 +47,7 @@ def test_call_ecrecover0_gas3000( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_call_ecrecover0_gas3000( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,14 +94,6 @@ def test_call_ecrecover0_gas3000( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_no_gas.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_no_gas.py index c2bb521a6c5..148ce74a70a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_no_gas.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_no_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_ecrecover0_no_gas( ) -> None: """Test_call_ecrecover0_no_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -82,9 +79,7 @@ def test_call_ecrecover0_no_gas( storage={0: 12, 1: 12, 2: 12}, balance=0x1312D00, nonce=0, - address=Address(0x9F2E40FCA484BDCF92B52E622EED58D6A3DF731F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_overlapping_input_output.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_overlapping_input_output.py index 2c23599a76f..38dc572832a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_overlapping_input_output.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover0_overlapping_input_output.py @@ -49,6 +49,7 @@ def test_call_ecrecover0_overlapping_input_output( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_call_ecrecover0_overlapping_input_output( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_call_ecrecover0_overlapping_input_output( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover1.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover1.py index 8f4c341d7ab..e2c3b6511c7 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover1.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_ecrecover1( ) -> None: """Test_call_ecrecover1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_call_ecrecover1( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x62549A73A158B67FDC175B0D94FC2826963FC3C2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover2.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover2.py index 03b12b13eee..e39aeb54a4f 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover2.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_ecrecover2( ) -> None: """Test_call_ecrecover2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_call_ecrecover2( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x42AA64FDFC0AF7140DA38474659AE0AB48ABA824), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover3.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover3.py index 832ba719e2e..fcae7ed32af 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover3.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover3.py @@ -46,6 +46,7 @@ def test_call_ecrecover3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_call_ecrecover3( nonce=0, address=Address(0x28D98D7CC227972A80FA4A16964272BF8738D792), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover80.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover80.py index 11ab45c55af..a24e67e9c17 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover80.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover80.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_ecrecover80( ) -> None: """Test_call_ecrecover80.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_call_ecrecover80( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xF5E90F13AA1637BA33175EA73221DD55443A6D5B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length.py index 0bd9f4717d7..adb6a64af72 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length.py @@ -49,6 +49,7 @@ def test_call_ecrecover_check_length( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 128 0x1122334455667788990011223344556677889900112233445566778899001122) (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) [[ 1 ]] (MSIZE) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -88,7 +89,6 @@ def test_call_ecrecover_check_length( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -98,14 +98,6 @@ def test_call_ecrecover_check_length( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 160, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 160, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length_wrong_v.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length_wrong_v.py index 53269df2492..6c31f8f8d4f 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length_wrong_v.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_check_length_wrong_v.py @@ -48,6 +48,7 @@ def test_call_ecrecover_check_length_wrong_v( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 128 0x1122334455667788990011223344556677889900112233445566778899001122) (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 29) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) [[ 1 ]] (MSIZE) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_call_ecrecover_check_length_wrong_v( nonce=0, address=Address(0x5CC93303C292C9573FA7DE40FF6281B18DBF491E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_h_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_h_prefixed0.py index cb33c065ef0..40d765e1dcc 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_h_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_h_prefixed0.py @@ -48,6 +48,7 @@ def test_call_ecrecover_h_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_call_ecrecover_h_prefixed0( nonce=0, address=Address(0x7B80A19CD6F97E5150A04B81956A57115C477C33), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_invalid_signature.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_invalid_signature.py index 298b6040045..8aeba668b39 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_invalid_signature.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_invalid_signature.py @@ -48,6 +48,7 @@ def test_call_ecrecover_invalid_signature( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 128 0x1122334455667788991011121314151617181920212223242526272829303132) (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -72,7 +73,6 @@ def test_call_ecrecover_invalid_signature( nonce=0, address=Address(0x2B8FD4ADB0602FE9EE5823B0576F619DAEFBD369), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_overflow.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_overflow.py index 8e8e11fb146..a2eaac17506 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_overflow.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_overflow.py @@ -108,6 +108,7 @@ def test_call_ecrecover_overflow( gas_limit=71794957647893862, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: yul # berlin # { @@ -137,7 +138,6 @@ def test_call_ecrecover_overflow( nonce=0, address=Address(0xDB8963071FEAE3B63E19D9D7AF8EE89A92E99356), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_r_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_r_prefixed0.py index 234dcdf9f4e..4410f66b67d 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_r_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_r_prefixed0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_ecrecover_r_prefixed0( ) -> None: """Test_call_ecrecover_r_prefixed0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -83,9 +80,7 @@ def test_call_ecrecover_r_prefixed0( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x0453735A25DF75808CCEB79D037904A5007C2058), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_s_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_s_prefixed0.py index 4a1eada93ba..66b679f89f9 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_s_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_s_prefixed0.py @@ -48,6 +48,7 @@ def test_call_ecrecover_s_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_call_ecrecover_s_prefixed0( nonce=0, address=Address(0xF292EC7B1106FBD3DF874A754F8C99155B961F92), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_unrecoverable_key.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_unrecoverable_key.py index 245f682cf5e..961c7e7c940 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_unrecoverable_key.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_unrecoverable_key.py @@ -48,6 +48,7 @@ def test_call_ecrecover_unrecoverable_key( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xa8b53bdf3306a35a7103ab5504a0c9b492295564b6202b1942a84ef300107281) (MSTORE 32 0x000000000000000000000000000000000000000000000000000000000000001b) (MSTORE 64 0x3078356531653033663533636531386237373263636230303933666637316633) (MSTORE 96 0x6635336635633735623734646362333161383561613862383839326234653862) (MSTORE 128 0x1122334455667788991011121314151617181920212223242526272829303132) (CALL 300000 1 0 0 128 128 32) (SSTORE 0 (MLOAD 128)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_call_ecrecover_unrecoverable_key( nonce=0, address=Address(0x85C44D846ED50AC9E384C1B575FD96F3EDF5751F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_v_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_v_prefixed0.py index a72ec373fe4..3ed45721580 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_v_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ecrecover_v_prefixed0.py @@ -49,6 +49,7 @@ def test_call_ecrecover_v_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 0x001c) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_call_ecrecover_v_prefixed0( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_call_ecrecover_v_prefixed0( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_1.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_1.py index 241f5d5da26..9db95d1b505 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_1.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_1.py @@ -46,6 +46,7 @@ def test_call_ripemd160_1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (CALL 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_call_ripemd160_1( nonce=0, address=Address(0xBB0A46F4D8842E6949FA40F7D4F5567213240BDE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_2.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_2.py index 26ab89c9d7c..a92de2d9538 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_2.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_2.py @@ -46,6 +46,7 @@ def test_call_ripemd160_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_call_ripemd160_2( nonce=0, address=Address(0x5DA48FFD1587258FB609ACEC343481BB238E2064), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3.py index 058c4289d20..08cc37fed3f 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3.py @@ -46,6 +46,7 @@ def test_call_ripemd160_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_call_ripemd160_3( nonce=0, address=Address(0x37120C525AAED676A19D7786C9296B708C0981E5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_postfixed0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_postfixed0.py index 5ec760e7f1d..d62b7ae7132 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_postfixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_postfixed0.py @@ -48,6 +48,7 @@ def test_call_ripemd160_3_postfixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_call_ripemd160_3_postfixed0( nonce=0, address=Address(0x0A7939B337794BF9784CA2EDBACCF4C289D2BD69), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_prefixed0.py index ebae76691ad..b457fd43897 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_3_prefixed0.py @@ -48,6 +48,7 @@ def test_call_ripemd160_3_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_call_ripemd160_3_prefixed0( nonce=0, address=Address(0x58FBC34303E81CFADD7D347E87E46B2D6CE7548F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4.py index e79a9da0ad0..ef89dddca53 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4.py @@ -46,6 +46,7 @@ def test_call_ripemd160_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 720 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_call_ripemd160_4( nonce=0, address=Address(0x93E74099C6B1CF5E73A1CDD021C6942F9A814D9B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4_gas719.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4_gas719.py index 16ecb86e620..2a5f10f0b84 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4_gas719.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_4_gas719.py @@ -46,6 +46,7 @@ def test_call_ripemd160_4_gas719( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 719 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_call_ripemd160_4_gas719( nonce=0, address=Address(0x061C5D0417A8B11331FAD2817630996289B925BF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_5.py b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_5.py index 8ffcc9a86f7..42b92783dca 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_5.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_ripemd160_5.py @@ -46,6 +46,7 @@ def test_call_ripemd160_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 6000 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_call_ripemd160_5( nonce=0, address=Address(0x51998B731842F87DAD142BFCC66310C3DC92C4FD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_0.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_0.py index e48a7f5ab82..9e87cccdb89 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_0.py @@ -46,6 +46,7 @@ def test_call_sha256_0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: hex # 0x600160005260206000602060006000600260fff1600051600055 target = pre.deploy_contract( # noqa: F841 @@ -64,7 +65,6 @@ def test_call_sha256_0( nonce=0, address=Address(0xDCDDAC785B7920159CF9AA510ECD630640710567), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1.py index d0c8134fba3..c36e97e91eb 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1.py @@ -46,6 +46,7 @@ def test_call_sha256_1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_call_sha256_1( nonce=0, address=Address(0x1E79F0FD2BB702C9FD72905DA2A5B109025FA4A6), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1_nonzero_value.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1_nonzero_value.py index 54af9a04fc6..9acde20fa83 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1_nonzero_value.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_1_nonzero_value.py @@ -48,6 +48,7 @@ def test_call_sha256_1_nonzero_value( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (CALL 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -69,7 +70,6 @@ def test_call_sha256_1_nonzero_value( nonce=0, address=Address(0x39BAF944BD1B21E643D8D207A7073EE34A5D2116), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_2.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_2.py index d3e7fdf33eb..e4fb44b8a0a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_2.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_2.py @@ -46,6 +46,7 @@ def test_call_sha256_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_call_sha256_2( nonce=0, address=Address(0x2558C91E1CA37007E96544E37E5348C5C209AE3D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3.py index e0d303b5831..0a8e95a99c9 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3.py @@ -46,6 +46,7 @@ def test_call_sha256_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_call_sha256_3( nonce=0, address=Address(0x5EF7A23F9BAEA93BD729FD89FDCE63578C13A01E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_postfix0.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_postfix0.py index b6856ba0ee1..8874981dc47 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_postfix0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_postfix0.py @@ -46,6 +46,7 @@ def test_call_sha256_3_postfix0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_call_sha256_3_postfix0( nonce=0, address=Address(0xDB90D5CD1BD42CE94A38B9D293AC7A1BE96ADEF9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_prefix0.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_prefix0.py index 35a0d74e6eb..23809f4456a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_prefix0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_3_prefix0.py @@ -46,6 +46,7 @@ def test_call_sha256_3_prefix0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_call_sha256_3_prefix0( nonce=0, address=Address(0x5D4B89A232555BC139AA244672611EDF28D276C7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4.py index a37438985fb..ec364d74c5c 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4.py @@ -46,6 +46,7 @@ def test_call_sha256_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_call_sha256_4( nonce=0, address=Address(0x6EAF78B8968E1AD784F281CC9FFC2ED8BDB61FBE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4_gas99.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4_gas99.py index c1108346f3f..fa8d6d5dbde 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4_gas99.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_4_gas99.py @@ -46,6 +46,7 @@ def test_call_sha256_4_gas99( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_call_sha256_4_gas99( nonce=0, address=Address(0x1B0415178117104203E61BE499A69BA4A5B2A3B9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_5.py b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_5.py index 28c7a236582..20914f28990 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_call_sha256_5.py +++ b/tests/ported_static/stPreCompiledContracts2/test_call_sha256_5.py @@ -46,6 +46,7 @@ def test_call_sha256_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_call_sha256_5( nonce=0, address=Address(0x66088F99C73AE9E87363561B19C69011205344D0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0.py index 3cff4226691..b80fc3a6fa8 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0.py @@ -47,6 +47,7 @@ def test_callcode_ecrecover0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_callcode_ecrecover0( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,14 +94,6 @@ def test_callcode_ecrecover0( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_0input.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_0input.py index d288553b762..0d540cb1ae4 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_0input.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_0input.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_ecrecover0_0input( ) -> None: """Test_callcode_ecrecover0_0input.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,9 +66,7 @@ def test_callcode_ecrecover0_0input( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xD87AADFE05DF880BC4C678F75154215CC6692D81), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_complete_return_value.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_complete_return_value.py index d062000bb96..41cbfc0a954 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_complete_return_value.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_complete_return_value.py @@ -49,6 +49,7 @@ def test_callcode_ecrecover0_complete_return_value( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 3000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_callcode_ecrecover0_complete_return_value( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -93,13 +93,6 @@ def test_callcode_ecrecover0_complete_return_value( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas2999.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas2999.py index 03787464191..8dc74be0591 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas2999.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas2999.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_ecrecover0_gas2999( ) -> None: """Test_callcode_ecrecover0_gas2999.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -83,9 +80,7 @@ def test_callcode_ecrecover0_gas2999( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xE70DCF2A2964DB146B6CB171326705F77B924943), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas3000.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas3000.py index 026596ffb8a..d5d73e659d1 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas3000.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_gas3000.py @@ -49,6 +49,7 @@ def test_callcode_ecrecover0_gas3000( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 3000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_callcode_ecrecover0_gas3000( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_callcode_ecrecover0_gas3000( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_no_gas.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_no_gas.py index 2dcd296562b..3c520af25f1 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_no_gas.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_no_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_ecrecover0_no_gas( ) -> None: """Test_callcode_ecrecover0_no_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -84,9 +81,7 @@ def test_callcode_ecrecover0_no_gas( storage={0: 12, 1: 12, 2: 12}, balance=0x1312D00, nonce=0, - address=Address(0x642B4BC6FE2E1633CAAF1AD06E473299ADB5CFD2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_overlapping_input_output.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_overlapping_input_output.py index 84bdc0e22b9..86850680e68 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_overlapping_input_output.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover0_overlapping_input_output.py @@ -49,6 +49,7 @@ def test_callcode_ecrecover0_overlapping_input_output( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_callcode_ecrecover0_overlapping_input_output( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_callcode_ecrecover0_overlapping_input_output( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover1.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover1.py index fdd07356ca9..e69d97a4675 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover1.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_ecrecover1( ) -> None: """Test_callcode_ecrecover1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_callcode_ecrecover1( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xC305C830833CCB72817F7B8B8D9C6D5645FC9E5F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover2.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover2.py index e576df9ffed..750675ab593 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover2.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_ecrecover2( ) -> None: """Test_callcode_ecrecover2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_callcode_ecrecover2( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x82FED9E1D9833BFED4D0DFAB03D1E35DBFFA4243), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover3.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover3.py index 6eb21a9f9d8..7281641e7aa 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover3.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover3.py @@ -46,6 +46,7 @@ def test_callcode_ecrecover3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALLCODE 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_callcode_ecrecover3( nonce=0, address=Address(0xFBEDF77EDB387C8E6D9B016F522D38201F4DE408), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover80.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover80.py index 26f83f07b5b..b65664bed6a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover80.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover80.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_ecrecover80( ) -> None: """Test_callcode_ecrecover80.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_callcode_ecrecover80( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xD5C4EA8FAA1028D8D10AA6BF9133E678D695B349), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_h_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_h_prefixed0.py index 34ff8b29e37..5af67bca2ee 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_h_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_h_prefixed0.py @@ -48,6 +48,7 @@ def test_callcode_ecrecover_h_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_callcode_ecrecover_h_prefixed0( nonce=0, address=Address(0x0E408D340F5CC7CB2602AD82D377DC8D849480BC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_r_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_r_prefixed0.py index 201ba47f434..4cf23a30a26 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_r_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_r_prefixed0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_ecrecover_r_prefixed0( ) -> None: """Test_callcode_ecrecover_r_prefixed0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -83,9 +80,7 @@ def test_callcode_ecrecover_r_prefixed0( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xB5EF5E7A96B20D5519B730BCA2E026BD49A95F3E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_s_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_s_prefixed0.py index 6d0887023b3..db3f82c5169 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_s_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_s_prefixed0.py @@ -48,6 +48,7 @@ def test_callcode_ecrecover_s_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_callcode_ecrecover_s_prefixed0( nonce=0, address=Address(0xEA150F7A83DC3C344EFB50FCA8FD1526B5D48935), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixed0.py index c006c842443..74faea77487 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixed0.py @@ -49,6 +49,7 @@ def test_callcode_ecrecover_v_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 0x001c) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_callcode_ecrecover_v_prefixed0( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_callcode_ecrecover_v_prefixed0( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixedf0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixedf0.py index 6b5113c3d54..faa4869ed6c 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixedf0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ecrecover_v_prefixedf0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,9 +56,7 @@ def test_callcode_ecrecover_v_prefixedf0( ) -> None: """Test_callcode_ecrecover_v_prefixedf0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -105,9 +102,7 @@ def test_callcode_ecrecover_v_prefixedf0( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xEBCDD28B5479DBDE3E8317EBAC82A6E019E256E4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(0xF01C), diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_0.py index 9a75d531f11..68d973a0d35 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_ripemd160_0( ) -> None: """Test_callcode_ripemd160_0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,9 +59,7 @@ def test_callcode_ripemd160_0( + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)), balance=0x1312D00, nonce=0, - address=Address(0x21C1AD575033F5EFBB9D40B78C24B18809902665), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_1.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_1.py index 195fce970ba..e4d89acbc75 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_1.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_1.py @@ -46,6 +46,7 @@ def test_callcode_ripemd160_1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (CALLCODE 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_callcode_ripemd160_1( nonce=0, address=Address(0xC2568EE355F0F71AA13FA54F6B01882D79A078C4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_2.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_2.py index 1d6efad3a6b..3eb132c2ce1 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_2.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_2.py @@ -46,6 +46,7 @@ def test_callcode_ripemd160_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 5 0xf34578907f) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_callcode_ripemd160_2( nonce=0, address=Address(0xB5505A4E16C6DC9A8F57A35F11D7A11FE0C62652), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3.py index 2d4cf574fa0..dfb5918c38a 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3.py @@ -46,6 +46,7 @@ def test_callcode_ripemd160_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_callcode_ripemd160_3( nonce=0, address=Address(0x8976B14FE4CDE9954494EC41AA275F87E2E13D0A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_postfixed0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_postfixed0.py index e9069da27ca..c9ae41cdee4 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_postfixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_postfixed0.py @@ -48,6 +48,7 @@ def test_callcode_ripemd160_3_postfixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_callcode_ripemd160_3_postfixed0( nonce=0, address=Address(0x4AE7F0A2D9EBEDE8E424C882C869DA67AC881DEB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_prefixed0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_prefixed0.py index 604a7271a32..2880463f03b 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_prefixed0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_3_prefixed0.py @@ -48,6 +48,7 @@ def test_callcode_ripemd160_3_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_callcode_ripemd160_3_prefixed0( nonce=0, address=Address(0x063102841B53CEA1BE51EBA298D1B86B90F7C071), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4.py index 3f65d961fa2..1a1f003383b 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4.py @@ -46,6 +46,7 @@ def test_callcode_ripemd160_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 720 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_callcode_ripemd160_4( nonce=0, address=Address(0x6E9A87C7B4F3D629DF2F099546D9250F1CCD92AF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4_gas719.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4_gas719.py index 1a5d86a9a98..ccfc5a27418 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4_gas719.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_4_gas719.py @@ -48,6 +48,7 @@ def test_callcode_ripemd160_4_gas719( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 719 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -73,7 +74,6 @@ def test_callcode_ripemd160_4_gas719( nonce=0, address=Address(0xE54144E08B2FAA0FB551D5DF635711386FD3E8F2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_5.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_5.py index b4bf188b266..4c0721cfd12 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_5.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_ripemd160_5.py @@ -46,6 +46,7 @@ def test_callcode_ripemd160_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 6000 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_callcode_ripemd160_5( nonce=0, address=Address(0x445F6977E8026D56E8B9A36B4CE7591EF0B9493A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_0.py index 1794e7cf29d..b1a4cf62997 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_0.py @@ -46,6 +46,7 @@ def test_callcode_sha256_0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: hex # 0x600160005260206000602060006000600260fff2600051600055 target = pre.deploy_contract( # noqa: F841 @@ -64,7 +65,6 @@ def test_callcode_sha256_0( nonce=0, address=Address(0xFAC135CDECD64B72CDA12C2B4764E9D4E474DE3E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1.py index 6c2a8829cd5..3aca9583c81 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1.py @@ -46,6 +46,7 @@ def test_callcode_sha256_1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (CALLCODE 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_callcode_sha256_1( nonce=0, address=Address(0xC4009BC3B312CE413BFB8734800AA7B54261856D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1_nonzero_value.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1_nonzero_value.py index 7236752cccf..88e216e0abd 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1_nonzero_value.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_1_nonzero_value.py @@ -48,6 +48,7 @@ def test_callcode_sha256_1_nonzero_value( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (CALLCODE 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -69,7 +70,6 @@ def test_callcode_sha256_1_nonzero_value( nonce=0, address=Address(0xA32D9AC4A5BA456F9E539AC5C756230EEBC72F85), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_2.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_2.py index a44f805e36b..83fb69530c9 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_2.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_2.py @@ -46,6 +46,7 @@ def test_callcode_sha256_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 5 0xf34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_callcode_sha256_2( nonce=0, address=Address(0x49EDFD0547A55D03FFB882894166FB4E19BCE699), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3.py index 9c448ae8fca..79347e7dbfb 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3.py @@ -46,6 +46,7 @@ def test_callcode_sha256_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_callcode_sha256_3( nonce=0, address=Address(0x66ADD49A7D6964132DEE6F9C01A7CE445976D7F1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_postfix0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_postfix0.py index 9ff3205b143..c924cc8ed2b 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_postfix0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_postfix0.py @@ -48,6 +48,7 @@ def test_callcode_sha256_3_postfix0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_callcode_sha256_3_postfix0( nonce=0, address=Address(0x47623157953751C765B038FEA97F26122EE130CA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_prefix0.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_prefix0.py index 41b0bdf16d5..b052e6d0650 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_prefix0.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_3_prefix0.py @@ -48,6 +48,7 @@ def test_callcode_sha256_3_prefix0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_callcode_sha256_3_prefix0( nonce=0, address=Address(0x350856CB8740C7A9F14DE1D4901111246CDBA0B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4.py index 51af5b40fa1..d69405bd039 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4.py @@ -46,6 +46,7 @@ def test_callcode_sha256_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_callcode_sha256_4( nonce=0, address=Address(0x081EB2E67904436211EEEF7B37055D5A08BF76B1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4_gas99.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4_gas99.py index 75b33067338..07205685dff 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4_gas99.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_4_gas99.py @@ -46,6 +46,7 @@ def test_callcode_sha256_4_gas99( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_callcode_sha256_4_gas99( nonce=0, address=Address(0xBDC43A81E62F216D623D3E91F1F5FE1E3730A068), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_5.py b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_5.py index d72b1fad837..9f4fb5580b6 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_5.py +++ b/tests/ported_static/stPreCompiledContracts2/test_callcode_sha256_5.py @@ -46,6 +46,7 @@ def test_callcode_sha256_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_callcode_sha256_5( nonce=0, address=Address(0x12D19AA9C20419BF0656FC7A93642F9CAFC744F4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_ecrecover_short_buff.py b/tests/ported_static/stPreCompiledContracts2/test_ecrecover_short_buff.py index 9acaa6fe2d2..cffcc678170 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_ecrecover_short_buff.py +++ b/tests/ported_static/stPreCompiledContracts2/test_ecrecover_short_buff.py @@ -47,6 +47,7 @@ def test_ecrecover_short_buff( gas_limit=71794957647893862, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) # Source: yul # berlin # { @@ -149,7 +150,6 @@ def test_ecrecover_short_buff( nonce=1, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stPreCompiledContracts2/test_ecrecover_weird_v.py b/tests/ported_static/stPreCompiledContracts2/test_ecrecover_weird_v.py index 72509eae8ce..3a607960508 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_ecrecover_weird_v.py +++ b/tests/ported_static/stPreCompiledContracts2/test_ecrecover_weird_v.py @@ -277,6 +277,7 @@ def test_ecrecover_weird_v( ) pre[coinbase] = Account(balance=0, nonce=1) + pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) # Source: yul # berlin # { @@ -315,7 +316,6 @@ def test_ecrecover_weird_v( nonce=1, address=Address(0x9121BB12ADE6BF12796E6007B21A204E05B1BD49), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_20500.py b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_20500.py index 5b5164d4e35..59e3af2c647 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_20500.py +++ b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_20500.py @@ -95,6 +95,78 @@ def test_modexp_0_0_0_20500( pre[sender] = Account(balance=0xDE0B6B3A761FE12, nonce=1) # Source: hex + # 0x + coinbase = pre.deploy_contract( # noqa: F841 + code="", + balance=0x201EE, + nonce=0, + address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 + ) + # Source: hex + # 0x + contract_1 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: hex + # 0x + contract_2 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 + ) + # Source: hex + # 0x + contract_3 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 + ) + # Source: hex + # 0x + contract_4 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 + ) + # Source: hex + # 0x + contract_5 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 + ) + # Source: hex + # 0x + contract_6 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 + ) + # Source: hex + # 0x + contract_7 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 + ) + # Source: hex + # 0x + contract_8 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 + ) + # Source: hex # 0x600035601c52740100000000000000000000000000000000000000006020526fffffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff000000000000000000000000000000016060527402540be3fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffdabf41c00000000000000000000000002540be40060a0526330c8d1da600051141561012b5760846004356004013511151558576004356004013560200160043560040161014037600161024061014051610160600060056305f5e0fff11558576001610220526102206021806102808284600060046015f150505061028080516020820120905060005561028060206020820352604081510160206001820306601f820103905060208203f350005b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1C, value=Op.CALLDATALOAD(offset=0x0)) @@ -189,78 +261,6 @@ def test_modexp_0_0_0_20500( nonce=1, address=Address(0xC305C901078781C232A2A521C2AF7980F8385EE9), # noqa: E501 ) - # Source: hex - # 0x - coinbase = pre.deploy_contract( # noqa: F841 - code="", - balance=0x201EE, - nonce=0, - address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 - ) - # Source: hex - # 0x - contract_1 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 - ) - # Source: hex - # 0x - contract_2 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 - ) - # Source: hex - # 0x - contract_3 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 - ) - # Source: hex - # 0x - contract_4 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 - ) - # Source: hex - # 0x - contract_5 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 - ) - # Source: hex - # 0x - contract_6 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 - ) - # Source: hex - # 0x - contract_7 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 - ) - # Source: hex - # 0x - contract_8 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_22000.py b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_22000.py index 5b3c05cf8c4..9390b7eb00c 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_22000.py +++ b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_22000.py @@ -92,6 +92,78 @@ def test_modexp_0_0_0_22000( pre[sender] = Account(balance=0xDE0B6B3A761FE12, nonce=1) # Source: hex + # 0x + coinbase = pre.deploy_contract( # noqa: F841 + code="", + balance=0x201EE, + nonce=0, + address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 + ) + # Source: hex + # 0x + contract_1 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: hex + # 0x + contract_2 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 + ) + # Source: hex + # 0x + contract_3 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 + ) + # Source: hex + # 0x + contract_4 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 + ) + # Source: hex + # 0x + contract_5 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 + ) + # Source: hex + # 0x + contract_6 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 + ) + # Source: hex + # 0x + contract_7 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 + ) + # Source: hex + # 0x + contract_8 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 + ) + # Source: hex # 0x600035601c52740100000000000000000000000000000000000000006020526fffffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff000000000000000000000000000000016060527402540be3fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffdabf41c00000000000000000000000002540be40060a0526330c8d1da600051141561012b5760846004356004013511151558576004356004013560200160043560040161014037600161024061014051610160600060056305f5e0fff11558576001610220526102206021806102808284600060046015f150505061028080516020820120905060005561028060206020820352604081510160206001820306601f820103905060208203f350005b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1C, value=Op.CALLDATALOAD(offset=0x0)) @@ -186,78 +258,6 @@ def test_modexp_0_0_0_22000( nonce=1, address=Address(0xC305C901078781C232A2A521C2AF7980F8385EE9), # noqa: E501 ) - # Source: hex - # 0x - coinbase = pre.deploy_contract( # noqa: F841 - code="", - balance=0x201EE, - nonce=0, - address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 - ) - # Source: hex - # 0x - contract_1 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 - ) - # Source: hex - # 0x - contract_2 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 - ) - # Source: hex - # 0x - contract_3 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 - ) - # Source: hex - # 0x - contract_4 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 - ) - # Source: hex - # 0x - contract_5 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 - ) - # Source: hex - # 0x - contract_6 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 - ) - # Source: hex - # 0x - contract_7 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 - ) - # Source: hex - # 0x - contract_8 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 - ) tx_data = [ Bytes("30c8d1da") diff --git a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_25000.py b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_25000.py index f807fd468bd..9ae5ef9d781 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_25000.py +++ b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_25000.py @@ -92,6 +92,78 @@ def test_modexp_0_0_0_25000( pre[sender] = Account(balance=0xDE0B6B3A761FE12, nonce=1) # Source: hex + # 0x + coinbase = pre.deploy_contract( # noqa: F841 + code="", + balance=0x201EE, + nonce=0, + address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 + ) + # Source: hex + # 0x + contract_1 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: hex + # 0x + contract_2 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 + ) + # Source: hex + # 0x + contract_3 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 + ) + # Source: hex + # 0x + contract_4 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 + ) + # Source: hex + # 0x + contract_5 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 + ) + # Source: hex + # 0x + contract_6 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 + ) + # Source: hex + # 0x + contract_7 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 + ) + # Source: hex + # 0x + contract_8 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 + ) + # Source: hex # 0x600035601c52740100000000000000000000000000000000000000006020526fffffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff000000000000000000000000000000016060527402540be3fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffdabf41c00000000000000000000000002540be40060a0526330c8d1da600051141561012b5760846004356004013511151558576004356004013560200160043560040161014037600161024061014051610160600060056305f5e0fff11558576001610220526102206021806102808284600060046015f150505061028080516020820120905060005561028060206020820352604081510160206001820306601f820103905060208203f350005b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1C, value=Op.CALLDATALOAD(offset=0x0)) @@ -186,78 +258,6 @@ def test_modexp_0_0_0_25000( nonce=1, address=Address(0xC305C901078781C232A2A521C2AF7980F8385EE9), # noqa: E501 ) - # Source: hex - # 0x - coinbase = pre.deploy_contract( # noqa: F841 - code="", - balance=0x201EE, - nonce=0, - address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 - ) - # Source: hex - # 0x - contract_1 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 - ) - # Source: hex - # 0x - contract_2 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 - ) - # Source: hex - # 0x - contract_3 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 - ) - # Source: hex - # 0x - contract_4 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 - ) - # Source: hex - # 0x - contract_5 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 - ) - # Source: hex - # 0x - contract_6 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 - ) - # Source: hex - # 0x - contract_7 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 - ) - # Source: hex - # 0x - contract_8 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 - ) tx_data = [ Bytes("30c8d1da") diff --git a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_35000.py b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_35000.py index 6e560ee537e..89b4b07c0e8 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_35000.py +++ b/tests/ported_static/stPreCompiledContracts2/test_modexp_0_0_0_35000.py @@ -92,6 +92,78 @@ def test_modexp_0_0_0_35000( pre[sender] = Account(balance=0xDE0B6B3A761FE12, nonce=1) # Source: hex + # 0x + coinbase = pre.deploy_contract( # noqa: F841 + code="", + balance=0x201EE, + nonce=0, + address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 + ) + # Source: hex + # 0x + contract_1 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: hex + # 0x + contract_2 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 + ) + # Source: hex + # 0x + contract_3 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 + ) + # Source: hex + # 0x + contract_4 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 + ) + # Source: hex + # 0x + contract_5 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 + ) + # Source: hex + # 0x + contract_6 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 + ) + # Source: hex + # 0x + contract_7 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 + ) + # Source: hex + # 0x + contract_8 = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 + ) + # Source: hex # 0x600035601c52740100000000000000000000000000000000000000006020526fffffffffffffffffffffffffffffffff6040527fffffffffffffffffffffffffffffffff000000000000000000000000000000016060527402540be3fffffffffffffffffffffffffdabf41c006080527ffffffffffffffffffffffffdabf41c00000000000000000000000002540be40060a0526330c8d1da600051141561012b5760846004356004013511151558576004356004013560200160043560040161014037600161024061014051610160600060056305f5e0fff11558576001610220526102206021806102808284600060046015f150505061028080516020820120905060005561028060206020820352604081510160206001820306601f820103905060208203f350005b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1C, value=Op.CALLDATALOAD(offset=0x0)) @@ -186,78 +258,6 @@ def test_modexp_0_0_0_35000( nonce=1, address=Address(0xC305C901078781C232A2A521C2AF7980F8385EE9), # noqa: E501 ) - # Source: hex - # 0x - coinbase = pre.deploy_contract( # noqa: F841 - code="", - balance=0x201EE, - nonce=0, - address=Address(0x3535353535353535353535353535353535353535), # noqa: E501 - ) - # Source: hex - # 0x - contract_1 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000001), # noqa: E501 - ) - # Source: hex - # 0x - contract_2 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000005), # noqa: E501 - ) - # Source: hex - # 0x - contract_3 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000008), # noqa: E501 - ) - # Source: hex - # 0x - contract_4 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000003), # noqa: E501 - ) - # Source: hex - # 0x - contract_5 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000006), # noqa: E501 - ) - # Source: hex - # 0x - contract_6 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000007), # noqa: E501 - ) - # Source: hex - # 0x - contract_7 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 - ) - # Source: hex - # 0x - contract_8 = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x0000000000000000000000000000000000000002), # noqa: E501 - ) tx_data = [ Bytes("30c8d1da") diff --git a/tests/ported_static/stPreCompiledContracts2/test_modexp_random_input.py b/tests/ported_static/stPreCompiledContracts2/test_modexp_random_input.py index 2840e3593cf..beb5e9d3a55 100644 --- a/tests/ported_static/stPreCompiledContracts2/test_modexp_random_input.py +++ b/tests/ported_static/stPreCompiledContracts2/test_modexp_random_input.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -68,7 +67,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_modexp_random_input( state_test: StateTestFiller, pre: Alloc, @@ -79,9 +77,7 @@ def test_modexp_random_input( ) -> None: """Fuzzed input discovered by Guido.""" coinbase = Address(0x3535353535353535353535353535353535353535) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -92,8 +88,6 @@ def test_modexp_random_input( gas_limit=100000000, ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) - tx_data = [ Bytes( "00000000000000000000000000000000000000000000000000000000000000e300000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call1_mb1024_calldepth.py b/tests/ported_static/stQuadraticComplexityTest/test_call1_mb1024_calldepth.py index 9753d9d8810..228828eea8c 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call1_mb1024_calldepth.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call1_mb1024_calldepth.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_call1_mb1024_calldepth( ) -> None: """Test_call1_mb1024_calldepth.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0x2AB8257767339461506C0C67824CF17BC77B52CA) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,8 +70,7 @@ def test_call1_mb1024_calldepth( gas_limit=882500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=0xFFFFFFFFFFFFF) + addr = pre.fund_eoa(amount=0xFFFFFFFFFFFFF) # noqa: F841 # Source: lll # { (def 'i 0x80) [[ 0 ]] (+ @@0 1) (if (LT @@0 1024) [[ 1 ]] (CALL (- (GAS) 1005000) 0 0 1000000 0 0) [[ 2 ]] 1 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_1.py b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_1.py index 95c49a5db4e..8d7d15a89d2 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_1.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_call20_kbytes_contract50_1( ) -> None: """Test_call20_kbytes_contract50_1.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,7 +71,6 @@ def test_call20_kbytes_contract50_1( gas_limit=882500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: raw # 0x6001600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600055 # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -83,7 +79,6 @@ def test_call20_kbytes_contract50_1( ), balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0xAE9C63D43225738DE8070CE25E1BE54F429DA182), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (CALL 88250000000 0 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 @@ -96,7 +91,7 @@ def test_call20_kbytes_contract50_1( key=0x0, value=Op.CALL( gas=0x148C1C2280, - address=0xAE9C63D43225738DE8070CE25E1BE54F429DA182, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -111,7 +106,6 @@ def test_call20_kbytes_contract50_1( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x8C9EC19D542269495230087C08602E5D70572FD5), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py index 02f27461722..e064cb3e94e 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_call20_kbytes_contract50_2( ) -> None: """Test_call20_kbytes_contract50_2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -75,7 +72,6 @@ def test_call20_kbytes_contract50_2( gas_limit=882500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: raw # 0x60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055 # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -85,7 +81,6 @@ def test_call20_kbytes_contract50_2( + Op.SSTORE(key=0x0, value=Op.ADD), balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0xE7EBAFA0FEA97A99A72B7F0996C07477E54DF0C2), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (CALL 88250000000 0 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 @@ -98,7 +93,7 @@ def test_call20_kbytes_contract50_2( key=0x0, value=Op.CALL( gas=0x148C1C2280, - address=0xE7EBAFA0FEA97A99A72B7F0996C07477E54DF0C2, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -113,7 +108,6 @@ def test_call20_kbytes_contract50_2( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x8C9EC19D542269495230087C08602E5D70572FD5), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_3.py b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_3.py index a64f8b0bfb8..172093e2818 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_3.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_call20_kbytes_contract50_3( ) -> None: """Potentially broken test: gas optimization shows that we can go as...""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -75,7 +72,6 @@ def test_call20_kbytes_contract50_3( gas_limit=882500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: raw # 0x6001614a8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055 # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -86,7 +82,6 @@ def test_call20_kbytes_contract50_3( + Op.SSTORE(key=0x0, value=Op.ADD), balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x2C496C63F4E9F426BFD41214147CDD3DCD2DE1C3), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (CALL 88250000000 0 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 @@ -99,7 +94,7 @@ def test_call20_kbytes_contract50_3( key=0x0, value=Op.CALL( gas=0x148C1C2280, - address=0x2C496C63F4E9F426BFD41214147CDD3DCD2DE1C3, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -114,7 +109,6 @@ def test_call20_kbytes_contract50_3( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x8C9EC19D542269495230087C08602E5D70572FD5), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call50000.py b/tests/ported_static/stQuadraticComplexityTest/test_call50000.py index 2d158c62b40..09054e27c25 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call50000.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call50000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_call50000( ) -> None: """Test_call50000.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,8 +70,7 @@ def test_call50000( gas_limit=860000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALL 1600 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +82,7 @@ def test_call50000( key=0x0, value=Op.CALL( gas=0x640, - address=0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0, + address=addr, value=0x1, args_offset=0x0, args_size=0xC350, @@ -102,7 +97,6 @@ def test_call50000( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x968A2606110EF719ED66F5E3688F6FB82D606FFA), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call50000_ecrec.py b/tests/ported_static/stQuadraticComplexityTest/test_call50000_ecrec.py index f536b3f8572..5ef0eba7901 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call50000_ecrec.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call50000_ecrec.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_call50000_ecrec( ) -> None: """Test_call50000_ecrec.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_call50000_ecrec( gas_limit=3000000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALL 500 1 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -100,7 +96,6 @@ def test_call50000_ecrec( + Op.STOP, balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, nonce=0, - address=Address(0x1C5BEF085B43F11A8A19AE08A0C20019E6D15236), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity.py b/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity.py index fcddf62356f..6d52d835c00 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_call50000_identity( ) -> None: """Test_call50000_identity.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_call50000_identity( gas_limit=882500000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALL 1564 4 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -100,7 +96,6 @@ def test_call50000_identity( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x25D58A9D3632EEA7B6146CDAA0B4D323A83A814E), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity2.py b/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity2.py index 77058afe23b..f2d27a68845 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity2.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call50000_identity2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_call50000_identity2( ) -> None: """Test_call50000_identity2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_call50000_identity2( gas_limit=882500000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (def 'i 0x80) [ 1 ] 42 (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALL 1564 4 1 0 50000 1 50000) ) [[ 1 ]] @i [[ 2 ]] @1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -102,7 +98,6 @@ def test_call50000_identity2( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x6DC17565113358633923F732D8C32382345D2D6F), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call50000_rip160.py b/tests/ported_static/stQuadraticComplexityTest/test_call50000_rip160.py index 8d3ee02644e..143a678a724 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call50000_rip160.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call50000_rip160.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_call50000_rip160( ) -> None: """Test_call50000_rip160.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_call50000_rip160( gas_limit=3925000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALL 78200 3 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -100,7 +96,6 @@ def test_call50000_rip160( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0xC10D84BAA3A4BB4E45C856EBE1EF386BFED327DB), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py b/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py index 59a73d24fbc..6d2ec3e0d83 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_callcode50000( ) -> None: """Test_callcode50000.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,8 +70,7 @@ def test_callcode50000( gas_limit=8600000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALLCODE 1600 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +82,7 @@ def test_callcode50000( key=0x0, value=Op.CALLCODE( gas=0x640, - address=0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0, + address=addr, value=0x1, args_offset=0x0, args_size=0xC350, @@ -102,7 +97,6 @@ def test_callcode50000( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x7FC89545BED7AF26B6EF809B53E9A93FD0718468), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stQuadraticComplexityTest/test_create1000.py b/tests/ported_static/stQuadraticComplexityTest/test_create1000.py index 0fd46530994..74c1e0f1112 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_create1000.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_create1000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_create1000( """Gas analysis showed this test's gas can go as low as 21053, and...""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_0 = Address(0xBBBF5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -75,7 +72,6 @@ def test_create1000( gas_limit=8600000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (def 'i 0x80) (for {} (< @i 1000) [i](+ @i 1) [[ 0 ]] (CREATE 1 0 50000) ) [[ 1 ]] @i} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -93,7 +89,6 @@ def test_create1000( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0xBBBF5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -101,30 +96,30 @@ def test_create1000( "indexes": {"data": -1, "gas": 0, "value": -1}, "network": [">=Cancun=Cancun=Cancun=Cancun None: """Test_random_statetest0.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest0( "7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff857ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1302056f60005155" # noqa: E501 ), nonce=0, - address=Address(0x3C2C1D569D955EE8D26CED4ADCD452C462A972AD), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest0( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest1.py b/tests/ported_static/stRandom/test_random_statetest1.py index bb480bae8d1..2d43d88fe21 100644 --- a/tests/ported_static/stRandom/test_random_statetest1.py +++ b/tests/ported_static/stRandom/test_random_statetest1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest1( """Test_random_statetest1.""" coinbase = Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest1( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest1( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest10.py b/tests/ported_static/stRandom/test_random_statetest10.py index 0e0b16c047b..f5c895545db 100644 --- a/tests/ported_static/stRandom/test_random_statetest10.py +++ b/tests/ported_static/stRandom/test_random_statetest10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest10( ) -> None: """Test_random_statetest10.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest10( "7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000000120417f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3508859a1740a0528f26a635216cd980a9a9255" # noqa: E501 ), nonce=0, - address=Address(0xA1941AE61E22D0850914D85E19B1BD7234265C66), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest10( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest100.py b/tests/ported_static/stRandom/test_random_statetest100.py index 148f44abbf9..4a17e601da9 100644 --- a/tests/ported_static/stRandom/test_random_statetest100.py +++ b/tests/ported_static/stRandom/test_random_statetest100.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest100( ) -> None: """Test_random_statetest100.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,7 +62,6 @@ def test_random_statetest100( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAC7AF608FDD0C1E915C85A0DDED54637285B93B0), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -83,7 +79,6 @@ def test_random_statetest100( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest102.py b/tests/ported_static/stRandom/test_random_statetest102.py index 9dc53197095..8301be48642 100644 --- a/tests/ported_static/stRandom/test_random_statetest102.py +++ b/tests/ported_static/stRandom/test_random_statetest102.py @@ -46,6 +46,23 @@ def test_random_statetest102( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457f00000000000000000000000044447f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f157094ffff1a04893a9cf3858b85765560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest102( nonce=0, address=Address(0x467DCDBF737C1EA416E75D9BC88E09533838889F), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest103.py b/tests/ported_static/stRandom/test_random_statetest103.py index e1809cc0f0a..40b67225a2c 100644 --- a/tests/ported_static/stRandom/test_random_statetest103.py +++ b/tests/ported_static/stRandom/test_random_statetest103.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest103( ) -> None: """Test_random_statetest103.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest103( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe92357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff597f00000000000000000000000000000000000000000000000000000000000000019385a39988160a205a93196d336428 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe92357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff597f00000000000000000000000000000000000000000000000000000000000000019385a39988160a205a93196d336428" # noqa: E501 - ), - nonce=0, - address=Address(0x7284C101C23E4AF67251BEEAAAFA61D3AC764B99), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest103( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe92357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff597f00000000000000000000000000000000000000000000000000000000000000019385a39988160a205a93196d336428 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe92357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff597f00000000000000000000000000000000000000000000000000000000000000019385a39988160a205a93196d336428" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest104.py b/tests/ported_static/stRandom/test_random_statetest104.py index eaf750378bf..afe9dcba48b 100644 --- a/tests/ported_static/stRandom/test_random_statetest104.py +++ b/tests/ported_static/stRandom/test_random_statetest104.py @@ -46,6 +46,7 @@ def test_random_statetest104( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f147d6b978c780a82619772417d5b6a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_random_statetest104( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest105.py b/tests/ported_static/stRandom/test_random_statetest105.py index ff83efee315..90f64842584 100644 --- a/tests/ported_static/stRandom/test_random_statetest105.py +++ b/tests/ported_static/stRandom/test_random_statetest105.py @@ -46,6 +46,23 @@ def test_random_statetest105( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f9914639111156d1759ff65039a02926c60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest105( nonce=0, address=Address(0x63CF59FFAAC800568AFBD0EEF9B295CF57A579EC), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest106.py b/tests/ported_static/stRandom/test_random_statetest106.py index 05b3b9c67bf..5ad21bb902b 100644 --- a/tests/ported_static/stRandom/test_random_statetest106.py +++ b/tests/ported_static/stRandom/test_random_statetest106.py @@ -46,6 +46,7 @@ def test_random_statetest106( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f327043726481f25094828e211557795560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest106( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest107.py b/tests/ported_static/stRandom/test_random_statetest107.py index 55d045b45c2..2f1309ef117 100644 --- a/tests/ported_static/stRandom/test_random_statetest107.py +++ b/tests/ported_static/stRandom/test_random_statetest107.py @@ -47,6 +47,23 @@ def test_random_statetest107( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b50960005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest107( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest108.py b/tests/ported_static/stRandom/test_random_statetest108.py index 77a3ec683a4..27eb868b255 100644 --- a/tests/ported_static/stRandom/test_random_statetest108.py +++ b/tests/ported_static/stRandom/test_random_statetest108.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest108( ) -> None: """Test_random_statetest108.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_random_statetest108( + Op.COINBASE, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF3C8D5EA3CE820D6B26253D4D1D9106008C757DB), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -74,7 +70,6 @@ def test_random_statetest108( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest11.py b/tests/ported_static/stRandom/test_random_statetest11.py index ec46da9bb86..72d45df370e 100644 --- a/tests/ported_static/stRandom/test_random_statetest11.py +++ b/tests/ported_static/stRandom/test_random_statetest11.py @@ -46,6 +46,23 @@ def test_random_statetest11( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3506fa093f3408a6e531735960a7617127a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest11( nonce=0, address=Address(0x5B43C2B5E72DEEE35ADD94AD33DF0D4A4C5C443E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest110.py b/tests/ported_static/stRandom/test_random_statetest110.py index 58f438b1054..d1979dc473f 100644 --- a/tests/ported_static/stRandom/test_random_statetest110.py +++ b/tests/ported_static/stRandom/test_random_statetest110.py @@ -46,6 +46,7 @@ def test_random_statetest110( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417f00000000000000000000000000000000000000000000000000000000000000016f97543c343476cb7c8c84066217f1025560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest110( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest111.py b/tests/ported_static/stRandom/test_random_statetest111.py index 3aa84517400..e9926c99608 100644 --- a/tests/ported_static/stRandom/test_random_statetest111.py +++ b/tests/ported_static/stRandom/test_random_statetest111.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest111( ) -> None: """Test_random_statetest111.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest111( "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c35059a17f0000000000000000000000000000000000000000000000000000000000000001f38f07bf60005155" # noqa: E501 ), nonce=0, - address=Address(0xC9EDD4CF792E9FEFFEE7968E9A49A0BD81A7BA40), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest111( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest112.py b/tests/ported_static/stRandom/test_random_statetest112.py index 742113f0fed..a9b2faece89 100644 --- a/tests/ported_static/stRandom/test_random_statetest112.py +++ b/tests/ported_static/stRandom/test_random_statetest112.py @@ -46,6 +46,7 @@ def test_random_statetest112( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff45447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000006f549c5779398a848c353075146505415560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_random_statetest112( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest114.py b/tests/ported_static/stRandom/test_random_statetest114.py index 97341fa83e9..f47ea665ee4 100644 --- a/tests/ported_static/stRandom/test_random_statetest114.py +++ b/tests/ported_static/stRandom/test_random_statetest114.py @@ -46,6 +46,7 @@ def test_random_statetest114( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f3584357ea388725483637d4471727f5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_random_statetest114( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest115.py b/tests/ported_static/stRandom/test_random_statetest115.py index 155354e29de..de2cae7b5b0 100644 --- a/tests/ported_static/stRandom/test_random_statetest115.py +++ b/tests/ported_static/stRandom/test_random_statetest115.py @@ -46,6 +46,23 @@ def test_random_statetest115( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3506f15448e363302150a6f56518aa005315560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest115( nonce=0, address=Address(0xB3287F1884B2A2955D0A6FBA5C8F9AD74D939E4E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest116.py b/tests/ported_static/stRandom/test_random_statetest116.py index 575a27c51cd..7a2db95bd91 100644 --- a/tests/ported_static/stRandom/test_random_statetest116.py +++ b/tests/ported_static/stRandom/test_random_statetest116.py @@ -46,6 +46,23 @@ def test_random_statetest116( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000753933760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,23 +87,6 @@ def test_random_statetest116( nonce=0, address=Address(0x78F8B360C7BDD3B4DDA493E8EEA4590ED562A6C3), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest117.py b/tests/ported_static/stRandom/test_random_statetest117.py index b7c1ef8d83f..4dd85d25fc1 100644 --- a/tests/ported_static/stRandom/test_random_statetest117.py +++ b/tests/ported_static/stRandom/test_random_statetest117.py @@ -46,21 +46,7 @@ def test_random_statetest117( gas_limit=9223372036854775807, ) - # Source: raw - # 0x447f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000427f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000006f8aa4a4980274f18c6158368d4157145560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PREVRANDAO - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.TIMESTAMP - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x8AA4A4980274F18C6158368D41571455 - ), - nonce=0, - address=Address(0x3374B8F7389A6ECD92DC42CBC9BB4E7CC0DCE3FF), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest117( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x447f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000427f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000006f8aa4a4980274f18c6158368d4157145560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PREVRANDAO + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.TIMESTAMP + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x8AA4A4980274F18C6158368D41571455 + ), + nonce=0, + address=Address(0x3374B8F7389A6ECD92DC42CBC9BB4E7CC0DCE3FF), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest118.py b/tests/ported_static/stRandom/test_random_statetest118.py index 84c5d230d3f..07766a98ece 100644 --- a/tests/ported_static/stRandom/test_random_statetest118.py +++ b/tests/ported_static/stRandom/test_random_statetest118.py @@ -46,6 +46,23 @@ def test_random_statetest118( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006f55817c037fa45bf3850320309a8f025560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,23 +85,6 @@ def test_random_statetest118( nonce=0, address=Address(0xC35874F463B793094544A6DE8C6BD10BAA69E812), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest119.py b/tests/ported_static/stRandom/test_random_statetest119.py index c95103a51cb..1b61ded5c5c 100644 --- a/tests/ported_static/stRandom/test_random_statetest119.py +++ b/tests/ported_static/stRandom/test_random_statetest119.py @@ -46,6 +46,7 @@ def test_random_statetest119( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x4559437f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006f52503b127c115a9673a431379095665560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest119( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest12.py b/tests/ported_static/stRandom/test_random_statetest12.py index 32909e3d183..86f7a58f916 100644 --- a/tests/ported_static/stRandom/test_random_statetest12.py +++ b/tests/ported_static/stRandom/test_random_statetest12.py @@ -46,6 +46,23 @@ def test_random_statetest12( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000027f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f165490a41215369ef27603794116335560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest12( nonce=0, address=Address(0xD52A7895F47045DACF362BBFD74AB386C9B62156), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest120.py b/tests/ported_static/stRandom/test_random_statetest120.py index e9d1ce0a700..af3ef063276 100644 --- a/tests/ported_static/stRandom/test_random_statetest120.py +++ b/tests/ported_static/stRandom/test_random_statetest120.py @@ -46,6 +46,7 @@ def test_random_statetest120( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe820860005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest120( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest121.py b/tests/ported_static/stRandom/test_random_statetest121.py index 24a85f157a6..f8b577b6d51 100644 --- a/tests/ported_static/stRandom/test_random_statetest121.py +++ b/tests/ported_static/stRandom/test_random_statetest121.py @@ -46,6 +46,23 @@ def test_random_statetest121( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c350456f305842321509108c689f7ca3195a9d5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest121( nonce=0, address=Address(0xED5527E2A67BD5A393DDAEE03F7E2367C171B6C7), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest122.py b/tests/ported_static/stRandom/test_random_statetest122.py index 309079d0dc6..6cc5f6b8caf 100644 --- a/tests/ported_static/stRandom/test_random_statetest122.py +++ b/tests/ported_static/stRandom/test_random_statetest122.py @@ -46,6 +46,23 @@ def test_random_statetest122( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6fa2825b6c338f8d717156560af045136b60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest122( nonce=0, address=Address(0x5AD019811A4034583D362B1619D74027A576B6E4), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest124.py b/tests/ported_static/stRandom/test_random_statetest124.py index 2df9bab1f7b..78e7b5a37e5 100644 --- a/tests/ported_static/stRandom/test_random_statetest124.py +++ b/tests/ported_static/stRandom/test_random_statetest124.py @@ -46,6 +46,7 @@ def test_random_statetest124( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08125580355b17457f7463587b9a7a435560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest124( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest125.py b/tests/ported_static/stRandom/test_random_statetest125.py index a69c23b90ca..eb54ea5851d 100644 --- a/tests/ported_static/stRandom/test_random_statetest125.py +++ b/tests/ported_static/stRandom/test_random_statetest125.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest125( ) -> None: """Test_random_statetest125.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest125( "7f0000000000000000000000000000000000000000000000000000000000000001207f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe406f" # noqa: E501 ), nonce=0, - address=Address(0x1B0E1DBC498C84F90C7FD8527D4769745EF1B402), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest125( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest126.py b/tests/ported_static/stRandom/test_random_statetest126.py index 4eca7fc1703..579c4fea63a 100644 --- a/tests/ported_static/stRandom/test_random_statetest126.py +++ b/tests/ported_static/stRandom/test_random_statetest126.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest126( ) -> None: """Test_random_statetest126.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest126( code=Op.COINBASE + Op.TIMESTAMP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x14D62B5F3407C5252CF14978B30AA72F1D70C9B7), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest126( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest129.py b/tests/ported_static/stRandom/test_random_statetest129.py index f0bfdf3ba7d..4d1bdf56d05 100644 --- a/tests/ported_static/stRandom/test_random_statetest129.py +++ b/tests/ported_static/stRandom/test_random_statetest129.py @@ -46,6 +46,23 @@ def test_random_statetest129( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f166e733343093a31a33b8e025a02705560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest129( nonce=0, address=Address(0xAFC41179EB323CA01EB2D38B409233EDD0BBFD84), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest13.py b/tests/ported_static/stRandom/test_random_statetest13.py index e96ab1baa88..69cbf6a3159 100644 --- a/tests/ported_static/stRandom/test_random_statetest13.py +++ b/tests/ported_static/stRandom/test_random_statetest13.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest13( ) -> None: """Test_random_statetest13.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest13( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000027ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe307f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000005255 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,25 +77,7 @@ def test_random_statetest13( ) + Op.SSTORE, nonce=0, - address=Address(0xD9C946D2F4E706FBE9FB6F91B4034BD946606105), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest130.py b/tests/ported_static/stRandom/test_random_statetest130.py index 06a0afbc8a0..b4d4e79efde 100644 --- a/tests/ported_static/stRandom/test_random_statetest130.py +++ b/tests/ported_static/stRandom/test_random_statetest130.py @@ -46,6 +46,23 @@ def test_random_statetest130( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000016f368a668b76306d181a3936119883175560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest130( nonce=0, address=Address(0x778A9E494C0C5BC6A3648B651752ADCDE32AF9FC), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest131.py b/tests/ported_static/stRandom/test_random_statetest131.py index 8c2d155517d..839150249a4 100644 --- a/tests/ported_static/stRandom/test_random_statetest131.py +++ b/tests/ported_static/stRandom/test_random_statetest131.py @@ -46,6 +46,7 @@ def test_random_statetest131( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000001000000000000000000000000000000000000000014416f36ff85758270710168547a977788609660005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest131( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest133.py b/tests/ported_static/stRandom/test_random_statetest133.py index 5ec348ad982..632885666d4 100644 --- a/tests/ported_static/stRandom/test_random_statetest133.py +++ b/tests/ported_static/stRandom/test_random_statetest133.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest133( ) -> None: """Test_random_statetest133.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest133( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001357f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000035830b503516a46d0b03 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001357f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000000035830b503516a46d0b03" # noqa: E501 - ), - nonce=0, - address=Address(0x329BC91A29577639030B3D2025ECFA2AB0FC3BA8), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest133( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001357f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000035830b503516a46d0b03 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001357f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000000035830b503516a46d0b03" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest134.py b/tests/ported_static/stRandom/test_random_statetest134.py index 1a6a1d55122..cc6196657b8 100644 --- a/tests/ported_static/stRandom/test_random_statetest134.py +++ b/tests/ported_static/stRandom/test_random_statetest134.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest134( ) -> None: """Test_random_statetest134.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest134( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x417f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff557f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff55836b636c9c395a0732014533405560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest134( key=Op.MLOAD(offset=0x0), value=0x636C9C395A07320145334055 ), nonce=0, - address=Address(0x955495CF3DC6D8B98B51E7C3F09C27A30C0E87F0), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest135.py b/tests/ported_static/stRandom/test_random_statetest135.py index e192bb812a2..6d91f04aee8 100644 --- a/tests/ported_static/stRandom/test_random_statetest135.py +++ b/tests/ported_static/stRandom/test_random_statetest135.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest135( ) -> None: """Test_random_statetest135.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest135( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000010000000000000000000000000000000000000000417f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0075a0b64319218663016870455 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,25 +90,7 @@ def test_random_statetest135( value=Op.PUSH32[0x0], ), nonce=0, - address=Address(0x8BE71DFBA7B6D76D26A281635B0D1A85D947C1E5), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest137.py b/tests/ported_static/stRandom/test_random_statetest137.py index c1cae51cfd0..fb64a290214 100644 --- a/tests/ported_static/stRandom/test_random_statetest137.py +++ b/tests/ported_static/stRandom/test_random_statetest137.py @@ -47,6 +47,7 @@ def test_random_statetest137( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000087f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5a130e86ca17390989355f092a25560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest137( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest138.py b/tests/ported_static/stRandom/test_random_statetest138.py index b46b17fe639..6f2086dd8ed 100644 --- a/tests/ported_static/stRandom/test_random_statetest138.py +++ b/tests/ported_static/stRandom/test_random_statetest138.py @@ -46,6 +46,7 @@ def test_random_statetest138( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350447f0000000000000000000000000000000000000000000000000000000000000001f1595160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest138( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest139.py b/tests/ported_static/stRandom/test_random_statetest139.py index 142ff4a134e..eeded5a3fb6 100644 --- a/tests/ported_static/stRandom/test_random_statetest139.py +++ b/tests/ported_static/stRandom/test_random_statetest139.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest139( ) -> None: """Test_random_statetest139.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest139( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x5B857B55E25462B8A882575CB794AD3FED2A8785), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest139( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest14.py b/tests/ported_static/stRandom/test_random_statetest14.py index 6b75061271a..8c06ccf6ca2 100644 --- a/tests/ported_static/stRandom/test_random_statetest14.py +++ b/tests/ported_static/stRandom/test_random_statetest14.py @@ -46,6 +46,7 @@ def test_random_statetest14( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff20547f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeff61853634f06b907f899d7455 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest14( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest142.py b/tests/ported_static/stRandom/test_random_statetest142.py index f8df08148db..fa2332d513d 100644 --- a/tests/ported_static/stRandom/test_random_statetest142.py +++ b/tests/ported_static/stRandom/test_random_statetest142.py @@ -46,6 +46,23 @@ def test_random_statetest142( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff959137630364087e1a640431107c880160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -72,23 +89,6 @@ def test_random_statetest142( nonce=0, address=Address(0x61F5C948887569A5488E7B6B31A0E46E8E9E0C7E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest143.py b/tests/ported_static/stRandom/test_random_statetest143.py index 9729cf2655b..b702e0e691e 100644 --- a/tests/ported_static/stRandom/test_random_statetest143.py +++ b/tests/ported_static/stRandom/test_random_statetest143.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest143( ) -> None: """Test_random_statetest143.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,7 +57,6 @@ def test_random_statetest143( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFCC847F31E7E75EAEC0B29CEAE4E989C97F49FB7), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -78,7 +74,6 @@ def test_random_statetest143( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -91,7 +86,7 @@ def test_random_statetest143( post = { target: Account( storage={ - 0xAE72E2BF2302EBCD309E003E5BE58830F96DEDDAF87BB89EEEA159388BFE3EC1: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, # noqa: E501 + 0xAE72E2BF2302EBCD309E003E5BE58830F96DEDDAF87BB89EEEA159388BFE3EC1: coinbase, # noqa: E501 }, balance=0xDE0B6B3A76586A0, nonce=0, diff --git a/tests/ported_static/stRandom/test_random_statetest144.py b/tests/ported_static/stRandom/test_random_statetest144.py index 4cbad499b8b..4f09a5cfc6b 100644 --- a/tests/ported_static/stRandom/test_random_statetest144.py +++ b/tests/ported_static/stRandom/test_random_statetest144.py @@ -47,6 +47,8 @@ def test_random_statetest144( gas_limit=1545160903, ) + pre[addr] = Account(balance=0x2401AC5958344E85, nonce=53) + pre[sender] = Account(balance=0x71E90493E6EB4C59) # Source: raw # 0x621da82575e942e4fd977abdb407069cf700116e02b4f9b25d866b6d13163fff2b8ef03cf8ab5d662afb7bb5c9e68462741090bc0976c9705b40411efe39e80c20b572c5e3d75f788f9be2f0981672b8de37f9e2d1515046cb77cc3ee74646fb096eadce98908499b6fd54725f3c6a725968761ba50494d1ecaf1e787db9a052952427c4f271c28d3e25728b2b76439a3166cd0ed37f30ec2421ed38ebd3b00b89ba9208391dc274e4eefa69161a37dfff7111756dd7971065f05aa9de4867609e7d847a290d0eeb08cde2ff294ae11dd16f8a3e32494d943fa0622cc04cd7476b6d2a1008e4ad1e2c33e2928e707c797f2a1a586bbf78658189bf58172ff77130be2ffc9bbf7f171939be260b30eb65b46a6cf107be1c9ed5c92c99d69fe0559389600e6013601c60096016601260016001600c6017016d200351654b9773409608aaa7db1f67b518d025727bdc6e0463b2bc334b658536d84dadc47a2288da62c36b9a35bf8934e3781a4c44e91637ce5c6b2f916d76706529d728b6f5ee076013601e601960086005601c6013601d96423568ce21a850c04a77ceb9 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -104,8 +106,6 @@ def test_random_statetest144( nonce=89, address=Address(0xEA1CD1B117B10AC33FD7BBF18889624625EDE7D4), # noqa: E501 ) - pre[addr] = Account(balance=0x2401AC5958344E85, nonce=53) - pre[sender] = Account(balance=0x71E90493E6EB4C59) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest145.py b/tests/ported_static/stRandom/test_random_statetest145.py index e09c9d76b4d..05baefb8eb7 100644 --- a/tests/ported_static/stRandom/test_random_statetest145.py +++ b/tests/ported_static/stRandom/test_random_statetest145.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest145( ) -> None: """Test_random_statetest145.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest145( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000427f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000139133360005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,25 +77,7 @@ def test_random_statetest145( + Op.SGT + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.CALLER), nonce=0, - address=Address(0x924D71D0675BBCE56965CA41556FA545DA2135A0), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -95,10 +90,7 @@ def test_random_statetest145( ) post = { - target: Account( - storage={0: 0x2E3D0156D2B99A6EACBA540C55F423C8F5A33143}, - nonce=0, - ), + target: Account(storage={0: sender}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom/test_random_statetest146.py b/tests/ported_static/stRandom/test_random_statetest146.py index 57e678cb840..09586cd9e74 100644 --- a/tests/ported_static/stRandom/test_random_statetest146.py +++ b/tests/ported_static/stRandom/test_random_statetest146.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest146( ) -> None: """Test_random_statetest146.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_random_statetest146( + Op.EXP(Op.CALLCODE, Op.EQ(Op.CALLDATASIZE, Op.ADDRESS)), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDE14E9D6C6F9145C355FDF3100FE961632D4CF85), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -76,7 +72,6 @@ def test_random_statetest146( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest147.py b/tests/ported_static/stRandom/test_random_statetest147.py index 0af9abc527a..476ca4fc8e8 100644 --- a/tests/ported_static/stRandom/test_random_statetest147.py +++ b/tests/ported_static/stRandom/test_random_statetest147.py @@ -46,6 +46,7 @@ def test_random_statetest147( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x657ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe43659a936055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest147( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest148.py b/tests/ported_static/stRandom/test_random_statetest148.py index fd1abbab49b..87290b860ac 100644 --- a/tests/ported_static/stRandom/test_random_statetest148.py +++ b/tests/ported_static/stRandom/test_random_statetest148.py @@ -46,19 +46,7 @@ def test_random_statetest148( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001537f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000006f34847e390773919b165590771644725560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.MSTORE8(offset=Op.PUSH32[0x1], value=Op.PUSH32[0xC350]) - + Op.PUSH32[0x0] * 2 - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x34847E390773919B1655907716447255 - ), - nonce=0, - address=Address(0xA795B1DE6184BCFA49D6EA7929439C5CA3A6B4BB), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -75,7 +63,19 @@ def test_random_statetest148( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001537f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000006f34847e390773919b165590771644725560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.MSTORE8(offset=Op.PUSH32[0x1], value=Op.PUSH32[0xC350]) + + Op.PUSH32[0x0] * 2 + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x34847E390773919B1655907716447255 + ), + nonce=0, + address=Address(0xA795B1DE6184BCFA49D6EA7929439C5CA3A6B4BB), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest149.py b/tests/ported_static/stRandom/test_random_statetest149.py index f751a51b3d4..8227cf138fc 100644 --- a/tests/ported_static/stRandom/test_random_statetest149.py +++ b/tests/ported_static/stRandom/test_random_statetest149.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest149( ) -> None: """Test_random_statetest149.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest149( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff099055510760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,25 +79,7 @@ def test_random_statetest149( + Op.MLOAD + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.SMOD), nonce=0, - address=Address(0xEE2A67362D09420884AE26DC5C2F1C69EC03C027), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest15.py b/tests/ported_static/stRandom/test_random_statetest15.py index d4467bfe279..7587f7cac55 100644 --- a/tests/ported_static/stRandom/test_random_statetest15.py +++ b/tests/ported_static/stRandom/test_random_statetest15.py @@ -46,6 +46,23 @@ def test_random_statetest15( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000016f436af043189b6197733280a2f1f0385560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest15( nonce=0, address=Address(0x9938A1CD42DF5BA9E9677FA018875C8DC2DEB317), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest150.py b/tests/ported_static/stRandom/test_random_statetest150.py index 8a19ba48705..6f9cc75c228 100644 --- a/tests/ported_static/stRandom/test_random_statetest150.py +++ b/tests/ported_static/stRandom/test_random_statetest150.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest150( ) -> None: """Test_random_statetest150.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest150( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x668254d76c6f24d4806677d83f3a46a1a66f20ae2688cf4b75842ac7265966f5f5ca603e6062a268aba89067dc278e1f86710462dae624ac683889038d26894af02617c06b39c4988a5a60a12c0d9ad0ca65839c92f7c75c6ad3d6a7b617ac7fbd41f5a29377ca6ad48748a94e31302254147fb3b5857568e516cb6e8aa23577af85d0e508dc17dc50e246130be577cb59826adc86af6c107fd8a98f47cccd9d22a867a43cd8ad77bbe8bb737af5acc0be67fd7b054f7281e771891dc4aad180996b9cb71c6016d0f6a9148c775e57ac8456a883eedc3182623898f32b5c83760465a2061c7652e785e7eef7a97b0aa6d6c15b5c296bcf05ee2e9b87aa60b5741b3f7d69a1df03df117b848b3a75f81c12dee2244f76e56bb261e9c75fb5ccc769db72bfaeadee3f68cf22bbca665b0647ac74c1409778c71b73ed4adaa2c6ba1c181b0747c27506478c403b3943129e79223e788bf8b81f60abecb73be035d03a8bbdfa112cd8cb2f7a1065250292740d2d72259b4d7e3ef844783da8118b72912b9f96a61f6168f160ef69d7dd3dfc7e4ef204766f789cbaf2abeceadcf5bdd8dddfef773f0a628afdf3988861662b77882a5cebffc61e75f11835b109e81f7c915a91c13b09097b792d3d59de0ef5b0f00f95ea49860917656263925da2fd6685359c6d7e4c3c4d2001a30111de14c56503788453df98a29b8715561b2c2021cf78e0ccc4701b192ebf67bb6f522656788b3d21428b50a2fa16224d926ce2ea5944760d501bfa0774238c6351dd224b743d3fc4d5a309166016a71b1c230fe9afd6479324716e71e3b27bdd3fb18cccc42f6ec973129f7958435f45da181aeb1608ed31713c33330ab4d2d4af54dd92d1df1560086014601d601f636b1d9a3573632aec0540f16cfb040c16bd7c3761bdb86dd6be658d2aefe157396217393663769965a66479176d702e7e2d5697681aac1beccc55825241cd77551f39526cfa77838faa9c4759aafa5c64df5e9199976f35f8298acd398d1913c1fd2ddacbbeac7cc29daee12c057385808f19d07110f30cfd900a130b0a713468bceaf4236153ab6c7bdc39cf86d0a5b03684624d187473b42a2968f1128872724b3d42218dbac11f5a9492651f09a866f61a72535c373274618d5914163abc7481bb7789394e62f247e78e7f83af55a5686926972af7c6519658aee40a564e3c2950f874def7a2110af0526f75629b20a108e1cfba0db03fcdee497ee2f8bcf78ef14317 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -134,23 +147,6 @@ def test_random_statetest150( nonce=0, address=Address(0xA00C267DA6E57A9318A096C6333C4BCED51306DA), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest151.py b/tests/ported_static/stRandom/test_random_statetest151.py index a9699c5adf2..192a0f7c215 100644 --- a/tests/ported_static/stRandom/test_random_statetest151.py +++ b/tests/ported_static/stRandom/test_random_statetest151.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest151( ) -> None: """Test_random_statetest151.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest151( code=bytes.fromhex("41424143445a42f35b10773574016c9f"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x832214236B4DC7829A505AFAFB05B91D152F9FF4), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest151( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest153.py b/tests/ported_static/stRandom/test_random_statetest153.py index cfbd2a8b1a1..242b2d246d1 100644 --- a/tests/ported_static/stRandom/test_random_statetest153.py +++ b/tests/ported_static/stRandom/test_random_statetest153.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest153( ) -> None: """Test_random_statetest153.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_random_statetest153( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x973AA64AFC19EAEB66865746FC4938231BCF3312), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -74,7 +70,6 @@ def test_random_statetest153( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest154.py b/tests/ported_static/stRandom/test_random_statetest154.py index f41e51f37b2..0bad5e9b660 100644 --- a/tests/ported_static/stRandom/test_random_statetest154.py +++ b/tests/ported_static/stRandom/test_random_statetest154.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest154( ) -> None: """Test_random_statetest154.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest154( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7db1267c8bba268d1408f7b3e269afee3fea86c5bc8aec8108fd6aaa954f5173b7d0e2328333e94698e0d570db9b316cba0adbae609d611ba1a2326004600d6005600f632de40a2773635c2491eef1 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +82,6 @@ def test_random_statetest154( nonce=0, address=Address(0xF8E70C18DB2BF1444417C2820AF74D3AB1D6A06F), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest155.py b/tests/ported_static/stRandom/test_random_statetest155.py index 09b14f110a9..e0b64cbff1a 100644 --- a/tests/ported_static/stRandom/test_random_statetest155.py +++ b/tests/ported_static/stRandom/test_random_statetest155.py @@ -46,6 +46,23 @@ def test_random_statetest155( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006f3494f39b6ca29473a19958030891015560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest155( nonce=0, address=Address(0xA8B18AE8F1784B75923DBC884C39419340A580EF), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest156.py b/tests/ported_static/stRandom/test_random_statetest156.py index 15f537271a9..ac350f1bd3f 100644 --- a/tests/ported_static/stRandom/test_random_statetest156.py +++ b/tests/ported_static/stRandom/test_random_statetest156.py @@ -46,6 +46,7 @@ def test_random_statetest156( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3506f813982583141966b389c159aa48b3a8860005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -76,7 +77,6 @@ def test_random_statetest156( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest157.py b/tests/ported_static/stRandom/test_random_statetest157.py index 2c26e9768bb..b7faca09a73 100644 --- a/tests/ported_static/stRandom/test_random_statetest157.py +++ b/tests/ported_static/stRandom/test_random_statetest157.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest157( ) -> None: """Test_random_statetest157.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest157( "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0966ff351691689162f371a38d9b789e4360005155" # noqa: E501 ), nonce=0, - address=Address(0xD86E1F5504D3579A67DB179F0CE158D0E8B252D9), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest157( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest158.py b/tests/ported_static/stRandom/test_random_statetest158.py index 1939b2556e7..a5ab51e59a3 100644 --- a/tests/ported_static/stRandom/test_random_statetest158.py +++ b/tests/ported_static/stRandom/test_random_statetest158.py @@ -46,6 +46,23 @@ def test_random_statetest158( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe435060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest158( nonce=0, address=Address(0xFA9512FFC9C4019C1680C63C1285D623D6579C46), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest159.py b/tests/ported_static/stRandom/test_random_statetest159.py index 9f9fb966491..cf7ad9cc324 100644 --- a/tests/ported_static/stRandom/test_random_statetest159.py +++ b/tests/ported_static/stRandom/test_random_statetest159.py @@ -47,6 +47,23 @@ def test_random_statetest159( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x324260e172acf6051580ff4e3ba75da449e7ab2b705cf75873b252caf4b51def86cf4988747e4b77d541c09d316acfebf3871d3a1944a5b975670f11d63a7d9c9b49750a0734d7313f746ba5fba6f3ff04148f4f39e4a28cc271e1ae0b89f2ad1413af2317c6a9628006d4157cdf7a3f30103f20611fe88431b16a79be995278aec271b56bc32543196c650621b66f1bfc718c0d9360cfb17a079aeca76a0b08cb4f0e5789426a6a26c3bef3710be80e4d646135f26076a178e17952f1667fa85f3b72ffa4c95bda9db87e2b8409a9b1c9e27346e5b9a49fd3689f943925eb4618577675acf6bf7b1b665940c32ef9086a95914496bc8bb76245fa2dc9cd3e29618e568966b2893ecd2e84766a8cf184a772e70b3e042b9584601e600b600760136304b1e2f2736339570738f16df327f570c11aa84a7a5480b98c5175cbd00120239df2d03db2fdd9c233df848ead9d3c84d4556f6030a17e0f41dfce8be36a92b0d5e0d67a71c146187edefc7923a8aad22ca228ecee824c2d7c237ace7e52fd62bd649662a4fe5f78a0b34d84a28c14c9fea0f18d1d55870173546b3b99e17cae467e2f1667b7c9445b11382bf9d7ff632d1ccdc973ba913d9ebbb219ac7aa0f3b579caa81065e433d2b8cf8cbfb998ec52fe1eaea6d87bc7728315cc653ccf904948918741 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -101,23 +118,6 @@ def test_random_statetest159( nonce=0, address=Address(0xBADAB8EC78E07CDBB4B25F913769FEA51E5A9C2A), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest16.py b/tests/ported_static/stRandom/test_random_statetest16.py index 5b201216811..9fd19a54c5c 100644 --- a/tests/ported_static/stRandom/test_random_statetest16.py +++ b/tests/ported_static/stRandom/test_random_statetest16.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest16( ) -> None: """Test_random_statetest16.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest16( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000557f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005531848f7aa4516d7d7578797e # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000000000000000000000000000000000000000000000557f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005531848f7aa4516d7d7578797e" # noqa: E501 - ), - nonce=0, - address=Address(0xAFBF96F4E8A345CC862021D826A7CAE52ADCCDE9), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest16( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000557f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005531848f7aa4516d7d7578797e # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000000000000000000000000000000000000000000000557f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005531848f7aa4516d7d7578797e" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest161.py b/tests/ported_static/stRandom/test_random_statetest161.py index e83e302fd1d..39c6b218f9f 100644 --- a/tests/ported_static/stRandom/test_random_statetest161.py +++ b/tests/ported_static/stRandom/test_random_statetest161.py @@ -46,6 +46,7 @@ def test_random_statetest161( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350437f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001416f458a458076526052650a418c9b40863c60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,7 +78,6 @@ def test_random_statetest161( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest162.py b/tests/ported_static/stRandom/test_random_statetest162.py index 01a6436fa55..963bdf0a924 100644 --- a/tests/ported_static/stRandom/test_random_statetest162.py +++ b/tests/ported_static/stRandom/test_random_statetest162.py @@ -46,6 +46,7 @@ def test_random_statetest162( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f355a7f614497339e3b63878b3698045560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest162( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest163.py b/tests/ported_static/stRandom/test_random_statetest163.py index e855aea06dc..e09dae5e866 100644 --- a/tests/ported_static/stRandom/test_random_statetest163.py +++ b/tests/ported_static/stRandom/test_random_statetest163.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest163( ) -> None: """Test_random_statetest163.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,7 +51,6 @@ def test_random_statetest163( "7f000000000000000000000000000000000000000000000000000000000000000034577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000426259cb6142a1196e3168c986758aa4" # noqa: E501 ), nonce=0, - address=Address(0xE9A32A9AD98C02FA9521B9AB066BCC683A8AB126), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -72,7 +68,6 @@ def test_random_statetest163( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest164.py b/tests/ported_static/stRandom/test_random_statetest164.py index 86fc0ce7eb4..2bd27133fea 100644 --- a/tests/ported_static/stRandom/test_random_statetest164.py +++ b/tests/ported_static/stRandom/test_random_statetest164.py @@ -46,6 +46,23 @@ def test_random_statetest164( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000831305395560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -72,23 +89,6 @@ def test_random_statetest164( nonce=0, address=Address(0x5C044383D81700714D9B211B8AF71746E4BA3EC6), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -103,7 +103,7 @@ def test_random_statetest164( post = { target: Account( storage={ - 0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, + 0: coinbase, 0x4F3F701464972E74606D6EA82D4D3080599A0E79: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 }, nonce=0, diff --git a/tests/ported_static/stRandom/test_random_statetest166.py b/tests/ported_static/stRandom/test_random_statetest166.py index 1cb2f1e0658..8dfb02fb2e1 100644 --- a/tests/ported_static/stRandom/test_random_statetest166.py +++ b/tests/ported_static/stRandom/test_random_statetest166.py @@ -46,6 +46,7 @@ def test_random_statetest166( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff817f0000000000000000000000010000000000000000000000000000000000000000417f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350456f8eb7099d9f160532785143c5937e185560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest166( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest167.py b/tests/ported_static/stRandom/test_random_statetest167.py index 2e112f4ec65..75073e2980f 100644 --- a/tests/ported_static/stRandom/test_random_statetest167.py +++ b/tests/ported_static/stRandom/test_random_statetest167.py @@ -46,6 +46,23 @@ def test_random_statetest167( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000001437f0000000000000000000000000000000000000000000000000000000000000001027f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6fa00b875630178a439384941395369e5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest167( nonce=0, address=Address(0x7DEB9D5A0AB7CC3CC567CA833C7DA186F1519963), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest169.py b/tests/ported_static/stRandom/test_random_statetest169.py index a96575ac1b8..77f4c6a16c0 100644 --- a/tests/ported_static/stRandom/test_random_statetest169.py +++ b/tests/ported_static/stRandom/test_random_statetest169.py @@ -46,6 +46,23 @@ def test_random_statetest169( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe447f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest169( nonce=0, address=Address(0xE3B775C5C06F3099B1B090E27C2F79356E8D4E9F), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest17.py b/tests/ported_static/stRandom/test_random_statetest17.py index 4ba7062450f..34d7b4762fa 100644 --- a/tests/ported_static/stRandom/test_random_statetest17.py +++ b/tests/ported_static/stRandom/test_random_statetest17.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest17( ) -> None: """Test_random_statetest17.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,7 +58,6 @@ def test_random_statetest17( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xE9D0379FA7CC1436C525C501B9538A9797140FBF), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -79,7 +75,6 @@ def test_random_statetest17( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest171.py b/tests/ported_static/stRandom/test_random_statetest171.py index 7320c71012f..085db9770a6 100644 --- a/tests/ported_static/stRandom/test_random_statetest171.py +++ b/tests/ported_static/stRandom/test_random_statetest171.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest171( ) -> None: """Test_random_statetest171.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest171( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c350437f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000197ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest171( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x698791D8A7C355091FA7BC3A0171CD426DBE2F51), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest172.py b/tests/ported_static/stRandom/test_random_statetest172.py index 7a87b12e703..69d3fbbe19d 100644 --- a/tests/ported_static/stRandom/test_random_statetest172.py +++ b/tests/ported_static/stRandom/test_random_statetest172.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest172( ) -> None: """Test_random_statetest172.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest172( ), ), nonce=0, - address=Address(0xF279F9F41A3A6ECF391D89AAC2E62FD83D4488B7), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest172( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest173.py b/tests/ported_static/stRandom/test_random_statetest173.py index 07f0eeac20a..bef3489d6d2 100644 --- a/tests/ported_static/stRandom/test_random_statetest173.py +++ b/tests/ported_static/stRandom/test_random_statetest173.py @@ -47,15 +47,7 @@ def test_random_statetest173( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b509ff979443703ca35560005155 # noqa: E501 - contract_0 = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b509ff979443703ca35560005155" # noqa: E501 - ), - nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -72,7 +64,15 @@ def test_random_statetest173( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b509ff979443703ca35560005155 # noqa: E501 + contract_0 = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b509ff979443703ca35560005155" # noqa: E501 + ), + nonce=0, + address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest174.py b/tests/ported_static/stRandom/test_random_statetest174.py index b447d0080e6..331cdc37ee6 100644 --- a/tests/ported_static/stRandom/test_random_statetest174.py +++ b/tests/ported_static/stRandom/test_random_statetest174.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest174( ) -> None: """Test_random_statetest174.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest174( code=Op.SSTORE(key=Op.COINBASE, value=Op.NUMBER), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x35A69854A524BB9FA20F350526F2CEF147E6789B), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest174( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest175.py b/tests/ported_static/stRandom/test_random_statetest175.py index ca5c8d2985e..9b87f8d928d 100644 --- a/tests/ported_static/stRandom/test_random_statetest175.py +++ b/tests/ported_static/stRandom/test_random_statetest175.py @@ -46,6 +46,7 @@ def test_random_statetest175( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3506f6985f2837e09689844171a0235833c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest175( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest176.py b/tests/ported_static/stRandom/test_random_statetest176.py index e1813fe5bd0..b38024b1239 100644 --- a/tests/ported_static/stRandom/test_random_statetest176.py +++ b/tests/ported_static/stRandom/test_random_statetest176.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest176( ) -> None: """Test_random_statetest176.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest176( gas_limit=9223372036854775807, ) - # Source: raw - # 0x327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350427f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff041469988517f6889d92799e74664160005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350427f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff041469988517f6889d92799e74664160005155" # noqa: E501 - ), - nonce=0, - address=Address(0x6520F3AED37C7B3960EC53119D5B0CEDD39FE2F6), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest176( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350427f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff041469988517f6889d92799e74664160005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "327fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350427f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff041469988517f6889d92799e74664160005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest177.py b/tests/ported_static/stRandom/test_random_statetest177.py index 6336b5fb25d..074d36783cc 100644 --- a/tests/ported_static/stRandom/test_random_statetest177.py +++ b/tests/ported_static/stRandom/test_random_statetest177.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest177( ) -> None: """Test_random_statetest177.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -154,7 +151,6 @@ def test_random_statetest177( size=0x483189606297788FBF55, ), nonce=0, - address=Address(0xD18174ABA5B877BD17DC67A4272D8A567CFA8925), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -172,7 +168,6 @@ def test_random_statetest177( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest178.py b/tests/ported_static/stRandom/test_random_statetest178.py index 63acfd5143d..db292922da6 100644 --- a/tests/ported_static/stRandom/test_random_statetest178.py +++ b/tests/ported_static/stRandom/test_random_statetest178.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest178( ) -> None: """Test_random_statetest178.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest178( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7d342beabe599e4bc177fd97d36df48d50650ba6129a9a83d4cf809ec21452357c620167f530c3265be9887f6e5b8186decdc00a6a801e5f56dd8d9d36a4806dbccc299e4bbf46ad577e25b5b1fc76b6999cb23a6a03c4035e36b8494135ee170647395da00b6e0a64c43f3358b8bdcf593c89fb70b865ef153b5195c77959256beb4f932095eb8ac80bc2c050f6f550a362aac77f5c4b197151df039d64b77dca22eb8fd4b8cf50fb85a36f1d909d1919a47fe97de5526726b4a47b866b7b13471056439457cd7cbc5060d978056ff5dd24a1f49e50b9f5924f473b2dc5306d67054ca575d0603e616291a3601460106009601f6338a57ddc73630e3319c8f133 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,23 +98,6 @@ def test_random_statetest178( nonce=0, address=Address(0x1B0A78BDF6595742D34BF13386BCC01EFADDF68C), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest179.py b/tests/ported_static/stRandom/test_random_statetest179.py index 40db8823720..77fea7abbff 100644 --- a/tests/ported_static/stRandom/test_random_statetest179.py +++ b/tests/ported_static/stRandom/test_random_statetest179.py @@ -46,6 +46,23 @@ def test_random_statetest179( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3506f515480126a50a173506e06676212925560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest179( nonce=0, address=Address(0xB4749744885EB1B84835F2745A646F4AB9E60FD2), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest18.py b/tests/ported_static/stRandom/test_random_statetest18.py index 79d0ba8929c..ad0ccda235e 100644 --- a/tests/ported_static/stRandom/test_random_statetest18.py +++ b/tests/ported_static/stRandom/test_random_statetest18.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest18( ) -> None: """Test_random_statetest18.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest18( "7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001077f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3504419860b9754998d503105a033436e67133a60005155" # noqa: E501 ), nonce=0, - address=Address(0x199E67129322E9EA96E433131D5CE947EF8B4892), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest18( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest180.py b/tests/ported_static/stRandom/test_random_statetest180.py index 7495358d9a4..a52580d90f4 100644 --- a/tests/ported_static/stRandom/test_random_statetest180.py +++ b/tests/ported_static/stRandom/test_random_statetest180.py @@ -46,22 +46,7 @@ def test_random_statetest180( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000006f11576b693c128a9e0820609c050a219d60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0x1] - + Op.PREVRANDAO - + Op.PUSH32[0xC350] - + Op.PUSH32[0x0] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x11576B693C128A9E0820609C050A219D - ), - nonce=0, - address=Address(0x1D834E4F60DB574A868A27E275F1460FE1888F96), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest180( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000006f11576b693c128a9e0820609c050a219d60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0x1] + + Op.PREVRANDAO + + Op.PUSH32[0xC350] + + Op.PUSH32[0x0] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x11576B693C128A9E0820609C050A219D + ), + nonce=0, + address=Address(0x1D834E4F60DB574A868A27E275F1460FE1888F96), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest183.py b/tests/ported_static/stRandom/test_random_statetest183.py index 267ce74ed8d..945168e9838 100644 --- a/tests/ported_static/stRandom/test_random_statetest183.py +++ b/tests/ported_static/stRandom/test_random_statetest183.py @@ -46,21 +46,7 @@ def test_random_statetest183( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000436f4134547075687854849d7b646586305560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xC350] * 3 - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.NUMBER - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x4134547075687854849D7B6465863055 - ), - nonce=0, - address=Address(0x2EC56A4059CC67195985735E8A72BB5A07301EB3), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest183( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000436f4134547075687854849d7b646586305560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xC350] * 3 + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.NUMBER + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x4134547075687854849D7B6465863055 + ), + nonce=0, + address=Address(0x2EC56A4059CC67195985735E8A72BB5A07301EB3), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest184.py b/tests/ported_static/stRandom/test_random_statetest184.py index dd88a0bda0e..6abaa548ff1 100644 --- a/tests/ported_static/stRandom/test_random_statetest184.py +++ b/tests/ported_static/stRandom/test_random_statetest184.py @@ -47,6 +47,8 @@ def test_random_statetest184( gas_limit=69449279085, ) + pre[addr] = Account(balance=0x9740421FF0FF3AE3, nonce=29) + pre[sender] = Account(balance=0x10C1142F2B8E8EB058) # Source: raw # 0x6f823a02877cef7c1afb60663009def564608c557bad2ae05769b991313726edbfa0881d9cc955b0f5154751da315696ea7ce130184b64f2507582c502d450349ff24fb8aeb2a46146687b666bd7bd0364946cb720c76d483f5afea0049251fd9793c4b0376afbb4ebcdc42fdd42edcd4b619cec787638009cea26a1abe570e3186ab790b7dc7db36e4cda2570b0847adf6e39579c7c43a4ac976cd507d493cdfaebe09936078e31c71c4665d34a4b816b8004 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,8 +71,6 @@ def test_random_statetest184( nonce=117, address=Address(0x898207F2D9B9FB11CEC9647A70E9390711732DAA), # noqa: E501 ) - pre[addr] = Account(balance=0x9740421FF0FF3AE3, nonce=29) - pre[sender] = Account(balance=0x10C1142F2B8E8EB058) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest185.py b/tests/ported_static/stRandom/test_random_statetest185.py index e1ac36b7c11..21863df133c 100644 --- a/tests/ported_static/stRandom/test_random_statetest185.py +++ b/tests/ported_static/stRandom/test_random_statetest185.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest185( ) -> None: """Test_random_statetest185.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest185( topic_3=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF], ), nonce=0, - address=Address(0x065AB564766A44260B57175A6F14DB1478FF080F), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest185( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest187.py b/tests/ported_static/stRandom/test_random_statetest187.py index 4f2f130c0ce..47699fda71c 100644 --- a/tests/ported_static/stRandom/test_random_statetest187.py +++ b/tests/ported_static/stRandom/test_random_statetest187.py @@ -46,6 +46,7 @@ def test_random_statetest187( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff457f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000006f75988036a0562096036b04518877199d60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,7 +78,6 @@ def test_random_statetest187( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest188.py b/tests/ported_static/stRandom/test_random_statetest188.py index 8aafc5facfc..b06c894e7e1 100644 --- a/tests/ported_static/stRandom/test_random_statetest188.py +++ b/tests/ported_static/stRandom/test_random_statetest188.py @@ -46,6 +46,7 @@ def test_random_statetest188( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff817f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4286687859f383797187945560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest188( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest189.py b/tests/ported_static/stRandom/test_random_statetest189.py index 1f1ac0a3978..4a6149f73b4 100644 --- a/tests/ported_static/stRandom/test_random_statetest189.py +++ b/tests/ported_static/stRandom/test_random_statetest189.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest189( ) -> None: """Test_random_statetest189.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest189( "7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000035900bf3740474765060005155" # noqa: E501 ), nonce=0, - address=Address(0x8979909F9CFE09C20D8B0D21AC5FB398B01B8DF1), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest189( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest19.py b/tests/ported_static/stRandom/test_random_statetest19.py index 1ae227c81d9..dbac44602d3 100644 --- a/tests/ported_static/stRandom/test_random_statetest19.py +++ b/tests/ported_static/stRandom/test_random_statetest19.py @@ -46,6 +46,7 @@ def test_random_statetest19( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3a7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417f0000000000000000000000000000000000000000000000000000000000000001587f000000000000000000000000000000000000000000000000000000000000c3506fff59876660063b7c8df1ff088a84145560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest19( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest190.py b/tests/ported_static/stRandom/test_random_statetest190.py index 3cce6ba5e32..08b54fdd625 100644 --- a/tests/ported_static/stRandom/test_random_statetest190.py +++ b/tests/ported_static/stRandom/test_random_statetest190.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest190( ) -> None: """Test_random_statetest190.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest190( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest190( ), ), nonce=0, - address=Address(0x2BF1E46C1EC71AC6066D16A4400CE88AE6ADE599), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest191.py b/tests/ported_static/stRandom/test_random_statetest191.py index f238740f730..f1044347324 100644 --- a/tests/ported_static/stRandom/test_random_statetest191.py +++ b/tests/ported_static/stRandom/test_random_statetest191.py @@ -46,6 +46,23 @@ def test_random_statetest191( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000010000000000000000000000000000000000000000447ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f678f0443457084700b645760018a105560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest191( nonce=0, address=Address(0x7823D6D4B3E7F30899CFB9DC7A825C19032FFD44), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest192.py b/tests/ported_static/stRandom/test_random_statetest192.py index aae773222c6..04ed5961ba6 100644 --- a/tests/ported_static/stRandom/test_random_statetest192.py +++ b/tests/ported_static/stRandom/test_random_statetest192.py @@ -46,6 +46,7 @@ def test_random_statetest192( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff347f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0460005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest192( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest194.py b/tests/ported_static/stRandom/test_random_statetest194.py index 94d424a0e5a..bf41a6bf262 100644 --- a/tests/ported_static/stRandom/test_random_statetest194.py +++ b/tests/ported_static/stRandom/test_random_statetest194.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest194( ) -> None: """Test_random_statetest194.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest194( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff097f0000000000000000000000005560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest194( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xD53F0EC62568CDBC447C9967C97DB408D33ECE9A), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest195.py b/tests/ported_static/stRandom/test_random_statetest195.py index 54bf8c575a1..f2ac8f1690d 100644 --- a/tests/ported_static/stRandom/test_random_statetest195.py +++ b/tests/ported_static/stRandom/test_random_statetest195.py @@ -46,6 +46,7 @@ def test_random_statetest195( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff097f000000000000000000000001000000000000000000000000000000000000000055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest195( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest196.py b/tests/ported_static/stRandom/test_random_statetest196.py index 0498b959809..a4d7bf36c81 100644 --- a/tests/ported_static/stRandom/test_random_statetest196.py +++ b/tests/ported_static/stRandom/test_random_statetest196.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest196( ) -> None: """Test_random_statetest196.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest196( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe447f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000003703659c5b3a6d7b9a93543660005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,25 +80,7 @@ def test_random_statetest196( + Op.SLOAD + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.CALLDATASIZE), nonce=0, - address=Address(0x6E796014BF8F0F2C291F15DDB2EBF203B1477144), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest197.py b/tests/ported_static/stRandom/test_random_statetest197.py index 41b5ce9b9d5..97a84e3878a 100644 --- a/tests/ported_static/stRandom/test_random_statetest197.py +++ b/tests/ported_static/stRandom/test_random_statetest197.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest197( ) -> None: """Test_random_statetest197.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest197( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c350437f00000000000000000000000000000000000000000000000000000000000000016e6a078e5652549f57423955" # noqa: E501 ), nonce=0, - address=Address(0x71102826FF0F31FB54CE1F4B51C4F72E17BD2312), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest197( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest198.py b/tests/ported_static/stRandom/test_random_statetest198.py index 43d7e2b9be4..04cad03d209 100644 --- a/tests/ported_static/stRandom/test_random_statetest198.py +++ b/tests/ported_static/stRandom/test_random_statetest198.py @@ -46,6 +46,7 @@ def test_random_statetest198( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x42417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09ff614044129a0169a2689415 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest198( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest199.py b/tests/ported_static/stRandom/test_random_statetest199.py index 4bcddd9ebc0..ed83e6f0733 100644 --- a/tests/ported_static/stRandom/test_random_statetest199.py +++ b/tests/ported_static/stRandom/test_random_statetest199.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest199( ) -> None: """Test_random_statetest199.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_random_statetest199( + Op.SSTORE(key=Op.BALANCE(address=Op.COINBASE), value=Op.TIMESTAMP), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x961CE95E83AD7816D5FEC439EA9847CA3A5543C5), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -74,7 +70,6 @@ def test_random_statetest199( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest2.py b/tests/ported_static/stRandom/test_random_statetest2.py index f3fed745d6a..792dac6965e 100644 --- a/tests/ported_static/stRandom/test_random_statetest2.py +++ b/tests/ported_static/stRandom/test_random_statetest2.py @@ -46,6 +46,23 @@ def test_random_statetest2( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000058437f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000016f3412a47c889e8da06a04049f0498885560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest2( nonce=0, address=Address(0x3C7B3E95899724C1F97C98DE3F67B2E41D785F69), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest20.py b/tests/ported_static/stRandom/test_random_statetest20.py index c1ee18da454..c6b30221733 100644 --- a/tests/ported_static/stRandom/test_random_statetest20.py +++ b/tests/ported_static/stRandom/test_random_statetest20.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest20( ) -> None: """Test_random_statetest20.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,7 +66,6 @@ def test_random_statetest20( + Op.SWAP11 + Op.SSTORE, nonce=0, - address=Address(0x14AAE767BFB5A29EE9B0F5B449EB48366103601C), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -87,7 +83,6 @@ def test_random_statetest20( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest200.py b/tests/ported_static/stRandom/test_random_statetest200.py index e97d1984f21..2739268e301 100644 --- a/tests/ported_static/stRandom/test_random_statetest200.py +++ b/tests/ported_static/stRandom/test_random_statetest200.py @@ -46,19 +46,7 @@ def test_random_statetest200( gas_limit=9223372036854775807, ) - # Source: raw - # 0x437f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000346f42051af2a24050039e9d3a678b028a0a8055 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.NUMBER - + Op.PUSH32[0xC350] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.CALLVALUE - + Op.SSTORE(key=Op.DUP1, value=0x42051AF2A24050039E9D3A678B028A0A), - nonce=0, - address=Address(0x16C2D1C5A69FA047F6C8F529EE8D728246515FA9), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -75,7 +63,19 @@ def test_random_statetest200( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x437f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000346f42051af2a24050039e9d3a678b028a0a8055 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.NUMBER + + Op.PUSH32[0xC350] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.CALLVALUE + + Op.SSTORE(key=Op.DUP1, value=0x42051AF2A24050039E9D3A678B028A0A), + nonce=0, + address=Address(0x16C2D1C5A69FA047F6C8F529EE8D728246515FA9), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest201.py b/tests/ported_static/stRandom/test_random_statetest201.py index 042c7da6eca..f38c3d0e026 100644 --- a/tests/ported_static/stRandom/test_random_statetest201.py +++ b/tests/ported_static/stRandom/test_random_statetest201.py @@ -46,6 +46,7 @@ def test_random_statetest201( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09ff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff8b8263974074da449e6861039960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest201( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest202.py b/tests/ported_static/stRandom/test_random_statetest202.py index ddfcc13a941..f3a36977176 100644 --- a/tests/ported_static/stRandom/test_random_statetest202.py +++ b/tests/ported_static/stRandom/test_random_statetest202.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest202( ) -> None: """Test_random_statetest202.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest202( "7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000000557f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6750a3190486f0" # noqa: E501 ), nonce=0, - address=Address(0x1099229C5D84D6BC6A189E2189357E91C30C6F6A), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest202( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest204.py b/tests/ported_static/stRandom/test_random_statetest204.py index 9e256fb682a..56c6d9a85cd 100644 --- a/tests/ported_static/stRandom/test_random_statetest204.py +++ b/tests/ported_static/stRandom/test_random_statetest204.py @@ -46,6 +46,23 @@ def test_random_statetest204( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff098255 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest204( nonce=0, address=Address(0xB8147A5AAED0750FDD9AC0D29F0A0E668FA3D30C), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest205.py b/tests/ported_static/stRandom/test_random_statetest205.py index 0a02472e6f0..a4e283aab9a 100644 --- a/tests/ported_static/stRandom/test_random_statetest205.py +++ b/tests/ported_static/stRandom/test_random_statetest205.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest205( ) -> None: """Test_random_statetest205.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest205( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x3360b261edefa0326fdc74d570982966277b49cdb30a453fa06c34a7423da44ba2d04341af08c478b17a57318ab10ab43b3744333b0aa8864ac27b3fd022e380056735a5fcda3e9fdc25695972a076884de6d6b6b06dd45416c8110bae3c70576b433a4672777847e81823024ddd1292b929ad28e64a732b74c0ae1941d5936ecd35738e2f279273788f4aaf19907a532a6b0f117c32b6cb967aae8bdfcf86e2d4d64599986abcf65a20754f5a816c58ed669138f6a0448670b906bbf1eb145ced896c578de5aa27769006b1a784e84b6316d4e60c7053b0b6550c70a177cb7a3e88d4e83fb1897a09c2161ff6cc2679c178292687137854da672e316c66ef03dc9ac37e8e430b7c64d1939bf67383c4bafeb2f0471fe896b7c0e114bf6f152b266cc769ae4d38f3df618f5eeb9085601f601060086016632c019e2e73626b8a0ef179e6b62e86237845e9605d61219d97c1d0145516f5355fe73384e87a6a87cc6d2378c81797ac3746bc562e2fd1145e14781307bc4ada39732e9d0e8725fde75c5abc313c11e3238c7cd9b7186a6a14f8d5c3cad9da5339446ad1311ccc67a0691559157a674825358b301ac42d7bcae31beb8b0849903402175ca3740f3fd690ad66287d6bf67a98c09e6de5717596052d30f4b9bb8046a6b67ef51b1b13c496e97bf9a2e67aeca97fa10a266f8cf22c10cc0375b514b25de466a146576b2cb565754efc80d4b8aa5497aa0fb4cbab90ee57298d322474d276366e04eab856c9f6070c80701fa30596dd0b6ea5bc38ba64e1d16aff1b8c61caa379064465a9308dbb1465294ddcb5fa32833e4ffb049c71761ed93472c7e58f171c6c8b51e2ec704d34897b80466e826b0c1ce2488511cbb1aaad26b075ed5ebf070be6e14eaa6b973423bcb2e0541307d88ff66d1b7e29fffb10218ca75bf3f9957d6ee27a0945278d5f9303b3e3f28a325a7f17905f7467c4afcbb3a43dbbd37e9591e3f5a82841ee9cb8b23f68b4572e8cd96d0f7daacbd3ab3bd5a8f427baf6ea7ae70d98d3948eafb74e2e4a158ac116c5219403c9073a457409c6e464bae32b2c856b15bda1b2176295fd1cecfe7d794ab2692061aa79387004112272204198437fc78d1dbe0e8932ce6f47828a2bf4df47446291b99d92a90de3623954589d36 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -119,23 +132,6 @@ def test_random_statetest205( nonce=0, address=Address(0xD6C9D572B7645ECAE86A7BDB66C7AE1FB04B0321), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest206.py b/tests/ported_static/stRandom/test_random_statetest206.py index 74be272c24a..f5cd2080539 100644 --- a/tests/ported_static/stRandom/test_random_statetest206.py +++ b/tests/ported_static/stRandom/test_random_statetest206.py @@ -46,6 +46,23 @@ def test_random_statetest206( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000427f0000000000000000000000000000000000000000000000000000000000000001427f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000006f45736d8e806138378d62087320313c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest206( nonce=0, address=Address(0xF62DC30A46D8736FF6C1CF524897B9EC5BCB62D7), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest207.py b/tests/ported_static/stRandom/test_random_statetest207.py index d79511062a5..586808a044e 100644 --- a/tests/ported_static/stRandom/test_random_statetest207.py +++ b/tests/ported_static/stRandom/test_random_statetest207.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest207( ) -> None: """Test_random_statetest207.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_random_statetest207( + Op.SSTORE, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x91D304E462C8CD746CA0A735A4E921B10CC49FE1), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -74,7 +70,6 @@ def test_random_statetest207( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest208.py b/tests/ported_static/stRandom/test_random_statetest208.py index 604ac238ee1..414e164a59f 100644 --- a/tests/ported_static/stRandom/test_random_statetest208.py +++ b/tests/ported_static/stRandom/test_random_statetest208.py @@ -46,6 +46,7 @@ def test_random_statetest208( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest208( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest209.py b/tests/ported_static/stRandom/test_random_statetest209.py index e9c894f5d5f..95ff6abc047 100644 --- a/tests/ported_static/stRandom/test_random_statetest209.py +++ b/tests/ported_static/stRandom/test_random_statetest209.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest209( ) -> None: """Test_random_statetest209.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest209( "7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0951537d3c6474623b781181a355" # noqa: E501 ), nonce=0, - address=Address(0x8BCAE160C58323E76F465E719B7F38A0049B17C9), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest209( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest210.py b/tests/ported_static/stRandom/test_random_statetest210.py index 654236bd6c4..aebd883f914 100644 --- a/tests/ported_static/stRandom/test_random_statetest210.py +++ b/tests/ported_static/stRandom/test_random_statetest210.py @@ -46,6 +46,7 @@ def test_random_statetest210( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x457f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest210( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest211.py b/tests/ported_static/stRandom/test_random_statetest211.py index 4f724711b3f..33bad535f67 100644 --- a/tests/ported_static/stRandom/test_random_statetest211.py +++ b/tests/ported_static/stRandom/test_random_statetest211.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest211( ) -> None: """Test_random_statetest211.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -77,7 +74,6 @@ def test_random_statetest211( + Op.PUSH21[0xF392A4AA2A84A99C9390AB4BD4C39F521A2B91C2EA] + Op.SWAP1, nonce=0, - address=Address(0xD7EB1DDC2F83F5620BD387BC6409BE3CC2D2422F), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -95,7 +91,6 @@ def test_random_statetest211( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest212.py b/tests/ported_static/stRandom/test_random_statetest212.py index 817ebf51d9b..6b6ed928909 100644 --- a/tests/ported_static/stRandom/test_random_statetest212.py +++ b/tests/ported_static/stRandom/test_random_statetest212.py @@ -46,6 +46,23 @@ def test_random_statetest212( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06180908ff3a68f28e61990a525560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,23 +94,6 @@ def test_random_statetest212( nonce=0, address=Address(0x4FCDEB59EA62AB23FBABB8475CC6B4D9A7B4EF10), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest214.py b/tests/ported_static/stRandom/test_random_statetest214.py index d89ae12e046..bed7fed40ef 100644 --- a/tests/ported_static/stRandom/test_random_statetest214.py +++ b/tests/ported_static/stRandom/test_random_statetest214.py @@ -46,6 +46,23 @@ def test_random_statetest214( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff150a6f7b056b335a15a48d7b8841163a50396360005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest214( nonce=0, address=Address(0xD1CAC1ED3EFF0ED4EA40EA82DDDCD79058F1BD25), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest215.py b/tests/ported_static/stRandom/test_random_statetest215.py index 275da2630e8..8b60689e9e6 100644 --- a/tests/ported_static/stRandom/test_random_statetest215.py +++ b/tests/ported_static/stRandom/test_random_statetest215.py @@ -46,20 +46,7 @@ def test_random_statetest215( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff446f728f4f1065583139780a981510173b9c60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x1] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 3 - + Op.PREVRANDAO - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x728F4F1065583139780A981510173B9C - ), - nonce=0, - address=Address(0xBE34DF8C26E53DBCAD75702212DEF7CC965BA9C4), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -76,7 +63,20 @@ def test_random_statetest215( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff446f728f4f1065583139780a981510173b9c60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x1] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 3 + + Op.PREVRANDAO + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x728F4F1065583139780A981510173B9C + ), + nonce=0, + address=Address(0xBE34DF8C26E53DBCAD75702212DEF7CC965BA9C4), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest216.py b/tests/ported_static/stRandom/test_random_statetest216.py index 3a8d5d54ef3..46b7748dc64 100644 --- a/tests/ported_static/stRandom/test_random_statetest216.py +++ b/tests/ported_static/stRandom/test_random_statetest216.py @@ -46,6 +46,23 @@ def test_random_statetest216( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350447f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3506d766d67fe0785320899130644945560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest216( nonce=0, address=Address(0x858B3A0BF7FDB672B31D89535881528C2214EB35), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest217.py b/tests/ported_static/stRandom/test_random_statetest217.py index 9aac9ca5d71..6ac0a1b7147 100644 --- a/tests/ported_static/stRandom/test_random_statetest217.py +++ b/tests/ported_static/stRandom/test_random_statetest217.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest217( ) -> None: """Test_random_statetest217.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,7 +56,6 @@ def test_random_statetest217( + Op.PUSH32[0x0] + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.PUSH32[0xC350]), nonce=0, - address=Address(0x83BE70F91F13B0D82FE2EA7D0551E807A7425F52), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -77,7 +73,6 @@ def test_random_statetest217( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest219.py b/tests/ported_static/stRandom/test_random_statetest219.py index 51f113f7a8d..11619b3a35e 100644 --- a/tests/ported_static/stRandom/test_random_statetest219.py +++ b/tests/ported_static/stRandom/test_random_statetest219.py @@ -46,6 +46,7 @@ def test_random_statetest219( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff437f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3506f6253443a4104027144577f339983205560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest219( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest22.py b/tests/ported_static/stRandom/test_random_statetest22.py index 442b7c1f6b5..07d72306d51 100644 --- a/tests/ported_static/stRandom/test_random_statetest22.py +++ b/tests/ported_static/stRandom/test_random_statetest22.py @@ -46,6 +46,7 @@ def test_random_statetest22( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6d417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e969f926084143c7960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest22( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest220.py b/tests/ported_static/stRandom/test_random_statetest220.py index 6ccf508f6d8..322eb005f67 100644 --- a/tests/ported_static/stRandom/test_random_statetest220.py +++ b/tests/ported_static/stRandom/test_random_statetest220.py @@ -46,21 +46,7 @@ def test_random_statetest220( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000016f420380a03c4282a3540a1a333a843a5560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ] - + Op.PUSH32[0x1] * 2 - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x420380A03C4282A3540A1A333A843A55 - ), - nonce=0, - address=Address(0xE245F75B111648E88B574DCC3BAC41A9665B655B), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest220( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000016f420380a03c4282a3540a1a333a843a5560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ] + + Op.PUSH32[0x1] * 2 + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x420380A03C4282A3540A1A333A843A55 + ), + nonce=0, + address=Address(0xE245F75B111648E88B574DCC3BAC41A9665B655B), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest221.py b/tests/ported_static/stRandom/test_random_statetest221.py index f504d998f96..6008fe23e11 100644 --- a/tests/ported_static/stRandom/test_random_statetest221.py +++ b/tests/ported_static/stRandom/test_random_statetest221.py @@ -46,6 +46,23 @@ def test_random_statetest221( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006f977789947e197f828151867a73771a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest221( nonce=0, address=Address(0x3DBB751081B1FB6B89523A708C6F333707AFF200), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest222.py b/tests/ported_static/stRandom/test_random_statetest222.py index f3a106c0419..afc7ae14c53 100644 --- a/tests/ported_static/stRandom/test_random_statetest222.py +++ b/tests/ported_static/stRandom/test_random_statetest222.py @@ -46,6 +46,7 @@ def test_random_statetest222( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000001000000000000000000000000000000000000000043397f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3508160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest222( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest225.py b/tests/ported_static/stRandom/test_random_statetest225.py index a9431d04b91..edb243054c4 100644 --- a/tests/ported_static/stRandom/test_random_statetest225.py +++ b/tests/ported_static/stRandom/test_random_statetest225.py @@ -46,6 +46,7 @@ def test_random_statetest225( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff506f69786c858e0703566f95f8993111901960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_random_statetest225( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest226.py b/tests/ported_static/stRandom/test_random_statetest226.py index 4fb7718504f..e8efcbb0224 100644 --- a/tests/ported_static/stRandom/test_random_statetest226.py +++ b/tests/ported_static/stRandom/test_random_statetest226.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest226( ) -> None: """Test_random_statetest226.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest226( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c350357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe5a605560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest226( + Op.GAS + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x55), nonce=0, - address=Address(0xC5676AEAB3D49C7E165B0F09B63906F533BC6232), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest227.py b/tests/ported_static/stRandom/test_random_statetest227.py index 5050dfbef6e..a7e4eb1926d 100644 --- a/tests/ported_static/stRandom/test_random_statetest227.py +++ b/tests/ported_static/stRandom/test_random_statetest227.py @@ -46,21 +46,7 @@ def test_random_statetest227( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000006f108fa27475689e44993a528752a152335955 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ] - + Op.PUSH32[0x0] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.SSTORE(key=Op.MSIZE, value=0x108FA27475689E44993A528752A15233), - nonce=0, - address=Address(0x2347A5C06FDB86220847AFAD360A945504752F3F), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest227( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000006f108fa27475689e44993a528752a152335955 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ] + + Op.PUSH32[0x0] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.SSTORE(key=Op.MSIZE, value=0x108FA27475689E44993A528752A15233), + nonce=0, + address=Address(0x2347A5C06FDB86220847AFAD360A945504752F3F), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest228.py b/tests/ported_static/stRandom/test_random_statetest228.py index 9d0b8b82b98..076b957a330 100644 --- a/tests/ported_static/stRandom/test_random_statetest228.py +++ b/tests/ported_static/stRandom/test_random_statetest228.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest228( ) -> None: """Test_random_statetest228.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,7 +57,6 @@ def test_random_statetest228( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5E86C1990271C79E1F71C1A16AE327A81EC9C863), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -78,7 +74,6 @@ def test_random_statetest228( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -89,10 +84,7 @@ def test_random_statetest228( ) post = { - target: Account( - storage={0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79}, - nonce=0, - ), + target: Account(storage={0: coinbase}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom/test_random_statetest23.py b/tests/ported_static/stRandom/test_random_statetest23.py index c17589acc88..58b93c80c3f 100644 --- a/tests/ported_static/stRandom/test_random_statetest23.py +++ b/tests/ported_static/stRandom/test_random_statetest23.py @@ -46,22 +46,7 @@ def test_random_statetest23( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000000000000000000000000000000000000000000001427f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f89418c1076f1544315601489386c915560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x1] - + Op.TIMESTAMP - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ] - * 2 - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x89418C1076F1544315601489386C9155 - ), - nonce=0, - address=Address(0xFC68069945CE60D6C215F7C22117D2FAD4A21CF4), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest23( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000000000000000000000000000000000000000000001427f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f89418c1076f1544315601489386c915560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x1] + + Op.TIMESTAMP + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ] + * 2 + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x89418C1076F1544315601489386C9155 + ), + nonce=0, + address=Address(0xFC68069945CE60D6C215F7C22117D2FAD4A21CF4), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest230.py b/tests/ported_static/stRandom/test_random_statetest230.py index 5797b56bc60..b197ea59848 100644 --- a/tests/ported_static/stRandom/test_random_statetest230.py +++ b/tests/ported_static/stRandom/test_random_statetest230.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest230( ) -> None: """Test_random_statetest230.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -64,7 +61,6 @@ def test_random_statetest230( ), ), nonce=0, - address=Address(0xF2D051C4061DE9BB62F3C8B53170AC76CAF27862), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -82,7 +78,6 @@ def test_random_statetest230( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest231.py b/tests/ported_static/stRandom/test_random_statetest231.py index 1f9ae45c87a..c80184d684b 100644 --- a/tests/ported_static/stRandom/test_random_statetest231.py +++ b/tests/ported_static/stRandom/test_random_statetest231.py @@ -46,6 +46,23 @@ def test_random_statetest231( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000006f7b98a491727a089df3365353329e805560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest231( nonce=0, address=Address(0x5EE95C2C0DB97541C35F0AFD60A2654AD805A5A6), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest232.py b/tests/ported_static/stRandom/test_random_statetest232.py index 14e720e5565..06d59d92bbc 100644 --- a/tests/ported_static/stRandom/test_random_statetest232.py +++ b/tests/ported_static/stRandom/test_random_statetest232.py @@ -46,15 +46,7 @@ def test_random_statetest232( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0945415883ff9d7760005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0945415883ff9d7760005155" # noqa: E501 - ), - nonce=0, - address=Address(0x037642EA84FC8808F2A16AF0EFEFF08B1649FADF), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +63,15 @@ def test_random_statetest232( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0945415883ff9d7760005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0945415883ff9d7760005155" # noqa: E501 + ), + nonce=0, + address=Address(0x037642EA84FC8808F2A16AF0EFEFF08B1649FADF), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest233.py b/tests/ported_static/stRandom/test_random_statetest233.py index 3b9da2acf65..023c0f438b0 100644 --- a/tests/ported_static/stRandom/test_random_statetest233.py +++ b/tests/ported_static/stRandom/test_random_statetest233.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest233( ) -> None: """Test_random_statetest233.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest233( + Op.PUSH32[0x10000000000000000000000000000000000000000] + Op.PUSH6[0x715460005155], nonce=0, - address=Address(0x05C62926921E990C1B91CB104C481076FF52B217), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest233( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest236.py b/tests/ported_static/stRandom/test_random_statetest236.py index a938617e353..6c905d7f42e 100644 --- a/tests/ported_static/stRandom/test_random_statetest236.py +++ b/tests/ported_static/stRandom/test_random_statetest236.py @@ -46,6 +46,7 @@ def test_random_statetest236( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000004339185560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest236( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest237.py b/tests/ported_static/stRandom/test_random_statetest237.py index a29a100d1ca..121d80b893e 100644 --- a/tests/ported_static/stRandom/test_random_statetest237.py +++ b/tests/ported_static/stRandom/test_random_statetest237.py @@ -46,6 +46,23 @@ def test_random_statetest237( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001537f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000000039385560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest237( nonce=0, address=Address(0xA5AB738681916D81130B09494A5E20288722B913), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -98,7 +98,7 @@ def test_random_statetest237( post = { target: Account( storage={ - 0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, + 0: coinbase, 239: 0x10000000000000000000000000000000000000000, }, nonce=0, diff --git a/tests/ported_static/stRandom/test_random_statetest238.py b/tests/ported_static/stRandom/test_random_statetest238.py index 72f74d8e706..0eefbdba085 100644 --- a/tests/ported_static/stRandom/test_random_statetest238.py +++ b/tests/ported_static/stRandom/test_random_statetest238.py @@ -46,6 +46,7 @@ def test_random_statetest238( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f7c748813587e990566719934f342316c60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest238( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest24.py b/tests/ported_static/stRandom/test_random_statetest24.py index 7643419280b..944d0513f3e 100644 --- a/tests/ported_static/stRandom/test_random_statetest24.py +++ b/tests/ported_static/stRandom/test_random_statetest24.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest24( ) -> None: """Test_random_statetest24.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest24( "41417f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff459d7f0000000000000000000000000000000000000000000000000000000000000001817f000000000000000000000000000000000000000000000000000000000000c35095418211337b0530435560005155" # noqa: E501 ), nonce=0, - address=Address(0x0EC19BD4E8D4C09BCCC0EDD6ECD58DD99B7B3212), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest24( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest242.py b/tests/ported_static/stRandom/test_random_statetest242.py index 741b8884608..c4ef8e01baf 100644 --- a/tests/ported_static/stRandom/test_random_statetest242.py +++ b/tests/ported_static/stRandom/test_random_statetest242.py @@ -46,6 +46,23 @@ def test_random_statetest242( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0860005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest242( nonce=0, address=Address(0xD7D4D253C278CBE720F14DC00ABE3DA337B583A1), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest243.py b/tests/ported_static/stRandom/test_random_statetest243.py index 48fea66f8e8..a7b3ff70602 100644 --- a/tests/ported_static/stRandom/test_random_statetest243.py +++ b/tests/ported_static/stRandom/test_random_statetest243.py @@ -46,6 +46,7 @@ def test_random_statetest243( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3506f4245446640764068625545586684905560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -73,7 +74,6 @@ def test_random_statetest243( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest244.py b/tests/ported_static/stRandom/test_random_statetest244.py index 0480047c7c7..528343eb2da 100644 --- a/tests/ported_static/stRandom/test_random_statetest244.py +++ b/tests/ported_static/stRandom/test_random_statetest244.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest244( ) -> None: """Test_random_statetest244.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_random_statetest244( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF02CC5C5E85BB5E8DA6BDC897CC5DA6E3AADE8AE), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -76,7 +72,6 @@ def test_random_statetest244( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -87,10 +82,7 @@ def test_random_statetest244( ) post = { - target: Account( - storage={0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79}, - nonce=0, - ), + target: Account(storage={0: coinbase}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom/test_random_statetest245.py b/tests/ported_static/stRandom/test_random_statetest245.py index bed80f5e9b3..36710ecc6df 100644 --- a/tests/ported_static/stRandom/test_random_statetest245.py +++ b/tests/ported_static/stRandom/test_random_statetest245.py @@ -46,6 +46,23 @@ def test_random_statetest245( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff157f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0469877c39141650434587895560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,23 +87,6 @@ def test_random_statetest245( nonce=0, address=Address(0x4F0F0D7E6642D0EC0C5AFFF326BD601D261562E1), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest246.py b/tests/ported_static/stRandom/test_random_statetest246.py index 0ca73f1e6a1..9faf3c0ea75 100644 --- a/tests/ported_static/stRandom/test_random_statetest246.py +++ b/tests/ported_static/stRandom/test_random_statetest246.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest246( """Test_random_statetest246.""" coinbase = Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,7 +58,6 @@ def test_random_statetest246( + Op.SSTORE(key=Op.MULMOD, value=Op.OR), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -79,7 +75,6 @@ def test_random_statetest246( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest247.py b/tests/ported_static/stRandom/test_random_statetest247.py index 06fb8df03c8..c60df68ff8d 100644 --- a/tests/ported_static/stRandom/test_random_statetest247.py +++ b/tests/ported_static/stRandom/test_random_statetest247.py @@ -46,6 +46,7 @@ def test_random_statetest247( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0460005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest247( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest248.py b/tests/ported_static/stRandom/test_random_statetest248.py index d25af824e49..ab1cb29ee75 100644 --- a/tests/ported_static/stRandom/test_random_statetest248.py +++ b/tests/ported_static/stRandom/test_random_statetest248.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest248( ) -> None: """Test_random_statetest248.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,7 +66,6 @@ def test_random_statetest248( + Op.SWAP1 + Op.SSTORE, nonce=0, - address=Address(0x6131276E33583C2356C9AC9B9EB5EEC9999EF591), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -87,7 +83,6 @@ def test_random_statetest248( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest249.py b/tests/ported_static/stRandom/test_random_statetest249.py index cfae8533c5f..7ab3fa90762 100644 --- a/tests/ported_static/stRandom/test_random_statetest249.py +++ b/tests/ported_static/stRandom/test_random_statetest249.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest249( ) -> None: """Test_random_statetest249.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest249( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x315A0A977EADE1395B4C6A0B078C1EF3CFAF03B9), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest249( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest25.py b/tests/ported_static/stRandom/test_random_statetest25.py index 1a57eb69d60..0d6cbc6c271 100644 --- a/tests/ported_static/stRandom/test_random_statetest25.py +++ b/tests/ported_static/stRandom/test_random_statetest25.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest25( ) -> None: """Test_random_statetest25.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest25( "427f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000010000000000000000000000000000000000000000437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6844f1389163a444405b123678749c55" # noqa: E501 ), nonce=0, - address=Address(0xA4BA89AEA3BBA17580E93A80135F218628A68101), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest25( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest250.py b/tests/ported_static/stRandom/test_random_statetest250.py index 840be0eca9e..49410929b7f 100644 --- a/tests/ported_static/stRandom/test_random_statetest250.py +++ b/tests/ported_static/stRandom/test_random_statetest250.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest250( ) -> None: """Test_random_statetest250.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest250( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x557ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000627f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000006a328b186e166407917c7af102925060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,25 +82,7 @@ def test_random_statetest250( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x089927DAF7E20B167E29C7DC686D18639371E6BF), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest251.py b/tests/ported_static/stRandom/test_random_statetest251.py index c9bb1b29d08..194201527c7 100644 --- a/tests/ported_static/stRandom/test_random_statetest251.py +++ b/tests/ported_static/stRandom/test_random_statetest251.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest251( ) -> None: """Test_random_statetest251.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest251( "7f0000000000000000000000000000000000000000000000000000000000000000447f000000000000000000000000000000000000000000000000000000000000c3505b7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417f00000000000000000000000000000000000000000000000000000000000000006867f1" # noqa: E501 ), nonce=0, - address=Address(0x75A7D42B361CA2FF027B1CBC1418D431D3C31F27), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest251( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest252.py b/tests/ported_static/stRandom/test_random_statetest252.py index ca773f8282f..092b4e019a5 100644 --- a/tests/ported_static/stRandom/test_random_statetest252.py +++ b/tests/ported_static/stRandom/test_random_statetest252.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest252( ) -> None: """Test_random_statetest252.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest252( code=bytes.fromhex("387b414543444043899e863a628b55"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCB10591583644B914D53D1D9538866320D00BAD3), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest252( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest254.py b/tests/ported_static/stRandom/test_random_statetest254.py index 56f7f235f77..0833e0aedfc 100644 --- a/tests/ported_static/stRandom/test_random_statetest254.py +++ b/tests/ported_static/stRandom/test_random_statetest254.py @@ -46,6 +46,7 @@ def test_random_statetest254( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000001000000000000000000000000000000000000000041417f0000000000000000000000000000000000000000000000000000000000000001447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3506f059b6b83f294740688598c52195a925560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest254( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest257.py b/tests/ported_static/stRandom/test_random_statetest257.py index 28530d23ed7..336a5e4d62e 100644 --- a/tests/ported_static/stRandom/test_random_statetest257.py +++ b/tests/ported_static/stRandom/test_random_statetest257.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest257( ) -> None: """Test_random_statetest257.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest257( "7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff337f000000000000000000000000000000000000000000000000000000000000000099447ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c350735b9f81208b6f526655" # noqa: E501 ), nonce=0, - address=Address(0x85004625C8C4EAAAFED36A6ECB4835FDEA0F2B6B), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest257( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest259.py b/tests/ported_static/stRandom/test_random_statetest259.py index 743a4de5e92..741bf622b88 100644 --- a/tests/ported_static/stRandom/test_random_statetest259.py +++ b/tests/ported_static/stRandom/test_random_statetest259.py @@ -46,6 +46,23 @@ def test_random_statetest259( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001587fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3506f04831adc0812f095449274079007095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest259( nonce=0, address=Address(0x55C5E809A00F9BD86D7E2F6EDAE5D54B76B881FF), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest26.py b/tests/ported_static/stRandom/test_random_statetest26.py index 57a6f8271e9..aaba1ac0402 100644 --- a/tests/ported_static/stRandom/test_random_statetest26.py +++ b/tests/ported_static/stRandom/test_random_statetest26.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest26( ) -> None: """Test_random_statetest26.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_random_statetest26( + Op.SSTORE(key=Op.SMOD, value=Op.BALANCE(address=Op.COINBASE)), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x40C94440235E91BD2D3E4555B8663698DC80D6CA), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -74,7 +70,6 @@ def test_random_statetest26( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest260.py b/tests/ported_static/stRandom/test_random_statetest260.py index 99815fa7703..1890f239eb6 100644 --- a/tests/ported_static/stRandom/test_random_statetest260.py +++ b/tests/ported_static/stRandom/test_random_statetest260.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest260( ) -> None: """Test_random_statetest260.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,7 +57,6 @@ def test_random_statetest260( + Op.JUMP(pc=0x413B) + Op.SSTORE(key=Op.ADDMOD, value=Op.CALLCODE), nonce=0, - address=Address(0x912E90647207810A8FA1F685D7CD4A5BAA06E85D), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -78,7 +74,6 @@ def test_random_statetest260( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest261.py b/tests/ported_static/stRandom/test_random_statetest261.py index cd1f42684ca..bd3d7c0e6ae 100644 --- a/tests/ported_static/stRandom/test_random_statetest261.py +++ b/tests/ported_static/stRandom/test_random_statetest261.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest261( ) -> None: """Test_random_statetest261.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest261( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000000000000000000000000000000000000000000000447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000001231b61993 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000000000000000000000000000000000000000000000447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000100000000000000000000000000000000000000001231b61993" # noqa: E501 - ), - nonce=0, - address=Address(0x439F60D09BA1D7E67458E16721B402EA66BB69EF), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest261( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000000000000000000000000000000000000000000000447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000001231b61993 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000000000000000000000000000000000000000000000447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000100000000000000000000000000000000000000001231b61993" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest263.py b/tests/ported_static/stRandom/test_random_statetest263.py index be0119ce632..002ca645f8f 100644 --- a/tests/ported_static/stRandom/test_random_statetest263.py +++ b/tests/ported_static/stRandom/test_random_statetest263.py @@ -48,6 +48,23 @@ def test_random_statetest263( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5807f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0418625560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -71,23 +88,6 @@ def test_random_statetest263( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest264.py b/tests/ported_static/stRandom/test_random_statetest264.py index 3bab4e44d25..ff0a9191e40 100644 --- a/tests/ported_static/stRandom/test_random_statetest264.py +++ b/tests/ported_static/stRandom/test_random_statetest264.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest264( ) -> None: """Test_random_statetest264.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest264( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0955 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,25 +77,7 @@ def test_random_statetest264( value=Op.PUSH32[0x1], ), nonce=0, - address=Address(0xC3FDD8CBA888F2C918DDC3B417AA58966E99B219), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest265.py b/tests/ported_static/stRandom/test_random_statetest265.py index 761374323f9..3d6e9b7db7a 100644 --- a/tests/ported_static/stRandom/test_random_statetest265.py +++ b/tests/ported_static/stRandom/test_random_statetest265.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest265( ) -> None: """Test_random_statetest265.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest265( "7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3503b7f000000000000000000000000000000000000000000000000000000000000c3506a7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000745b9b824070397f921960005155" # noqa: E501 ), nonce=0, - address=Address(0x897196687E79DB7A21310478E9BA6CC9D6C1209E), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest265( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest266.py b/tests/ported_static/stRandom/test_random_statetest266.py index c0070a5f7c5..99e4fe62d6a 100644 --- a/tests/ported_static/stRandom/test_random_statetest266.py +++ b/tests/ported_static/stRandom/test_random_statetest266.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest266( ) -> None: """Test_random_statetest266.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest266( + Op.MLOAD + Op.SSTORE, nonce=0, - address=Address(0x118B2FA6CFAB667C42CCB5C5EEEE4DC3AF2CAE15), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest266( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest267.py b/tests/ported_static/stRandom/test_random_statetest267.py index f535268e398..8e738d330bb 100644 --- a/tests/ported_static/stRandom/test_random_statetest267.py +++ b/tests/ported_static/stRandom/test_random_statetest267.py @@ -47,6 +47,23 @@ def test_random_statetest267( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x447f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f00000000000000000000000000000000000000000000000000000000000000007e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5a132776d398e3b7c14686a07346f60005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest267( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest268.py b/tests/ported_static/stRandom/test_random_statetest268.py index aea0f21b0e2..f6c95ccca4c 100644 --- a/tests/ported_static/stRandom/test_random_statetest268.py +++ b/tests/ported_static/stRandom/test_random_statetest268.py @@ -46,6 +46,23 @@ def test_random_statetest268( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000016f7466f0a0733d8632639340634094425560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest268( nonce=0, address=Address(0xD08041E77CE5A71EF2702EC933DC4F4377406A27), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest269.py b/tests/ported_static/stRandom/test_random_statetest269.py index 28e9f509afe..208ba09f6da 100644 --- a/tests/ported_static/stRandom/test_random_statetest269.py +++ b/tests/ported_static/stRandom/test_random_statetest269.py @@ -46,6 +46,23 @@ def test_random_statetest269( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6676029968ffa27d0455 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest269( nonce=0, address=Address(0x406AAE16E0D6F5CBB11D327D208F8EBC342A7D5B), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest27.py b/tests/ported_static/stRandom/test_random_statetest27.py index 7f7e030dba1..c45f829d231 100644 --- a/tests/ported_static/stRandom/test_random_statetest27.py +++ b/tests/ported_static/stRandom/test_random_statetest27.py @@ -46,6 +46,23 @@ def test_random_statetest27( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000000960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest27( nonce=0, address=Address(0x7474A32FA320E72DFE3023106276E5D2B810D1F4), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest270.py b/tests/ported_static/stRandom/test_random_statetest270.py index 35d8d849e21..1331693dee1 100644 --- a/tests/ported_static/stRandom/test_random_statetest270.py +++ b/tests/ported_static/stRandom/test_random_statetest270.py @@ -46,6 +46,23 @@ def test_random_statetest270( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x427f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001395560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest270( nonce=0, address=Address(0x2EF12D7C660739849FA667BC47E3800325185541), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest271.py b/tests/ported_static/stRandom/test_random_statetest271.py index 5ed18719793..3d33887fec9 100644 --- a/tests/ported_static/stRandom/test_random_statetest271.py +++ b/tests/ported_static/stRandom/test_random_statetest271.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest271( ) -> None: """Test_random_statetest271.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest271( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000000000000000000000000000000000000000000001457f000000000000000000000000000000000000000000000000000000000000c350417f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000357f00000000000000000000000000000000000000000000000000000000000000000b6d7d958a0269995560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000000000000000000000000000000000000000000001457f000000000000000000000000000000000000000000000000000000000000c350417f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000000000000000000000000000000000000000000000357f00000000000000000000000000000000000000000000000000000000000000000b6d7d958a0269995560005155" # noqa: E501 - ), - nonce=0, - address=Address(0xB45F31DD95616972767DD62E9B996E22566AAEC1), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest271( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000000000000000000000000000000000000000000001457f000000000000000000000000000000000000000000000000000000000000c350417f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000357f00000000000000000000000000000000000000000000000000000000000000000b6d7d958a0269995560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000000000000000000000000000000000000000000001457f000000000000000000000000000000000000000000000000000000000000c350417f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000000000000000000000000000000000000000000000357f00000000000000000000000000000000000000000000000000000000000000000b6d7d958a0269995560005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest273.py b/tests/ported_static/stRandom/test_random_statetest273.py index 8aea76827b9..d7d77f8c1bc 100644 --- a/tests/ported_static/stRandom/test_random_statetest273.py +++ b/tests/ported_static/stRandom/test_random_statetest273.py @@ -46,6 +46,7 @@ def test_random_statetest273( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x4342424343425b4495fff04285609955 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest273( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest274.py b/tests/ported_static/stRandom/test_random_statetest274.py index faa36bae460..b095ed1ebcb 100644 --- a/tests/ported_static/stRandom/test_random_statetest274.py +++ b/tests/ported_static/stRandom/test_random_statetest274.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest274( ) -> None: """Test_random_statetest274.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest274( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffffa405457f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000088015a9a0542a13a051497514215 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,25 +80,7 @@ def test_random_statetest274( + Op.MLOAD + Op.ISZERO(Op.TIMESTAMP), nonce=0, - address=Address(0x89CD1261AD57A9678AC21ADB1C06750567D685F4), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest275.py b/tests/ported_static/stRandom/test_random_statetest275.py index f2446be9245..72f1dadc0e8 100644 --- a/tests/ported_static/stRandom/test_random_statetest275.py +++ b/tests/ported_static/stRandom/test_random_statetest275.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest275( ) -> None: """Test_random_statetest275.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest275( ), ), nonce=0, - address=Address(0x69D3E12FB87D7EFFEB9DED3D46879EBE02925B4E), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest275( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest276.py b/tests/ported_static/stRandom/test_random_statetest276.py index 6121acfce3e..8815e7bf241 100644 --- a/tests/ported_static/stRandom/test_random_statetest276.py +++ b/tests/ported_static/stRandom/test_random_statetest276.py @@ -46,6 +46,7 @@ def test_random_statetest276( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f4382349f7b370589141a31f39741a4f260005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest276( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest278.py b/tests/ported_static/stRandom/test_random_statetest278.py index c7b49dd427a..b659b93237d 100644 --- a/tests/ported_static/stRandom/test_random_statetest278.py +++ b/tests/ported_static/stRandom/test_random_statetest278.py @@ -46,6 +46,7 @@ def test_random_statetest278( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001377f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest278( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest279.py b/tests/ported_static/stRandom/test_random_statetest279.py index a30ec6c5fd9..2420986fd76 100644 --- a/tests/ported_static/stRandom/test_random_statetest279.py +++ b/tests/ported_static/stRandom/test_random_statetest279.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest279( ) -> None: """Test_random_statetest279.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest279( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000010000000000000000000000000000000000000000947f00000000000000000000000060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest279( value=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], ), nonce=0, - address=Address(0x35596AA142F6FC0097B6FBE0D02A4E1CB3B7B043), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,10 +91,7 @@ def test_random_statetest279( ) post = { - target: Account( - storage={0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79}, - nonce=0, - ), + target: Account(storage={0: coinbase}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom/test_random_statetest28.py b/tests/ported_static/stRandom/test_random_statetest28.py index d72f3572d13..fd926360efa 100644 --- a/tests/ported_static/stRandom/test_random_statetest28.py +++ b/tests/ported_static/stRandom/test_random_statetest28.py @@ -46,6 +46,23 @@ def test_random_statetest28( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000006f38129d68939a19a2697172926f6a67363055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest28( nonce=0, address=Address(0xDF2D980D762338E0DA723885B33558D435309A78), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest280.py b/tests/ported_static/stRandom/test_random_statetest280.py index 468dd52daf2..40474d5a42d 100644 --- a/tests/ported_static/stRandom/test_random_statetest280.py +++ b/tests/ported_static/stRandom/test_random_statetest280.py @@ -46,6 +46,7 @@ def test_random_statetest280( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000000143507f000000000000000000000000000000000000000000000000000000000000c350417f00000000000000000000000000000000000000000000000000000000000000006f423b3c407e7c6f16718668738d193cf260005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -76,7 +77,6 @@ def test_random_statetest280( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest281.py b/tests/ported_static/stRandom/test_random_statetest281.py index f9e0cb44030..eb2fffccff2 100644 --- a/tests/ported_static/stRandom/test_random_statetest281.py +++ b/tests/ported_static/stRandom/test_random_statetest281.py @@ -46,20 +46,7 @@ def test_random_statetest281( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f000000000000000000000000457f000000000000000000000000000000000000000000000000000000000000c350417f00000000000000000000000000000000000000000000000000000000000000016f649a7a3457645670a27fa170639718a260005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 - + Op.GASLIMIT - + Op.PUSH32[0xC350] - + Op.COINBASE - + Op.PUSH32[0x1] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x649A7A3457645670A27FA170639718A2 - ), - nonce=0, - address=Address(0xED3690010055EAB6A7103A13E1E74492E67FD00F), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -76,7 +63,20 @@ def test_random_statetest281( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f000000000000000000000000457f000000000000000000000000000000000000000000000000000000000000c350417f00000000000000000000000000000000000000000000000000000000000000016f649a7a3457645670a27fa170639718a260005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 + + Op.GASLIMIT + + Op.PUSH32[0xC350] + + Op.COINBASE + + Op.PUSH32[0x1] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x649A7A3457645670A27FA170639718A2 + ), + nonce=0, + address=Address(0xED3690010055EAB6A7103A13E1E74492E67FD00F), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest282.py b/tests/ported_static/stRandom/test_random_statetest282.py index 2fd31c3f6cd..490fe3bac97 100644 --- a/tests/ported_static/stRandom/test_random_statetest282.py +++ b/tests/ported_static/stRandom/test_random_statetest282.py @@ -46,6 +46,23 @@ def test_random_statetest282( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ff447f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff429d415560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest282( nonce=0, address=Address(0x14209E1C3D86DEC137A40E23CA3CEEC80421DA46), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest283.py b/tests/ported_static/stRandom/test_random_statetest283.py index e8af79a9407..b0f7f17ceff 100644 --- a/tests/ported_static/stRandom/test_random_statetest283.py +++ b/tests/ported_static/stRandom/test_random_statetest283.py @@ -46,6 +46,7 @@ def test_random_statetest283( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000013960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest283( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest285.py b/tests/ported_static/stRandom/test_random_statetest285.py index 189e98f6ab8..c2e21d35bd7 100644 --- a/tests/ported_static/stRandom/test_random_statetest285.py +++ b/tests/ported_static/stRandom/test_random_statetest285.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest285( ) -> None: """Test_random_statetest285.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest285( code=bytes.fromhex("413443f3404242433389ff723810"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x42C6DF39ABD3D7DE1C64C50B0D8BB0E6085FB6AF), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest285( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest286.py b/tests/ported_static/stRandom/test_random_statetest286.py index 20cc937c830..0c4d5538e24 100644 --- a/tests/ported_static/stRandom/test_random_statetest286.py +++ b/tests/ported_static/stRandom/test_random_statetest286.py @@ -47,6 +47,23 @@ def test_random_statetest286( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x5a7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000009582860460005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest286( nonce=0, address=Address(0xF72E559DBB45A1B06CEFDB38D53632F23795EC0E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest287.py b/tests/ported_static/stRandom/test_random_statetest287.py index 4664d93b3bf..88ee08e38b4 100644 --- a/tests/ported_static/stRandom/test_random_statetest287.py +++ b/tests/ported_static/stRandom/test_random_statetest287.py @@ -46,6 +46,23 @@ def test_random_statetest287( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ff7f00000000000000000000000100000000000000000000000000000000000000000759 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest287( nonce=0, address=Address(0x31C15A33D833B7C1A49E3F28E6D2B2D975F578BD), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest288.py b/tests/ported_static/stRandom/test_random_statetest288.py index b209dd90594..9b7cf063be2 100644 --- a/tests/ported_static/stRandom/test_random_statetest288.py +++ b/tests/ported_static/stRandom/test_random_statetest288.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest288( ) -> None: """Test_random_statetest288.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest288( code=bytes.fromhex("76404140424242458c1f11410b"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x491EC6B2F8EC53C669DB820E13F80F4987CDD1E4), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest288( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest29.py b/tests/ported_static/stRandom/test_random_statetest29.py index c11d6f44d3a..348e55ad7d8 100644 --- a/tests/ported_static/stRandom/test_random_statetest29.py +++ b/tests/ported_static/stRandom/test_random_statetest29.py @@ -46,6 +46,7 @@ def test_random_statetest29( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0955 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest29( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest290.py b/tests/ported_static/stRandom/test_random_statetest290.py index 1c3af984856..34a94a78a58 100644 --- a/tests/ported_static/stRandom/test_random_statetest290.py +++ b/tests/ported_static/stRandom/test_random_statetest290.py @@ -46,6 +46,23 @@ def test_random_statetest290( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe830960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest290( nonce=0, address=Address(0xBBAE1A0C728B648C79D5AD774502558645162573), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest291.py b/tests/ported_static/stRandom/test_random_statetest291.py index b0749b9cfe5..6fae04c441a 100644 --- a/tests/ported_static/stRandom/test_random_statetest291.py +++ b/tests/ported_static/stRandom/test_random_statetest291.py @@ -46,6 +46,7 @@ def test_random_statetest291( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000015560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest291( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest292.py b/tests/ported_static/stRandom/test_random_statetest292.py index 557f3c85da1..33dd50d35a6 100644 --- a/tests/ported_static/stRandom/test_random_statetest292.py +++ b/tests/ported_static/stRandom/test_random_statetest292.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest292( ) -> None: """Test_random_statetest292.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest292( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000417f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000013063a09c825a338e # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,25 +79,7 @@ def test_random_statetest292( + Op.CALLER + Op.DUP15, nonce=0, - address=Address(0x6F333ED29BA1F098BA2B1F681F8E6131C7F3D2C2), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest293.py b/tests/ported_static/stRandom/test_random_statetest293.py index 9b516d51016..735739a25eb 100644 --- a/tests/ported_static/stRandom/test_random_statetest293.py +++ b/tests/ported_static/stRandom/test_random_statetest293.py @@ -46,6 +46,7 @@ def test_random_statetest293( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f458962699489837460090897f3056682845560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest293( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest294.py b/tests/ported_static/stRandom/test_random_statetest294.py index b951f2aa971..e1ac3b28387 100644 --- a/tests/ported_static/stRandom/test_random_statetest294.py +++ b/tests/ported_static/stRandom/test_random_statetest294.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest294( ) -> None: """Test_random_statetest294.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest294( "057fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9d0718f377825843028dfa02158878" # noqa: E501 ), nonce=0, - address=Address(0xEAF8F32047C68F3092D0C23D440C8F5E910865B0), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest294( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest295.py b/tests/ported_static/stRandom/test_random_statetest295.py index f6df4452515..2bfdf406f3e 100644 --- a/tests/ported_static/stRandom/test_random_statetest295.py +++ b/tests/ported_static/stRandom/test_random_statetest295.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest295( ) -> None: """Test_random_statetest295.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest295( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000031353a0b3c8b17eb55 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e7931353a0b3c8b17eb55" # noqa: E501 - ), - nonce=0, - address=Address(0x8B2CF534E72A2AF416B63FAE177D57DEDAEEC9E9), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest295( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000031353a0b3c8b17eb55 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e7931353a0b3c8b17eb55" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest296.py b/tests/ported_static/stRandom/test_random_statetest296.py index 82c36e2e27e..5a61d0e00b1 100644 --- a/tests/ported_static/stRandom/test_random_statetest296.py +++ b/tests/ported_static/stRandom/test_random_statetest296.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest296( ) -> None: """Test_random_statetest296.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest296( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000385b9655558f510a6c73 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79385b9655558f510a6c73" # noqa: E501 - ), - nonce=0, - address=Address(0xC2006FD0F9C78C5404B143C53D5E4E7AA4B20324), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest296( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000385b9655558f510a6c73 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79385b9655558f510a6c73" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest297.py b/tests/ported_static/stRandom/test_random_statetest297.py index 6b853bb0c01..88f9ae81fcd 100644 --- a/tests/ported_static/stRandom/test_random_statetest297.py +++ b/tests/ported_static/stRandom/test_random_statetest297.py @@ -46,6 +46,23 @@ def test_random_statetest297( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000437f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe426f91085661509214157d9c8a777585185560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest297( nonce=0, address=Address(0x63B282B5DF9618A0F5C8B782F7286EB615A43B27), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest298.py b/tests/ported_static/stRandom/test_random_statetest298.py index fb4f277235f..05af899ef1a 100644 --- a/tests/ported_static/stRandom/test_random_statetest298.py +++ b/tests/ported_static/stRandom/test_random_statetest298.py @@ -46,21 +46,7 @@ def test_random_statetest298( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3500a6f7c542006528b69ff3a7a3a0401613c5560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xC350] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0x0] - + Op.EXP(Op.PUSH32[0xC350], Op.PUSH32[0x0]) - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x7C542006528B69FF3A7A3A0401613C55 - ), - nonce=0, - address=Address(0xF6D0D02E9E0BF01606955313230D637E54E8525A), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest298( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3500a6f7c542006528b69ff3a7a3a0401613c5560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xC350] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0x0] + + Op.EXP(Op.PUSH32[0xC350], Op.PUSH32[0x0]) + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x7C542006528B69FF3A7A3A0401613C55 + ), + nonce=0, + address=Address(0xF6D0D02E9E0BF01606955313230D637E54E8525A), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest299.py b/tests/ported_static/stRandom/test_random_statetest299.py index 9e5024203e6..bc153c40fd5 100644 --- a/tests/ported_static/stRandom/test_random_statetest299.py +++ b/tests/ported_static/stRandom/test_random_statetest299.py @@ -46,6 +46,7 @@ def test_random_statetest299( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f540813697adf70f20906389d128bf05560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_random_statetest299( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest3.py b/tests/ported_static/stRandom/test_random_statetest3.py index f52c40879bc..c29a08bfa7f 100644 --- a/tests/ported_static/stRandom/test_random_statetest3.py +++ b/tests/ported_static/stRandom/test_random_statetest3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest3( ) -> None: """Test_random_statetest3.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,21 +43,6 @@ def test_random_statetest3( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000000000000000000000000000000000000000c3504160005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.TIMESTAMP - + Op.PUSH32[0xC350] - + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.COINBASE), - nonce=0, - address=Address(0xA2F0E94715A4D0E22C705690F7CACBF1D4EEF1F6), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +59,20 @@ def test_random_statetest3( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000000000000000000000000000000000000000c3504160005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.TIMESTAMP + + Op.PUSH32[0xC350] + + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.COINBASE), + nonce=0, + ) tx = Transaction( sender=sender, @@ -90,10 +85,7 @@ def test_random_statetest3( ) post = { - target: Account( - storage={0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79}, - nonce=0, - ), + target: Account(storage={0: coinbase}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom/test_random_statetest30.py b/tests/ported_static/stRandom/test_random_statetest30.py index a46994583ae..261a71122b7 100644 --- a/tests/ported_static/stRandom/test_random_statetest30.py +++ b/tests/ported_static/stRandom/test_random_statetest30.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest30( ) -> None: """Test_random_statetest30.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest30( code=Op.SSTORE(key=Op.COINBASE, value=Op.BALANCE(address=Op.COINBASE)), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7801ABE412E60E0E8ECD8C01F4E464732476B1F8), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest30( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest300.py b/tests/ported_static/stRandom/test_random_statetest300.py index e01413617c0..66861dbcf29 100644 --- a/tests/ported_static/stRandom/test_random_statetest300.py +++ b/tests/ported_static/stRandom/test_random_statetest300.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest300( ) -> None: """Test_random_statetest300.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,7 +58,6 @@ def test_random_statetest300( ] + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.PUSH32[0xC350]), nonce=0, - address=Address(0xC4E0B0EE0EF1C851E1FF17D15C1E0EC5318B2A07), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -79,7 +75,6 @@ def test_random_statetest300( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest301.py b/tests/ported_static/stRandom/test_random_statetest301.py index adcdbbb5be9..c7b65ce2bf7 100644 --- a/tests/ported_static/stRandom/test_random_statetest301.py +++ b/tests/ported_static/stRandom/test_random_statetest301.py @@ -46,6 +46,7 @@ def test_random_statetest301( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000003784946a737aa092f1975664518a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_random_statetest301( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest302.py b/tests/ported_static/stRandom/test_random_statetest302.py index 806cb9b87d1..b1efad7461a 100644 --- a/tests/ported_static/stRandom/test_random_statetest302.py +++ b/tests/ported_static/stRandom/test_random_statetest302.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest302( ) -> None: """Test_random_statetest302.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest302( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000971a7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff447f00000000000000000000000000000000000000000000000000000000000000006989206c0b8a01867bf155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.SWAP8 - + Op.BYTE - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PREVRANDAO - + Op.PUSH32[0x0] - + Op.PUSH10[0x89206C0B8A01867BF155], - nonce=0, - address=Address(0xFCBCBA7CBA75059C569BE5870CA9B87A68DA093A), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest302( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000971a7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff447f00000000000000000000000000000000000000000000000000000000000000006989206c0b8a01867bf155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.SWAP8 + + Op.BYTE + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PREVRANDAO + + Op.PUSH32[0x0] + + Op.PUSH10[0x89206C0B8A01867BF155], + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest303.py b/tests/ported_static/stRandom/test_random_statetest303.py index 01abb28e1bf..cf1d7bebbec 100644 --- a/tests/ported_static/stRandom/test_random_statetest303.py +++ b/tests/ported_static/stRandom/test_random_statetest303.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest303( ) -> None: """Test_random_statetest303.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest303( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000457f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba46699913755 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79457f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba46699913755" # noqa: E501 - ), - nonce=0, - address=Address(0xBDFD7B81900BFD715187BFA71345114F62FB7494), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest303( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000457f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba46699913755 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79457f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff441a35803a0ba46699913755" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest304.py b/tests/ported_static/stRandom/test_random_statetest304.py index c8cb6b16f5c..b1e7d637b36 100644 --- a/tests/ported_static/stRandom/test_random_statetest304.py +++ b/tests/ported_static/stRandom/test_random_statetest304.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest304( ) -> None: """Test_random_statetest304.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_random_statetest304( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xEED16AB98D10EE33A19828F9FD044B86553A6F06), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -91,7 +87,6 @@ def test_random_statetest304( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest305.py b/tests/ported_static/stRandom/test_random_statetest305.py index 83e92c975b9..d9093d48f46 100644 --- a/tests/ported_static/stRandom/test_random_statetest305.py +++ b/tests/ported_static/stRandom/test_random_statetest305.py @@ -46,6 +46,23 @@ def test_random_statetest305( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006f606e048240069c409313318736200b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest305( nonce=0, address=Address(0xB84CACE13BD713234F804BD202EF20EC6360C36C), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest306.py b/tests/ported_static/stRandom/test_random_statetest306.py index 91a13c84119..17f34a3a28f 100644 --- a/tests/ported_static/stRandom/test_random_statetest306.py +++ b/tests/ported_static/stRandom/test_random_statetest306.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest306( ) -> None: """Test_random_statetest306.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest306( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x60d36e84517b3285b0867cd4144ff5f688d60b6a07592395d95e37246c06736c78c9fa9e4b5e5db5a4b6ac4ced6dd169cda4fc3c11e9a6f0b4cec2f56019617df7a363788c155473412582d556f06c6d5864cf4be6a2d1318b8e40ba1377454cc8d0510823591dee680d7dddc8c149bfcc24c65c69e66c2b9d3e28f05faf2587c446509405759901ec0946bf3d786827225faf5da81e158cd9b2b4666f71a29fbe89f77c340dcbd7d67aedf852136b6c76affb38beb802e0af269e65c22f52807c677b5e2c7d8c473aff18fe912c7ed21ab60fe5d4916a76c93539332c6ab16b3f81b990f4b34b0228c7f5b1656bdd21d458717330e4be7d7bb91cc95818140eef086cd82d2d6f0d66c92a7ffb27125a625c77a8967268f212339508d6f60d9c93a9e201f2ae883cb9752460ec0dcb4ba3b84a4db899c29f08ef1b0f506b4f3c05601f6001601060116328b0eb5f73630a4eb375f17df238e15d7d51240301521f173d628e7a68d01354faaf406ce541f753db89671f6aedcf261f632e6244e8c3799a2de002f15ba4681fd3c609c0f522dfd964f95def9926f812327781b2de33196cc22776e9b26d8a0d65c57bdac987d0b3e0db66c0f1232c7add3365f209cc53592f73502d0c5889b1bbf131f8bb6a6b5e2e067b9ef676768d48b3f5790c3304e046f0a9c8a838a0596583d6258f196dcf982a9de5cec4f871470e7a6c9289615e1e7d140fdc038972916223fb8012e29350295f3919cb28a36411845930d5e91b68510faac5e0677953467cedb653f73818749e8cbaf15a5d64ba7ee5cabc98137167b924a2aac9147f159713d115e0225a84a54d6471dc7a01a7e4e814145305c9d04d2880c5be42fc6c52ced3e983d91a580a4142021b73e99c3180117914b9ad03c580a8dac862be9b599a73ccfcfb230bcffc425c13c265f3b06b8c9f104c10752740765567374c211601a5f51501d18c48081998ff7b7a8bfdf0bec9eb4385b554870a996e0cab662d991d0e5f9357f2f99f98 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -122,23 +135,6 @@ def test_random_statetest306( nonce=0, address=Address(0xCE8D3E84F685B2EED55366547289AC4D314DE277), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest307.py b/tests/ported_static/stRandom/test_random_statetest307.py index 4e6aae35945..b2a8f51c93f 100644 --- a/tests/ported_static/stRandom/test_random_statetest307.py +++ b/tests/ported_static/stRandom/test_random_statetest307.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_random_statetest307( """Test_random_statetest307.""" coinbase = Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,23 +45,6 @@ def test_random_statetest307( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5547f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000037f055 # noqa: E501 - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x945304EB96065B2A98B57A48A06AE28D285A71B5] - + Op.PUSH32[0xC350] - + Op.SLOAD(key=Op.PUSH32[0x945304EB96065B2A98B57A48A06AE28D285A71B5]) - + Op.PUSH32[0xC350] - + Op.CALLDATACOPY( - dest_offset=Op.PUSH32[0x0], - offset=Op.PUSH32[0x0], - size=Op.PUSH32[0xC350], - ) - + Op.CREATE - + Op.SSTORE, - nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -81,7 +61,22 @@ def test_random_statetest307( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5547f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000037f055 # noqa: E501 + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x945304EB96065B2A98B57A48A06AE28D285A71B5] + + Op.PUSH32[0xC350] + + Op.SLOAD(key=Op.PUSH32[0x945304EB96065B2A98B57A48A06AE28D285A71B5]) + + Op.PUSH32[0xC350] + + Op.CALLDATACOPY( + dest_offset=Op.PUSH32[0x0], + offset=Op.PUSH32[0x0], + size=Op.PUSH32[0xC350], + ) + + Op.CREATE + + Op.SSTORE, + nonce=0, + ) tx = Transaction( sender=sender, @@ -95,11 +90,13 @@ def test_random_statetest307( post = { contract_0: Account(storage={}, nonce=0), - Address( - 0x62C01474F089B07DAE603491675DC5B5748F7049 + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=0, ): Account.NONEXISTENT, - Address( - 0x91ED00A0A906270D466AF043C4E111DADCA970A3 + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=1, ): Account.NONEXISTENT, coinbase: Account(storage={}, nonce=0), compute_create_address( diff --git a/tests/ported_static/stRandom/test_random_statetest308.py b/tests/ported_static/stRandom/test_random_statetest308.py index 5e1fb34da37..9dde60983e7 100644 --- a/tests/ported_static/stRandom/test_random_statetest308.py +++ b/tests/ported_static/stRandom/test_random_statetest308.py @@ -48,6 +48,23 @@ def test_random_statetest308( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5357f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000010000000000000000000000000000000000000000085a01096630f38c9a60005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -73,23 +90,6 @@ def test_random_statetest308( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest309.py b/tests/ported_static/stRandom/test_random_statetest309.py index edf2726755f..114d8e3352a 100644 --- a/tests/ported_static/stRandom/test_random_statetest309.py +++ b/tests/ported_static/stRandom/test_random_statetest309.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest309( ) -> None: """Test_random_statetest309.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -55,7 +52,6 @@ def test_random_statetest309( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x80F26BF6EA7E69C54687BEB66D90438E7F0286B4), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -73,7 +69,6 @@ def test_random_statetest309( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest31.py b/tests/ported_static/stRandom/test_random_statetest31.py index 3782d9e1c1d..0e99e6b5a26 100644 --- a/tests/ported_static/stRandom/test_random_statetest31.py +++ b/tests/ported_static/stRandom/test_random_statetest31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest31( ) -> None: """Test_random_statetest31.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,7 +58,6 @@ def test_random_statetest31( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xF96AA31000BB2A6B92F34B6A9F626A5DA00BF714), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -79,7 +75,6 @@ def test_random_statetest31( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest310.py b/tests/ported_static/stRandom/test_random_statetest310.py index 0761896419c..86dfb9f61bc 100644 --- a/tests/ported_static/stRandom/test_random_statetest310.py +++ b/tests/ported_static/stRandom/test_random_statetest310.py @@ -46,6 +46,7 @@ def test_random_statetest310( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x44587fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff59907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1a37160b6a650645597c796e9c97955560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_random_statetest310( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest311.py b/tests/ported_static/stRandom/test_random_statetest311.py index e4f20bb3d25..e4a48c3787b 100644 --- a/tests/ported_static/stRandom/test_random_statetest311.py +++ b/tests/ported_static/stRandom/test_random_statetest311.py @@ -46,6 +46,23 @@ def test_random_statetest311( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x447f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3506f13971264a1197d72ff18971902387b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest311( nonce=0, address=Address(0xCF4F4827D44BFACB993F9EF6499444F992A60E2E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest312.py b/tests/ported_static/stRandom/test_random_statetest312.py index de22d083b93..7b559d0f92a 100644 --- a/tests/ported_static/stRandom/test_random_statetest312.py +++ b/tests/ported_static/stRandom/test_random_statetest312.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest312( ) -> None: """Test_random_statetest312.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest312( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000187b55 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000000000000000000000000000000000000000000000187b55" # noqa: E501 - ), - nonce=0, - address=Address(0xA7A903566ABEAB1B0A9EB4F54909E6B00848A2A6), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest312( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000187b55 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000000000000000000000000000000000000000000000187b55" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest313.py b/tests/ported_static/stRandom/test_random_statetest313.py index 89fb9065d7f..ae122af2e4b 100644 --- a/tests/ported_static/stRandom/test_random_statetest313.py +++ b/tests/ported_static/stRandom/test_random_statetest313.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest313( ) -> None: """Test_random_statetest313.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,7 +62,6 @@ def test_random_statetest313( + Op.DUP13 * 2 + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.GAS), nonce=0, - address=Address(0x9F0B64FB000394E77826EA5EE94FE9CF30284BF2), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -83,7 +79,6 @@ def test_random_statetest313( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest315.py b/tests/ported_static/stRandom/test_random_statetest315.py index b35562ecd4a..0c49be25102 100644 --- a/tests/ported_static/stRandom/test_random_statetest315.py +++ b/tests/ported_static/stRandom/test_random_statetest315.py @@ -46,6 +46,23 @@ def test_random_statetest315( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff067f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f98516a388683755669892b8b3719575560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,23 +87,6 @@ def test_random_statetest315( nonce=0, address=Address(0xBE5726DD998FF7F8A8ACDC8172DB5C692C934199), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest316.py b/tests/ported_static/stRandom/test_random_statetest316.py index 0cbf77e8d5c..efa655732af 100644 --- a/tests/ported_static/stRandom/test_random_statetest316.py +++ b/tests/ported_static/stRandom/test_random_statetest316.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest316( ) -> None: """Test_random_statetest316.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -66,7 +63,6 @@ def test_random_statetest316( value=Op.PUSH32[0x1], ), nonce=0, - address=Address(0xCE903785F0831BD0D5E00A4629399383EF7ED516), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -84,7 +80,6 @@ def test_random_statetest316( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest318.py b/tests/ported_static/stRandom/test_random_statetest318.py index e585fcfaa01..4dbe1f506c2 100644 --- a/tests/ported_static/stRandom/test_random_statetest318.py +++ b/tests/ported_static/stRandom/test_random_statetest318.py @@ -46,6 +46,23 @@ def test_random_statetest318( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350457f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3506f8206a30a83887e5a3164667796308d5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest318( nonce=0, address=Address(0x93C49734A285572E734BBA592627BBF22815F95F), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest320.py b/tests/ported_static/stRandom/test_random_statetest320.py index 6828cf1b2e1..7e08ad0c477 100644 --- a/tests/ported_static/stRandom/test_random_statetest320.py +++ b/tests/ported_static/stRandom/test_random_statetest320.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest320( ) -> None: """Test_random_statetest320.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest320( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff45457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3505b0a36095511805131558f14fc3b # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff45457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3505b0a36095511805131558f14fc3b" # noqa: E501 - ), - nonce=0, - address=Address(0x10450E65DFDE8718B82D012B8B2A6005E1A164DD), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest320( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff45457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3505b0a36095511805131558f14fc3b # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff45457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3505b0a36095511805131558f14fc3b" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest321.py b/tests/ported_static/stRandom/test_random_statetest321.py index 2d4faa7acbe..43ef478e72e 100644 --- a/tests/ported_static/stRandom/test_random_statetest321.py +++ b/tests/ported_static/stRandom/test_random_statetest321.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest321( ) -> None: """Test_random_statetest321.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -72,7 +69,6 @@ def test_random_statetest321( + Op.MLOAD + Op.SSTORE, nonce=0, - address=Address(0x4F557114709BBDB63366DA99F52FAE471C987703), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -90,7 +86,6 @@ def test_random_statetest321( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest322.py b/tests/ported_static/stRandom/test_random_statetest322.py index b8ebcee78fd..28424aecc18 100644 --- a/tests/ported_static/stRandom/test_random_statetest322.py +++ b/tests/ported_static/stRandom/test_random_statetest322.py @@ -46,6 +46,7 @@ def test_random_statetest322( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000427f000000000000000000000000000000000000000000000000000000000000c3506f1206060508840294304101a3128f345560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest322( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest323.py b/tests/ported_static/stRandom/test_random_statetest323.py index 3ea11b4e0a5..8a9ebfa5ddf 100644 --- a/tests/ported_static/stRandom/test_random_statetest323.py +++ b/tests/ported_static/stRandom/test_random_statetest323.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest323( ) -> None: """Test_random_statetest323.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest323( gas_limit=9223372036854775807, ) - # Source: raw - # 0x6f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe74977f000000000000000000000000000000000000000000000000000000000000c3506f6b7936181136392060005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "6f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe74977f000000000000000000000000000000000000000000000000000000000000c3506f6b7936181136392060005155" # noqa: E501 - ), - nonce=0, - address=Address(0x70DA9B48406E4B67E6CC0458D7376116D08EB806), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest323( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe74977f000000000000000000000000000000000000000000000000000000000000c3506f6b7936181136392060005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "6f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe74977f000000000000000000000000000000000000000000000000000000000000c3506f6b7936181136392060005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest325.py b/tests/ported_static/stRandom/test_random_statetest325.py index 8e9192c0e4d..b72f02566ec 100644 --- a/tests/ported_static/stRandom/test_random_statetest325.py +++ b/tests/ported_static/stRandom/test_random_statetest325.py @@ -46,6 +46,7 @@ def test_random_statetest325( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81090360005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_random_statetest325( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest326.py b/tests/ported_static/stRandom/test_random_statetest326.py index 8a20c16dd8c..d5cc7e9155e 100644 --- a/tests/ported_static/stRandom/test_random_statetest326.py +++ b/tests/ported_static/stRandom/test_random_statetest326.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest326( ) -> None: """Test_random_statetest326.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,7 +51,6 @@ def test_random_statetest326( "7f000000000000000000000000000000000000000000000000000000000000000034577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000426259cb6142a1196e3168c986758aa4" # noqa: E501 ), nonce=0, - address=Address(0xE9A32A9AD98C02FA9521B9AB066BCC683A8AB126), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -72,7 +68,6 @@ def test_random_statetest326( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest327.py b/tests/ported_static/stRandom/test_random_statetest327.py index a81d37924c5..69a0ef27e4b 100644 --- a/tests/ported_static/stRandom/test_random_statetest327.py +++ b/tests/ported_static/stRandom/test_random_statetest327.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest327( ) -> None: """Test_random_statetest327.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest327( "457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000001458b5554397513" # noqa: E501 ), nonce=0, - address=Address(0x85F19E026A6F76DB9583E20941653F5E029C9671), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest327( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest329.py b/tests/ported_static/stRandom/test_random_statetest329.py index b6ae6465a4a..a7c487bdc86 100644 --- a/tests/ported_static/stRandom/test_random_statetest329.py +++ b/tests/ported_static/stRandom/test_random_statetest329.py @@ -46,6 +46,23 @@ def test_random_statetest329( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff426fa48d775458574133769c8b750207ff5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest329( nonce=0, address=Address(0x06D608C689F673F068B91332000854260A1FD3E0), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest33.py b/tests/ported_static/stRandom/test_random_statetest33.py index 8c0577035c5..ef3cfc91ce3 100644 --- a/tests/ported_static/stRandom/test_random_statetest33.py +++ b/tests/ported_static/stRandom/test_random_statetest33.py @@ -47,6 +47,7 @@ def test_random_statetest33( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000015a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3506f6940566279386017a362876372698f5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest33( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest332.py b/tests/ported_static/stRandom/test_random_statetest332.py index 60ce2f262eb..af3acdd68fc 100644 --- a/tests/ported_static/stRandom/test_random_statetest332.py +++ b/tests/ported_static/stRandom/test_random_statetest332.py @@ -46,6 +46,7 @@ def test_random_statetest332( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3506f7c098e7d625a64319d9e514bf350755560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest332( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest333.py b/tests/ported_static/stRandom/test_random_statetest333.py index d9ea95b1a30..07a193ba630 100644 --- a/tests/ported_static/stRandom/test_random_statetest333.py +++ b/tests/ported_static/stRandom/test_random_statetest333.py @@ -46,6 +46,23 @@ def test_random_statetest333( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f410263f305963310856c15ff5037a05560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest333( nonce=0, address=Address(0x608F842C00417D627FEB0F72D9ABAE6CC478E7F1), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest334.py b/tests/ported_static/stRandom/test_random_statetest334.py index 128a5bae8b4..7d50a34d622 100644 --- a/tests/ported_static/stRandom/test_random_statetest334.py +++ b/tests/ported_static/stRandom/test_random_statetest334.py @@ -46,6 +46,7 @@ def test_random_statetest334( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000013a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f424468208e181851308b7c7a776863a160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest334( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest335.py b/tests/ported_static/stRandom/test_random_statetest335.py index 2d59c29a1af..7196d9db3ec 100644 --- a/tests/ported_static/stRandom/test_random_statetest335.py +++ b/tests/ported_static/stRandom/test_random_statetest335.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest335( ) -> None: """Test_random_statetest335.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest335( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350617e7608617c95f3ff584076e07b5a4460005155" # noqa: E501 ), nonce=0, - address=Address(0xA3A709FECE04184D06401D32D39F133EA3B800A8), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest335( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest336.py b/tests/ported_static/stRandom/test_random_statetest336.py index 1297395a4e3..408d267cf3b 100644 --- a/tests/ported_static/stRandom/test_random_statetest336.py +++ b/tests/ported_static/stRandom/test_random_statetest336.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest336( ) -> None: """Test_random_statetest336.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_random_statetest336( + Op.COINBASE, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF3C8D5EA3CE820D6B26253D4D1D9106008C757DB), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -74,7 +70,6 @@ def test_random_statetest336( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest337.py b/tests/ported_static/stRandom/test_random_statetest337.py index 0485a7bdf61..f8b1422cbe0 100644 --- a/tests/ported_static/stRandom/test_random_statetest337.py +++ b/tests/ported_static/stRandom/test_random_statetest337.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest337( ) -> None: """Test_random_statetest337.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,7 +57,6 @@ def test_random_statetest337( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xC91DE65C756CAAA7D9EDBC50AC7494254A4E2CF6), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -78,7 +74,6 @@ def test_random_statetest337( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest338.py b/tests/ported_static/stRandom/test_random_statetest338.py index 7d1b6df3490..d623ef7d74d 100644 --- a/tests/ported_static/stRandom/test_random_statetest338.py +++ b/tests/ported_static/stRandom/test_random_statetest338.py @@ -46,6 +46,23 @@ def test_random_statetest338( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff677a9df32e6851606c0119065560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -74,23 +91,6 @@ def test_random_statetest338( nonce=0, address=Address(0x271814042945813B1628EB698BF09C4AE384485F), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest339.py b/tests/ported_static/stRandom/test_random_statetest339.py index efe34496456..6437037b241 100644 --- a/tests/ported_static/stRandom/test_random_statetest339.py +++ b/tests/ported_static/stRandom/test_random_statetest339.py @@ -46,6 +46,23 @@ def test_random_statetest339( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3506f89029e850708a293905668f1a367a25560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest339( nonce=0, address=Address(0x978DD1566835C8AD84120731B668015399EABE79), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest340.py b/tests/ported_static/stRandom/test_random_statetest340.py index 3637a979161..4fd262687f8 100644 --- a/tests/ported_static/stRandom/test_random_statetest340.py +++ b/tests/ported_static/stRandom/test_random_statetest340.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest340( ) -> None: """Test_random_statetest340.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest340( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest340( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xE55B3D86C30351B3B3C173C83C73ACEDEA2578AE), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest341.py b/tests/ported_static/stRandom/test_random_statetest341.py index 61082f6017e..0a99e3f670b 100644 --- a/tests/ported_static/stRandom/test_random_statetest341.py +++ b/tests/ported_static/stRandom/test_random_statetest341.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest341( ) -> None: """Test_random_statetest341.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest341( gas_limit=9223372036854775807, ) - # Source: raw - # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.TIMESTAMP - + Op.PUSH32[0x0] - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PC - + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) - + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), - nonce=0, - address=Address(0xB2DA1F608A7E0626E721677FA30FC46D2D99C655), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest341( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.TIMESTAMP + + Op.PUSH32[0x0] + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PC + + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) + + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest342.py b/tests/ported_static/stRandom/test_random_statetest342.py index 4efd2c646f1..9bad4431ff6 100644 --- a/tests/ported_static/stRandom/test_random_statetest342.py +++ b/tests/ported_static/stRandom/test_random_statetest342.py @@ -46,6 +46,7 @@ def test_random_statetest342( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000000041147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f36314297399455797b42569e8f05565560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest342( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest343.py b/tests/ported_static/stRandom/test_random_statetest343.py index a96ba857755..2127a424e0e 100644 --- a/tests/ported_static/stRandom/test_random_statetest343.py +++ b/tests/ported_static/stRandom/test_random_statetest343.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest343( ) -> None: """Test_random_statetest343.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -70,7 +67,6 @@ def test_random_statetest343( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x0C6077C4B33CD05C78D87CB0C0186BB869D3C773), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -88,7 +84,6 @@ def test_random_statetest343( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest345.py b/tests/ported_static/stRandom/test_random_statetest345.py index d1195e58e8a..9959a5d94ba 100644 --- a/tests/ported_static/stRandom/test_random_statetest345.py +++ b/tests/ported_static/stRandom/test_random_statetest345.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest345( ) -> None: """Test_random_statetest345.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest345( "417f0000000000000000000000000000000000000000000000000000000000000001447fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000000035420b417f056699168fa16d8d94113b60005155" # noqa: E501 ), nonce=0, - address=Address(0xC4B87D307584985FC7448651ECDA800B709D96A2), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest345( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest346.py b/tests/ported_static/stRandom/test_random_statetest346.py index 5419273fdcc..3adafb84a38 100644 --- a/tests/ported_static/stRandom/test_random_statetest346.py +++ b/tests/ported_static/stRandom/test_random_statetest346.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest346( ) -> None: """Test_random_statetest346.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -68,7 +65,6 @@ def test_random_statetest346( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xF27D15CBABF0EE5FF4E3C4F9F754AED2EFB556C6), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -86,7 +82,6 @@ def test_random_statetest346( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest347.py b/tests/ported_static/stRandom/test_random_statetest347.py index a13a820cb93..c4ad3281d1e 100644 --- a/tests/ported_static/stRandom/test_random_statetest347.py +++ b/tests/ported_static/stRandom/test_random_statetest347.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stRandom/randomStatetest347Filler.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_random_statetest347( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_random_statetest347.""" coinbase = Address(0xA7F7C8EF9BBBCFB0F7E81C1FD46BB732FBA60592) - sender = EOA( - key=0x1F2F6944F70460E655546D414267BD3491A2DD9DAFB2280605404C858990D053 - ) + sender = pre.fund_eoa(amount=0x1024D289465FA51769) env = Environment( fee_recipient=coinbase, @@ -159,7 +155,6 @@ def test_random_statetest347( + Op.SWAP6, balance=0x33498455, nonce=233, - address=Address(0x97BC67B6EE773E59E516D02EDB13B971C3CBD856), # noqa: E501 ) # Source: raw # 0x36 @@ -167,9 +162,7 @@ def test_random_statetest347( code=Op.CALLDATASIZE, balance=0x4EA91708, nonce=89, - address=Address(0x79D9FBE6AC70917CB2E16EC4CD32968CE19C724D), # noqa: E501 ) - pre[sender] = Account(balance=0x1024D289465FA51769) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest348.py b/tests/ported_static/stRandom/test_random_statetest348.py index 249dc323fc3..b4fff8ac8d8 100644 --- a/tests/ported_static/stRandom/test_random_statetest348.py +++ b/tests/ported_static/stRandom/test_random_statetest348.py @@ -46,6 +46,23 @@ def test_random_statetest348( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000142186f18208119191509036365739735608a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest348( nonce=0, address=Address(0x1AC875748792954A75C59986BAE7851BDC422122), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest349.py b/tests/ported_static/stRandom/test_random_statetest349.py index 6bf74557b64..5f1aedfc476 100644 --- a/tests/ported_static/stRandom/test_random_statetest349.py +++ b/tests/ported_static/stRandom/test_random_statetest349.py @@ -46,6 +46,7 @@ def test_random_statetest349( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe04425560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest349( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest350.py b/tests/ported_static/stRandom/test_random_statetest350.py index c5bb975caa1..42f404eea9c 100644 --- a/tests/ported_static/stRandom/test_random_statetest350.py +++ b/tests/ported_static/stRandom/test_random_statetest350.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest350( ) -> None: """Test_random_statetest350.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -67,7 +64,6 @@ def test_random_statetest350( ), ), nonce=0, - address=Address(0xE81D688B7D2E6264DEEC5B61C7E8E02426C7256F), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -85,7 +81,6 @@ def test_random_statetest350( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest351.py b/tests/ported_static/stRandom/test_random_statetest351.py index 630da8605b3..63abf6c95d8 100644 --- a/tests/ported_static/stRandom/test_random_statetest351.py +++ b/tests/ported_static/stRandom/test_random_statetest351.py @@ -46,6 +46,7 @@ def test_random_statetest351( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0509355534707785320175fca41455 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest351( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest352.py b/tests/ported_static/stRandom/test_random_statetest352.py index 9d5e3dd6f5d..c375ac9de31 100644 --- a/tests/ported_static/stRandom/test_random_statetest352.py +++ b/tests/ported_static/stRandom/test_random_statetest352.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest352( ) -> None: """Test_random_statetest352.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest352( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000003a457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000013428284f28a980b4539a39d1408 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -76,25 +89,7 @@ def test_random_statetest352( + Op.EQ + Op.ADDMOD, nonce=0, - address=Address(0x936CFC08BEE110B939B632FE581FDC10E3484E0F), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest353.py b/tests/ported_static/stRandom/test_random_statetest353.py index 0f866e32de3..23459f796bc 100644 --- a/tests/ported_static/stRandom/test_random_statetest353.py +++ b/tests/ported_static/stRandom/test_random_statetest353.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest353( ) -> None: """Test_random_statetest353.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest353( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000120ba49036880f86529655 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000120ba49036880f86529655" # noqa: E501 - ), - nonce=0, - address=Address(0xDFB2DE0E2DC6BCF9941A4B2040AF9A9CD6CC8CA7), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest353( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000120ba49036880f86529655 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000120ba49036880f86529655" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest354.py b/tests/ported_static/stRandom/test_random_statetest354.py index c2cc368c893..53d7e262a47 100644 --- a/tests/ported_static/stRandom/test_random_statetest354.py +++ b/tests/ported_static/stRandom/test_random_statetest354.py @@ -46,6 +46,23 @@ def test_random_statetest354( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c350603b35641a8e739f86980a433760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -76,23 +93,6 @@ def test_random_statetest354( nonce=0, address=Address(0xF5128D151D2B28EAB17B340C1BD00E96683B90D6), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest355.py b/tests/ported_static/stRandom/test_random_statetest355.py index 6d28a80f3b5..b33a0979d45 100644 --- a/tests/ported_static/stRandom/test_random_statetest355.py +++ b/tests/ported_static/stRandom/test_random_statetest355.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest355( ) -> None: """Test_random_statetest355.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest355( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001666b56e87c5a499d5389306e55 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001666b56e87c5a499d5389306e55" # noqa: E501 - ), - nonce=0, - address=Address(0xCECD2AE07D64D406743F25363AF5C2CD6E8FFC2A), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest355( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001666b56e87c5a499d5389306e55 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79457f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001666b56e87c5a499d5389306e55" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest356.py b/tests/ported_static/stRandom/test_random_statetest356.py index 2d5e2ba9b7d..9c8ed826c38 100644 --- a/tests/ported_static/stRandom/test_random_statetest356.py +++ b/tests/ported_static/stRandom/test_random_statetest356.py @@ -46,6 +46,23 @@ def test_random_statetest356( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000827f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0460005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest356( nonce=0, address=Address(0x744CD72CA97273B1A4C6495DB482D22141B79C36), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest357.py b/tests/ported_static/stRandom/test_random_statetest357.py index 353052701b3..6a473f03531 100644 --- a/tests/ported_static/stRandom/test_random_statetest357.py +++ b/tests/ported_static/stRandom/test_random_statetest357.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest357( ) -> None: """Test_random_statetest357.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest357( "7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350427fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff09377c5380715560005155" # noqa: E501 ), nonce=0, - address=Address(0x625C4C0C1932D06A13B656F82B55ACAF57689DDA), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest357( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest358.py b/tests/ported_static/stRandom/test_random_statetest358.py index 04cf428c3e6..32035f4e334 100644 --- a/tests/ported_static/stRandom/test_random_statetest358.py +++ b/tests/ported_static/stRandom/test_random_statetest358.py @@ -46,6 +46,23 @@ def test_random_statetest358( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000c3506f679b82a092078f136b5541888c057a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest358( nonce=0, address=Address(0x009C8651CA2D7C8DFBF9E9DB5C57A213E25F0AAC), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest359.py b/tests/ported_static/stRandom/test_random_statetest359.py index ba8f93dfc85..64a5342d6fa 100644 --- a/tests/ported_static/stRandom/test_random_statetest359.py +++ b/tests/ported_static/stRandom/test_random_statetest359.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest359( ) -> None: """Test_random_statetest359.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest359( "7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff428d06809e75f26764867d853b0555" # noqa: E501 ), nonce=0, - address=Address(0x2E42FA9E3E939BC1AF51A19D6E8D3D80CD923842), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest359( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest36.py b/tests/ported_static/stRandom/test_random_statetest36.py index dc746636153..1a31f763bf3 100644 --- a/tests/ported_static/stRandom/test_random_statetest36.py +++ b/tests/ported_static/stRandom/test_random_statetest36.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest36( ) -> None: """Test_random_statetest36.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -72,7 +69,6 @@ def test_random_statetest36( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xAD6FFFED2E41E6D57F10DEBDF91B1DC35758B7AD), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -90,7 +86,6 @@ def test_random_statetest36( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest360.py b/tests/ported_static/stRandom/test_random_statetest360.py index 2bca9f22373..97a0128ab69 100644 --- a/tests/ported_static/stRandom/test_random_statetest360.py +++ b/tests/ported_static/stRandom/test_random_statetest360.py @@ -46,6 +46,23 @@ def test_random_statetest360( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000016f0441548af30803135562840563829c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest360( nonce=0, address=Address(0xEE7C7C19EF09791C7B863CCBEE181FEFD5EBDCAE), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest361.py b/tests/ported_static/stRandom/test_random_statetest361.py index 3cb0f4b6ea6..ffefa4de78a 100644 --- a/tests/ported_static/stRandom/test_random_statetest361.py +++ b/tests/ported_static/stRandom/test_random_statetest361.py @@ -46,6 +46,7 @@ def test_random_statetest361( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x41417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff066f9e9092673a8f430b6ba115209018165560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest361( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest362.py b/tests/ported_static/stRandom/test_random_statetest362.py index 809c5e6e002..d0dc5cdacf9 100644 --- a/tests/ported_static/stRandom/test_random_statetest362.py +++ b/tests/ported_static/stRandom/test_random_statetest362.py @@ -47,6 +47,23 @@ def test_random_statetest362( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b50955 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest362( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest363.py b/tests/ported_static/stRandom/test_random_statetest363.py index eff59ba1925..e5ca12e8a91 100644 --- a/tests/ported_static/stRandom/test_random_statetest363.py +++ b/tests/ported_static/stRandom/test_random_statetest363.py @@ -46,6 +46,23 @@ def test_random_statetest363( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350117ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f7b20937d953695f369719f9a4479055560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,23 +87,6 @@ def test_random_statetest363( nonce=0, address=Address(0xCAF50C7EFED9C2AC1920749B5B1DA29C765DCDD7), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest364.py b/tests/ported_static/stRandom/test_random_statetest364.py index 9a891f45f31..50baeaa3a88 100644 --- a/tests/ported_static/stRandom/test_random_statetest364.py +++ b/tests/ported_static/stRandom/test_random_statetest364.py @@ -46,6 +46,23 @@ def test_random_statetest364( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350076f7332988d746694918859185920446d5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest364( nonce=0, address=Address(0x81C6B6D0445898D97501D83D77947B4365EA2533), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest365.py b/tests/ported_static/stRandom/test_random_statetest365.py index 5c463813126..2e722acb713 100644 --- a/tests/ported_static/stRandom/test_random_statetest365.py +++ b/tests/ported_static/stRandom/test_random_statetest365.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest365( ) -> None: """Test_random_statetest365.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_random_statetest365( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x51D8E96D50235F1ECB7B408B657349B038E7A135), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -91,7 +87,6 @@ def test_random_statetest365( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -106,7 +101,7 @@ def test_random_statetest365( post = { target: Account( storage={ - 0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, + 0: coinbase, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF: 0, # noqa: E501 }, nonce=0, diff --git a/tests/ported_static/stRandom/test_random_statetest366.py b/tests/ported_static/stRandom/test_random_statetest366.py index cda95137f66..2c03fd159a0 100644 --- a/tests/ported_static/stRandom/test_random_statetest366.py +++ b/tests/ported_static/stRandom/test_random_statetest366.py @@ -46,6 +46,23 @@ def test_random_statetest366( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff446f516f0395f57433725580758f32f1945560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest366( nonce=0, address=Address(0x0BC2CE358220862EDA2BA9B6A96BA6E93692593D), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest367.py b/tests/ported_static/stRandom/test_random_statetest367.py index 32aea776b38..b0bf5dfc335 100644 --- a/tests/ported_static/stRandom/test_random_statetest367.py +++ b/tests/ported_static/stRandom/test_random_statetest367.py @@ -47,6 +47,23 @@ def test_random_statetest367( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000447f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5447f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b51905810a6c7a5959339f3342838b5560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -71,23 +88,6 @@ def test_random_statetest367( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest368.py b/tests/ported_static/stRandom/test_random_statetest368.py index 433992755f4..931daeccdaf 100644 --- a/tests/ported_static/stRandom/test_random_statetest368.py +++ b/tests/ported_static/stRandom/test_random_statetest368.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_random_statetest368( """Test_random_statetest368.""" coinbase = Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,15 +45,6 @@ def test_random_statetest368( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe097f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b54206f06d870339356057907760005155 # noqa: E501 - contract_0 = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe097f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b54206f06d870339356057907760005155" # noqa: E501 - ), - nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -73,7 +61,14 @@ def test_random_statetest368( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe097f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b54206f06d870339356057907760005155 # noqa: E501 + contract_0 = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe097f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b54206f06d870339356057907760005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest369.py b/tests/ported_static/stRandom/test_random_statetest369.py index 1c7c1cc2894..dc7b6e31a3b 100644 --- a/tests/ported_static/stRandom/test_random_statetest369.py +++ b/tests/ported_static/stRandom/test_random_statetest369.py @@ -46,6 +46,7 @@ def test_random_statetest369( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000001000000000000000000000000000000000000000060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest369( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest37.py b/tests/ported_static/stRandom/test_random_statetest37.py index d0654699731..d12c00792ca 100644 --- a/tests/ported_static/stRandom/test_random_statetest37.py +++ b/tests/ported_static/stRandom/test_random_statetest37.py @@ -46,6 +46,7 @@ def test_random_statetest37( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000016fa49835863514f0f29b930b97f116935560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest37( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest370.py b/tests/ported_static/stRandom/test_random_statetest370.py index fea8d036af1..118b5f29d62 100644 --- a/tests/ported_static/stRandom/test_random_statetest370.py +++ b/tests/ported_static/stRandom/test_random_statetest370.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest370( ) -> None: """Test_random_statetest370.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest370( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x44207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000001145344846604627f5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,25 +79,7 @@ def test_random_statetest370( + Op.PREVRANDAO + Op.SSTORE(key=0x4627F55600051, value=Op.DUP5), nonce=0, - address=Address(0xE73096EDE5F7C095146A2B72C29B48A70F2DC518), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest371.py b/tests/ported_static/stRandom/test_random_statetest371.py index 4026c3b3e2f..a2a302b67b4 100644 --- a/tests/ported_static/stRandom/test_random_statetest371.py +++ b/tests/ported_static/stRandom/test_random_statetest371.py @@ -46,6 +46,7 @@ def test_random_statetest371( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000010000000000000000000000000000000000000000435a10395560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest371( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest372.py b/tests/ported_static/stRandom/test_random_statetest372.py index 4298609eab4..8db67f5e1f8 100644 --- a/tests/ported_static/stRandom/test_random_statetest372.py +++ b/tests/ported_static/stRandom/test_random_statetest372.py @@ -47,6 +47,23 @@ def test_random_statetest372( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f0000000000000000000000000000000000000000000000000000000000000001180860005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest372( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest376.py b/tests/ported_static/stRandom/test_random_statetest376.py index 7e95b6a18a9..9a25b9ccd87 100644 --- a/tests/ported_static/stRandom/test_random_statetest376.py +++ b/tests/ported_static/stRandom/test_random_statetest376.py @@ -46,6 +46,7 @@ def test_random_statetest376( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09ff8c316460005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest376( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest378.py b/tests/ported_static/stRandom/test_random_statetest378.py index e286ab11ed6..580339d4db8 100644 --- a/tests/ported_static/stRandom/test_random_statetest378.py +++ b/tests/ported_static/stRandom/test_random_statetest378.py @@ -47,6 +47,7 @@ def test_random_statetest378( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff547f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000005a7f00000000000000000000000000000000000000000000000000000000000000016f855b445834721a5706f2891711f0025560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest378( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest379.py b/tests/ported_static/stRandom/test_random_statetest379.py index 0979c6dbab1..eb39731d420 100644 --- a/tests/ported_static/stRandom/test_random_statetest379.py +++ b/tests/ported_static/stRandom/test_random_statetest379.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest379( ) -> None: """Test_random_statetest379.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest379( code=Op.SSTORE(key=Op.TIMESTAMP, value=Op.TIMESTAMP), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2295EF51F8519C010AB5C25F25866BC0AB5EC2EE), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest379( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest380.py b/tests/ported_static/stRandom/test_random_statetest380.py index 90868703cdd..3f78aad3b7e 100644 --- a/tests/ported_static/stRandom/test_random_statetest380.py +++ b/tests/ported_static/stRandom/test_random_statetest380.py @@ -46,6 +46,7 @@ def test_random_statetest380( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f967737653485593c63408b399439755560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest380( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest381.py b/tests/ported_static/stRandom/test_random_statetest381.py index 7b4df8c81a5..ea94c2e026e 100644 --- a/tests/ported_static/stRandom/test_random_statetest381.py +++ b/tests/ported_static/stRandom/test_random_statetest381.py @@ -46,6 +46,23 @@ def test_random_statetest381( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff417f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f098ba088881a64904570927a8618355560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest381( nonce=0, address=Address(0xA8CAB300C7463531929F671107D559CC4C6DCEA7), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest382.py b/tests/ported_static/stRandom/test_random_statetest382.py index d72c62f553e..bf176290fca 100644 --- a/tests/ported_static/stRandom/test_random_statetest382.py +++ b/tests/ported_static/stRandom/test_random_statetest382.py @@ -46,6 +46,23 @@ def test_random_statetest382( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0855 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest382( nonce=0, address=Address(0xF4845CAC94E57781E8B85C32DBD16EFC1EE54EE6), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest383.py b/tests/ported_static/stRandom/test_random_statetest383.py index f30689b3818..6ea6cfd8913 100644 --- a/tests/ported_static/stRandom/test_random_statetest383.py +++ b/tests/ported_static/stRandom/test_random_statetest383.py @@ -46,15 +46,7 @@ def test_random_statetest383( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09150255436c75107e # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09150255436c75107e" # noqa: E501 - ), - nonce=0, - address=Address(0x9306B5E9E12F8E3524CB929C05E3F817FD403029), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +63,15 @@ def test_random_statetest383( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09150255436c75107e # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09150255436c75107e" # noqa: E501 + ), + nonce=0, + address=Address(0x9306B5E9E12F8E3524CB929C05E3F817FD403029), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest384.py b/tests/ported_static/stRandom/test_random_statetest384.py index 7f52150fd8c..4e5808ba262 100644 --- a/tests/ported_static/stRandom/test_random_statetest384.py +++ b/tests/ported_static/stRandom/test_random_statetest384.py @@ -46,6 +46,7 @@ def test_random_statetest384( gas_limit=71794957647893862, ) + pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) # Source: raw # 0x786675A4758D443DBFF535F034A4EDA729A6FFC1E59F674E0C553b655D7974272AC76e18CE2014249172572ED5EAC0B9D2E461FFFF169061FFFF16a033114861C0CD619FE161A9BB61AD137F4D84673D975D1811374A239EF14EE26532D643CC4DD6E9115E28815562C2EB945AF46c513376BC288AA1FDB973C149CD143b7889CC6512F8D604E5D0656C17F2D45B916DF6816A1999719F2B71D521394F07100138B341F1DEBC06C3FB3CBC600116586008015760CB505B7227E1DC4C54400E52AB133F162C6DF107151D1145939445807e5153417E8FF00D138F0DFFC0CD79CED2ECECD6F0DCE826302E4129CB6C37AB43415B6145C16173CE6152A9610C307FA5D352916626FE6BE4AA6EF0E7634DB7909FD79752E5BCB504B358D36AF708495AF461FFFF169061FFFF16a26cE900F727806828F5EE6088EBF861FFFF165170015C1269FA9F5387AB7387A81F5190564098601F9471B46EB2F2D66EE0B4C6845455E9C5EEFF021875BAE1D66F6CB6213C6CE69859F1046AE4CB5E5B743AB76d66120B1A7A97C93A6A04BD493F4A07963d0b69471B70DEC306FA6142CE9c60FF164303406aA04EA7E0BD9D9CDA29962B05067246CE83AB26762D5E2CFB614AA2394AD1D70EA938856b938D5C3FF280BF7EFDA95E668a70149AFA7A18BF9C2D796DE03773E0D35C9A7e8E0E968BA16F3AD59D6442DDBDB9E537908DB1F791BB3F17B33A14333401071961A1689c7b413ED4A9B16E7D66A17B07730188A08FA9E6148100F0311EA269ECC588607D7fCBFFF9F42E22612E938809AF2674B0CEDC8548F47EE642097C0C4ABC9BF7C76B9678996410D0BF28E5E3E1B35B37FFCE70E346E013D5345494D47690334261771761ABAE6174FD61F1957F1396B439A0049676213FD1FF8B75232DBD2117C0C5DCC184D76E2534EA9628AC5AF4863a9761FFFF169061FFFF16a07e486085A7047BD1ACAB7C048C2AE5A07A9E25934021CFAF0651EFBD393B72141461FFFF165361FFFF169061FFFF16a16a84ED962562151D0B903FB2863004140473380357280D5DBC434298AC45559FC2855C0D2A045a66AF59655ED483A0583160FF16430340795F1536B1893659FBB9FFA023722BEB2F24B5693BE6B572737FED1b9d0a646F7A2658B58b5B417220E684F471111724A4F72553B4FDC9593AE22C96959961A631615AD461199161F3F6618FE07F39DBE091B64B8BE6A557A93BF2C25DD042E8C8FEA4DB3BD8EE5BE3EABDE2835E5AF105600055600155600255600355600455600555600655600755600855600955600a55600b55600c55600d55600e55600f55601055601155601255601355601455601555601655601755601855601955601a55601b55601c55601d55601e5561273961C065F3 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -273,7 +274,6 @@ def test_random_statetest384( nonce=1, address=Address(0x14CEED78F6E86EEAD0A39E3F5C3481C7C233E8EA), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest39.py b/tests/ported_static/stRandom/test_random_statetest39.py index 96d74ca8de3..9ad4e952cad 100644 --- a/tests/ported_static/stRandom/test_random_statetest39.py +++ b/tests/ported_static/stRandom/test_random_statetest39.py @@ -46,6 +46,7 @@ def test_random_statetest39( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff427f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9604638ea2179a58035560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_random_statetest39( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest4.py b/tests/ported_static/stRandom/test_random_statetest4.py index 9a3f6a5291b..55bfd614278 100644 --- a/tests/ported_static/stRandom/test_random_statetest4.py +++ b/tests/ported_static/stRandom/test_random_statetest4.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest4( ) -> None: """Test_random_statetest4.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest4( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350617e7608617c95f3ff584076e07b5a4460005155" # noqa: E501 ), nonce=0, - address=Address(0xA3A709FECE04184D06401D32D39F133EA3B800A8), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest4( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest41.py b/tests/ported_static/stRandom/test_random_statetest41.py index 4570a3f8e22..6b633b051ff 100644 --- a/tests/ported_static/stRandom/test_random_statetest41.py +++ b/tests/ported_static/stRandom/test_random_statetest41.py @@ -47,6 +47,23 @@ def test_random_statetest41( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350517f0000000000000000000000010000000000000000000000000000000000000000417f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b56a84a10719a1786a6510349b028255 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest41( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest42.py b/tests/ported_static/stRandom/test_random_statetest42.py index 2b0cfe85bae..7e67db9f820 100644 --- a/tests/ported_static/stRandom/test_random_statetest42.py +++ b/tests/ported_static/stRandom/test_random_statetest42.py @@ -47,6 +47,7 @@ def test_random_statetest42( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3505a7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350356436f0f119011a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest42( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest43.py b/tests/ported_static/stRandom/test_random_statetest43.py index 3af81c0dd74..e0061e13bbe 100644 --- a/tests/ported_static/stRandom/test_random_statetest43.py +++ b/tests/ported_static/stRandom/test_random_statetest43.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest43( ) -> None: """Test_random_statetest43.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest43( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3b0a55096941861a3755a196f259a155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,25 +82,7 @@ def test_random_statetest43( ) + Op.SSTORE(key=0x41861A3755A196F259A1, value=Op.MULMOD), nonce=0, - address=Address(0x32DDDB92ACB638EEDE178AE680D1C7362BD89FD5), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -101,10 +96,7 @@ def test_random_statetest43( post = { target: Account( - storage={ - 0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, - 0x41861A3755A196F259A1: 1, - }, + storage={0: coinbase, 0x41861A3755A196F259A1: 1}, nonce=0, ), coinbase: Account(storage={}, nonce=0), diff --git a/tests/ported_static/stRandom/test_random_statetest45.py b/tests/ported_static/stRandom/test_random_statetest45.py index 668669b4dcf..c3e26575f14 100644 --- a/tests/ported_static/stRandom/test_random_statetest45.py +++ b/tests/ported_static/stRandom/test_random_statetest45.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest45( ) -> None: """Test_random_statetest45.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest45( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe43147256a3130255 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe43147256a3130255" # noqa: E501 - ), - nonce=0, - address=Address(0x868A35CB88C48251A7470E4FB638C4CB395BA4DA), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest45( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe43147256a3130255 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe43147256a3130255" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest47.py b/tests/ported_static/stRandom/test_random_statetest47.py index 7d55a94e0e8..b3ad3b7862b 100644 --- a/tests/ported_static/stRandom/test_random_statetest47.py +++ b/tests/ported_static/stRandom/test_random_statetest47.py @@ -46,6 +46,23 @@ def test_random_statetest47( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350437f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f1544898b167c6a6f6d5b953714457e5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest47( nonce=0, address=Address(0x44038E40B466D5B343B7DC04756087AB122AF57A), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest48.py b/tests/ported_static/stRandom/test_random_statetest48.py index 694b50aa389..f6dbb6131eb 100644 --- a/tests/ported_static/stRandom/test_random_statetest48.py +++ b/tests/ported_static/stRandom/test_random_statetest48.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest48( ) -> None: """Test_random_statetest48.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest48( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x38785231d8e75db11d6da7040cee1a12ebf739e5022caa60f92d51636060b6d96d698fc0e9ced2f6a0087344559c43612f0561a73ba3600a600d6014600963186262c1736370f82d9ff1604166f49ef1fea120af77ba4cce3f35bc52ca5c40bf14c77e95ea92e69520143ff9c7827bcfe760aee06d241e31a0773476da22f7ce8131475838c23b59f7a3c46b2b99c0955e169ee3527ca9f7674467bdf2c0eebf6f60129232 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,23 +93,6 @@ def test_random_statetest48( nonce=0, address=Address(0x292E762689B448DEBE7899ADE7ACB27A84A85C44), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest49.py b/tests/ported_static/stRandom/test_random_statetest49.py index 8698edcd739..9544cdc81ab 100644 --- a/tests/ported_static/stRandom/test_random_statetest49.py +++ b/tests/ported_static/stRandom/test_random_statetest49.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest49( ) -> None: """Test_random_statetest49.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest49( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000807f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000061859c55 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest49( value=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], ), nonce=0, - address=Address(0xCAA0686603C881F386878DDB79D8F293BF095D80), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,12 +89,7 @@ def test_random_statetest49( ) post = { - target: Account( - storage={ - 34204: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, - }, - nonce=0, - ), + target: Account(storage={34204: coinbase}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom/test_random_statetest5.py b/tests/ported_static/stRandom/test_random_statetest5.py index 508ff230dba..8d3e1597827 100644 --- a/tests/ported_static/stRandom/test_random_statetest5.py +++ b/tests/ported_static/stRandom/test_random_statetest5.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest5( ) -> None: """Test_random_statetest5.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest5( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x427f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest5( ), ), nonce=0, - address=Address(0x5A9F935F66941EC08A862F860B76B49E4A9D90EC), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest51.py b/tests/ported_static/stRandom/test_random_statetest51.py index d5b60a12e6d..bde53ad9ac1 100644 --- a/tests/ported_static/stRandom/test_random_statetest51.py +++ b/tests/ported_static/stRandom/test_random_statetest51.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest51( ) -> None: """Test_random_statetest51.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest51( "7f0000000000000000000000000000000000000000000000000000000000000001757f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57a7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5447ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe83189b60005155" # noqa: E501 ), nonce=0, - address=Address(0x53AF81E2A686427DE42E7B8B55A0C6C66C8C6051), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest51( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest52.py b/tests/ported_static/stRandom/test_random_statetest52.py index ce762c6fa98..3f22f5cc80d 100644 --- a/tests/ported_static/stRandom/test_random_statetest52.py +++ b/tests/ported_static/stRandom/test_random_statetest52.py @@ -46,6 +46,7 @@ def test_random_statetest52( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe410a81437f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000006f59a130a10a189fc653057a185b886c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest52( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest53.py b/tests/ported_static/stRandom/test_random_statetest53.py index 7f193b5e221..c943d93f166 100644 --- a/tests/ported_static/stRandom/test_random_statetest53.py +++ b/tests/ported_static/stRandom/test_random_statetest53.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest53( ) -> None: """Test_random_statetest53.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest53( gas_limit=9223372036854775807, ) - # Source: raw - # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.TIMESTAMP - + Op.PUSH32[0x0] - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PC - + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) - + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), - nonce=0, - address=Address(0xB2DA1F608A7E0626E721677FA30FC46D2D99C655), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest53( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.TIMESTAMP + + Op.PUSH32[0x0] + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PC + + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) + + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest54.py b/tests/ported_static/stRandom/test_random_statetest54.py index 666e82893c5..0a34d31110b 100644 --- a/tests/ported_static/stRandom/test_random_statetest54.py +++ b/tests/ported_static/stRandom/test_random_statetest54.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest54( ) -> None: """Test_random_statetest54.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest54( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001c9206e3b8f9d858f438a # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001c9206e3b8f9d858f438a" # noqa: E501 - ), - nonce=0, - address=Address(0x9D6DE455BE29A83C61E3E6E4B8895B579BBB938B), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest54( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001c9206e3b8f9d858f438a # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001c9206e3b8f9d858f438a" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest55.py b/tests/ported_static/stRandom/test_random_statetest55.py index 727b77cd3f6..32bfe5576e6 100644 --- a/tests/ported_static/stRandom/test_random_statetest55.py +++ b/tests/ported_static/stRandom/test_random_statetest55.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest55( ) -> None: """Test_random_statetest55.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest55( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084967f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff137ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016f3a5b594088a2f238089b71 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000000084967f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff137ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016f3a5b594088a2f238089b71" # noqa: E501 - ), - nonce=0, - address=Address(0xB5111BFE81B8D7566E584C3D02429543652DD051), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest55( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084967f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff137ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016f3a5b594088a2f238089b71 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000000084967f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff137ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016f3a5b594088a2f238089b71" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest57.py b/tests/ported_static/stRandom/test_random_statetest57.py index 65b539a24c7..98e81b8ccb1 100644 --- a/tests/ported_static/stRandom/test_random_statetest57.py +++ b/tests/ported_static/stRandom/test_random_statetest57.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest57( ) -> None: """Test_random_statetest57.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest57( + Op.SWAP1 + Op.SSTORE, nonce=0, - address=Address(0x8EAEDCBE884499A7F8D284384C1DF38AA6ED68AD), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest57( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest58.py b/tests/ported_static/stRandom/test_random_statetest58.py index e5a5408f89c..09e405888d9 100644 --- a/tests/ported_static/stRandom/test_random_statetest58.py +++ b/tests/ported_static/stRandom/test_random_statetest58.py @@ -46,6 +46,7 @@ def test_random_statetest58( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe096902947d567838719e97f30160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,7 +89,6 @@ def test_random_statetest58( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest59.py b/tests/ported_static/stRandom/test_random_statetest59.py index a5472d5d973..ae2df70abd0 100644 --- a/tests/ported_static/stRandom/test_random_statetest59.py +++ b/tests/ported_static/stRandom/test_random_statetest59.py @@ -46,6 +46,7 @@ def test_random_statetest59( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0208673a06756406548b9955 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_random_statetest59( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest6.py b/tests/ported_static/stRandom/test_random_statetest6.py index 4aab0c9fd11..39c3c2d8d13 100644 --- a/tests/ported_static/stRandom/test_random_statetest6.py +++ b/tests/ported_static/stRandom/test_random_statetest6.py @@ -46,6 +46,23 @@ def test_random_statetest6( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004143416f1732797105f237768fe506871ac8535560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest6( nonce=0, address=Address(0xE5DB1B85799B6A617AECD2562B23B6F957B67E36), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest60.py b/tests/ported_static/stRandom/test_random_statetest60.py index d78f70f999d..fe8731cdbe4 100644 --- a/tests/ported_static/stRandom/test_random_statetest60.py +++ b/tests/ported_static/stRandom/test_random_statetest60.py @@ -46,6 +46,7 @@ def test_random_statetest60( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x427f0000000000000000000000000000000000000000000000000000000000000000427f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f969001091aa15b8b9b75459d015a045560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest60( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest62.py b/tests/ported_static/stRandom/test_random_statetest62.py index 442b9011abe..cda4ae7bfe4 100644 --- a/tests/ported_static/stRandom/test_random_statetest62.py +++ b/tests/ported_static/stRandom/test_random_statetest62.py @@ -46,6 +46,23 @@ def test_random_statetest62( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000016f7268713013964a96ac5758043325015560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest62( nonce=0, address=Address(0x972B86541005A9B0855DE262A308C53797030ED5), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest63.py b/tests/ported_static/stRandom/test_random_statetest63.py index 38147ee62fe..b2ee59d3ab3 100644 --- a/tests/ported_static/stRandom/test_random_statetest63.py +++ b/tests/ported_static/stRandom/test_random_statetest63.py @@ -46,6 +46,7 @@ def test_random_statetest63( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000006f977f157e088003767a86928e8252965560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest63( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest64.py b/tests/ported_static/stRandom/test_random_statetest64.py index ce3d4e0270f..1a7f95a3d07 100644 --- a/tests/ported_static/stRandom/test_random_statetest64.py +++ b/tests/ported_static/stRandom/test_random_statetest64.py @@ -47,6 +47,23 @@ def test_random_statetest64( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x427f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b50a5560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -68,23 +85,6 @@ def test_random_statetest64( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest66.py b/tests/ported_static/stRandom/test_random_statetest66.py index 81b92185f74..7bdcae93402 100644 --- a/tests/ported_static/stRandom/test_random_statetest66.py +++ b/tests/ported_static/stRandom/test_random_statetest66.py @@ -47,6 +47,23 @@ def test_random_statetest66( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe097f000000000000000000000001000000000000000000000000000000000000000055 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest66( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest67.py b/tests/ported_static/stRandom/test_random_statetest67.py index 2fbbed4a3c0..fd4c0352f86 100644 --- a/tests/ported_static/stRandom/test_random_statetest67.py +++ b/tests/ported_static/stRandom/test_random_statetest67.py @@ -46,6 +46,7 @@ def test_random_statetest67( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000016f699776659a06a27607a2166d5373315560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest67( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest69.py b/tests/ported_static/stRandom/test_random_statetest69.py index 8b066bca5a1..eaadb4756a1 100644 --- a/tests/ported_static/stRandom/test_random_statetest69.py +++ b/tests/ported_static/stRandom/test_random_statetest69.py @@ -46,6 +46,7 @@ def test_random_statetest69( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe43596f15a0770a7676611a6595057b768b645560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest69( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest72.py b/tests/ported_static/stRandom/test_random_statetest72.py index 79ac93f7fb8..60430872c5f 100644 --- a/tests/ported_static/stRandom/test_random_statetest72.py +++ b/tests/ported_static/stRandom/test_random_statetest72.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest72( ) -> None: """Test_random_statetest72.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest72( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff417f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe65688dff579830091304 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest72( Op.COINBASE, ), nonce=0, - address=Address(0xD8AE0334E34CE6256B4C50A0E7D74FFE2FCAB7E8), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest73.py b/tests/ported_static/stRandom/test_random_statetest73.py index 04baaff4cbd..8f39446b096 100644 --- a/tests/ported_static/stRandom/test_random_statetest73.py +++ b/tests/ported_static/stRandom/test_random_statetest73.py @@ -47,6 +47,23 @@ def test_random_statetest73( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5b573198d729b711671056e0a055534613855 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest73( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest74.py b/tests/ported_static/stRandom/test_random_statetest74.py index 2c803c5f414..ab71e17db0d 100644 --- a/tests/ported_static/stRandom/test_random_statetest74.py +++ b/tests/ported_static/stRandom/test_random_statetest74.py @@ -46,6 +46,23 @@ def test_random_statetest74( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff3a7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006f141097788a7b5a72139c07076f18425560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest74( nonce=0, address=Address(0x1388416097405B5998A7B07D85A1AAADF337E5DA), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest75.py b/tests/ported_static/stRandom/test_random_statetest75.py index e20bcf44f92..c342198fc47 100644 --- a/tests/ported_static/stRandom/test_random_statetest75.py +++ b/tests/ported_static/stRandom/test_random_statetest75.py @@ -46,6 +46,23 @@ def test_random_statetest75( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f5893504553386c7d154001779287765560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest75( nonce=0, address=Address(0x6EA6BBAC1C9C438B7854633DCF8D299F4004A0D5), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest77.py b/tests/ported_static/stRandom/test_random_statetest77.py index 700d60bad6b..8dfd8020d48 100644 --- a/tests/ported_static/stRandom/test_random_statetest77.py +++ b/tests/ported_static/stRandom/test_random_statetest77.py @@ -46,6 +46,7 @@ def test_random_statetest77( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000141937f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f79a06df1a08d05373216d3721903415560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest77( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest78.py b/tests/ported_static/stRandom/test_random_statetest78.py index 6c338566d55..cb714aeed87 100644 --- a/tests/ported_static/stRandom/test_random_statetest78.py +++ b/tests/ported_static/stRandom/test_random_statetest78.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest78( ) -> None: """Test_random_statetest78.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest78( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000437f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1174648789aa349e0915aa5911 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79437f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1174648789aa349e0915aa5911" # noqa: E501 - ), - nonce=0, - address=Address(0xC0CF981B416DB73110AAC9D4DBE6D1358CF4E6DB), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest78( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000437f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1174648789aa349e0915aa5911 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79437f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1174648789aa349e0915aa5911" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest80.py b/tests/ported_static/stRandom/test_random_statetest80.py index 399c892d8f8..b294ed4588b 100644 --- a/tests/ported_static/stRandom/test_random_statetest80.py +++ b/tests/ported_static/stRandom/test_random_statetest80.py @@ -47,6 +47,23 @@ def test_random_statetest80( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f0000000000000000000000010000000000000000000000000000000000000000117fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5681069127b3b9c877d6f6169ff3660005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest80( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest81.py b/tests/ported_static/stRandom/test_random_statetest81.py index 1ced651dcd3..ae48614266f 100644 --- a/tests/ported_static/stRandom/test_random_statetest81.py +++ b/tests/ported_static/stRandom/test_random_statetest81.py @@ -46,6 +46,7 @@ def test_random_statetest81( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff436f616c327e0435743c515b078453a03c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest81( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest82.py b/tests/ported_static/stRandom/test_random_statetest82.py index 899fa717632..f91cbb5aacb 100644 --- a/tests/ported_static/stRandom/test_random_statetest82.py +++ b/tests/ported_static/stRandom/test_random_statetest82.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest82( ) -> None: """Test_random_statetest82.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,7 +62,6 @@ def test_random_statetest82( ), ), nonce=0, - address=Address(0x3D8EEF1923018C3CAE225F836AB9821321D39496), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -83,7 +79,6 @@ def test_random_statetest82( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest83.py b/tests/ported_static/stRandom/test_random_statetest83.py index 9013f6c0731..adb1b9f4b2a 100644 --- a/tests/ported_static/stRandom/test_random_statetest83.py +++ b/tests/ported_static/stRandom/test_random_statetest83.py @@ -46,6 +46,7 @@ def test_random_statetest83( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000307ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6fa1109af20740728e72150a7a9c09595560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest83( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest84.py b/tests/ported_static/stRandom/test_random_statetest84.py index 4657f38fa27..8a7e5edfb71 100644 --- a/tests/ported_static/stRandom/test_random_statetest84.py +++ b/tests/ported_static/stRandom/test_random_statetest84.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest84( ) -> None: """Test_random_statetest84.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,7 +58,6 @@ def test_random_statetest84( ) + Op.SSTORE(key=Op.MSIZE, value=Op.ISZERO), nonce=0, - address=Address(0x08E8BE5786DB8A32DF25C732DEA4A9F3E1B16E1B), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -79,7 +75,6 @@ def test_random_statetest84( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest85.py b/tests/ported_static/stRandom/test_random_statetest85.py index b58cb9d5709..85d9941e15e 100644 --- a/tests/ported_static/stRandom/test_random_statetest85.py +++ b/tests/ported_static/stRandom/test_random_statetest85.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest85( ) -> None: """Test_random_statetest85.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest85( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350f25b557e348ff374819d123109539b55 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350f25b557e348ff374819d123109539b55" # noqa: E501 - ), - nonce=0, - address=Address(0xD2FD98D49A70F7C4B524B8E53C8E5FC695555554), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest85( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350f25b557e348ff374819d123109539b55 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350f25b557e348ff374819d123109539b55" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest87.py b/tests/ported_static/stRandom/test_random_statetest87.py index 21cecdc8e74..50a064810eb 100644 --- a/tests/ported_static/stRandom/test_random_statetest87.py +++ b/tests/ported_static/stRandom/test_random_statetest87.py @@ -46,6 +46,7 @@ def test_random_statetest87( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000005b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f446e638e7e16736c030393727d74817460005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest87( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest88.py b/tests/ported_static/stRandom/test_random_statetest88.py index 9e273ece72f..c6b24419222 100644 --- a/tests/ported_static/stRandom/test_random_statetest88.py +++ b/tests/ported_static/stRandom/test_random_statetest88.py @@ -46,6 +46,23 @@ def test_random_statetest88( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000004343537f000000000000000000000000000000000000000000000000000000000000c350117fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000016f34f06a7014541167033909103620f35560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest88( nonce=0, address=Address(0x4150A4F366C525B471E788D777BFD0D118CE5B23), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest89.py b/tests/ported_static/stRandom/test_random_statetest89.py index 59eacda0dd9..37bb4e367c3 100644 --- a/tests/ported_static/stRandom/test_random_statetest89.py +++ b/tests/ported_static/stRandom/test_random_statetest89.py @@ -46,6 +46,7 @@ def test_random_statetest89( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000016f05648ce0ad106b7a6f3483379e62876b60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -76,7 +77,6 @@ def test_random_statetest89( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest9.py b/tests/ported_static/stRandom/test_random_statetest9.py index 68df686661b..9fd7f121cad 100644 --- a/tests/ported_static/stRandom/test_random_statetest9.py +++ b/tests/ported_static/stRandom/test_random_statetest9.py @@ -46,6 +46,7 @@ def test_random_statetest9( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000016f757fb845405bf1ff959ba03a9c336b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest9( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest90.py b/tests/ported_static/stRandom/test_random_statetest90.py index cb2a81f251f..b6c9a96b8d3 100644 --- a/tests/ported_static/stRandom/test_random_statetest90.py +++ b/tests/ported_static/stRandom/test_random_statetest90.py @@ -46,22 +46,7 @@ def test_random_statetest90( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff45157f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000016f116b4177f25178d7048212877e95685560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.ISZERO(Op.GASLIMIT) - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x1] - + Op.PUSH32[0xC350] - + Op.PUSH32[0x1] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x116B4177F25178D7048212877E956855 - ), - nonce=0, - address=Address(0xC826D0D6D0CD47CC972A44A7B4E8E76759E5E07E), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest90( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff45157f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000016f116b4177f25178d7048212877e95685560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.ISZERO(Op.GASLIMIT) + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x1] + + Op.PUSH32[0xC350] + + Op.PUSH32[0x1] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x116B4177F25178D7048212877E956855 + ), + nonce=0, + address=Address(0xC826D0D6D0CD47CC972A44A7B4E8E76759E5E07E), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest92.py b/tests/ported_static/stRandom/test_random_statetest92.py index 2a52569bfa5..15f258e054a 100644 --- a/tests/ported_static/stRandom/test_random_statetest92.py +++ b/tests/ported_static/stRandom/test_random_statetest92.py @@ -46,6 +46,23 @@ def test_random_statetest92( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000006f59640c655956799087168f0658a11a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest92( nonce=0, address=Address(0xEBA81E870FD988A7CA5504D2CE5972BD0E094DF8), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest95.py b/tests/ported_static/stRandom/test_random_statetest95.py index ed652de0add..572f85c4f68 100644 --- a/tests/ported_static/stRandom/test_random_statetest95.py +++ b/tests/ported_static/stRandom/test_random_statetest95.py @@ -46,6 +46,7 @@ def test_random_statetest95( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff14447ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest95( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest96.py b/tests/ported_static/stRandom/test_random_statetest96.py index a15faa41c60..f957c3f1d60 100644 --- a/tests/ported_static/stRandom/test_random_statetest96.py +++ b/tests/ported_static/stRandom/test_random_statetest96.py @@ -46,6 +46,23 @@ def test_random_statetest96( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006f183b68a09b08953085a854a39d92125560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest96( nonce=0, address=Address(0x1116E19BE1B4C4FC96B618A6A6C487B587572BE9), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest97.py b/tests/ported_static/stRandom/test_random_statetest97.py index 6c8499b4c5f..ba81619ccf4 100644 --- a/tests/ported_static/stRandom/test_random_statetest97.py +++ b/tests/ported_static/stRandom/test_random_statetest97.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest97( ) -> None: """Test_random_statetest97.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest97( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000587f0000000000000000000000000000000000000000000000000000000000000001957f0000000000000000000000000000000000000000000000000000000000000000407f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3509781040107338b35071887a186 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,25 +79,7 @@ def test_random_statetest97( ) + Op.DUP7, nonce=0, - address=Address(0x987A2BCE4EB6B8B9B42B371C1229B8BC73F029FC), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom/test_random_statetest98.py b/tests/ported_static/stRandom/test_random_statetest98.py index 288e0b63702..9ab7e9bac2e 100644 --- a/tests/ported_static/stRandom/test_random_statetest98.py +++ b/tests/ported_static/stRandom/test_random_statetest98.py @@ -46,6 +46,23 @@ def test_random_statetest98( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000000b085560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,23 +85,6 @@ def test_random_statetest98( nonce=0, address=Address(0x471B3EF5770A3FDBDBF9DBCDE26DFEE32181A61B), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -99,7 +99,7 @@ def test_random_statetest98( post = { target: Account( storage={ - 0: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, + 0: coinbase, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, diff --git a/tests/ported_static/stRandom2/test_random_statetest.py b/tests/ported_static/stRandom2/test_random_statetest.py index 97c32be70b7..9efe1661320 100644 --- a/tests/ported_static/stRandom2/test_random_statetest.py +++ b/tests/ported_static/stRandom2/test_random_statetest.py @@ -46,6 +46,23 @@ def test_random_statetest( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f29199c9aa4054170f1a15a55056f965560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest( nonce=0, address=Address(0xA482D90F6CDA557C1E8E41C3755C25821C27BB9D), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest384.py b/tests/ported_static/stRandom2/test_random_statetest384.py index 41a8e90eb2e..a6ffddfd636 100644 --- a/tests/ported_static/stRandom2/test_random_statetest384.py +++ b/tests/ported_static/stRandom2/test_random_statetest384.py @@ -46,6 +46,7 @@ def test_random_statetest384( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f16133502727c0a7f679b456df093576360005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest384( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest385.py b/tests/ported_static/stRandom2/test_random_statetest385.py index 17065a6b2a7..da8d8a10539 100644 --- a/tests/ported_static/stRandom2/test_random_statetest385.py +++ b/tests/ported_static/stRandom2/test_random_statetest385.py @@ -46,21 +46,7 @@ def test_random_statetest385( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000547f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f785188182063156955631a7a85093a5560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0x0] - + Op.SLOAD(key=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79]) - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0x1] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x785188182063156955631A7A85093A55 - ), - nonce=0, - address=Address(0x72E025A11FDE515931BA4AF263005C4A19385A5B), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest385( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000547f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f785188182063156955631a7a85093a5560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0x0] + + Op.SLOAD(key=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79]) + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0x1] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x785188182063156955631A7A85093A55 + ), + nonce=0, + address=Address(0x72E025A11FDE515931BA4AF263005C4A19385A5B), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest386.py b/tests/ported_static/stRandom2/test_random_statetest386.py index 291f849f5f4..a27676913c5 100644 --- a/tests/ported_static/stRandom2/test_random_statetest386.py +++ b/tests/ported_static/stRandom2/test_random_statetest386.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest386( ) -> None: """Test_random_statetest386.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,7 +68,6 @@ def test_random_statetest386( ), ), nonce=0, - address=Address(0xC36F24A2628CA6BF3D13FB8E6090844962DFBB86), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -89,7 +85,6 @@ def test_random_statetest386( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest387.py b/tests/ported_static/stRandom2/test_random_statetest387.py index 98149c6facf..6e5ca17b57a 100644 --- a/tests/ported_static/stRandom2/test_random_statetest387.py +++ b/tests/ported_static/stRandom2/test_random_statetest387.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest387( ) -> None: """Test_random_statetest387.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest387( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350617e7608617c95f3ff584076e07b5a4460005155" # noqa: E501 ), nonce=0, - address=Address(0xA3A709FECE04184D06401D32D39F133EA3B800A8), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest387( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest388.py b/tests/ported_static/stRandom2/test_random_statetest388.py index 89f4a13f313..075141dd621 100644 --- a/tests/ported_static/stRandom2/test_random_statetest388.py +++ b/tests/ported_static/stRandom2/test_random_statetest388.py @@ -47,6 +47,23 @@ def test_random_statetest388( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5765b8f743b9979a0905b6a18916560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest388( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest389.py b/tests/ported_static/stRandom2/test_random_statetest389.py index 65369035a61..43e4d648db8 100644 --- a/tests/ported_static/stRandom2/test_random_statetest389.py +++ b/tests/ported_static/stRandom2/test_random_statetest389.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest389( ) -> None: """Test_random_statetest389.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest389( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000427f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3503a86385458123760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,25 +82,7 @@ def test_random_statetest389( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x6442010FD6C7D107410FD0589B8059DF1C45F0D0), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest393.py b/tests/ported_static/stRandom2/test_random_statetest393.py index 2a26c42383e..ce1924283af 100644 --- a/tests/ported_static/stRandom2/test_random_statetest393.py +++ b/tests/ported_static/stRandom2/test_random_statetest393.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest393( ) -> None: """Test_random_statetest393.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest393( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20b39838f628b96846cff0455 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20b39838f628b96846cff0455" # noqa: E501 - ), - nonce=0, - address=Address(0x64114B073F76ABEBB752B7A08BBD288BCE55A63B), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest393( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20b39838f628b96846cff0455 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20b39838f628b96846cff0455" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest395.py b/tests/ported_static/stRandom2/test_random_statetest395.py index 4fd03e91938..7f637d20858 100644 --- a/tests/ported_static/stRandom2/test_random_statetest395.py +++ b/tests/ported_static/stRandom2/test_random_statetest395.py @@ -46,6 +46,7 @@ def test_random_statetest395( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x447f0000000000000000000000000000000000000000000000000000000000000001417f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f823140710bf13990e4500136726d8b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest395( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest396.py b/tests/ported_static/stRandom2/test_random_statetest396.py index 8774dd9deff..8a1b2677128 100644 --- a/tests/ported_static/stRandom2/test_random_statetest396.py +++ b/tests/ported_static/stRandom2/test_random_statetest396.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest396( ) -> None: """Test_random_statetest396.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest396( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001719f197c5560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001719f197c5560005155" # noqa: E501 - ), - nonce=0, - address=Address(0x69A358C1F8B2F5139037E6E391189E45334CCCC4), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest396( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001719f197c5560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001719f197c5560005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest397.py b/tests/ported_static/stRandom2/test_random_statetest397.py index e25d83e12f5..8b4aec81bd5 100644 --- a/tests/ported_static/stRandom2/test_random_statetest397.py +++ b/tests/ported_static/stRandom2/test_random_statetest397.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest397( ) -> None: """Test_random_statetest397.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest397( code=bytes.fromhex("413443f3404242433389ff723810"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x42C6DF39ABD3D7DE1C64C50B0D8BB0E6085FB6AF), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest397( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest398.py b/tests/ported_static/stRandom2/test_random_statetest398.py index af48eaad6d2..8d291f4499d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest398.py +++ b/tests/ported_static/stRandom2/test_random_statetest398.py @@ -46,22 +46,7 @@ def test_random_statetest398( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f0000000000000000000000006f3781413b695a69079d7f51058292075560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0xC350] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x3781413B695A69079D7F510582920755 - ), - nonce=0, - address=Address(0x08E74992E0868E4133C1164234A6064D6F708A5B), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest398( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f0000000000000000000000006f3781413b695a69079d7f51058292075560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0xC350] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x3781413B695A69079D7F510582920755 + ), + nonce=0, + address=Address(0x08E74992E0868E4133C1164234A6064D6F708A5B), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest399.py b/tests/ported_static/stRandom2/test_random_statetest399.py index 1c74d7d6a15..28398ba81ae 100644 --- a/tests/ported_static/stRandom2/test_random_statetest399.py +++ b/tests/ported_static/stRandom2/test_random_statetest399.py @@ -46,6 +46,7 @@ def test_random_statetest399( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4544437f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f98324016076d428a9898129b16849a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_random_statetest399( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest401.py b/tests/ported_static/stRandom2/test_random_statetest401.py index 18fadca3bee..97cd69f2b1f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest401.py +++ b/tests/ported_static/stRandom2/test_random_statetest401.py @@ -46,6 +46,23 @@ def test_random_statetest401( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c35044427f000000000000000000000000ff60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest401( nonce=0, address=Address(0x88643BC22681E376675775EAAA381D0BA45054DE), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest402.py b/tests/ported_static/stRandom2/test_random_statetest402.py index d7ef9fa2d0a..8f64d20bf31 100644 --- a/tests/ported_static/stRandom2/test_random_statetest402.py +++ b/tests/ported_static/stRandom2/test_random_statetest402.py @@ -46,6 +46,7 @@ def test_random_statetest402( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f62138c87028162ea32a2db7e3010045560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest402( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest404.py b/tests/ported_static/stRandom2/test_random_statetest404.py index 1b8ee9042f3..b9caca651f7 100644 --- a/tests/ported_static/stRandom2/test_random_statetest404.py +++ b/tests/ported_static/stRandom2/test_random_statetest404.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest404( ) -> None: """Test_random_statetest404.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest404( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6a7f0000000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff906606425655" # noqa: E501 ), nonce=0, - address=Address(0xFD0CF74E622C5C2B33C88CDF3A3E12FF25D0E090), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest404( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest405.py b/tests/ported_static/stRandom2/test_random_statetest405.py index bc457846146..1ef48d84f27 100644 --- a/tests/ported_static/stRandom2/test_random_statetest405.py +++ b/tests/ported_static/stRandom2/test_random_statetest405.py @@ -46,6 +46,7 @@ def test_random_statetest405( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44457f0000000000000000000000010000000000000000000000000000000000000000037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f318d0707977199361171756f6d458e5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -85,7 +86,6 @@ def test_random_statetest405( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest406.py b/tests/ported_static/stRandom2/test_random_statetest406.py index 371ea18b201..5dbbc156458 100644 --- a/tests/ported_static/stRandom2/test_random_statetest406.py +++ b/tests/ported_static/stRandom2/test_random_statetest406.py @@ -47,6 +47,23 @@ def test_random_statetest406( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b58b8e99f33c647165337e389f7b9c909cba5560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -68,23 +85,6 @@ def test_random_statetest406( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest407.py b/tests/ported_static/stRandom2/test_random_statetest407.py index 05e73413576..6590ba5af0e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest407.py +++ b/tests/ported_static/stRandom2/test_random_statetest407.py @@ -46,6 +46,23 @@ def test_random_statetest407( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff437ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c350437f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000006f6d71656f054471181163037902615b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest407( nonce=0, address=Address(0x819EE19601AD27EDAEEEAD744E0BBF165FDFB9F1), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest408.py b/tests/ported_static/stRandom2/test_random_statetest408.py index 3fa49b5137e..72ea03a898e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest408.py +++ b/tests/ported_static/stRandom2/test_random_statetest408.py @@ -46,6 +46,23 @@ def test_random_statetest408( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe447f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f80656e8e6478946a323482135a8bf75560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest408( nonce=0, address=Address(0x2672C88394A86F962D51444FF8B8047F130D4DF5), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest409.py b/tests/ported_static/stRandom2/test_random_statetest409.py index 05b23e80351..4852316345a 100644 --- a/tests/ported_static/stRandom2/test_random_statetest409.py +++ b/tests/ported_static/stRandom2/test_random_statetest409.py @@ -46,6 +46,23 @@ def test_random_statetest409( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x5b7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000001000000000000000000000000000000000000000009ff511287868833063aa3579d8e585560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,23 +96,6 @@ def test_random_statetest409( nonce=0, address=Address(0x68076CF2C7430BB5E7CBAA157DEBE1C7CC9B30AE), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest410.py b/tests/ported_static/stRandom2/test_random_statetest410.py index 3c371209e91..5c931cd5883 100644 --- a/tests/ported_static/stRandom2/test_random_statetest410.py +++ b/tests/ported_static/stRandom2/test_random_statetest410.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest410( ) -> None: """Test_random_statetest410.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest410( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000045086201771880f35560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest410( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x99E6F87CBA9C1737F49965828C1BADEC51A91DFD), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest411.py b/tests/ported_static/stRandom2/test_random_statetest411.py index 3780298d4e8..8e07e657fa8 100644 --- a/tests/ported_static/stRandom2/test_random_statetest411.py +++ b/tests/ported_static/stRandom2/test_random_statetest411.py @@ -46,6 +46,7 @@ def test_random_statetest411( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000006f44a17892738b6895619d7a93507d649d60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest411( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest412.py b/tests/ported_static/stRandom2/test_random_statetest412.py index f8fceb90e89..9d8f554e677 100644 --- a/tests/ported_static/stRandom2/test_random_statetest412.py +++ b/tests/ported_static/stRandom2/test_random_statetest412.py @@ -46,6 +46,23 @@ def test_random_statetest412( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6fa46ef06a5a858b9742198a37e1153c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest412( nonce=0, address=Address(0x1C3B1B9BCB79A7BCD1CA94D88D06E4F798A35538), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest413.py b/tests/ported_static/stRandom2/test_random_statetest413.py index 6863b2abe4e..f919d7767e6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest413.py +++ b/tests/ported_static/stRandom2/test_random_statetest413.py @@ -46,6 +46,7 @@ def test_random_statetest413( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000010000000000000000000000000000000000000000817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe037f00000000000000000000000000000000000000000000000000000000000000016f086e2055149345ad1a018b063708145560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest413( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest414.py b/tests/ported_static/stRandom2/test_random_statetest414.py index 4eb0afe1afe..40ef090a01c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest414.py +++ b/tests/ported_static/stRandom2/test_random_statetest414.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest414( ) -> None: """Test_random_statetest414.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -64,7 +61,6 @@ def test_random_statetest414( ), ), nonce=0, - address=Address(0x16000B6B36A20D3093A8B71A9FD8292C8A641002), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -82,7 +78,6 @@ def test_random_statetest414( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest415.py b/tests/ported_static/stRandom2/test_random_statetest415.py index 6254bf00454..5a4d886f054 100644 --- a/tests/ported_static/stRandom2/test_random_statetest415.py +++ b/tests/ported_static/stRandom2/test_random_statetest415.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest415( ) -> None: """Test_random_statetest415.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest415( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000000142427f000000000000000000000000357f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff62010a8c8794a17e8ea4f260005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000000142427f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79357f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff62010a8c8794a17e8ea4f260005155" # noqa: E501 - ), - nonce=0, - address=Address(0xCFEB1138E487C3084750A899713B20307D5B4217), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest415( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000000142427f000000000000000000000000357f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff62010a8c8794a17e8ea4f260005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000000142427f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79357f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff62010a8c8794a17e8ea4f260005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest416.py b/tests/ported_static/stRandom2/test_random_statetest416.py index 1d7be8d0b5e..853a3e034d1 100644 --- a/tests/ported_static/stRandom2/test_random_statetest416.py +++ b/tests/ported_static/stRandom2/test_random_statetest416.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest416( ) -> None: """Test_random_statetest416.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,22 +43,6 @@ def test_random_statetest416( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000004355 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x0] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0x0] - + Op.PUSH32[0x1] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.TIMESTAMP - + Op.SSTORE( - key=Op.NUMBER, - value=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], - ), - nonce=0, - address=Address(0xD57DEFD369A62E5099D173D42772D3345138BEDE), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +59,21 @@ def test_random_statetest416( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000004355 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x0] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0x0] + + Op.PUSH32[0x1] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.TIMESTAMP + + Op.SSTORE( + key=Op.NUMBER, + value=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], + ), + nonce=0, + ) tx = Transaction( sender=sender, @@ -91,10 +86,7 @@ def test_random_statetest416( ) post = { - target: Account( - storage={1: 0x4F3F701464972E74606D6EA82D4D3080599A0E79}, - nonce=0, - ), + target: Account(storage={1: coinbase}, nonce=0), coinbase: Account(storage={}, nonce=0), sender: Account(storage={}, code=b"", nonce=1), } diff --git a/tests/ported_static/stRandom2/test_random_statetest417.py b/tests/ported_static/stRandom2/test_random_statetest417.py index bf6db38c013..5f93c560673 100644 --- a/tests/ported_static/stRandom2/test_random_statetest417.py +++ b/tests/ported_static/stRandom2/test_random_statetest417.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest417( ) -> None: """Test_random_statetest417.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest417( code=bytes.fromhex("4343424344444242f26d69"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x632AD35D6E1A733FBBCF49749FD63D526EBDAEA1), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest417( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest418.py b/tests/ported_static/stRandom2/test_random_statetest418.py index c950e6c1062..d9365524831 100644 --- a/tests/ported_static/stRandom2/test_random_statetest418.py +++ b/tests/ported_static/stRandom2/test_random_statetest418.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest418( ) -> None: """Test_random_statetest418.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest418( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000000000000000000000000000000000000000000000437f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000000417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff12a36234970658a03160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest418( + Op.LOG0(offset=Op.PC, size=0x349706) + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.BALANCE), nonce=0, - address=Address(0xB3CEB9E1CE94D2E429039525E57315F4BD255F06), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest419.py b/tests/ported_static/stRandom2/test_random_statetest419.py index e67f0f39a59..bc87d278efa 100644 --- a/tests/ported_static/stRandom2/test_random_statetest419.py +++ b/tests/ported_static/stRandom2/test_random_statetest419.py @@ -46,6 +46,7 @@ def test_random_statetest419( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x437ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f73095b7ee211595a6b80a311900a785560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_random_statetest419( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest420.py b/tests/ported_static/stRandom2/test_random_statetest420.py index 7a894d11c0d..7dce7d0ee0a 100644 --- a/tests/ported_static/stRandom2/test_random_statetest420.py +++ b/tests/ported_static/stRandom2/test_random_statetest420.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest420( ) -> None: """Test_random_statetest420.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest420( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000003a7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001817d7b8956970660129f5015fe0a355560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e793a7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001817d7b8956970660129f5015fe0a355560005155" # noqa: E501 - ), - nonce=0, - address=Address(0x0F48FA271D166C58E40759BE208471B6BC233332), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest420( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000003a7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001817d7b8956970660129f5015fe0a355560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e793a7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001817d7b8956970660129f5015fe0a355560005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest421.py b/tests/ported_static/stRandom2/test_random_statetest421.py index 8f5ee065b06..0ae5687e6cc 100644 --- a/tests/ported_static/stRandom2/test_random_statetest421.py +++ b/tests/ported_static/stRandom2/test_random_statetest421.py @@ -46,6 +46,7 @@ def test_random_statetest421( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x437f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f38454051968ff184a47d50091231971760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest421( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest422.py b/tests/ported_static/stRandom2/test_random_statetest422.py index 95b2dee5a2a..b8c339de059 100644 --- a/tests/ported_static/stRandom2/test_random_statetest422.py +++ b/tests/ported_static/stRandom2/test_random_statetest422.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest422( ) -> None: """Test_random_statetest422.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest422( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe527f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xC350] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.MSTORE( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 - value=Op.PUSH32[0x10000000000000000000000000000000000000000], - ) - + Op.PUSH32[0x1] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], - nonce=0, - address=Address(0x3D1B9833BEB5E086AACD5155322683351C26AF63), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest422( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe527f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xC350] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.MSTORE( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 + value=Op.PUSH32[0x10000000000000000000000000000000000000000], + ) + + Op.PUSH32[0x1] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest424.py b/tests/ported_static/stRandom2/test_random_statetest424.py index c6a26ac7bfa..306991317fe 100644 --- a/tests/ported_static/stRandom2/test_random_statetest424.py +++ b/tests/ported_static/stRandom2/test_random_statetest424.py @@ -46,6 +46,23 @@ def test_random_statetest424( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000437f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000000436f18116552626186825096665471140a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest424( nonce=0, address=Address(0xACDC215BC90EEAC81BC6CB817C78E5A65A8ABCCE), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest425.py b/tests/ported_static/stRandom2/test_random_statetest425.py index 157d9a55f87..46142661c25 100644 --- a/tests/ported_static/stRandom2/test_random_statetest425.py +++ b/tests/ported_static/stRandom2/test_random_statetest425.py @@ -46,6 +46,7 @@ def test_random_statetest425( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f0000000000000000000000010000000000000000000000000000000000000000417f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f885707818b889a89975552f01284425560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -76,7 +77,6 @@ def test_random_statetest425( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest426.py b/tests/ported_static/stRandom2/test_random_statetest426.py index 281e3a85b80..ed5c86a7885 100644 --- a/tests/ported_static/stRandom2/test_random_statetest426.py +++ b/tests/ported_static/stRandom2/test_random_statetest426.py @@ -46,6 +46,23 @@ def test_random_statetest426( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000006f456d1687795a95938b0139976099f05560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest426( nonce=0, address=Address(0xC5D2C6E130510D2CF47922CFC2E517E235268490), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest428.py b/tests/ported_static/stRandom2/test_random_statetest428.py index 67ebfcbee73..5cf0d72ce61 100644 --- a/tests/ported_static/stRandom2/test_random_statetest428.py +++ b/tests/ported_static/stRandom2/test_random_statetest428.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest428( ) -> None: """Test_random_statetest428.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest428( code=bytes.fromhex("4244417b4542404409523b200283"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8C822B21830B172651BCD2C2FEC3016423769AFA), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest428( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest429.py b/tests/ported_static/stRandom2/test_random_statetest429.py index ff5f1a07a05..72b994a345e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest429.py +++ b/tests/ported_static/stRandom2/test_random_statetest429.py @@ -46,6 +46,23 @@ def test_random_statetest429( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f98121f3887867290877734763313665560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest429( nonce=0, address=Address(0x1F3C76FED529A06C56374004D1A3822D2D621062), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest430.py b/tests/ported_static/stRandom2/test_random_statetest430.py index 2410a6dd540..5eb40ab0a04 100644 --- a/tests/ported_static/stRandom2/test_random_statetest430.py +++ b/tests/ported_static/stRandom2/test_random_statetest430.py @@ -46,6 +46,23 @@ def test_random_statetest430( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000006f7d41a29934035b748e96a3135b69645560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest430( nonce=0, address=Address(0x477526F193CFA214F3D2BCBB76AC3612B1DAD747), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest433.py b/tests/ported_static/stRandom2/test_random_statetest433.py index 5e4c30b8cec..3b4a65f8041 100644 --- a/tests/ported_static/stRandom2/test_random_statetest433.py +++ b/tests/ported_static/stRandom2/test_random_statetest433.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest433( ) -> None: """Test_random_statetest433.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest433( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350a3f305205bf156207259573055 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350a3f305205bf156207259573055" # noqa: E501 - ), - nonce=0, - address=Address(0x76AD89792A42A92B922C9BE589A0C02B14E7E928), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest433( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350a3f305205bf156207259573055 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350a3f305205bf156207259573055" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest435.py b/tests/ported_static/stRandom2/test_random_statetest435.py index 4f0d16ebf94..22fc8ca14e9 100644 --- a/tests/ported_static/stRandom2/test_random_statetest435.py +++ b/tests/ported_static/stRandom2/test_random_statetest435.py @@ -46,6 +46,7 @@ def test_random_statetest435( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000000447ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000042613488076233797f553960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest435( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest436.py b/tests/ported_static/stRandom2/test_random_statetest436.py index fb3322e36fa..187a7c4ac79 100644 --- a/tests/ported_static/stRandom2/test_random_statetest436.py +++ b/tests/ported_static/stRandom2/test_random_statetest436.py @@ -46,6 +46,23 @@ def test_random_statetest436( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x367f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000456f8108067a345b7a76a20a835a0a0b6c1060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest436( nonce=0, address=Address(0x39542C1F6D75AA2F9065BE137D36D26E222E8814), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest437.py b/tests/ported_static/stRandom2/test_random_statetest437.py index 7a115c277f7..81f5042bee2 100644 --- a/tests/ported_static/stRandom2/test_random_statetest437.py +++ b/tests/ported_static/stRandom2/test_random_statetest437.py @@ -47,6 +47,23 @@ def test_random_statetest437( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe437f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000013a1339085560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest437( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest438.py b/tests/ported_static/stRandom2/test_random_statetest438.py index 5b5f32520e4..c91b9a70a5c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest438.py +++ b/tests/ported_static/stRandom2/test_random_statetest438.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest438( ) -> None: """Test_random_statetest438.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,7 +62,6 @@ def test_random_statetest438( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x5494EB40EF20819E957FDD263677CED0C6F9CB72), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -83,7 +79,6 @@ def test_random_statetest438( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest439.py b/tests/ported_static/stRandom2/test_random_statetest439.py index 76989cff9a9..fc18736d3e1 100644 --- a/tests/ported_static/stRandom2/test_random_statetest439.py +++ b/tests/ported_static/stRandom2/test_random_statetest439.py @@ -46,6 +46,23 @@ def test_random_statetest439( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f5b1609653438813340097c53a493165560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest439( nonce=0, address=Address(0xEA249997DD278A186516CB58C5999E0F51983D1C), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest440.py b/tests/ported_static/stRandom2/test_random_statetest440.py index 4d0bc4d2bbc..873e5515793 100644 --- a/tests/ported_static/stRandom2/test_random_statetest440.py +++ b/tests/ported_static/stRandom2/test_random_statetest440.py @@ -46,21 +46,7 @@ def test_random_statetest440( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000045457f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff416f01513a9b8216816f74f3676e9ea2615560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xC350] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.GASLIMIT * 2 - + Op.PUSH32[0x1] * 2 - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.COINBASE - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x1513A9B8216816F74F3676E9EA26155 - ), - nonce=0, - address=Address(0x411175E7899EA90AC5011543380D9C09A8EE199F), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +63,21 @@ def test_random_statetest440( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000045457f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff416f01513a9b8216816f74f3676e9ea2615560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xC350] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.GASLIMIT * 2 + + Op.PUSH32[0x1] * 2 + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.COINBASE + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x1513A9B8216816F74F3676E9EA26155 + ), + nonce=0, + address=Address(0x411175E7899EA90AC5011543380D9C09A8EE199F), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest442.py b/tests/ported_static/stRandom2/test_random_statetest442.py index 13c6d3e4f10..7959e6b1ef6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest442.py +++ b/tests/ported_static/stRandom2/test_random_statetest442.py @@ -46,6 +46,7 @@ def test_random_statetest442( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff917f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3501833815560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest442( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -98,7 +98,7 @@ def test_random_statetest442( target: Account( storage={ 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3CAE, # noqa: E501 - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3CAE: 0x2E3D0156D2B99A6EACBA540C55F423C8F5A33143, # noqa: E501 + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3CAE: sender, # noqa: E501 }, nonce=0, ), diff --git a/tests/ported_static/stRandom2/test_random_statetest443.py b/tests/ported_static/stRandom2/test_random_statetest443.py index b66a51151e7..12dca394e25 100644 --- a/tests/ported_static/stRandom2/test_random_statetest443.py +++ b/tests/ported_static/stRandom2/test_random_statetest443.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest443( ) -> None: """Test_random_statetest443.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest443( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001155933704 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,25 +80,7 @@ def test_random_statetest443( + Op.CALLDATACOPY + Op.DIV, nonce=0, - address=Address(0x692A3C1272CA7FF11550AF64D7C6CAFFFBE467F8), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest444.py b/tests/ported_static/stRandom2/test_random_statetest444.py index c7ea0c7c351..65c27cc519b 100644 --- a/tests/ported_static/stRandom2/test_random_statetest444.py +++ b/tests/ported_static/stRandom2/test_random_statetest444.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest444( ) -> None: """Test_random_statetest444.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest444( "7f0000000000000000000000010000000000000000000000000000000000000000607f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff661392843555" # noqa: E501 ), nonce=0, - address=Address(0x3630F8AC14310E923A9B6F57148A873829B27144), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest444( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest445.py b/tests/ported_static/stRandom2/test_random_statetest445.py index fcf7d51f873..1e429145745 100644 --- a/tests/ported_static/stRandom2/test_random_statetest445.py +++ b/tests/ported_static/stRandom2/test_random_statetest445.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest445( ) -> None: """Test_random_statetest445.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest445( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008756993365a1376155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008756993365a1376155" # noqa: E501 - ), - nonce=0, - address=Address(0xDF00487753FAFB7D8AC061B9F2FBE3488F0D83D7), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest445( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008756993365a1376155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008756993365a1376155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest446.py b/tests/ported_static/stRandom2/test_random_statetest446.py index e664b4ad2cb..29fe4b0606d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest446.py +++ b/tests/ported_static/stRandom2/test_random_statetest446.py @@ -46,6 +46,7 @@ def test_random_statetest446( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0955 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest446( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest447.py b/tests/ported_static/stRandom2/test_random_statetest447.py index 165de5b1757..d1240b7a71a 100644 --- a/tests/ported_static/stRandom2/test_random_statetest447.py +++ b/tests/ported_static/stRandom2/test_random_statetest447.py @@ -46,6 +46,23 @@ def test_random_statetest447( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff085560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,23 +87,6 @@ def test_random_statetest447( nonce=0, address=Address(0xE1655B4F3E5F4FD17126A28F5CC273EFEB1C89B3), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest448.py b/tests/ported_static/stRandom2/test_random_statetest448.py index 93d833f5681..84cf86ec705 100644 --- a/tests/ported_static/stRandom2/test_random_statetest448.py +++ b/tests/ported_static/stRandom2/test_random_statetest448.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest448( ) -> None: """Test_random_statetest448.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest448( gas_limit=9223372036854775807, ) - # Source: raw - # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.TIMESTAMP - + Op.PUSH32[0x0] - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PC - + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) - + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), - nonce=0, - address=Address(0xB2DA1F608A7E0626E721677FA30FC46D2D99C655), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest448( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.TIMESTAMP + + Op.PUSH32[0x0] + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PC + + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) + + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest449.py b/tests/ported_static/stRandom2/test_random_statetest449.py index b8b10a9afc1..d098fe1bf57 100644 --- a/tests/ported_static/stRandom2/test_random_statetest449.py +++ b/tests/ported_static/stRandom2/test_random_statetest449.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest449( ) -> None: """Test_random_statetest449.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest449( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x197f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000008b66e4ff65a056f39b529f # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,25 +77,7 @@ def test_random_statetest449( + Op.MSTORE(offset=0xE4FF65A056F39B, value=Op.DUP12) + Op.SWAP16, nonce=0, - address=Address(0xA744E6FA67E6F6717D1AF2356F4679AE961CAD1E), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest450.py b/tests/ported_static/stRandom2/test_random_statetest450.py index d3e1e43de6e..f19bbc92f7c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest450.py +++ b/tests/ported_static/stRandom2/test_random_statetest450.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest450( ) -> None: """Test_random_statetest450.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xEC7C2DE039694D1868A1956B3126454E8E17448344A219E03D859B64831B6AF8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A764000000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest450( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000010000000000000000000000000000000000000000033a8060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,25 +80,7 @@ def test_random_statetest450( + Op.GASPRICE + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.DUP1), nonce=0, - address=Address(0x4CDA9E76F4EC620CA74C0321E2393998B84F4B99), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A764000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest451.py b/tests/ported_static/stRandom2/test_random_statetest451.py index 7123a211373..f8c29c42d22 100644 --- a/tests/ported_static/stRandom2/test_random_statetest451.py +++ b/tests/ported_static/stRandom2/test_random_statetest451.py @@ -46,6 +46,23 @@ def test_random_statetest451( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000006fed05989a0659453076573a870411745560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest451( nonce=0, address=Address(0xD3D2709429A6489E16C9CBCD44A7BBF746EEB5F2), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest452.py b/tests/ported_static/stRandom2/test_random_statetest452.py index 8f12131f648..f293656b762 100644 --- a/tests/ported_static/stRandom2/test_random_statetest452.py +++ b/tests/ported_static/stRandom2/test_random_statetest452.py @@ -46,6 +46,23 @@ def test_random_statetest452( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006f0a3289746806163630047dff9831055560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest452( nonce=0, address=Address(0xF0FF5931AD08530E3D77980D2F2DE3D8A81A5AB4), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest454.py b/tests/ported_static/stRandom2/test_random_statetest454.py index 8fbfba7003e..8602d2c5dc3 100644 --- a/tests/ported_static/stRandom2/test_random_statetest454.py +++ b/tests/ported_static/stRandom2/test_random_statetest454.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest454( ) -> None: """Test_random_statetest454.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest454( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000000557f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000557f0000000000000000000000000a84339188646595668352a061855560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,25 +75,7 @@ def test_random_statetest454( + Op.LOG0(offset=0x6595668352, size=Op.DUP9) + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x8555), nonce=0, - address=Address(0x0089D9313F6C18F62805E3A145739544EE1459A7), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest455.py b/tests/ported_static/stRandom2/test_random_statetest455.py index ef2324e8980..29f79d69583 100644 --- a/tests/ported_static/stRandom2/test_random_statetest455.py +++ b/tests/ported_static/stRandom2/test_random_statetest455.py @@ -46,6 +46,23 @@ def test_random_statetest455( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000006f858b1411f218693ca2245b918274f35560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest455( nonce=0, address=Address(0xFFBFD097BCE347E41311BED3648AAFFC63840DD6), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest456.py b/tests/ported_static/stRandom2/test_random_statetest456.py index 12994399809..c280a649e02 100644 --- a/tests/ported_static/stRandom2/test_random_statetest456.py +++ b/tests/ported_static/stRandom2/test_random_statetest456.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest456( ) -> None: """Test_random_statetest456.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest456( code=bytes.fromhex("41424143445a42f35b10773574016c9f"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x832214236B4DC7829A505AFAFB05B91D152F9FF4), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest456( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest457.py b/tests/ported_static/stRandom2/test_random_statetest457.py index c9bcaf57971..f8fca23bc05 100644 --- a/tests/ported_static/stRandom2/test_random_statetest457.py +++ b/tests/ported_static/stRandom2/test_random_statetest457.py @@ -46,6 +46,7 @@ def test_random_statetest457( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x44417f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f949fa28af308a37a136c626218927d5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest457( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest458.py b/tests/ported_static/stRandom2/test_random_statetest458.py index 9f678875984..04a0977cb90 100644 --- a/tests/ported_static/stRandom2/test_random_statetest458.py +++ b/tests/ported_static/stRandom2/test_random_statetest458.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest458( ) -> None: """Test_random_statetest458.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest458( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7689747fb3520231748bbe5eb9617666e630019e3e84ce7179c5d83b7e36050e5c05623956e599f54eb56213e4f96f69f402cd73e13c366095a3fe56bdd6a815d9ba23f3a9729bc462385c697ed9f24192c949e33ff7ed256c84979d70148b8fd8a62438ca053de2642271456dde46ce78cf7c6d1d2cc48eee658a73ad9f9ca1e550720490e2d0769e0a429773e42fc965ea1030f6c0787b4e7bc4915150a99fc758d3373561d8917c4c7d605f0cd8d2203f4d69606198437429e2f2d2bf742b28760a9c0ab51203d0c5d5b9e16d74ce0428945aaff2d0f99240a901d3233bd04e366c367ab93ecea0c206fbf01084254636df9c1f308c7d6875d5d5d37f3ce27989e39048f175f0d2dc49eaa86530def7ab70553f5d3904c843b5736025e321e7e2ab92af570e5b3bef4014c54e65316bb546eb8906f155f7b9405326740104d8f5d98dc97ac374ad0c58f4385e086891b9b2657e982eb15a367eab6683b51ea9f219abae5ca39f669a1a88a82e14efd4192a3edbe04a12d35679cf6338130d67f37c324464d16cc866be846b0304ef9fd3c6611e6cdf1277d65f6b2a58ffb61ba979740b8df72816602071e979e6029c9307d718ffdc70f37ea0019353c06b0fb56d8e3738dfdb18418e952092e8625b51749f276cc6ae416a85bd070c61e65240d8c2719c76b0420f84ece41c9be0f93d4f30581c28f69768395163937f95b86da30fa76b6937870245d9250e06b6e07dffea8f849a37647378dd59ac8365a37dd908eea26be2f53375e1dbee32ecaa7e957eace8c6f0883e4ef830485bd43b2b7851a0b11497f752d3ee4560e312a7a91b7b2a88c109737c92feb7807d481ac3fd823f038c4ba82df40a60982a7c7a6f6ba2cb95233c257b30e1c9d3c84aa37b6f4268fec34fb9eef1f8602e6a7bf1ebfa162680b57af09f7a7fc584055ff32d68a92e59ddaf20bcaaaa70d5970fd71c04cdbab46cf86e566e870664b6df2c6861347b2a3886788bbebbd03cbb51ed29357f699c8b974c61528a0423f67a837bfab83afa78a0bff70a653ea0f398f73632d5e3bea0a31115d65486fb6d667110448e0208264a3f76f35972666e7aa7339f23b08e6028616337a0366016601d6014600b630e6db38e73635706352bf1695bb9e53d5ad3ba1191ea65ae1880d46c687605148e427a09d40172dbdd5fc72fffb1443080a39a0ee77feed9ddc9050affce41d68c34ad97c484f204a987bcfaf46b9fa4a9ed2dad3738771a3cf86b43f303a8db8cde3ed8a40ae35574b9084f4cab88701d150e628d9b2a33e71c8f9fb0ce9e72866257691776f999b7ddf64f22532351bd34743e08facd1acc94b0d6b56bf97491d5ed9d726af684d1a47abcb243b7c29d12a315e939f70af8d2617df63567c3bc56c16609a27871af77631fe1ccaa0d15f8da9bd9a712a544abb92b925b1d7561fced60b09b6b22f2121b105a65a209e151b76b31be481d57353d10a1d968ca7a185495a8a2935571a0d17443a327bf11cb421baca9064bc4e4497c7d4c486c40082cc2d01b3f6023b726de95ac2ad53ae0b731d741676338181e66c8ac8daf0d54776827987e79d9f617c51f6f4b87cf8fee734c99e5e3fc2e37f17e626cbfd1195157215d10fa39b4b0947c3339139b280c0b042da7ec93a24416d5c52e0ba21ec9d39d6fbcd3d74266580eef6ca9bb9d76bb4dc441f3d6d0cf38307b505251deea82ab39f9ccd17a6507bf16b38640679c22f2134e8258f79b # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -151,23 +164,6 @@ def test_random_statetest458( nonce=0, address=Address(0x4F391713BDCA6E610DEA121DF82FF743D96D33B6), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest460.py b/tests/ported_static/stRandom2/test_random_statetest460.py index 0cf688d99e0..d710b0a6ea2 100644 --- a/tests/ported_static/stRandom2/test_random_statetest460.py +++ b/tests/ported_static/stRandom2/test_random_statetest460.py @@ -46,6 +46,7 @@ def test_random_statetest460( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000003a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350046f16a23c6c90739ba201697b4315778a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest460( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest461.py b/tests/ported_static/stRandom2/test_random_statetest461.py index 83e09db8050..2a9d8c2284d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest461.py +++ b/tests/ported_static/stRandom2/test_random_statetest461.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest461( ) -> None: """Test_random_statetest461.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest461( ) + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.MSIZE), nonce=0, - address=Address(0x65331D87609C6ECD5A695B8AF79603E6F023FC3D), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest461( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest462.py b/tests/ported_static/stRandom2/test_random_statetest462.py index 163f48d89d0..64e66e327df 100644 --- a/tests/ported_static/stRandom2/test_random_statetest462.py +++ b/tests/ported_static/stRandom2/test_random_statetest462.py @@ -46,20 +46,7 @@ def test_random_statetest462( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f8e0186019d029d1354681482826f375560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 3 - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x8E0186019D029D1354681482826F3755 - ), - nonce=0, - address=Address(0xEDEF025388CA5B473F7F8A4F3FF29633328064C6), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -76,7 +63,20 @@ def test_random_statetest462( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f0000000000000000000000007f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f8e0186019d029d1354681482826f375560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 3 + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x8E0186019D029D1354681482826F3755 + ), + nonce=0, + address=Address(0xEDEF025388CA5B473F7F8A4F3FF29633328064C6), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest464.py b/tests/ported_static/stRandom2/test_random_statetest464.py index 1148054cb23..fd502ab1fac 100644 --- a/tests/ported_static/stRandom2/test_random_statetest464.py +++ b/tests/ported_static/stRandom2/test_random_statetest464.py @@ -46,6 +46,7 @@ def test_random_statetest464( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x447f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest464( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest465.py b/tests/ported_static/stRandom2/test_random_statetest465.py index c458271a777..d1ceeac89e2 100644 --- a/tests/ported_static/stRandom2/test_random_statetest465.py +++ b/tests/ported_static/stRandom2/test_random_statetest465.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest465( ) -> None: """Test_random_statetest465.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest465( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000437f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,25 +75,7 @@ def test_random_statetest465( ] + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.PUSH32[0x1]), nonce=0, - address=Address(0x39C49DE6B1821E4BF091113386607CC5533AB190), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest466.py b/tests/ported_static/stRandom2/test_random_statetest466.py index 63227140abe..d538ce72f00 100644 --- a/tests/ported_static/stRandom2/test_random_statetest466.py +++ b/tests/ported_static/stRandom2/test_random_statetest466.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest466( ) -> None: """Test_random_statetest466.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest466( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x01B1E973A4D051CFBB5ACDE495ECCDF5AD34A422), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest466( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest467.py b/tests/ported_static/stRandom2/test_random_statetest467.py index c19f585f025..14eb143ce07 100644 --- a/tests/ported_static/stRandom2/test_random_statetest467.py +++ b/tests/ported_static/stRandom2/test_random_statetest467.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest467( ) -> None: """Test_random_statetest467.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest467( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x700ab6605e03171122aeebd20b63699a72d454628639346ffaf92bcd1855c6dde5c90ba78a966a256c777ce8880c23f90f4a2ecc999a6cd42da7121d5e1fde1c9c340f9660b571a71e20a5753bc4e291adbd41a228289a0be175a606bc44dd2079ece46a2cba498bee0d80a41673d8016e7232f97a66b29954364570f6e2d08b6d429c6a75f737c594aca21580bc0d60e67c38a50ce1ddf0ce9963fd79da8a590429f5fcfb6e7fd9ee2d27201f95707235ce3dbc5997e44baa174111977f51dc6b333a9a63483e6a3d6f423ed5778057702664b65d4af9aab14d773a787d60bd24c439b29533c6b172278b6a78e64f8e319fbd6b45eeca466afd1eb2eecbaeed773da8711c4c65787e0a0a1297f525b7418f49fbc1b2446a847d74bb0a66e3b06ef70d8a8aa09a910a6be623c6a8239960381512da962eb868a21f99d90741128fcb711e029cff42f4f8f5d35947c4a7b39cff7fd46f916cc8612b146bbf52db1cd36e6c2fce7cd9ed232e21946081d78d87e61bc42fce313fa32b458d1e898e52cc2e607570a7e1d2ae3b5b7d58e0a70396bcfaae0789cd9202876488bb595d457a45bc48e190f5d56b34be6d244070ffe02107ceaf9313db08d9a1809b366fc956e6c5567da1d8a656406871eb0dd46268b5127366225cb464667bd081c949847a95e2821f589dad60c061ef2fa36b9e17c2b3a94181a8f8a89b486734ca1a8a0c86c26d076004601160066012635e0d738673636158e2e1f166e10de5d590572335 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -106,23 +119,6 @@ def test_random_statetest467( nonce=0, address=Address(0x79940E2F1225EBA4FAB3405B111535075C733270), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest469.py b/tests/ported_static/stRandom2/test_random_statetest469.py index 976fc3df018..5a99fa3f9b4 100644 --- a/tests/ported_static/stRandom2/test_random_statetest469.py +++ b/tests/ported_static/stRandom2/test_random_statetest469.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest469( ) -> None: """Test_random_statetest469.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,7 +57,6 @@ def test_random_statetest469( + Op.JUMP(pc=0x413B) + Op.SSTORE(key=Op.ADDMOD, value=Op.CALLCODE), nonce=0, - address=Address(0x912E90647207810A8FA1F685D7CD4A5BAA06E85D), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -78,7 +74,6 @@ def test_random_statetest469( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest470.py b/tests/ported_static/stRandom2/test_random_statetest470.py index fb98e3a10b1..61e748904b7 100644 --- a/tests/ported_static/stRandom2/test_random_statetest470.py +++ b/tests/ported_static/stRandom2/test_random_statetest470.py @@ -46,6 +46,7 @@ def test_random_statetest470( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x457f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000001357f00000000000000000000000000000000000000000000000000000000000000000b60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest470( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest471.py b/tests/ported_static/stRandom2/test_random_statetest471.py index b6d9efc752c..ee806426281 100644 --- a/tests/ported_static/stRandom2/test_random_statetest471.py +++ b/tests/ported_static/stRandom2/test_random_statetest471.py @@ -46,6 +46,7 @@ def test_random_statetest471( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09650618701355040655183a51377d8260005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest471( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest472.py b/tests/ported_static/stRandom2/test_random_statetest472.py index b135610ea3c..a2790261184 100644 --- a/tests/ported_static/stRandom2/test_random_statetest472.py +++ b/tests/ported_static/stRandom2/test_random_statetest472.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest472( ) -> None: """Test_random_statetest472.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest472( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000041437ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff090a60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest472( ), ), nonce=0, - address=Address(0x5B9EFB31B8BE05E6E52F6921F9EE79769A6792D0), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest473.py b/tests/ported_static/stRandom2/test_random_statetest473.py index 684ce3f34f4..77696035ad1 100644 --- a/tests/ported_static/stRandom2/test_random_statetest473.py +++ b/tests/ported_static/stRandom2/test_random_statetest473.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest473( """Test_random_statetest473.""" coinbase = Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest473( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff317f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b59102095560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -70,25 +83,7 @@ def test_random_statetest473( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest474.py b/tests/ported_static/stRandom2/test_random_statetest474.py index 08f4aa4a5b8..897f4e4170c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest474.py +++ b/tests/ported_static/stRandom2/test_random_statetest474.py @@ -46,6 +46,7 @@ def test_random_statetest474( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe027f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f7d6f6b1051778ea1670387810b58055560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest474( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest475.py b/tests/ported_static/stRandom2/test_random_statetest475.py index 9527bb1877b..2cdd0f7836b 100644 --- a/tests/ported_static/stRandom2/test_random_statetest475.py +++ b/tests/ported_static/stRandom2/test_random_statetest475.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest475( ) -> None: """Test_random_statetest475.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest475( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0955 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,25 +77,7 @@ def test_random_statetest475( value=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79], ), nonce=0, - address=Address(0x4992E682E800CD8E1379EABF4279FF7AFEC36CC6), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -97,7 +92,7 @@ def test_random_statetest475( post = { target: Account( storage={ - 0xFFFFFFFFFFFFFFFFFFFFFFFE000000000000000000000001FFFFFFFFFFFFFFFF: 0x4F3F701464972E74606D6EA82D4D3080599A0E79, # noqa: E501 + 0xFFFFFFFFFFFFFFFFFFFFFFFE000000000000000000000001FFFFFFFFFFFFFFFF: coinbase, # noqa: E501 }, nonce=0, ), diff --git a/tests/ported_static/stRandom2/test_random_statetest476.py b/tests/ported_static/stRandom2/test_random_statetest476.py index d6c0f36122b..4478cded4e6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest476.py +++ b/tests/ported_static/stRandom2/test_random_statetest476.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest476( ) -> None: """Test_random_statetest476.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -72,7 +69,6 @@ def test_random_statetest476( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xAD6FFFED2E41E6D57F10DEBDF91B1DC35758B7AD), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -90,7 +86,6 @@ def test_random_statetest476( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest477.py b/tests/ported_static/stRandom2/test_random_statetest477.py index 8c86d2bbc8c..17c6da2359e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest477.py +++ b/tests/ported_static/stRandom2/test_random_statetest477.py @@ -46,6 +46,23 @@ def test_random_statetest477( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001417ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f9084a3758d3456763aa4f09c8b735b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest477( nonce=0, address=Address(0x50235D3527B930D9031704AA08E62B9D72A7CFBA), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest478.py b/tests/ported_static/stRandom2/test_random_statetest478.py index 5ce01792554..6780cc9c185 100644 --- a/tests/ported_static/stRandom2/test_random_statetest478.py +++ b/tests/ported_static/stRandom2/test_random_statetest478.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest478( ) -> None: """Test_random_statetest478.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest478( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001447f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f1606588a909558021569" # noqa: E501 ), nonce=0, - address=Address(0xCFBDED6C35B6AEFFC2AFE1C21FC42D489AD4E002), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest478( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest480.py b/tests/ported_static/stRandom2/test_random_statetest480.py index 5cb15764a91..c9504c8e817 100644 --- a/tests/ported_static/stRandom2/test_random_statetest480.py +++ b/tests/ported_static/stRandom2/test_random_statetest480.py @@ -46,6 +46,7 @@ def test_random_statetest480( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff037f0000000000000000000000000000000000000000000000000000000000000000427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f5af3a474ff64f3a37d51f36a6a607f5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest480( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest481.py b/tests/ported_static/stRandom2/test_random_statetest481.py index d63f80b9b65..f63abbb04b3 100644 --- a/tests/ported_static/stRandom2/test_random_statetest481.py +++ b/tests/ported_static/stRandom2/test_random_statetest481.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest481( ) -> None: """Test_random_statetest481.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest481( "447f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff09437f0000000000000000000000010000000000000000000000000000000000000000a2695a7d52064361127350" # noqa: E501 ), nonce=0, - address=Address(0x6566EB05C057CAD2FD88C1FEC362190264DDE517), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest481( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest482.py b/tests/ported_static/stRandom2/test_random_statetest482.py index 9f8f8b787da..7f0b462f558 100644 --- a/tests/ported_static/stRandom2/test_random_statetest482.py +++ b/tests/ported_static/stRandom2/test_random_statetest482.py @@ -46,6 +46,23 @@ def test_random_statetest482( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f027c9d313d9b09376505927c8e71565560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest482( nonce=0, address=Address(0x10BBDCD5333CACA2B44AA07ADDC53E8ED2654B3C), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest483.py b/tests/ported_static/stRandom2/test_random_statetest483.py index 29956de705d..e337fc6a653 100644 --- a/tests/ported_static/stRandom2/test_random_statetest483.py +++ b/tests/ported_static/stRandom2/test_random_statetest483.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest483( ) -> None: """Test_random_statetest483.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest483( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe840955 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0x0] * 2 - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.SSTORE( - key=Op.MULMOD( - Op.DUP5, - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 - ), - value=Op.PUSH32[0x1], - ), - nonce=0, - address=Address(0xB86AF9DC2BDCC686FFAB19D6CAC02521FD762055), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest483( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe840955 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0x0] * 2 + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.SSTORE( + key=Op.MULMOD( + Op.DUP5, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, # noqa: E501 + ), + value=Op.PUSH32[0x1], + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest484.py b/tests/ported_static/stRandom2/test_random_statetest484.py index 4731b266e5b..2c67f679087 100644 --- a/tests/ported_static/stRandom2/test_random_statetest484.py +++ b/tests/ported_static/stRandom2/test_random_statetest484.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest484( ) -> None: """Test_random_statetest484.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest484( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff35427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000595584a2558493a25b5a6a60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff35427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79595584a2558493a25b5a6a60005155" # noqa: E501 - ), - nonce=0, - address=Address(0x55CFF4F5475D77A24015AB0F01029B182814B37B), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest484( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff35427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000595584a2558493a25b5a6a60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff35427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79595584a2558493a25b5a6a60005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest485.py b/tests/ported_static/stRandom2/test_random_statetest485.py index 20fd3919473..8a8a0cceb40 100644 --- a/tests/ported_static/stRandom2/test_random_statetest485.py +++ b/tests/ported_static/stRandom2/test_random_statetest485.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest485( ) -> None: """Test_random_statetest485.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest485( "7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000008e447f00000000000000000000000100000000000000000000000000000000000000003a1a7e" # noqa: E501 ), nonce=0, - address=Address(0x91A7CC63F8BB623D64FE789D8CC49C06427BB9C2), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest485( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest487.py b/tests/ported_static/stRandom2/test_random_statetest487.py index e568bef5005..5e3e4ff58ee 100644 --- a/tests/ported_static/stRandom2/test_random_statetest487.py +++ b/tests/ported_static/stRandom2/test_random_statetest487.py @@ -46,6 +46,7 @@ def test_random_statetest487( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe337fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0308ff9f708d1710086a73a0766a6b55 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest487( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest488.py b/tests/ported_static/stRandom2/test_random_statetest488.py index 95d783e3890..e0a3e2346b5 100644 --- a/tests/ported_static/stRandom2/test_random_statetest488.py +++ b/tests/ported_static/stRandom2/test_random_statetest488.py @@ -46,6 +46,23 @@ def test_random_statetest488( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000427f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f3250648093577f6364a218f0907e7d5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest488( nonce=0, address=Address(0xDFD379AB9052FD0504226C54A761237FF69333B4), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest489.py b/tests/ported_static/stRandom2/test_random_statetest489.py index 4d99a89c114..2371883ee4f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest489.py +++ b/tests/ported_static/stRandom2/test_random_statetest489.py @@ -46,22 +46,7 @@ def test_random_statetest489( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000456f2b8e846b91987417705a126e7707645560005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ] - * 3 - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0x0] * 2 - + Op.GASLIMIT - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x2B8E846B91987417705A126E77076455 - ), - nonce=0, - address=Address(0x92E909C60772D315706B32F2A3271091EADD78ED), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest489( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000456f2b8e846b91987417705a126e7707645560005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ] + * 3 + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0x0] * 2 + + Op.GASLIMIT + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x2B8E846B91987417705A126E77076455 + ), + nonce=0, + address=Address(0x92E909C60772D315706B32F2A3271091EADD78ED), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest491.py b/tests/ported_static/stRandom2/test_random_statetest491.py index 5c76a9dd2b4..13bcc9e74bb 100644 --- a/tests/ported_static/stRandom2/test_random_statetest491.py +++ b/tests/ported_static/stRandom2/test_random_statetest491.py @@ -46,6 +46,7 @@ def test_random_statetest491( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000006fa0f670645a778c71127d3b5598308b1760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest491( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest493.py b/tests/ported_static/stRandom2/test_random_statetest493.py index 5e438585237..84bd05560e1 100644 --- a/tests/ported_static/stRandom2/test_random_statetest493.py +++ b/tests/ported_static/stRandom2/test_random_statetest493.py @@ -46,6 +46,23 @@ def test_random_statetest493( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest493( nonce=0, address=Address(0xB48BF563D8D32F5C2632D374277B74F85810617D), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest494.py b/tests/ported_static/stRandom2/test_random_statetest494.py index fd948b351b8..e4f6950cd24 100644 --- a/tests/ported_static/stRandom2/test_random_statetest494.py +++ b/tests/ported_static/stRandom2/test_random_statetest494.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest494( ) -> None: """Test_random_statetest494.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest494( "847f000000000000000000000000000000000000000000000000000000000000c35043657f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4362f03c897f50f073f219105455" # noqa: E501 ), nonce=0, - address=Address(0x38B239AB7D6AAF0165C4AD27921248D64F77A368), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest494( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest495.py b/tests/ported_static/stRandom2/test_random_statetest495.py index 9362c1419ad..9813c87ffcf 100644 --- a/tests/ported_static/stRandom2/test_random_statetest495.py +++ b/tests/ported_static/stRandom2/test_random_statetest495.py @@ -46,15 +46,7 @@ def test_random_statetest495( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7e6410f26f519c538ea2070a6c60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000100000000000000000000000000000000000000006f427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7e6410f26f519c538ea2070a6c60005155" # noqa: E501 - ), - nonce=0, - address=Address(0x3960D00F7AF05F0183BA04D1DB89BFE241A50926), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +63,15 @@ def test_random_statetest495( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7e6410f26f519c538ea2070a6c60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f00000000000000000000000100000000000000000000000000000000000000006f427ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7e6410f26f519c538ea2070a6c60005155" # noqa: E501 + ), + nonce=0, + address=Address(0x3960D00F7AF05F0183BA04D1DB89BFE241A50926), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest496.py b/tests/ported_static/stRandom2/test_random_statetest496.py index 05b427a8f2b..6026a342b94 100644 --- a/tests/ported_static/stRandom2/test_random_statetest496.py +++ b/tests/ported_static/stRandom2/test_random_statetest496.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest496( ) -> None: """Test_random_statetest496.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest496( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x3CD8F98E1691532041C91DF7D39EBF449B04CB9D), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest496( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest497.py b/tests/ported_static/stRandom2/test_random_statetest497.py index 511f9f4ed96..74327c70b2d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest497.py +++ b/tests/ported_static/stRandom2/test_random_statetest497.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest497( ) -> None: """Test_random_statetest497.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,7 +60,6 @@ def test_random_statetest497( value=Op.PUSH32[0xC350], ), nonce=0, - address=Address(0xFCD27DEBF054614355478E0FF6C51D24676987C6), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -81,7 +77,6 @@ def test_random_statetest497( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest498.py b/tests/ported_static/stRandom2/test_random_statetest498.py index 4f2ac888eba..97cfbdbd7ac 100644 --- a/tests/ported_static/stRandom2/test_random_statetest498.py +++ b/tests/ported_static/stRandom2/test_random_statetest498.py @@ -47,6 +47,23 @@ def test_random_statetest498( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x6bd243dbcfdc6982733e4cd6261574fc6cdec93282ff50ef24d8be05d58be29301ddb00d7547f6b65997e73d232b76d6484c11eb15c87b01f89e2779c427711ba193e4e163967efd1b9315187c3227f67b9282fc7524692fbf851cb370d396d53f7a86353aacecc5c1eadeddbb3925522f935fc5ed03568fbf40261c056a124f1334cc9fa8eea2bdbf68f04c10cc08b6babcbb6ee8d3fb88dd42d06d445b5eab34cb5d64408cf652fd7568acaa81b573f66fa8781e83185438e42796631ae9a9987f714d986f94fc6354921a9367bb6b9e555f24107cb814557f8bd87547ad612c3e726f9f495b0ac9e37fbe5f23014c68d8d032bfae779a5213c33778af679417d77733645f87b6042be92c553dbb6d85a2c56b21a53c0e612ae0a8d78d60f162b52efea464ebb0472b3e7794198cdb286cd2f21f06659320130750e7aa2c83ceb2801555785c9f02455252560846587006e90cbffc955445d9ef1f55eeb07011c02cee02df12dc35b36702539873e4b766e4ae9e829a442460dd7f845cd37dc08f93bef98a4d5b53ecd4cf4dd1a5c416f92116160f0fb673c30b7873b85a2ff6331a5d371f3d109f5794d712e03493b17fc562ac7589411127e654ce32d273f8300cc8544e7bd782aa7828b543958dadf872d7f13401a51b13835cc8a36be87cc7347cdf0f7aa2df420bb03e925c117d4befbc7e69472fd75f01f3f6c966de818174aba3b7a43014c3dd39414fb3d239d72e06852ae48e6203c60a7e844d6fd61c5b519d43780d383d103989f9bfce5ed122804cba183c188f5ce47c348a96973eca904f096aed4fb77d40ca9139447527f267a028eae5e3706e1975fc3e38327505e81d0e8c9fab1f60ec7ece71cc87510f308984ebdcb8ab84e1905dfdc0a19ee3c5f37e88dc3a9f26497c51427da28f6d777d9585b4ec790722bacaa179b1dc5b086d945623f9d29f6013600c60096019634f4421eb73631ac754faf17506f9cc63229e7fe309b7a2f1acf074a43aa4dd2b75bf6dadf21aadb9a3e239a9592f576c9265eebd2420e2626d2b2f1f7ee7a56725d7d4fe23da45725e8b709d2976703147ef66a8fc9a6c1225df7b79eec95ddda5e91c6e19bbc55baf9d6c440cc805f0d229738d17a76f95e329f94d5bc48cc5964933f9597fb57a6f7290649722d68a72fa2d081c4547943b3bbca2edc5f4032c5c916e585fa6abd1b209e2b6fb64498a37b9796c95da3fdb8013c13ef99ed49b29282ae55458c651fdb8598b527024d2da1e8a7015f65ee4ab0178b68ab8c877d55f3c89a7f1f7bc6c0d86bc69688cbcc252972693993bf766aac4efb2b65b216cca2e721dea3f3b3df3abbbfb7b8d # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -131,23 +148,6 @@ def test_random_statetest498( nonce=0, address=Address(0x1A819DD2E8CEC87D7E886DF4843E21775F6672A4), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest499.py b/tests/ported_static/stRandom2/test_random_statetest499.py index c86a08df6b5..ef12fccaec7 100644 --- a/tests/ported_static/stRandom2/test_random_statetest499.py +++ b/tests/ported_static/stRandom2/test_random_statetest499.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest499( ) -> None: """Test_random_statetest499.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -68,7 +65,6 @@ def test_random_statetest499( + Op.CALLER + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.CODESIZE), nonce=0, - address=Address(0x3E92E47A39045FB9403EE960C8567D343DD24997), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -86,7 +82,6 @@ def test_random_statetest499( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest500.py b/tests/ported_static/stRandom2/test_random_statetest500.py index 5f704ff3d29..6033b4afb37 100644 --- a/tests/ported_static/stRandom2/test_random_statetest500.py +++ b/tests/ported_static/stRandom2/test_random_statetest500.py @@ -46,6 +46,23 @@ def test_random_statetest500( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f87196584968a97046c6791993114825560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest500( nonce=0, address=Address(0x869EFA3F6679D21D5A02396162D019DC6646B502), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest501.py b/tests/ported_static/stRandom2/test_random_statetest501.py index 7eb49ed7e1a..a33fb39f1db 100644 --- a/tests/ported_static/stRandom2/test_random_statetest501.py +++ b/tests/ported_static/stRandom2/test_random_statetest501.py @@ -46,6 +46,7 @@ def test_random_statetest501( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,7 +89,6 @@ def test_random_statetest501( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest502.py b/tests/ported_static/stRandom2/test_random_statetest502.py index 25f5fe7418e..9e1ab6746df 100644 --- a/tests/ported_static/stRandom2/test_random_statetest502.py +++ b/tests/ported_static/stRandom2/test_random_statetest502.py @@ -47,6 +47,23 @@ def test_random_statetest502( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c350807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b59c66369a85a46da182186158637860005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest502( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest503.py b/tests/ported_static/stRandom2/test_random_statetest503.py index c9faf48c8eb..5a92ce9d5c8 100644 --- a/tests/ported_static/stRandom2/test_random_statetest503.py +++ b/tests/ported_static/stRandom2/test_random_statetest503.py @@ -46,6 +46,7 @@ def test_random_statetest503( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000006f0886a83c66553c9889528d8f1294ff5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +80,6 @@ def test_random_statetest503( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest504.py b/tests/ported_static/stRandom2/test_random_statetest504.py index 0a3f6789056..6fed29c3e1c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest504.py +++ b/tests/ported_static/stRandom2/test_random_statetest504.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest504( ) -> None: """Test_random_statetest504.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest504( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f0000000000000000000000000000000000000000000000000000000000000001e37f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c35001589a84106d9c60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f0000000000000000000000000000000000000000000000000000000000000001e37f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c35001589a84106d9c60005155" # noqa: E501 - ), - nonce=0, - address=Address(0x2505F255CAEC67DD060D15A5D7A77EFB5612B8B2), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest504( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f0000000000000000000000000000000000000000000000000000000000000001e37f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c35001589a84106d9c60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f0000000000000000000000000000000000000000000000000000000000000001e37f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000c35001589a84106d9c60005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest505.py b/tests/ported_static/stRandom2/test_random_statetest505.py index 0819fbe3ed0..7b8c09a831b 100644 --- a/tests/ported_static/stRandom2/test_random_statetest505.py +++ b/tests/ported_static/stRandom2/test_random_statetest505.py @@ -46,6 +46,7 @@ def test_random_statetest505( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000006f44a06f550371317376738c539984375560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest505( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest506.py b/tests/ported_static/stRandom2/test_random_statetest506.py index a60ce2a0663..f80b3b175e9 100644 --- a/tests/ported_static/stRandom2/test_random_statetest506.py +++ b/tests/ported_static/stRandom2/test_random_statetest506.py @@ -46,6 +46,23 @@ def test_random_statetest506( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000000042377f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000006ba218f370862059149e3cff2060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest506( nonce=0, address=Address(0xF1812415DD5CF70796F6FF36F7BE5BD8ACD52A9B), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest507.py b/tests/ported_static/stRandom2/test_random_statetest507.py index 00c96ea5327..a2b16f06bd5 100644 --- a/tests/ported_static/stRandom2/test_random_statetest507.py +++ b/tests/ported_static/stRandom2/test_random_statetest507.py @@ -47,6 +47,23 @@ def test_random_statetest507( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x5a7f0000000000000000000000010000000000000000000000000000000000000000327f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000006f99a4527612a199a06d1a348b02563a9b60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest507( nonce=0, address=Address(0xDA04E91DAE336F3095911CE42A208D591605593E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest508.py b/tests/ported_static/stRandom2/test_random_statetest508.py index e7d3533fc2c..526b840b681 100644 --- a/tests/ported_static/stRandom2/test_random_statetest508.py +++ b/tests/ported_static/stRandom2/test_random_statetest508.py @@ -46,6 +46,7 @@ def test_random_statetest508( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x41414444424143448231537241317f55 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_random_statetest508( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest509.py b/tests/ported_static/stRandom2/test_random_statetest509.py index df596f05e0b..ddc305bab70 100644 --- a/tests/ported_static/stRandom2/test_random_statetest509.py +++ b/tests/ported_static/stRandom2/test_random_statetest509.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest509( ) -> None: """Test_random_statetest509.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest509( code=Op.GASLIMIT + Op.TIMESTAMP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBE28CDE0901EDA46D09A636150C7577A6CBA7D0F), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest509( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest510.py b/tests/ported_static/stRandom2/test_random_statetest510.py index 5687c6349da..38e7ac14b97 100644 --- a/tests/ported_static/stRandom2/test_random_statetest510.py +++ b/tests/ported_static/stRandom2/test_random_statetest510.py @@ -47,6 +47,23 @@ def test_random_statetest510( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000447f00000000000000000000000000000000000000000000000000000000000000005a456ff23a88535564545969f162615b93325560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest510( nonce=0, address=Address(0xABDD1DD76E15AE75FF51BD7F2B12571004CDD8BA), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest511.py b/tests/ported_static/stRandom2/test_random_statetest511.py index 3c157fa97a1..41a7c01c3d0 100644 --- a/tests/ported_static/stRandom2/test_random_statetest511.py +++ b/tests/ported_static/stRandom2/test_random_statetest511.py @@ -46,6 +46,23 @@ def test_random_statetest511( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff416f6a52027f41f267453843630a6644414560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest511( nonce=0, address=Address(0x5918A547A35780BD0961433F6B0A8AB1158E16F2), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest512.py b/tests/ported_static/stRandom2/test_random_statetest512.py index 7651cb9e11a..f870798e489 100644 --- a/tests/ported_static/stRandom2/test_random_statetest512.py +++ b/tests/ported_static/stRandom2/test_random_statetest512.py @@ -46,6 +46,23 @@ def test_random_statetest512( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f3b5bff4056709774995150026344925560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest512( nonce=0, address=Address(0xE3CC9753FC23E1570C7CDE7B9C7D2253CE100254), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest513.py b/tests/ported_static/stRandom2/test_random_statetest513.py index 01c5d6eaaef..fb1baafd951 100644 --- a/tests/ported_static/stRandom2/test_random_statetest513.py +++ b/tests/ported_static/stRandom2/test_random_statetest513.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest513( ) -> None: """Test_random_statetest513.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest513( "7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff3b437ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001982046817382a13afa3760088d55" # noqa: E501 ), nonce=0, - address=Address(0x7254B47942E53D7BEB2E156F9239A7690AF65736), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest513( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest514.py b/tests/ported_static/stRandom2/test_random_statetest514.py index 9893ae4df66..dd6bb60d822 100644 --- a/tests/ported_static/stRandom2/test_random_statetest514.py +++ b/tests/ported_static/stRandom2/test_random_statetest514.py @@ -46,6 +46,7 @@ def test_random_statetest514( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe44447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3506c8ea356796d65546d3883768f5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest514( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest516.py b/tests/ported_static/stRandom2/test_random_statetest516.py index 70a22ec2f03..12d4b1a5f6f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest516.py +++ b/tests/ported_static/stRandom2/test_random_statetest516.py @@ -46,6 +46,7 @@ def test_random_statetest516( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6a32787358019b39186861940960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,7 +89,6 @@ def test_random_statetest516( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest517.py b/tests/ported_static/stRandom2/test_random_statetest517.py index 4cee0263f2a..b0fb58a9a2e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest517.py +++ b/tests/ported_static/stRandom2/test_random_statetest517.py @@ -46,6 +46,7 @@ def test_random_statetest517( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff3a6f450831a46a867f32569596f0099f7b8c915560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest517( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest518.py b/tests/ported_static/stRandom2/test_random_statetest518.py index f50a051705e..45a3b2ba671 100644 --- a/tests/ported_static/stRandom2/test_random_statetest518.py +++ b/tests/ported_static/stRandom2/test_random_statetest518.py @@ -46,6 +46,23 @@ def test_random_statetest518( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f3c589f416d947a5134f268515b6c925560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest518( nonce=0, address=Address(0x47E68ACDBFC1ED42DCA998D584EAB31897F4D6A7), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest519.py b/tests/ported_static/stRandom2/test_random_statetest519.py index f9698ab7c8d..6d76d819710 100644 --- a/tests/ported_static/stRandom2/test_random_statetest519.py +++ b/tests/ported_static/stRandom2/test_random_statetest519.py @@ -46,15 +46,7 @@ def test_random_statetest519( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000001000000000000000000000000000000000000000009457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3501a02556b85a4531155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000001000000000000000000000000000000000000000009457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3501a02556b85a4531155" # noqa: E501 - ), - nonce=0, - address=Address(0x085D89DCBF18EB3DA2E46582049E75A78B4B3667), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +63,15 @@ def test_random_statetest519( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000001000000000000000000000000000000000000000009457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3501a02556b85a4531155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000001000000000000000000000000000000000000000009457f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3501a02556b85a4531155" # noqa: E501 + ), + nonce=0, + address=Address(0x085D89DCBF18EB3DA2E46582049E75A78B4B3667), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest520.py b/tests/ported_static/stRandom2/test_random_statetest520.py index 2418d03c7ac..c51999e59c8 100644 --- a/tests/ported_static/stRandom2/test_random_statetest520.py +++ b/tests/ported_static/stRandom2/test_random_statetest520.py @@ -46,6 +46,7 @@ def test_random_statetest520( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff19030860005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -89,7 +90,6 @@ def test_random_statetest520( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest521.py b/tests/ported_static/stRandom2/test_random_statetest521.py index 0dfb47b65dd..c361b820dab 100644 --- a/tests/ported_static/stRandom2/test_random_statetest521.py +++ b/tests/ported_static/stRandom2/test_random_statetest521.py @@ -46,6 +46,23 @@ def test_random_statetest521( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6a73905597946a57769a6d9209335560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,23 +85,6 @@ def test_random_statetest521( nonce=0, address=Address(0x8F8604CF78869E976E9002B80CBFF3995443AE17), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest523.py b/tests/ported_static/stRandom2/test_random_statetest523.py index 91e030fc3c5..5873c25cd21 100644 --- a/tests/ported_static/stRandom2/test_random_statetest523.py +++ b/tests/ported_static/stRandom2/test_random_statetest523.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest523( ) -> None: """Test_random_statetest523.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest523( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x78E06DD6F641C103CEEF456E564348A48A6F0BEF), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest523( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest524.py b/tests/ported_static/stRandom2/test_random_statetest524.py index 82e51bb75c4..39bd39c5f56 100644 --- a/tests/ported_static/stRandom2/test_random_statetest524.py +++ b/tests/ported_static/stRandom2/test_random_statetest524.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest524( ) -> None: """Test_random_statetest524.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -66,7 +63,6 @@ def test_random_statetest524( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0xAA56EE356B0DD8022AD49A794FB5A37C554B32AA), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -84,7 +80,6 @@ def test_random_statetest524( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest525.py b/tests/ported_static/stRandom2/test_random_statetest525.py index db99b8a01dd..7e84b7db303 100644 --- a/tests/ported_static/stRandom2/test_random_statetest525.py +++ b/tests/ported_static/stRandom2/test_random_statetest525.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest525( ) -> None: """Test_random_statetest525.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest525( "7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff097ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02207160005155" # noqa: E501 ), nonce=0, - address=Address(0x2A83E67B69429CFB983B8ED79B7E8A53E6824092), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest525( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest526.py b/tests/ported_static/stRandom2/test_random_statetest526.py index 6e8aa766a68..783e1d35401 100644 --- a/tests/ported_static/stRandom2/test_random_statetest526.py +++ b/tests/ported_static/stRandom2/test_random_statetest526.py @@ -47,20 +47,7 @@ def test_random_statetest526( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5417e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5419e01950777810975058c746f5560005155 # noqa: E501 - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x10000000000000000000000000000000000000000] * 2 - + Op.PUSH32[0x0] - + Op.PUSH32[0x945304EB96065B2A98B57A48A06AE28D285A71B5] - + Op.COINBASE - + Op.SSTORE( - key=0xB5419E01950777810975058C746F55600051, - value=0x7F000000000000000000000000945304EB96065B2A98B57A48A06AE28D285A, # noqa: E501 - ), - nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -77,7 +64,20 @@ def test_random_statetest526( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5417e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5419e01950777810975058c746f5560005155 # noqa: E501 + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x10000000000000000000000000000000000000000] * 2 + + Op.PUSH32[0x0] + + Op.PUSH32[0x945304EB96065B2A98B57A48A06AE28D285A71B5] + + Op.COINBASE + + Op.SSTORE( + key=0xB5419E01950777810975058C746F55600051, + value=0x7F000000000000000000000000945304EB96065B2A98B57A48A06AE28D285A, # noqa: E501 + ), + nonce=0, + address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest527.py b/tests/ported_static/stRandom2/test_random_statetest527.py index 1b0dfbde10b..13bf5da4e70 100644 --- a/tests/ported_static/stRandom2/test_random_statetest527.py +++ b/tests/ported_static/stRandom2/test_random_statetest527.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest527( ) -> None: """Test_random_statetest527.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest527( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x347f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff447f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff80a160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest527( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x490584E08E20CA97487089106B76679F5986D234), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest528.py b/tests/ported_static/stRandom2/test_random_statetest528.py index 1bc46774fd7..fb7c2eed010 100644 --- a/tests/ported_static/stRandom2/test_random_statetest528.py +++ b/tests/ported_static/stRandom2/test_random_statetest528.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest528( ) -> None: """Test_random_statetest528.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -70,7 +67,6 @@ def test_random_statetest528( + Op.DUP13 + Op.SSTORE(key=Op.DUP5, value=Op.DUP6), nonce=0, - address=Address(0xE95BB71003200148E7E9559EC3ECF538802C42BF), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -88,7 +84,6 @@ def test_random_statetest528( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest531.py b/tests/ported_static/stRandom2/test_random_statetest531.py index e05e6588fd3..0b97e16c02a 100644 --- a/tests/ported_static/stRandom2/test_random_statetest531.py +++ b/tests/ported_static/stRandom2/test_random_statetest531.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest531( ) -> None: """Test_random_statetest531.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest531( code=bytes.fromhex("41414143434344456a12c140f3933655"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x83C3FD438BEC2A4BB605AE688641469341532D9F), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest531( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest532.py b/tests/ported_static/stRandom2/test_random_statetest532.py index 4bfd62be2bb..a8750d93096 100644 --- a/tests/ported_static/stRandom2/test_random_statetest532.py +++ b/tests/ported_static/stRandom2/test_random_statetest532.py @@ -46,6 +46,7 @@ def test_random_statetest532( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe54447f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f78297ba08ba478507f413b3597109c5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest532( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest533.py b/tests/ported_static/stRandom2/test_random_statetest533.py index 3a35bc666ea..1661aa8af34 100644 --- a/tests/ported_static/stRandom2/test_random_statetest533.py +++ b/tests/ported_static/stRandom2/test_random_statetest533.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest533( ) -> None: """Test_random_statetest533.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest533( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000001847f00000000000000000000000100000000000000000000000000000000000000003a0761525560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,25 +75,7 @@ def test_random_statetest533( ) + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x5255), nonce=0, - address=Address(0x6905EBD1D92150C8ABD7E0EDC3CA2E570143A674), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest534.py b/tests/ported_static/stRandom2/test_random_statetest534.py index 6457b95e4a3..e68f56aceb9 100644 --- a/tests/ported_static/stRandom2/test_random_statetest534.py +++ b/tests/ported_static/stRandom2/test_random_statetest534.py @@ -46,6 +46,23 @@ def test_random_statetest534( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000001000000000000000000000000000000000000000045437f0000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff457f0000000000000000000000000000000000000000000000000000000000000000436ff3075243846d88747b6a9e7ff28c615560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest534( nonce=0, address=Address(0x9114C469B911CB7089FE6B881F7E6F10C2109681), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest535.py b/tests/ported_static/stRandom2/test_random_statetest535.py index fe086a7901f..7c769fc3896 100644 --- a/tests/ported_static/stRandom2/test_random_statetest535.py +++ b/tests/ported_static/stRandom2/test_random_statetest535.py @@ -46,6 +46,23 @@ def test_random_statetest535( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest535( nonce=0, address=Address(0xFB33A18F5315642FAC0F83122A6C44C9FB6F4F4D), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest536.py b/tests/ported_static/stRandom2/test_random_statetest536.py index e1fd50f5ad9..99167111ed0 100644 --- a/tests/ported_static/stRandom2/test_random_statetest536.py +++ b/tests/ported_static/stRandom2/test_random_statetest536.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest536( ) -> None: """Test_random_statetest536.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest536( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c350537f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9309f3999c7d92795a947a6f317f55" # noqa: E501 ), nonce=0, - address=Address(0x85E66F40EB86A2D63DF2DC248B3D6F4FC138B003), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest536( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest537.py b/tests/ported_static/stRandom2/test_random_statetest537.py index e3663c7b6e3..416ba260478 100644 --- a/tests/ported_static/stRandom2/test_random_statetest537.py +++ b/tests/ported_static/stRandom2/test_random_statetest537.py @@ -47,6 +47,7 @@ def test_random_statetest537( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5688068515a6a996a540a03686d6d60005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest537( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest539.py b/tests/ported_static/stRandom2/test_random_statetest539.py index 4ab1b585327..c6711af7f16 100644 --- a/tests/ported_static/stRandom2/test_random_statetest539.py +++ b/tests/ported_static/stRandom2/test_random_statetest539.py @@ -46,6 +46,7 @@ def test_random_statetest539( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff457f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff096794200bf18b0b316e415560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest539( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest541.py b/tests/ported_static/stRandom2/test_random_statetest541.py index e4c361076c8..5e168521b8b 100644 --- a/tests/ported_static/stRandom2/test_random_statetest541.py +++ b/tests/ported_static/stRandom2/test_random_statetest541.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest541( ) -> None: """Test_random_statetest541.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -66,7 +63,6 @@ def test_random_statetest541( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x854F4406999B8BB46770D32CA10F059498717BFC), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -84,7 +80,6 @@ def test_random_statetest541( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest542.py b/tests/ported_static/stRandom2/test_random_statetest542.py index d261ddd2d66..1d68c75d6ca 100644 --- a/tests/ported_static/stRandom2/test_random_statetest542.py +++ b/tests/ported_static/stRandom2/test_random_statetest542.py @@ -46,6 +46,23 @@ def test_random_statetest542( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x427f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000397f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000925560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest542( nonce=0, address=Address(0x0173C63BEF6FF158E671BD806EDE19A25095E723), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest543.py b/tests/ported_static/stRandom2/test_random_statetest543.py index 99a861f4bf7..da90447e74e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest543.py +++ b/tests/ported_static/stRandom2/test_random_statetest543.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest543( ) -> None: """Test_random_statetest543.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest543( + Op.GASLIMIT + Op.DUP7, nonce=0, - address=Address(0xB04D75CC292C99077DA7BC4149CEAFB239447F01), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest543( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest544.py b/tests/ported_static/stRandom2/test_random_statetest544.py index 1c8bf4beccc..028aaf69bea 100644 --- a/tests/ported_static/stRandom2/test_random_statetest544.py +++ b/tests/ported_static/stRandom2/test_random_statetest544.py @@ -46,6 +46,7 @@ def test_random_statetest544( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3503b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff097f000000000000000000000000000000000000000000000000000000000000000055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,7 +78,6 @@ def test_random_statetest544( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest545.py b/tests/ported_static/stRandom2/test_random_statetest545.py index 1e12624c6ca..f54ba8d7035 100644 --- a/tests/ported_static/stRandom2/test_random_statetest545.py +++ b/tests/ported_static/stRandom2/test_random_statetest545.py @@ -47,6 +47,7 @@ def test_random_statetest545( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c350637c9c8213300560005155 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest545( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest546.py b/tests/ported_static/stRandom2/test_random_statetest546.py index ea3a0b634aa..f4e83ed8904 100644 --- a/tests/ported_static/stRandom2/test_random_statetest546.py +++ b/tests/ported_static/stRandom2/test_random_statetest546.py @@ -46,6 +46,23 @@ def test_random_statetest546( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff447f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007f0000000000000000000000010000000000000000000000000000000000000000956f895258826c355765922086717315015560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest546( nonce=0, address=Address(0x6CAA66514A7ADF4757188ED6466A7FF7B1D3FE88), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest547.py b/tests/ported_static/stRandom2/test_random_statetest547.py index 743047f764d..162adbf1b50 100644 --- a/tests/ported_static/stRandom2/test_random_statetest547.py +++ b/tests/ported_static/stRandom2/test_random_statetest547.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest547( ) -> None: """Test_random_statetest547.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,7 +51,6 @@ def test_random_statetest547( "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000001417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c35014623971943854a009768255" # noqa: E501 ), nonce=0, - address=Address(0x63D5E8A1C6E9BB983F0C2249ADB82C045A7510A7), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -72,7 +68,6 @@ def test_random_statetest547( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest548.py b/tests/ported_static/stRandom2/test_random_statetest548.py index f7941a89e73..3b095a329e6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest548.py +++ b/tests/ported_static/stRandom2/test_random_statetest548.py @@ -46,6 +46,7 @@ def test_random_statetest548( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f0000000000000000000000010000000000000000000000000000000000000000417fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000001000000000000000000000000000000000000000019417f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f777a349a646633977da01a315a3c035560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest548( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest550.py b/tests/ported_static/stRandom2/test_random_statetest550.py index 6254af7e41c..f43654e5852 100644 --- a/tests/ported_static/stRandom2/test_random_statetest550.py +++ b/tests/ported_static/stRandom2/test_random_statetest550.py @@ -46,6 +46,7 @@ def test_random_statetest550( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000006f4472a17829659c94a29041419564313a60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest550( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest552.py b/tests/ported_static/stRandom2/test_random_statetest552.py index fceb225140b..3ac771d3ecb 100644 --- a/tests/ported_static/stRandom2/test_random_statetest552.py +++ b/tests/ported_static/stRandom2/test_random_statetest552.py @@ -46,6 +46,7 @@ def test_random_statetest552( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff42147ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe547f00000000000000000000000000000000000000000000000000000000000000006f6a72a37b5219f089416d4336a08e825560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest552( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest553.py b/tests/ported_static/stRandom2/test_random_statetest553.py index 01cf511dce8..94406603337 100644 --- a/tests/ported_static/stRandom2/test_random_statetest553.py +++ b/tests/ported_static/stRandom2/test_random_statetest553.py @@ -46,6 +46,23 @@ def test_random_statetest553( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000016f94819c780585376da073368c45828ca060005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest553( nonce=0, address=Address(0x4DC764749FDEAB4FEFFB6D542712EBD2465EADDE), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest554.py b/tests/ported_static/stRandom2/test_random_statetest554.py index 667fb3c5175..5a4435ea941 100644 --- a/tests/ported_static/stRandom2/test_random_statetest554.py +++ b/tests/ported_static/stRandom2/test_random_statetest554.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest554( ) -> None: """Test_random_statetest554.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest554( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x601460dca06029728b67ba4c2fc8c63c46f19bb45a4be3f678b30669ba571e944074c21b140a7a65d14a921ec804a45ecf4d952aa923fb23a0574acd8ef9f82c7db17e157f651bbeb520203bd398160345137b0419a395630fce1a7ed24c0cccfd91766140e0682f6bd571db701b4616b567f215faf42fb37d2a7c43c05a634612322eda99f09cc2907a6cba01bb6869b7d24b897ec43b9b63a8747a897af14c1f4c0b186c6311d36de86b8c8172aa43c3dfe3ea16503380877fa7f32deb9f60254d124338105942b4b5b88c443351de5ebf14c2380f4a91327d68a0da66abd627db75739942675f5855728fd677646cafec536e37d0da8122cf8681bc106013601b600360086307efe33a7363176fe819f16566b603cccf387c5f10e5cdb2ba1b456d2a0386ee72ddf3ff65b33a551afa423f8af05e347b5c50b6fe69c77f0682ef890d8ed8ab3833f128389f6407911fb20590642c9765e97c7f31dfa251377a47ca45b72ce5c1896a697990d60a01cabaf5e4d8f55f11fd37427351d1f8e89810c7aeec6482fd03d7e7ca58fbaae361e3936936543d6dacb1f97f19c3721866491bad73f32faea37b4a8c273668e04dff8863a542e11775a693c3b4bcd4fc1a87ddb6450f8f6c2f1ba807aaffb67e62af22cd93175b5ffb428ee9116dad4a695aa514b8ca4d615fd728a61c124c796554a98241320ac2d6b9f16ee1c203dbba537a211142df4c2e626e4108f87ab6d5b8e9ce86f92aba50a47acc60d734e7a066131d99dad149451b386120eed210723bd8304caa61048c67512ca417ae8857a46ad24ca1f2cb75f75ef86a927152bd86981a216d8147f49ead4be46967dd10751491f9f1ac2f50fd5dad394b7838a9eb89b372698362647bddbb90586e4e921a8cc96ea0c50d07da472b3e6360a39c # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -114,23 +127,6 @@ def test_random_statetest554( nonce=0, address=Address(0xD4932C914A13BD1791675290FDD56965C3FCBD03), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest555.py b/tests/ported_static/stRandom2/test_random_statetest555.py index 79f4b703327..64260d4b894 100644 --- a/tests/ported_static/stRandom2/test_random_statetest555.py +++ b/tests/ported_static/stRandom2/test_random_statetest555.py @@ -46,6 +46,23 @@ def test_random_statetest555( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff437f000000000000000000000000000000000000000000000000000000000000c3506f3b8f936e6f3874603c59120707e3588c60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest555( nonce=0, address=Address(0x7178694ADA9132CC970358F783090308D849DFAE), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest556.py b/tests/ported_static/stRandom2/test_random_statetest556.py index b188723be9c..52be5dae51c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest556.py +++ b/tests/ported_static/stRandom2/test_random_statetest556.py @@ -46,6 +46,7 @@ def test_random_statetest556( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000010000000000000000000000000000000000000000437f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000006f726e757692a2ad96526b9e8b77a33a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest556( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest558.py b/tests/ported_static/stRandom2/test_random_statetest558.py index ff4ba1b42bc..d3ada857876 100644 --- a/tests/ported_static/stRandom2/test_random_statetest558.py +++ b/tests/ported_static/stRandom2/test_random_statetest558.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest558( ) -> None: """Test_random_statetest558.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest558( code=bytes.fromhex("43767855"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFEA0FD6F8E6416AF47AB5057D310ED005855772A), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest558( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest559.py b/tests/ported_static/stRandom2/test_random_statetest559.py index 914656d8623..3b3ae3ead1f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest559.py +++ b/tests/ported_static/stRandom2/test_random_statetest559.py @@ -46,6 +46,7 @@ def test_random_statetest559( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000008509ff1555 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_random_statetest559( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest560.py b/tests/ported_static/stRandom2/test_random_statetest560.py index 44eeabf0f7b..cb807ff1815 100644 --- a/tests/ported_static/stRandom2/test_random_statetest560.py +++ b/tests/ported_static/stRandom2/test_random_statetest560.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest560( ) -> None: """Test_random_statetest560.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest560( "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c35059a17f0000000000000000000000000000000000000000000000000000000000000001f38f07bf60005155" # noqa: E501 ), nonce=0, - address=Address(0xC9EDD4CF792E9FEFFEE7968E9A49A0BD81A7BA40), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest560( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest562.py b/tests/ported_static/stRandom2/test_random_statetest562.py index c099274d4b0..fdecc6b3f61 100644 --- a/tests/ported_static/stRandom2/test_random_statetest562.py +++ b/tests/ported_static/stRandom2/test_random_statetest562.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest562( ) -> None: """Test_random_statetest562.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -67,7 +64,6 @@ def test_random_statetest562( + Op.DUP8 + Op.PREVRANDAO, nonce=0, - address=Address(0x86E63B3928D89817589609C1E2180E22939D6A62), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -85,7 +81,6 @@ def test_random_statetest562( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest563.py b/tests/ported_static/stRandom2/test_random_statetest563.py index 09ed06b301c..48692f9193b 100644 --- a/tests/ported_static/stRandom2/test_random_statetest563.py +++ b/tests/ported_static/stRandom2/test_random_statetest563.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest563( ) -> None: """Test_random_statetest563.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest563( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe418b7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000461098038315ba267 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe418b7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e790461098038315ba267" # noqa: E501 - ), - nonce=0, - address=Address(0x2F5F042C5D61DA63B8AFA98D3502FF4B4950C22B), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest563( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe418b7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000461098038315ba267 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe418b7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e790461098038315ba267" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest564.py b/tests/ported_static/stRandom2/test_random_statetest564.py index 4812eaa5058..039a19f683f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest564.py +++ b/tests/ported_static/stRandom2/test_random_statetest564.py @@ -47,6 +47,23 @@ def test_random_statetest564( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 + ) # Source: raw # 0x5b7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4550081655 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest564( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest565.py b/tests/ported_static/stRandom2/test_random_statetest565.py index a6a3993b0f4..322caed6750 100644 --- a/tests/ported_static/stRandom2/test_random_statetest565.py +++ b/tests/ported_static/stRandom2/test_random_statetest565.py @@ -46,6 +46,7 @@ def test_random_statetest565( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c350137f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000010000000000000000000000000000000000000000923760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest565( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest566.py b/tests/ported_static/stRandom2/test_random_statetest566.py index b2b6f020b69..88158c925a3 100644 --- a/tests/ported_static/stRandom2/test_random_statetest566.py +++ b/tests/ported_static/stRandom2/test_random_statetest566.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest566( ) -> None: """Test_random_statetest566.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest566( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x9a7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000000117f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff427f00000000000000000000000093963332578665734360005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest566( + Op.DUP7 + Op.PUSH6[0x734360005155], nonce=0, - address=Address(0xE8FDA25222733F9C226C2E5B6DCA729EB71076FD), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest567.py b/tests/ported_static/stRandom2/test_random_statetest567.py index 4146843bf4d..0359dcba008 100644 --- a/tests/ported_static/stRandom2/test_random_statetest567.py +++ b/tests/ported_static/stRandom2/test_random_statetest567.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest567( ) -> None: """Test_random_statetest567.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest567( "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017e7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe906697998df1160b" # noqa: E501 ), nonce=0, - address=Address(0x4860849F881F7ECBB6A4C146EEF8F95F52F462BB), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest567( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest569.py b/tests/ported_static/stRandom2/test_random_statetest569.py index 8be41c17132..22705f10709 100644 --- a/tests/ported_static/stRandom2/test_random_statetest569.py +++ b/tests/ported_static/stRandom2/test_random_statetest569.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest569( ) -> None: """Test_random_statetest569.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest569( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000097f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8e0781816fff31986c0a773c9b014460005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79097f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8e0781816fff31986c0a773c9b014460005155" # noqa: E501 - ), - nonce=0, - address=Address(0xA3FC9ABF6758B048BB28CEE4C8F4F9722C90AFE2), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest569( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f000000000000000000000000097f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8e0781816fff31986c0a773c9b014460005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe427f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79097f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8e0781816fff31986c0a773c9b014460005155" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest571.py b/tests/ported_static/stRandom2/test_random_statetest571.py index 1e6cb3dbd88..92a3b7df336 100644 --- a/tests/ported_static/stRandom2/test_random_statetest571.py +++ b/tests/ported_static/stRandom2/test_random_statetest571.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest571( ) -> None: """Test_random_statetest571.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest571( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000015b7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000003c6508766c8b6b403a60005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest571( + Op.PUSH6[0x8766C8B6B40] + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=Op.GASPRICE), nonce=0, - address=Address(0xC983BD5257B89D1C32D59E0251C5456BC7397124), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest572.py b/tests/ported_static/stRandom2/test_random_statetest572.py index b3520e74675..0cc16d4916d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest572.py +++ b/tests/ported_static/stRandom2/test_random_statetest572.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest572( ) -> None: """Test_random_statetest572.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest572( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x457f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe097f000000000000000000000000440ba13b38 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,25 +78,7 @@ def test_random_statetest572( + Op.EXTCODESIZE + Op.CODESIZE, nonce=0, - address=Address(0x78F04949EEF09FC73B40744730BE09013E89F197), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest574.py b/tests/ported_static/stRandom2/test_random_statetest574.py index 5124864ae2c..941ad48d67e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest574.py +++ b/tests/ported_static/stRandom2/test_random_statetest574.py @@ -46,6 +46,7 @@ def test_random_statetest574( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000001047f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff046d369354827d7433a335af5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest574( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest575.py b/tests/ported_static/stRandom2/test_random_statetest575.py index d734d409077..a741736b223 100644 --- a/tests/ported_static/stRandom2/test_random_statetest575.py +++ b/tests/ported_static/stRandom2/test_random_statetest575.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest575( ) -> None: """Test_random_statetest575.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest575( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000095949655558f6771c7798d047d7b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,25 +81,7 @@ def test_random_statetest575( + Op.DUP16 + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x71C7798D047D7B55), nonce=0, - address=Address(0xB14048581095A497D29ABD14EA870A27E1BCDC77), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest576.py b/tests/ported_static/stRandom2/test_random_statetest576.py index e2fc5041966..c1b5f771703 100644 --- a/tests/ported_static/stRandom2/test_random_statetest576.py +++ b/tests/ported_static/stRandom2/test_random_statetest576.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest576( ) -> None: """Test_random_statetest576.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest576( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000000000000000000000000000000000000000000000447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086053a0b43890710810651116e1555 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f0000000000000000000000000000000000000000000000000000000000000000447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000000086053a0b43890710810651116e1555" # noqa: E501 - ), - nonce=0, - address=Address(0x447D08ABED1518B3B0D1ADEE769AF4E010F53737), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest576( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000000000000000000000000000000000000000000000447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086053a0b43890710810651116e1555 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f0000000000000000000000000000000000000000000000000000000000000000447f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797f000000000000000000000000000000000000000000000000000000000000000086053a0b43890710810651116e1555" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest577.py b/tests/ported_static/stRandom2/test_random_statetest577.py index 4d6bfa70a4b..6196d40cf1d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest577.py +++ b/tests/ported_static/stRandom2/test_random_statetest577.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest577( ) -> None: """Test_random_statetest577.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_random_statetest577( + Op.SSTORE(key=Op.BALANCE(address=Op.COINBASE), value=Op.PREVRANDAO), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE2A7C7DE420AFC2CD4066E4B3782AD5BBAE7260C), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -76,7 +72,6 @@ def test_random_statetest577( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest578.py b/tests/ported_static/stRandom2/test_random_statetest578.py index 1e5c6a6c4e9..5cf34b9d666 100644 --- a/tests/ported_static/stRandom2/test_random_statetest578.py +++ b/tests/ported_static/stRandom2/test_random_statetest578.py @@ -46,6 +46,7 @@ def test_random_statetest578( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c350457f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff4255 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest578( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest579.py b/tests/ported_static/stRandom2/test_random_statetest579.py index 69d435af74c..7ab0ddf9106 100644 --- a/tests/ported_static/stRandom2/test_random_statetest579.py +++ b/tests/ported_static/stRandom2/test_random_statetest579.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest579( ) -> None: """Test_random_statetest579.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest579( "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350f2075b67c755" # noqa: E501 ), nonce=0, - address=Address(0x78442C2F07F963337C3CEF742D2A1BA66986A918), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest579( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest580.py b/tests/ported_static/stRandom2/test_random_statetest580.py index 4a411e13462..48f1d7352d7 100644 --- a/tests/ported_static/stRandom2/test_random_statetest580.py +++ b/tests/ported_static/stRandom2/test_random_statetest580.py @@ -46,6 +46,7 @@ def test_random_statetest580( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000000457f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000006f4640879d18777b953a209836379a305560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest580( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest581.py b/tests/ported_static/stRandom2/test_random_statetest581.py index 712efab1f3a..62ed09442c4 100644 --- a/tests/ported_static/stRandom2/test_random_statetest581.py +++ b/tests/ported_static/stRandom2/test_random_statetest581.py @@ -46,6 +46,7 @@ def test_random_statetest581( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000000000000000000000000000000000000000000001037f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff44920907ff7e7d701260005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_random_statetest581( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest582.py b/tests/ported_static/stRandom2/test_random_statetest582.py index 35043f6656e..62bc7a401ca 100644 --- a/tests/ported_static/stRandom2/test_random_statetest582.py +++ b/tests/ported_static/stRandom2/test_random_statetest582.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest582( ) -> None: """Test_random_statetest582.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest582( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000417f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000045086201771880f35560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,25 +76,7 @@ def test_random_statetest582( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x99E6F87CBA9C1737F49965828C1BADEC51A91DFD), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest583.py b/tests/ported_static/stRandom2/test_random_statetest583.py index dd7f390a1cf..b564ad40a77 100644 --- a/tests/ported_static/stRandom2/test_random_statetest583.py +++ b/tests/ported_static/stRandom2/test_random_statetest583.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest583( ) -> None: """Test_random_statetest583.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest583( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000425162327c5536a36af3809c3a8f396660005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,25 +81,7 @@ def test_random_statetest583( ) + Op.PUSH11[0xF3809C3A8F396660005155], nonce=0, - address=Address(0x5ED77238CFAC99CEDF0D4438DDADFE34ED439D7F), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest584.py b/tests/ported_static/stRandom2/test_random_statetest584.py index 184bf97bd23..0d4ed6bebc1 100644 --- a/tests/ported_static/stRandom2/test_random_statetest584.py +++ b/tests/ported_static/stRandom2/test_random_statetest584.py @@ -46,6 +46,23 @@ def test_random_statetest584( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe96921909335560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,23 +87,6 @@ def test_random_statetest584( nonce=0, address=Address(0xA6EB2C6959A0B259080FF4156A01C2B5CCAD2E29), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest585.py b/tests/ported_static/stRandom2/test_random_statetest585.py index ee7a07907da..e103f51782c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest585.py +++ b/tests/ported_static/stRandom2/test_random_statetest585.py @@ -46,6 +46,23 @@ def test_random_statetest585( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe55 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,23 +83,6 @@ def test_random_statetest585( nonce=0, address=Address(0xAC0F5185BABC3F1B583C2B31429E4F4B5F843AC3), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest586.py b/tests/ported_static/stRandom2/test_random_statetest586.py index ae76adb4b9d..6dfec8e8411 100644 --- a/tests/ported_static/stRandom2/test_random_statetest586.py +++ b/tests/ported_static/stRandom2/test_random_statetest586.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest586( ) -> None: """Test_random_statetest586.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest586( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x92CF87191DD055F997CA7B4479B54F4345467BA9), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest586( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest587.py b/tests/ported_static/stRandom2/test_random_statetest587.py index 707a9247b2a..037dc6d5095 100644 --- a/tests/ported_static/stRandom2/test_random_statetest587.py +++ b/tests/ported_static/stRandom2/test_random_statetest587.py @@ -46,6 +46,23 @@ def test_random_statetest587( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350117f0000000000000000000000000000000000000000000000000000000000000001457f0000000000000000000000006f8b7152a3958a923c1665b27557089a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,23 +80,6 @@ def test_random_statetest587( nonce=0, address=Address(0x5A19607CF239E82E6C621692577EEF772162D139), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest588.py b/tests/ported_static/stRandom2/test_random_statetest588.py index 72f305a5b4d..d7d56fc223f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest588.py +++ b/tests/ported_static/stRandom2/test_random_statetest588.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest588( ) -> None: """Test_random_statetest588.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -66,7 +63,6 @@ def test_random_statetest588( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x2C3D41995B7F3D32E08C6575E2DDAA1AE5CF2067), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -84,7 +80,6 @@ def test_random_statetest588( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest589.py b/tests/ported_static/stRandom2/test_random_statetest589.py index 09fd635981d..9843c5030ad 100644 --- a/tests/ported_static/stRandom2/test_random_statetest589.py +++ b/tests/ported_static/stRandom2/test_random_statetest589.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest589( ) -> None: """Test_random_statetest589.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,23 +43,6 @@ def test_random_statetest589( gas_limit=9223372036854775807, ) - # Source: raw - # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.TIMESTAMP - + Op.PUSH32[0x0] - + Op.PUSH32[0x1] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[ - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - ] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PC - + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) - + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), - nonce=0, - address=Address(0xB2DA1F608A7E0626E721677FA30FC46D2D99C655), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -79,7 +59,22 @@ def test_random_statetest589( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x427f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff583481f36a85646d53671639175b940860005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.TIMESTAMP + + Op.PUSH32[0x0] + + Op.PUSH32[0x1] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[ + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PC + + Op.RETURN(offset=Op.DUP2, size=Op.CALLVALUE) + + Op.SSTORE(key=Op.MLOAD(offset=0x0), value=0x85646D53671639175B9408), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest592.py b/tests/ported_static/stRandom2/test_random_statetest592.py index 116fa17621c..8fcb0a5fbbf 100644 --- a/tests/ported_static/stRandom2/test_random_statetest592.py +++ b/tests/ported_static/stRandom2/test_random_statetest592.py @@ -46,6 +46,23 @@ def test_random_statetest592( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000457fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest592( nonce=0, address=Address(0x19CC73462C6B04D360707355AC19146DB67EB609), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest596.py b/tests/ported_static/stRandom2/test_random_statetest596.py index f6608164630..378a0feb172 100644 --- a/tests/ported_static/stRandom2/test_random_statetest596.py +++ b/tests/ported_static/stRandom2/test_random_statetest596.py @@ -46,6 +46,7 @@ def test_random_statetest596( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000001317f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000006f7066a3507f6e0906539456383065205560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,7 +78,6 @@ def test_random_statetest596( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest597.py b/tests/ported_static/stRandom2/test_random_statetest597.py index 7060a11d36a..56d8fd21a72 100644 --- a/tests/ported_static/stRandom2/test_random_statetest597.py +++ b/tests/ported_static/stRandom2/test_random_statetest597.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest597( ) -> None: """Test_random_statetest597.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,15 +43,6 @@ def test_random_statetest597( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000967f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3a7e737d40070a156482930a0875 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79967f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3a7e737d40070a156482930a0875" # noqa: E501 - ), - nonce=0, - address=Address(0x2F021DA657FB4D77FBCC8556101F287DDC7E44DB), # noqa: E501 - ) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -71,7 +59,14 @@ def test_random_statetest597( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000967f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3a7e737d40070a156482930a0875 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e79967f0000000000000000000000004f3f701464972e74606d6ea82d4d3080599a0e797ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3a7e737d40070a156482930a0875" # noqa: E501 + ), + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest599.py b/tests/ported_static/stRandom2/test_random_statetest599.py index 9f35d88ac51..4c95373662d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest599.py +++ b/tests/ported_static/stRandom2/test_random_statetest599.py @@ -46,6 +46,23 @@ def test_random_statetest599( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f8d6c60440a44449372068a976a83825560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest599( nonce=0, address=Address(0xDF8466089BD5913066F6D053AC12C5CF376BE1EC), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest600.py b/tests/ported_static/stRandom2/test_random_statetest600.py index 9652cd21b9f..a1aaa216c67 100644 --- a/tests/ported_static/stRandom2/test_random_statetest600.py +++ b/tests/ported_static/stRandom2/test_random_statetest600.py @@ -46,6 +46,7 @@ def test_random_statetest600( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c35043457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f0b6f37208e76a402927039198c96990760005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -81,7 +82,6 @@ def test_random_statetest600( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest601.py b/tests/ported_static/stRandom2/test_random_statetest601.py index 63caca6e3fd..045e18c7ec7 100644 --- a/tests/ported_static/stRandom2/test_random_statetest601.py +++ b/tests/ported_static/stRandom2/test_random_statetest601.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest601( ) -> None: """Test_random_statetest601.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest601( "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350377f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000000b3a09785b1084418866100af0868a3455" # noqa: E501 ), nonce=0, - address=Address(0x287D3F26FEBB148710A503235EBF7AC1F1B75838), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest601( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest602.py b/tests/ported_static/stRandom2/test_random_statetest602.py index f04e4c1640b..79e37586ce8 100644 --- a/tests/ported_static/stRandom2/test_random_statetest602.py +++ b/tests/ported_static/stRandom2/test_random_statetest602.py @@ -46,22 +46,7 @@ def test_random_statetest602( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x0] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0x1] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.PUSH32[0x1] - + Op.PUSH32[0x10000000000000000000000000000000000000000] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), - value=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF], - ), - nonce=0, - address=Address(0x1A15031B3876144E7362EE8E8E2DDFBE56E0CB51), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest602( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x0] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0x1] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.PUSH32[0x1] + + Op.PUSH32[0x10000000000000000000000000000000000000000] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), + value=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF], + ), + nonce=0, + address=Address(0x1A15031B3876144E7362EE8E8E2DDFBE56E0CB51), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest603.py b/tests/ported_static/stRandom2/test_random_statetest603.py index d996cb9f084..cac980e3f24 100644 --- a/tests/ported_static/stRandom2/test_random_statetest603.py +++ b/tests/ported_static/stRandom2/test_random_statetest603.py @@ -46,6 +46,23 @@ def test_random_statetest603( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000427f0000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000086f655860560745326476a03cdc3606345560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -64,23 +81,6 @@ def test_random_statetest603( nonce=0, address=Address(0x503333F6D5DDC17E393A7A209DB4CF7842CE6D94), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest604.py b/tests/ported_static/stRandom2/test_random_statetest604.py index be96f4eadd2..389d4667196 100644 --- a/tests/ported_static/stRandom2/test_random_statetest604.py +++ b/tests/ported_static/stRandom2/test_random_statetest604.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest604( ) -> None: """Test_random_statetest604.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,7 +66,6 @@ def test_random_statetest604( ) + Op.MOD(Op.GAS, Op.MOD), nonce=0, - address=Address(0x7619F7A13BA66BB3E74B1D609BC4C979FDFDA283), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -87,7 +83,6 @@ def test_random_statetest604( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest605.py b/tests/ported_static/stRandom2/test_random_statetest605.py index c24891105ad..49d73144b9e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest605.py +++ b/tests/ported_static/stRandom2/test_random_statetest605.py @@ -46,6 +46,23 @@ def test_random_statetest605( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c350437f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905803850855 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest605( nonce=0, address=Address(0x389EE64BA69526FD0E3F1C8A92544CB4B24B7A23), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest607.py b/tests/ported_static/stRandom2/test_random_statetest607.py index 1b2d9a3beb4..25d34d7fb5d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest607.py +++ b/tests/ported_static/stRandom2/test_random_statetest607.py @@ -46,22 +46,7 @@ def test_random_statetest607( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0955 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 - + Op.SSTORE( - key=Op.MULMOD( - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF], - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ), - value=Op.PUSH32[0x10000000000000000000000000000000000000000], - ), - nonce=0, - address=Address(0xC89AE2A04DEC1D7AEF4B220588D9A25FF766DBE1), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -78,7 +63,22 @@ def test_random_statetest607( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0955 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] * 2 + + Op.SSTORE( + key=Op.MULMOD( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF], + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ), + value=Op.PUSH32[0x10000000000000000000000000000000000000000], + ), + nonce=0, + address=Address(0xC89AE2A04DEC1D7AEF4B220588D9A25FF766DBE1), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest608.py b/tests/ported_static/stRandom2/test_random_statetest608.py index c1314942e61..c2e3f263a97 100644 --- a/tests/ported_static/stRandom2/test_random_statetest608.py +++ b/tests/ported_static/stRandom2/test_random_statetest608.py @@ -46,6 +46,7 @@ def test_random_statetest608( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c350537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0855 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_random_statetest608( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest609.py b/tests/ported_static/stRandom2/test_random_statetest609.py index ba6ee4afcf1..a47e6b355e1 100644 --- a/tests/ported_static/stRandom2/test_random_statetest609.py +++ b/tests/ported_static/stRandom2/test_random_statetest609.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest609( ) -> None: """Test_random_statetest609.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_random_statetest609( "7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000001a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000001a736e628f796436739660005155" # noqa: E501 ), nonce=0, - address=Address(0xD9B6A1D9A0741C62DC96E8D37A972BE5ADB708E8), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -71,7 +67,6 @@ def test_random_statetest609( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest610.py b/tests/ported_static/stRandom2/test_random_statetest610.py index c7598756b05..cf244576c52 100644 --- a/tests/ported_static/stRandom2/test_random_statetest610.py +++ b/tests/ported_static/stRandom2/test_random_statetest610.py @@ -46,6 +46,23 @@ def test_random_statetest610( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x417f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f01f353a2437e4384726497587b85565560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,23 +82,6 @@ def test_random_statetest610( nonce=0, address=Address(0xB31C72B16A9C3C9684628B4F39B4AAFDAFA85C1E), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest611.py b/tests/ported_static/stRandom2/test_random_statetest611.py index 76d7452a4a4..9ae93c6cade 100644 --- a/tests/ported_static/stRandom2/test_random_statetest611.py +++ b/tests/ported_static/stRandom2/test_random_statetest611.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest611( ) -> None: """Test_random_statetest611.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -61,7 +58,6 @@ def test_random_statetest611( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x54F36E7E44CEAB6D23E4D7EBD547858553649B64), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -79,7 +75,6 @@ def test_random_statetest611( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest612.py b/tests/ported_static/stRandom2/test_random_statetest612.py index befe03ced89..2bef95ebe43 100644 --- a/tests/ported_static/stRandom2/test_random_statetest612.py +++ b/tests/ported_static/stRandom2/test_random_statetest612.py @@ -46,6 +46,7 @@ def test_random_statetest612( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000100000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff095560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_random_statetest612( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest615.py b/tests/ported_static/stRandom2/test_random_statetest615.py index 354e1a4d9ec..db257da65f6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest615.py +++ b/tests/ported_static/stRandom2/test_random_statetest615.py @@ -46,6 +46,7 @@ def test_random_statetest615( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe837f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000001000000000000000000000000000000000000000009556c6f390a3054d7368a9a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_random_statetest615( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest616.py b/tests/ported_static/stRandom2/test_random_statetest616.py index 8767459945f..7e1333d043e 100644 --- a/tests/ported_static/stRandom2/test_random_statetest616.py +++ b/tests/ported_static/stRandom2/test_random_statetest616.py @@ -46,6 +46,7 @@ def test_random_statetest616( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000006f86a2409b991539f0423c0342363c3b5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest616( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest618.py b/tests/ported_static/stRandom2/test_random_statetest618.py index 7ad782f88aa..1db1b9752e6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest618.py +++ b/tests/ported_static/stRandom2/test_random_statetest618.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest618( ) -> None: """Test_random_statetest618.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest618( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f0000000000000000000000000000000000000000000000000000000000000000427f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff437f00000000000000000000000100000000000000000000000000000000000000003bf1135a3a58 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,25 +83,7 @@ def test_random_statetest618( + Op.GASPRICE + Op.PC, nonce=0, - address=Address(0xCE2DE07F0AF237ED58F6F7E008C3A9D82EB1769A), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest620.py b/tests/ported_static/stRandom2/test_random_statetest620.py index 84b9233f8d5..1cee588f78d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest620.py +++ b/tests/ported_static/stRandom2/test_random_statetest620.py @@ -46,6 +46,7 @@ def test_random_statetest620( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff427f0000000000000000000000010000000000000000000000000000000000000000457ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f6c54a420327d73727d9d1a667bf3895560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_random_statetest620( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest621.py b/tests/ported_static/stRandom2/test_random_statetest621.py index d84548fc93c..5e4e914e873 100644 --- a/tests/ported_static/stRandom2/test_random_statetest621.py +++ b/tests/ported_static/stRandom2/test_random_statetest621.py @@ -46,19 +46,7 @@ def test_random_statetest621( gas_limit=9223372036854775807, ) - # Source: raw - # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000441a7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f3ba187a19366899e595220741232905b60005155 # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 - + Op.BYTE(Op.PREVRANDAO, Op.PUSH32[0x0]) - + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] - + Op.SSTORE( - key=Op.MLOAD(offset=0x0), value=0x3BA187A19366899E595220741232905B - ), - nonce=0, - address=Address(0x3E00AB7141473834E4482F5650561879FEEB3E7B), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 coinbase = pre.deploy_contract( # noqa: F841 @@ -75,7 +63,19 @@ def test_random_statetest621( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f0000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000441a7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6f3ba187a19366899e595220741232905b60005155 # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.PUSH32[0x4F3F701464972E74606D6EA82D4D3080599A0E79] * 2 + + Op.BYTE(Op.PREVRANDAO, Op.PUSH32[0x0]) + + Op.PUSH32[0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF] + + Op.SSTORE( + key=Op.MLOAD(offset=0x0), value=0x3BA187A19366899E595220741232905B + ), + nonce=0, + address=Address(0x3E00AB7141473834E4482F5650561879FEEB3E7B), # noqa: E501 + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest624.py b/tests/ported_static/stRandom2/test_random_statetest624.py index b89093a8f1f..0354e149a84 100644 --- a/tests/ported_static/stRandom2/test_random_statetest624.py +++ b/tests/ported_static/stRandom2/test_random_statetest624.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest624( ) -> None: """Test_random_statetest624.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest624( code=bytes.fromhex("43424244457943455409635939"), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5ED2AE8463A1745023951E424FA0BF024F04FA55), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest624( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest625.py b/tests/ported_static/stRandom2/test_random_statetest625.py index 1af091857f7..9bf9d9ad615 100644 --- a/tests/ported_static/stRandom2/test_random_statetest625.py +++ b/tests/ported_static/stRandom2/test_random_statetest625.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest625( ) -> None: """Test_random_statetest625.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -64,7 +61,6 @@ def test_random_statetest625( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x2C7C249FD8A5BF9D65B5F5E62E5F093202F0E4AC), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -82,7 +78,6 @@ def test_random_statetest625( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest626.py b/tests/ported_static/stRandom2/test_random_statetest626.py index 0e3c822052a..b482213562f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest626.py +++ b/tests/ported_static/stRandom2/test_random_statetest626.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest626( ) -> None: """Test_random_statetest626.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,22 @@ def test_random_statetest626( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c350f4fd94058f06a255 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,25 +79,7 @@ def test_random_statetest626( + Op.LOG2 + Op.SSTORE, nonce=0, - address=Address(0xF55F25B074CBF8502ED5A9D1E2AAB4D351B67AF2), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest627.py b/tests/ported_static/stRandom2/test_random_statetest627.py index 4644b0921de..8d8c8380c38 100644 --- a/tests/ported_static/stRandom2/test_random_statetest627.py +++ b/tests/ported_static/stRandom2/test_random_statetest627.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest627( ) -> None: """Test_random_statetest627.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -64,7 +61,6 @@ def test_random_statetest627( ), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xADE7DE10D61D1AC88700ADA2A18CB4D070D34F9E), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -82,7 +78,6 @@ def test_random_statetest627( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest628.py b/tests/ported_static/stRandom2/test_random_statetest628.py index 30cc17f247e..c005e0c17c6 100644 --- a/tests/ported_static/stRandom2/test_random_statetest628.py +++ b/tests/ported_static/stRandom2/test_random_statetest628.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest628( ) -> None: """Test_random_statetest628.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_random_statetest628( code=Op.SSTORE(key=Op.BALANCE(address=Op.COINBASE), value=Op.COINBASE), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC897A0296ABEF0CC2B8E1CF7F133DD171D665337), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,7 +66,6 @@ def test_random_statetest628( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -82,7 +77,7 @@ def test_random_statetest628( post = { target: Account( - storage={46: 0x4F3F701464972E74606D6EA82D4D3080599A0E79}, + storage={46: coinbase}, balance=0xDE0B6B3A76586A0, nonce=0, ), diff --git a/tests/ported_static/stRandom2/test_random_statetest629.py b/tests/ported_static/stRandom2/test_random_statetest629.py index 813a4a59324..93bf1f10e4d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest629.py +++ b/tests/ported_static/stRandom2/test_random_statetest629.py @@ -46,6 +46,23 @@ def test_random_statetest629( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000347f000000000000000000000000116f427277147c617f4354a35a1a47977a5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest629( nonce=0, address=Address(0xD4302FBF760860B03F9B86B05D19F7F41567DC69), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest630.py b/tests/ported_static/stRandom2/test_random_statetest630.py index 42ec158dd52..6718fbb3a99 100644 --- a/tests/ported_static/stRandom2/test_random_statetest630.py +++ b/tests/ported_static/stRandom2/test_random_statetest630.py @@ -46,6 +46,7 @@ def test_random_statetest630( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f0000000000000000000000000000000000000000000000000000000000000001427f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000100000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f9461a46e61507a1206917b17137e7e5560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest630( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest632.py b/tests/ported_static/stRandom2/test_random_statetest632.py index f56c65bd5e9..b79f0ab6d8f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest632.py +++ b/tests/ported_static/stRandom2/test_random_statetest632.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest632( ) -> None: """Test_random_statetest632.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_random_statetest632( + Op.EXP(Op.CALLCODE, Op.EQ(Op.CALLDATASIZE, Op.ADDRESS)), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDE14E9D6C6F9145C355FDF3100FE961632D4CF85), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -76,7 +72,6 @@ def test_random_statetest632( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest633.py b/tests/ported_static/stRandom2/test_random_statetest633.py index bfff82b2f1d..983500bac3d 100644 --- a/tests/ported_static/stRandom2/test_random_statetest633.py +++ b/tests/ported_static/stRandom2/test_random_statetest633.py @@ -46,6 +46,23 @@ def test_random_statetest633( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006f82941340756317567250f1573a89765560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,23 +86,6 @@ def test_random_statetest633( nonce=0, address=Address(0x3B397829D56C4555587F2C995A886CF28D35D63D), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest635.py b/tests/ported_static/stRandom2/test_random_statetest635.py index 4827a18c760..a7e209f191f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest635.py +++ b/tests/ported_static/stRandom2/test_random_statetest635.py @@ -46,6 +46,7 @@ def test_random_statetest635( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff6a5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe66f2707d83713b6b8f320855 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest635( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest636.py b/tests/ported_static/stRandom2/test_random_statetest636.py index f69cad28738..28817f7fd00 100644 --- a/tests/ported_static/stRandom2/test_random_statetest636.py +++ b/tests/ported_static/stRandom2/test_random_statetest636.py @@ -47,6 +47,23 @@ def test_random_statetest636( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x74619921c0750ac3268e7a6703ca2bf6c43308e6fc36607561af1ca16db843f7a2e05bfc2e46afc179930b7a8724a04f9f561bdc65bba0ad5797dde0a28d5e8aca56e1510b724f676a6d33dee473d74664561e49e3d86338c8dcf260f06cbfa6283966d2d0f2591f54088e6f36545c0d90fcdea10d5629629ffb1b16626c339f6490829f1b1675f0f2f62b0b7c9d3f070fafd53f99f90f31e19e81d3db688929213e34affc41116e6ae6f54ad5c2062b27a9fbec78a52f7a26c6347408631a6c0efcf33fe576953a4043e846b686471403f38a615a0a8e601d600a600e60146301019a517363314bc0fef1600c7eb69785d3593d3a8552018a4faba5b591975e8b8056ebc01f5ce5f5f7c04eca9062b458a835649be8fbaa906f3c4d8f92f8c27517f0addd45e050bfcf55792d8bf87c39d39ed9b1ef6c8c070d8da4a624ce548b37d03ae8107ca6da49be4adffc9f5ae896c52b936a18bed4bd9fcbae531274706e9e9b9030619a40714bb4b22e7bef8cf7b01551327188ee4bb6247118d0e95549a92f7dd9305484cc054e5f206d70d008699a85896061427b05ae2a7f16230f66ab4dd548e03b0972010f5afff39a4f9a90e55e91584e86629f3e8775f53da16fceedd834103a50dbe72a6634e4dbf374c70e6bd041628dc8b30de3c3d7aa0e7bb48df927c78ed30b286e249c2cbe79fb55956f492e413e771d0cd63f7357ab1e9a38026a4ba9278427812728699a2c747189 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,23 +124,6 @@ def test_random_statetest636( nonce=0, address=Address(0xBDC4B8AF0F40B0EC2256166F7145B81CD824A868), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest637.py b/tests/ported_static/stRandom2/test_random_statetest637.py index 8491b472ac7..93704fddf5f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest637.py +++ b/tests/ported_static/stRandom2/test_random_statetest637.py @@ -46,6 +46,7 @@ def test_random_statetest637( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f00000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6f44931064138e9df1768334028c20147160005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -80,7 +81,6 @@ def test_random_statetest637( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest638.py b/tests/ported_static/stRandom2/test_random_statetest638.py index c95b274521c..1d1fee7b18a 100644 --- a/tests/ported_static/stRandom2/test_random_statetest638.py +++ b/tests/ported_static/stRandom2/test_random_statetest638.py @@ -46,6 +46,7 @@ def test_random_statetest638( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000100000000000000000000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0960005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -82,7 +83,6 @@ def test_random_statetest638( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest639.py b/tests/ported_static/stRandom2/test_random_statetest639.py index 7fabc96e3bc..65239f95c60 100644 --- a/tests/ported_static/stRandom2/test_random_statetest639.py +++ b/tests/ported_static/stRandom2/test_random_statetest639.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest639( ) -> None: """Test_random_statetest639.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_random_statetest639( gas_limit=9223372036854775807, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x6e993d78e80807a0d34bdbfa4e0afa9d7eab95e6f8772a548229700e2dcc612ac9ceeb898af8436680a2e1074df8ced0137964d71c8fe8a10fb58f8706ea3ee1b54a0848e742ca357e3d023460c161b1f5a17c48da2ae1e6987c52223414746fab0e39130693d15a48d39b5130096a7c1570c4fb89343ef5d10e912decba682bf205de79e84c573c9e2b0ffbd4d6117e40046b4c2d77156ada28960d9bb97f56d243429aa245c32e1f800a686ebe298dd08349d864486d7a1569b5aae495776bb5e71206cd09f54d1cd713966557567542184c74b95cc0d8ac3d0e05d0264b8d42a3563826123fc0d964521b61b86374591a821818672ef0dea05d259bc4f98c34418d9e7a677173b211649c07df7670aca688053842de6157c4fb5e678adc0611fcc20a1d836ec69b9370d09b83f1b0293a1b102d6d73978584b14fb2ab517001867e6545dd2dc3438f9c7828f6d3c6e4da98113ce2486c1ad028dc9947b28590071b977e651d352b078cb96b27f9ff7252c9f3ce9e5151ae7af1064ab8a5d92ed543b9d59c341f85bb22aa2fa7d7ee7310ac8f519e66da165b9efe3663657b1e28f4eb3e7338391339af5346d12c14bbc0863c26d7e999776c7939cefac542ed69f518bbef5461c0df385004f5411c3faaa65c7b6abf900ca1ef1f40bb938f727695a1ca14012ba07cc01548f3df75544b11bb52b7693bed7e2fc1537b2f8d63c4db4c3d8fc72b6f5f7e7b4d1ec8c1ac89230936975d19626788f03504a8c9acf66437d6d885607778bee6fe54742ddc9a7d8373dbfe2e21aacf8816944c02ef983260156009600960186329ec801e736356837182f175259fc2ea2df7d720fb0914ed44bcb12b8ff15e712ef67d868fe7fba6b46fac671a45bcace82fa83b87b8744835ac63d2b6cf3d157d7526909f9c4d1efbf68d780af1c0f2dabbfc53d2c71dc461bf7f788e3a9c48cd1df8d146a7df97125985162ecd37b059204323d066cb4709a3a1715f7c4a9fb905c26ba87933ef2499d3447d5cd4df27a6205c8a1ce06719c3e065e66ab80222ff7ed1f72f533a1160330dbd8dcd0489ec2dac84d7522a4d8732c5ae9e08d9a251682fb33fa08ecc05197d897a1d5f28328caa78ca6cd6b86fd08a1748fa959665861d18c25a3cae79732fe4fb3ad8b48c17c8efeeb5ec22be8b20ec4eae2955d65b9a6c1415c23047aa8f2c29aeddd78765c1bc3eda63416d84cdb9b8d7942020db3b1ed861a966475eb6ef9f9920692a879ee6bf9d0a1dd9d386 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -132,23 +145,6 @@ def test_random_statetest639( nonce=0, address=Address(0x9FECB32D9AE49C08DA1E2551BA9257BE9A181E76), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest640.py b/tests/ported_static/stRandom2/test_random_statetest640.py index fdd132094ba..fa10463591f 100644 --- a/tests/ported_static/stRandom2/test_random_statetest640.py +++ b/tests/ported_static/stRandom2/test_random_statetest640.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest640( ) -> None: """Test_random_statetest640.""" coinbase = Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,7 +59,6 @@ def test_random_statetest640( + Op.MLOAD(offset=0x0) + Op.SSTORE, nonce=0, - address=Address(0x63EA2AA7FCD26F2C76102BE53BCB49AFFE48AEDA), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -80,7 +76,6 @@ def test_random_statetest640( nonce=0, address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest641.py b/tests/ported_static/stRandom2/test_random_statetest641.py index 7b8920397cc..83cb0c21f18 100644 --- a/tests/ported_static/stRandom2/test_random_statetest641.py +++ b/tests/ported_static/stRandom2/test_random_statetest641.py @@ -46,6 +46,23 @@ def test_random_statetest641( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6000355415600957005b60203560003555 + coinbase = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=46, + nonce=0, + address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 + ) # Source: raw # 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000007f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6f29199c9aa4054170f1a15a55056f965560005155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -67,23 +84,6 @@ def test_random_statetest641( nonce=0, address=Address(0xA482D90F6CDA557C1E8E41C3755C25821C27BB9D), # noqa: E501 ) - # Source: raw - # 0x6000355415600957005b60203560003555 - coinbase = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=46, - nonce=0, - address=Address(0x4F3F701464972E74606D6EA82D4D3080599A0E79), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest642.py b/tests/ported_static/stRandom2/test_random_statetest642.py index 6ed885da421..64930192d13 100644 --- a/tests/ported_static/stRandom2/test_random_statetest642.py +++ b/tests/ported_static/stRandom2/test_random_statetest642.py @@ -47,6 +47,7 @@ def test_random_statetest642( ) pre[sender] = Account(balance=0x26551A696CACB206) + pre[addr_2] = Account(balance=0x11BAE0BB79D6A164, nonce=163) # Source: raw # 0x62f46a4f547b169c9edf92f4b39273fe47accc75d1209ae58463c2585607ce051ff6714c4f0fbf6de0659784434fb240652ff52d08576408f168a43a6651f765a4788a05537086290691d5a3239db43eefea96b0012ea26534e99e4ba9ee7f92f37fa731707f800683bafb70815757d861ad8cc6804154ce5b9de3146b58cd53 # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -65,7 +66,6 @@ def test_random_statetest642( nonce=112, address=Address(0x88F8BB676EB054B4F4788ABF1200CB51361038CF), # noqa: E501 ) - pre[addr_2] = Account(balance=0x11BAE0BB79D6A164, nonce=163) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest643.py b/tests/ported_static/stRandom2/test_random_statetest643.py index 6ee17f075c3..8de4eb0b70c 100644 --- a/tests/ported_static/stRandom2/test_random_statetest643.py +++ b/tests/ported_static/stRandom2/test_random_statetest643.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -31,9 +30,7 @@ def test_random_statetest643( pre: Alloc, ) -> None: """Return ~1 MB out of bounds of the init code.""" - sender = EOA( - key=0x2C6BEC15D915620A88056CC6BFB70707AFA902ABD52C7DFEAB0864BE472CB8AF - ) + sender = pre.fund_eoa(amount=0xA015CDDAB7107B04) env = Environment( fee_recipient=sender, @@ -65,9 +62,7 @@ def test_random_statetest643( ), balance=0x3F91B25C1601534B, nonce=210, - address=Address(0x6E40C70F8BE9A7633E8A31580C85F275B86362EF), # noqa: E501 ) - pre[sender] = Account(balance=0xA015CDDAB7107B04) # Source: raw # 0x436debc3912504eded08f73b9ff9490d73fc4f820a0890b7e8417fa97940713aeb870e59a790607f6b3d5649e57458ea8692da323253735967657e3fc6e02f6de1c0ff6cc18e051bdd52ad7b1eb441440620426b3485ab683d44ff8d5544eb7f7fb3e1f4c30063640b5a626f341b6271dd596212084762084319736338f86b9af4 # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRandom2/test_random_statetest644.py b/tests/ported_static/stRandom2/test_random_statetest644.py index 0d951cafb83..6d36dd43b81 100644 --- a/tests/ported_static/stRandom2/test_random_statetest644.py +++ b/tests/ported_static/stRandom2/test_random_statetest644.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest644( ) -> None: """Geth Failed this test on Frontier and Homestead.""" coinbase = Address(0x02EBBA385BD7F6DDE6C57E2D3929A11A1EA0DA7E) - sender = EOA( - key=0xA10C9449493A34FD272F4BF6FC827C5B46ECE7D0253518E71286F47EC3AE23A - ) + sender = pre.fund_eoa(amount=0x236D08FE524712CB) env = Environment( fee_recipient=coinbase, @@ -71,9 +68,7 @@ def test_random_statetest644( + Op.COINBASE, balance=0x23C22AEB4961B17E, nonce=148, - address=Address(0x0346AD0B28EA31B7C3D398881DC11EBC97869461), # noqa: E501 ) - pre[sender] = Account(balance=0x236D08FE524712CB) # Source: raw # 0x74357a5ade2da3b4a5f5459faff84e5ea9b714b60ed26257ef597d9aa2e6d9316426366fe24fb9ed56c4a9e5dcf06af08c42368fdaa12b71476283c5bd6147ed93625663ae6252d373624971d86228ec1a730000000000000000000000000000000000000005630c30a604f478fe44add6669b247cad0f00251697572fa913a16c98038931df54 # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 @@ -96,7 +91,6 @@ def test_random_statetest644( + Op.SLOAD(key=0xFE44ADD6669B247CAD0F00251697572FA913A16C98038931DF), balance=0x9183FD5B40D86E03, nonce=28, - address=Address(0xE4882BA8527DF19159E6536F4AEE12C298D28F33), # noqa: E501 ) # Source: raw # 0x77351c4c5a02c8f13fa7c7f5800fa5c9ba2f3b971c13764f9b61c2db66c3f909c17e434a68d685402956cc341dbf6779516900ed0a1e2666dfa40e70f3bcee773c2bffd5b5422a2cf32b19e541f15ae2b6fbe16fd19bbd567728190f83569f036dccd3886aa69c1e685736da06152e3b24728b13546ea1abd48ee47b1b2e1ec70b37fa14cc709d35fce7380230f426455385da80771ffc6e261f3bfe7bfe7f1827d17b0cf49a7d7ff8ceb60b6a86ebbb762eb3e4dd1a8a09eaa9a500bc65cbefd4251865b70ca7e26682f1a2bad52a4a697aa0baf4ebe05130ec6a62e66e719d6bb753654f0ff08533f6d088e16d682dca6786082a55eda4d65f21e91074345d12b775ce0f47447731e5eeeff44ca0a946e1df77f77e3d07cc9daa30a1b2941c17f9039ffa3baddf70dce808a071acb22d3fe0b1ecea101f659fd3fcfe7d9f16546273b0236232b79262118942733c6247f037626ab8de621acb67625b60d5636bd2696273630b2df5d6f1623402af629589806317ef5652f032 # noqa: E501 diff --git a/tests/ported_static/stRandom2/test_random_statetest645.py b/tests/ported_static/stRandom2/test_random_statetest645.py index 34e478b5292..fb3fae390ae 100644 --- a/tests/ported_static/stRandom2/test_random_statetest645.py +++ b/tests/ported_static/stRandom2/test_random_statetest645.py @@ -69,6 +69,8 @@ def test_random_statetest645( gas_limit=13175566155172316, ) + pre[sender] = Account(balance=0x6F1F70FEA641F30A) + pre[addr_2] = Account(balance=0xB3508C0F8A22F8A1, nonce=28) # Source: raw # 0x58679b8e24022d8c28f3620b55a06384bc2f83136515b61916f0f579ea3e9d28799d45aa77bf1fc1a84edf0193dea2d610209eaaf9c814 # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -83,7 +85,6 @@ def test_random_statetest645( nonce=29, address=Address(0x322C72DEDAD1A81092AB9BA908FBEC8779CE1C32), # noqa: E501 ) - pre[sender] = Account(balance=0x6F1F70FEA641F30A) # Source: raw # 0x63cbb01282621d72de5268022948f746c938a0cb7c01ef17f23ed237d9f3262c4eb1b95112820595b127c516074df06223db7e0c396eb18074f148d96fd766dda35b6cc250661b5f83f0ed625ba68a5ff49aa1 # noqa: E501 coinbase = pre.deploy_contract( # noqa: F841 @@ -97,7 +98,6 @@ def test_random_statetest645( nonce=175, address=Address(0xAA0103980A7C3113D3A8F81478B0281492EB3D38), # noqa: E501 ) - pre[addr_2] = Account(balance=0xB3508C0F8A22F8A1, nonce=28) tx_data = [ Bytes( diff --git a/tests/ported_static/stRandom2/test_random_statetest647.py b/tests/ported_static/stRandom2/test_random_statetest647.py index 6e369d401fd..04b997bddbd 100644 --- a/tests/ported_static/stRandom2/test_random_statetest647.py +++ b/tests/ported_static/stRandom2/test_random_statetest647.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stRandom2/randomStatetest647Filler.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_random_statetest647( state_test: StateTestFiller, pre: Alloc, ) -> None: """Malicious bytecode found by fuzztest tool: returndatacopy(0,-1).""" coinbase = Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x5B7B8EFB6D003CD481E408D8759A25ADC79955092F1A380D8F8B57346C1D1342 - ) + sender = pre.fund_eoa(amount=0x174876E800) env = Environment( fee_recipient=coinbase, @@ -46,7 +42,6 @@ def test_random_statetest647( gas_limit=18857228215205537, ) - pre[sender] = Account(balance=0x174876E800) # Source: raw # 0x6001600160000360003e00 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +50,6 @@ def test_random_statetest647( ) + Op.STOP, nonce=7, - address=Address(0x782B7C65205E1C08192DF7357E2FE778C81256A9), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRandom2/test_random_statetest648.py b/tests/ported_static/stRandom2/test_random_statetest648.py index 5a22cb04b9d..e08661220fa 100644 --- a/tests/ported_static/stRandom2/test_random_statetest648.py +++ b/tests/ported_static/stRandom2/test_random_statetest648.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_random_statetest648( ) -> None: """Consensus issue test produced by fuzz testing team...""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xFF348633B687EC0F553647F4DDEED7590E90C7EA65B87C5BD399F4C869B9C9FC - ) + sender = pre.fund_eoa(amount=0xFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -64,16 +61,13 @@ def test_random_statetest648( + Op.SELFDESTRUCT(address=0xF5) + Op.REVERT, nonce=0, - address=Address(0xCA5C69FA03B9DFF4D059971AC17EDAC7EF758725), # noqa: E501 ) # Source: raw # 0x600050 addr = pre.deploy_contract( # noqa: F841 code=Op.POP(0x0), nonce=0, - address=Address(0xA828265D4B2DB08E65A1C68D2878F15368B5AE75), # noqa: E501 ) - pre[sender] = Account(balance=0xFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest649.py b/tests/ported_static/stRandom2/test_random_statetest649.py index 9a4305bee5c..72333b88ceb 100644 --- a/tests/ported_static/stRandom2/test_random_statetest649.py +++ b/tests/ported_static/stRandom2/test_random_statetest649.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest649( ) -> None: """Consensus issue test produced by fuzz testing team...""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x61EC5E5029A151E121E39AE4D7546D549EA4B130F645F6F650CEEC0416FE27F4 - ) + sender = pre.fund_eoa(amount=0x3FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -152,9 +149,7 @@ def test_random_statetest649( + Op.PUSH2[0x365C] + Op.STOP, nonce=0, - address=Address(0x39AB27391D04D35CAE13DCDF2FACABA711F0588F), # noqa: E501 ) - pre[sender] = Account(balance=0x3FFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRandom2/test_random_statetest650.py b/tests/ported_static/stRandom2/test_random_statetest650.py index c84cfc8e8eb..383d82978cc 100644 --- a/tests/ported_static/stRandom2/test_random_statetest650.py +++ b/tests/ported_static/stRandom2/test_random_statetest650.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_random_statetest650( ) -> None: """Consensus issue test produced by fuzz testing team...""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x61EC5E5029A151E121E39AE4D7546D549EA4B130F645F6F650CEEC0416FE27F4 - ) + sender = pre.fund_eoa(amount=0x3FFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -3303,9 +3300,7 @@ def test_random_statetest650( ret_size=0x20, ), nonce=0, - address=Address(0x9D258197DE5279A844B4BE3D23547CA4233A70BC), # noqa: E501 ) - pre[sender] = Account(balance=0x3FFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRecursiveCreate/test_recursive_create.py b/tests/ported_static/stRecursiveCreate/test_recursive_create.py index 7bfcde15d6e..80d5901bc12 100644 --- a/tests/ported_static/stRecursiveCreate/test_recursive_create.py +++ b/tests/ported_static/stRecursiveCreate/test_recursive_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_recursive_create( """Test_recursive_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,9 +53,7 @@ def test_recursive_create( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRecursiveCreate/test_recursive_create_return_value.py b/tests/ported_static/stRecursiveCreate/test_recursive_create_return_value.py index ac0d8780754..041f86ff498 100644 --- a/tests/ported_static/stRecursiveCreate/test_recursive_create_return_value.py +++ b/tests/ported_static/stRecursiveCreate/test_recursive_create_return_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_recursive_create_return_value( """Test_recursive_create_return_value.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,9 +57,7 @@ def test_recursive_create_return_value( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund50_1.py b/tests/ported_static/stRefundTest/test_refund50_1.py index 4c3dc22599e..1135b777d09 100644 --- a/tests/ported_static/stRefundTest/test_refund50_1.py +++ b/tests/ported_static/stRefundTest/test_refund50_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund50_1( ) -> None: """Test_refund50_1.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xDC4EFA209AECDD4C2D5201A419EA27506151B4EC687F14A613229E310932491B - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_refund50_1( storage={1: 1, 2: 1, 3: 1, 4: 1, 5: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6737EAC10F0B6FF19A1C903CAFC30B26752A5AF4), # noqa: E501 ) - pre[sender] = Account(balance=0x989680) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund50_2.py b/tests/ported_static/stRefundTest/test_refund50_2.py index ed6f0dddafc..4d471f24074 100644 --- a/tests/ported_static/stRefundTest/test_refund50_2.py +++ b/tests/ported_static/stRefundTest/test_refund50_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund50_2( ) -> None: """Test_refund50_2.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xDC4EFA209AECDD4C2D5201A419EA27506151B4EC687F14A613229E310932491B - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -61,9 +58,7 @@ def test_refund50_2( storage={1: 1, 2: 1, 3: 1, 4: 1, 5: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDD9BC2AEC4F69625B8F1D9D0FACB81C72E9A4D59), # noqa: E501 ) - pre[sender] = Account(balance=0x989680) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund50percent_cap.py b/tests/ported_static/stRefundTest/test_refund50percent_cap.py index 8aac98451c8..d92a991123c 100644 --- a/tests/ported_static/stRefundTest/test_refund50percent_cap.py +++ b/tests/ported_static/stRefundTest/test_refund50percent_cap.py @@ -47,6 +47,7 @@ def test_refund50percent_cap( ) pre[coinbase] = Account(balance=0, nonce=1) + pre[sender] = Account(balance=0x989680) # Source: lll # { @@1 @@2 [[ 10 ]] (EXP 2 0xff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,7 +67,6 @@ def test_refund50percent_cap( nonce=0, address=Address(0xEF67F354C8505E1056889970C3D9B5E0FE65D1E2), # noqa: E501 ) - pre[sender] = Account(balance=0x989680) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund600.py b/tests/ported_static/stRefundTest/test_refund600.py index 64d950e48f0..cce448a08c4 100644 --- a/tests/ported_static/stRefundTest/test_refund600.py +++ b/tests/ported_static/stRefundTest/test_refund600.py @@ -47,6 +47,7 @@ def test_refund600( ) pre[coinbase] = Account(balance=0, nonce=1) + pre[sender] = Account(balance=0x989680) # Source: lll # { @@1 @@2 [[ 10 ]] (EXP 2 0xffff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -66,7 +67,6 @@ def test_refund600( nonce=0, address=Address(0xC09923E2275E4EE7822A1FEB5EEE1C18143575C7), # noqa: E501 ) - pre[sender] = Account(balance=0x989680) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_call_a.py b/tests/ported_static/stRefundTest/test_refund_call_a.py index f78495153f9..bc745f449be 100644 --- a/tests/ported_static/stRefundTest/test_refund_call_a.py +++ b/tests/ported_static/stRefundTest/test_refund_call_a.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_call_a( ) -> None: """Test_refund_call_a.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x752660E61324E901F7231DFAE39984F4D433A241D533838E4700925F477814FD - ) + sender = pre.fund_eoa(amount=0x1312D00) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,21 @@ def test_refund_call_a( pre[coinbase] = Account(balance=0, nonce=1) # Source: lll + # { [[ 1 ]] 0 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, + storage={1: 1}, + balance=0xDE0B6B3A7640000, + nonce=0, + ) + # Source: lll # { [[ 0 ]] (CALL 5500 0 0 0 0 0 )} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.CALL( gas=0x157C, - address=0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,17 +71,6 @@ def test_refund_call_a( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3D72F604B4D56320853A5ECE45772DBBF419F315), # noqa: E501 - ) - pre[sender] = Account(balance=0x1312D00) - # Source: lll - # { [[ 1 ]] 0 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, - storage={1: 1}, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRefundTest/test_refund_call_a_not_enough_gas_in_call.py b/tests/ported_static/stRefundTest/test_refund_call_a_not_enough_gas_in_call.py index 9a31197d1a1..def38bc9f7b 100644 --- a/tests/ported_static/stRefundTest/test_refund_call_a_not_enough_gas_in_call.py +++ b/tests/ported_static/stRefundTest/test_refund_call_a_not_enough_gas_in_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_call_a_not_enough_gas_in_call( ) -> None: """Test_refund_call_a_not_enough_gas_in_call.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x7C857D62C76CE09F2E8EC3FA9277578C67B69C6547364568FDDB841071E5BD7 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,21 @@ def test_refund_call_a_not_enough_gas_in_call( pre[coinbase] = Account(balance=0, nonce=1) # Source: lll + # { [[ 1 ]] 0 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, + storage={1: 1}, + balance=0xDE0B6B3A7640000, + nonce=0, + ) + # Source: lll # { [[ 0 ]] (CALL 5005 0 0 0 0 0 )} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.CALL( gas=0x138D, - address=0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,17 +71,6 @@ def test_refund_call_a_not_enough_gas_in_call( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8329332CCFB6AE9DF0412E842619FB1C989FBF48), # noqa: E501 - ) - pre[sender] = Account(balance=0xF4240) - # Source: lll - # { [[ 1 ]] 0 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, - storage={1: 1}, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRefundTest/test_refund_call_a_oog.py b/tests/ported_static/stRefundTest/test_refund_call_a_oog.py index aca7b380114..b9b0bda841c 100644 --- a/tests/ported_static/stRefundTest/test_refund_call_a_oog.py +++ b/tests/ported_static/stRefundTest/test_refund_call_a_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_call_a_oog( ) -> None: """Test_refund_call_a_oog.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x27B48AAA30A609C11C7ABA1CB67FC191B5B59F9FF876930F0085D5FAEF4A4824 - ) + sender = pre.fund_eoa(amount=0x2DC6C0) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,21 @@ def test_refund_call_a_oog( pre[coinbase] = Account(balance=0, nonce=1) # Source: lll + # { [[ 1 ]] 0 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, + storage={1: 1}, + balance=0xDE0B6B3A7640000, + nonce=0, + ) + # Source: lll # { [[ 0 ]] (CALL 6000 0 0 0 0 0 )} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.CALL( gas=0x1770, - address=0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,17 +71,6 @@ def test_refund_call_a_oog( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1B98D6B82E06B90C71C779925AE5B84E28401256), # noqa: E501 - ) - pre[sender] = Account(balance=0x2DC6C0) - # Source: lll - # { [[ 1 ]] 0 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, - storage={1: 1}, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRefundTest/test_refund_call_to_suicide_no_storage.py b/tests/ported_static/stRefundTest/test_refund_call_to_suicide_no_storage.py index e5b4113c10d..a374d190c0b 100644 --- a/tests/ported_static/stRefundTest/test_refund_call_to_suicide_no_storage.py +++ b/tests/ported_static/stRefundTest/test_refund_call_to_suicide_no_storage.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_refund_call_to_suicide_no_storage( ) -> None: """Test_refund_call_to_suicide_no_storage.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x6F0117D3E9C684C7D6E1E6B79DC3880DA2BEBE77C765B171C062FDFFD38A673F - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -92,7 +89,6 @@ def test_refund_call_to_suicide_no_storage( nonce=0, address=Address(0x5BE4B33890F720EFF72BE0019B122E0FF75CB937), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) # Source: lll # { (SELFDESTRUCT ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRefundTest/test_refund_call_to_suicide_storage.py b/tests/ported_static/stRefundTest/test_refund_call_to_suicide_storage.py index d9d88b0c1df..ebc41bce622 100644 --- a/tests/ported_static/stRefundTest/test_refund_call_to_suicide_storage.py +++ b/tests/ported_static/stRefundTest/test_refund_call_to_suicide_storage.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_refund_call_to_suicide_storage( ) -> None: """Test_refund_call_to_suicide_storage.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x6F0117D3E9C684C7D6E1E6B79DC3880DA2BEBE77C765B171C062FDFFD38A673F - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -92,7 +89,6 @@ def test_refund_call_to_suicide_storage( nonce=0, address=Address(0x5BE4B33890F720EFF72BE0019B122E0FF75CB937), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) # Source: lll # { (SELFDESTRUCT ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRefundTest/test_refund_call_to_suicide_twice.py b/tests/ported_static/stRefundTest/test_refund_call_to_suicide_twice.py index 817d9990510..bbcce3a6ed0 100644 --- a/tests/ported_static/stRefundTest/test_refund_call_to_suicide_twice.py +++ b/tests/ported_static/stRefundTest/test_refund_call_to_suicide_twice.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_refund_call_to_suicide_twice( ) -> None: """Test_refund_call_to_suicide_twice.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x6F0117D3E9C684C7D6E1E6B79DC3880DA2BEBE77C765B171C062FDFFD38A673F - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_refund_call_to_suicide_twice( nonce=0, address=Address(0x81BDBAA560B5AD52B0F9857CF4CA40B74D4B6996), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) # Source: lll # { (SELFDESTRUCT ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRefundTest/test_refund_change_non_zero_storage.py b/tests/ported_static/stRefundTest/test_refund_change_non_zero_storage.py index 6a8453af941..b82dcefae41 100644 --- a/tests/ported_static/stRefundTest/test_refund_change_non_zero_storage.py +++ b/tests/ported_static/stRefundTest/test_refund_change_non_zero_storage.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_change_non_zero_storage( ) -> None: """Test_refund_change_non_zero_storage.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x4D9FC6FDF95098986741EE78843AC52BEED77C8C801DC87BD3F04CD6BBF1A3EB - ) + sender = pre.fund_eoa(amount=0x3C336080) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_refund_change_non_zero_storage( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x904261B07D3A5F213BBD6FB9F3BB66F4FB65C7EB), # noqa: E501 ) - pre[sender] = Account(balance=0x3C336080) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_ff.py b/tests/ported_static/stRefundTest/test_refund_ff.py index e6da1b6192c..06c1e9435f2 100644 --- a/tests/ported_static/stRefundTest/test_refund_ff.py +++ b/tests/ported_static/stRefundTest/test_refund_ff.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_refund_ff( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3) - sender = EOA( - key=0xD6B0676AFDE099A078F9D00F24D2C1CB4278546E1734927015023DB0980A92C5 - ) + sender = pre.fund_eoa(amount=0xE8D6599218, nonce=1) env = Environment( fee_recipient=coinbase, @@ -47,20 +43,16 @@ def test_refund_ff( gas_limit=16777216, ) + addr = pre.fund_eoa(amount=0) # noqa: F841 # Source: yul # berlin # { # selfdestruct() # } target = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3 - ), + code=Op.SELFDESTRUCT(address=addr), nonce=1, - address=Address(0xA45B53C7B70ADF8EA2E910D0E826DF8D895B2B49), # noqa: E501 ) - pre[addr] = Account(balance=0, nonce=1) - pre[sender] = Account(balance=0xE8D6599218, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_get_ether_back.py b/tests/ported_static/stRefundTest/test_refund_get_ether_back.py index 97d15c97dd6..81633765711 100644 --- a/tests/ported_static/stRefundTest/test_refund_get_ether_back.py +++ b/tests/ported_static/stRefundTest/test_refund_get_ether_back.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_get_ether_back( ) -> None: """Test_refund_get_ether_back.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x29268B0C3308094249E9A06C02739F688D492D6325CA24B36EF949E5FC20AF27 - ) + sender = pre.fund_eoa(amount=0x3CF773D0) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_refund_get_ether_back( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) - pre[sender] = Account(balance=0x3CF773D0) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_max.py b/tests/ported_static/stRefundTest/test_refund_max.py index 211468231e7..4924bc77fa2 100644 --- a/tests/ported_static/stRefundTest/test_refund_max.py +++ b/tests/ported_static/stRefundTest/test_refund_max.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_max( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB5555C6F8171A6EB3C0A84ED8F01AF5CE65A85A096A824A60EE5E2C2C2E076D1 - ) + sender = pre.fund_eoa(amount=0xE8D848C3A0, nonce=1) env = Environment( fee_recipient=coinbase, @@ -86,9 +83,7 @@ def test_refund_max( }, balance=0xDE0B6B3A7640000, nonce=1, - address=Address(0x7E9D1FF50F8EB9591A0434ABFE3230054A934124), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D848C3A0, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_multimple_suicide.py b/tests/ported_static/stRefundTest/test_refund_multimple_suicide.py index 5b88df85551..015e02e5d2a 100644 --- a/tests/ported_static/stRefundTest/test_refund_multimple_suicide.py +++ b/tests/ported_static/stRefundTest/test_refund_multimple_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_multimple_suicide( ) -> None: """Test_refund_multimple_suicide.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xC69694690A07D1418B0AADFD424A00EA9F25D84B94FECEF12943DE9CD38EDE14 - ) + sender = pre.fund_eoa(amount=0x623A7C0) env = Environment( fee_recipient=coinbase, @@ -145,9 +142,7 @@ def test_refund_multimple_suicide( + Op.JUMP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8B9574E5049501F581886404ADF7037002276E78), # noqa: E501 ) - pre[sender] = Account(balance=0x623A7C0) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_no_oog_1.py b/tests/ported_static/stRefundTest/test_refund_no_oog_1.py index 17b04e13d68..79eb43dc804 100644 --- a/tests/ported_static/stRefundTest/test_refund_no_oog_1.py +++ b/tests/ported_static/stRefundTest/test_refund_no_oog_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_no_oog_1( ) -> None: """Test_refund_no_oog_1.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x791307ECE6DFD40DF62DC66EFBC482096DD34650382AEB5D46DBEEDED66508F7 - ) + sender = pre.fund_eoa(amount=0xA03F70) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_refund_no_oog_1( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) - pre[sender] = Account(balance=0xA03F70) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_oog.py b/tests/ported_static/stRefundTest/test_refund_oog.py index c5f1f3d0a7a..1054df57c65 100644 --- a/tests/ported_static/stRefundTest/test_refund_oog.py +++ b/tests/ported_static/stRefundTest/test_refund_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_oog( ) -> None: """Test_refund_oog.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x8518C6B13163F88376ADBDE956B3D6C1E4E027E25E20994C1AD0D78B8FD7FAC9 - ) + sender = pre.fund_eoa(amount=0x7A120) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_refund_oog( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) - pre[sender] = Account(balance=0x7A120) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_single_suicide.py b/tests/ported_static/stRefundTest/test_refund_single_suicide.py index 2896869cb47..4cee829af0d 100644 --- a/tests/ported_static/stRefundTest/test_refund_single_suicide.py +++ b/tests/ported_static/stRefundTest/test_refund_single_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_single_suicide( ) -> None: """Test_refund_single_suicide.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x2B75D0C814EB07C075FCCBDD9A036FAF651D9C46D7477D6C4F30772CFCA90D38 - ) + sender = pre.fund_eoa(amount=0x1C9C380) env = Environment( fee_recipient=coinbase, @@ -120,9 +117,7 @@ def test_refund_single_suicide( + Op.JUMP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFC2C9403120F755B844FD30D99C231483E701631), # noqa: E501 ) - pre[sender] = Account(balance=0x1C9C380) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_sstore.py b/tests/ported_static/stRefundTest/test_refund_sstore.py index 70bd9105a19..9a8cd6f7ddc 100644 --- a/tests/ported_static/stRefundTest/test_refund_sstore.py +++ b/tests/ported_static/stRefundTest/test_refund_sstore.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_sstore( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x8C45B94DCA330650C0392398FB2097BB64764E973720A845EE67605FFABF0C7C - ) + sender = pre.fund_eoa(amount=0xE8D631F190, nonce=1) env = Environment( fee_recipient=coinbase, @@ -56,9 +53,7 @@ def test_refund_sstore( storage={0: 24743}, balance=0xDE0B6B3A7640000, nonce=1, - address=Address(0xF5F86B947FC07A75E19106A6B7E4953D431AD57F), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D631F190, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRefundTest/test_refund_suicide50procent_cap.py b/tests/ported_static/stRefundTest/test_refund_suicide50procent_cap.py index 2a5b94d69dd..2fc32dac534 100644 --- a/tests/ported_static/stRefundTest/test_refund_suicide50procent_cap.py +++ b/tests/ported_static/stRefundTest/test_refund_suicide50procent_cap.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_refund_suicide50procent_cap( ) -> None: """Test_refund_suicide50procent_cap.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -104,7 +101,6 @@ def test_refund_suicide50procent_cap( nonce=0, address=Address(0xA6CC2CA5611255D50118601AA8ECE6F124FC4C45), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) # Source: lll # { (SELFDESTRUCT ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRefundTest/test_refund_tx_to_suicide_oog.py b/tests/ported_static/stRefundTest/test_refund_tx_to_suicide_oog.py index ea7b0792815..a1bc150ca20 100644 --- a/tests/ported_static/stRefundTest/test_refund_tx_to_suicide_oog.py +++ b/tests/ported_static/stRefundTest/test_refund_tx_to_suicide_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_refund_tx_to_suicide_oog( ) -> None: """Test_refund_tx_to_suicide_oog.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_refund_tx_to_suicide_oog( ) pre[coinbase] = Account(balance=0, nonce=1) - pre[sender] = Account(balance=0x5F5E100) # Source: lll # { (SELFDESTRUCT 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) } target = pre.deploy_contract( # noqa: F841 @@ -56,7 +52,6 @@ def test_refund_tx_to_suicide_oog( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2BC33A472F0FBA1E30BF2317D07910367908C7F6), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stReturnDataTest/test_call_ecrec_success_empty_then_returndatasize.py b/tests/ported_static/stReturnDataTest/test_call_ecrec_success_empty_then_returndatasize.py index ed27bb9acc7..d08d9d790c3 100644 --- a/tests/ported_static/stReturnDataTest/test_call_ecrec_success_empty_then_returndatasize.py +++ b/tests/ported_static/stReturnDataTest/test_call_ecrec_success_empty_then_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_ecrec_success_empty_then_returndatasize( ) -> None: """Test_call_ecrec_success_empty_then_returndatasize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -66,9 +63,7 @@ def test_call_ecrec_success_empty_then_returndatasize( + Op.STOP, storage={0: 24743}, nonce=0, - address=Address(0x77E2F61794BCFD86B1C2380C34AAB5FB7C25E95E), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_call_outsize_then_create_successful_then_returndatasize.py b/tests/ported_static/stReturnDataTest/test_call_outsize_then_create_successful_then_returndatasize.py index a09332a6a48..51835c7831d 100644 --- a/tests/ported_static/stReturnDataTest/test_call_outsize_then_create_successful_then_returndatasize.py +++ b/tests/ported_static/stReturnDataTest/test_call_outsize_then_create_successful_then_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_outsize_then_create_successful_then_returndatasize( ) -> None: """Test_call_outsize_then_create_successful_then_returndatasize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_call_outsize_then_create_successful_then_returndatasize( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP * 2, nonce=0, - address=Address(0x24B406508240D6F2783499D1FD65FEDD0FEEEF37), # noqa: E501 ) # Source: lll # { (seq (CALL 0x0900000000 0 0 0 0 0x20) (CREATE 0 0 (lll (seq (mstore 0 0x112233) (RETURN 0 32) (STOP) ) 0)) (SSTORE 0 (RETURNDATASIZE)) (STOP) )} # noqa: E501 @@ -66,7 +62,7 @@ def test_call_outsize_then_create_successful_then_returndatasize( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x24B406508240D6F2783499D1FD65FEDD0FEEEF37, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -86,9 +82,7 @@ def test_call_outsize_then_create_successful_then_returndatasize( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0x3875F9536B829CB75F84CDCB2F72B000B5A41855), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_call_then_call_value_fail_then_returndatasize.py b/tests/ported_static/stReturnDataTest/test_call_then_call_value_fail_then_returndatasize.py index bcea45321de..884719f7a4d 100644 --- a/tests/ported_static/stReturnDataTest/test_call_then_call_value_fail_then_returndatasize.py +++ b/tests/ported_static/stReturnDataTest/test_call_then_call_value_fail_then_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_then_call_value_fail_then_returndatasize( ) -> None: """Test_call_then_call_value_fail_then_returndatasize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_call_then_call_value_fail_then_returndatasize( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x9898DD5E5C526B55EC49B1047E298705C13279F1), # noqa: E501 ) # Source: lll # { (seq (CALL 0x0900000000 0 0 0 0 0x20) (CALL 0x0900000000 0xffffffffffff 0 0 0 0x20) (SSTORE 0 (RETURNDATASIZE)) )} # noqa: E501 @@ -66,7 +62,7 @@ def test_call_then_call_value_fail_then_returndatasize( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x9898DD5E5C526B55EC49B1047E298705C13279F1, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -77,7 +73,7 @@ def test_call_then_call_value_fail_then_returndatasize( + Op.POP( Op.CALL( gas=0x900000000, - address=0x9898DD5E5C526B55EC49B1047E298705C13279F1, + address=addr, value=0xFFFFFFFFFFFF, args_offset=0x0, args_size=0x0, @@ -89,9 +85,7 @@ def test_call_then_call_value_fail_then_returndatasize( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x0E496B29AD2F0E55ADF292C08A6A9289CB163835), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_call_then_create_successful_then_returndatasize.py b/tests/ported_static/stReturnDataTest/test_call_then_create_successful_then_returndatasize.py index 849239321ec..d4206eef60c 100644 --- a/tests/ported_static/stReturnDataTest/test_call_then_create_successful_then_returndatasize.py +++ b/tests/ported_static/stReturnDataTest/test_call_then_create_successful_then_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_then_create_successful_then_returndatasize( ) -> None: """Test_call_then_create_successful_then_returndatasize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_call_then_create_successful_then_returndatasize( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP * 2, nonce=0, - address=Address(0x24B406508240D6F2783499D1FD65FEDD0FEEEF37), # noqa: E501 ) # Source: lll # { (seq (CALL 0x0900000000 0 0 0 0 0) (CREATE 0 0 (lll (seq (mstore 0 0x112233) (RETURN 0 32) (STOP) ) 0)) (SSTORE 0 (RETURNDATASIZE)) (STOP) )} # noqa: E501 @@ -66,7 +62,7 @@ def test_call_then_create_successful_then_returndatasize( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x24B406508240D6F2783499D1FD65FEDD0FEEEF37, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -86,9 +82,7 @@ def test_call_then_create_successful_then_returndatasize( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0xCC5FBABB1E86F7744ED4840B4153736D3C0AE2A2), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_clear_return_buffer.py b/tests/ported_static/stReturnDataTest/test_clear_return_buffer.py index 254e8928038..dbe6e759b27 100644 --- a/tests/ported_static/stReturnDataTest/test_clear_return_buffer.py +++ b/tests/ported_static/stReturnDataTest/test_clear_return_buffer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -1061,9 +1060,7 @@ def test_clear_return_buffer( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x48DC5A9F099CAAAA557742CA3A990A94BE45B9969126A1BC74E5E8BE5A2B5B47 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE, nonce=1) env = Environment( fee_recipient=coinbase, @@ -1089,7 +1086,6 @@ def test_clear_return_buffer( + Op.RETURN, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0xBD0BB2600F59ACDEE19A917DB4F3F7B00C9C9759), # noqa: E501 ) # Source: yul # berlin @@ -1106,7 +1102,6 @@ def test_clear_return_buffer( + Op.REVERT, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x4C24D17E84F86907F0A33776F83C754D52E46D13), # noqa: E501 ) # Source: yul # berlin @@ -1135,7 +1130,6 @@ def test_clear_return_buffer( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x4940BB1DE279F6B55DC0BF40ED1FDEF517D8C2E9), # noqa: E501 ) # Source: yul # berlin @@ -1164,7 +1158,6 @@ def test_clear_return_buffer( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x0FABE6F4DFA10093ECD1C05DF08EE0B199F2F36D), # noqa: E501 ) # Source: yul # berlin @@ -1182,7 +1175,6 @@ def test_clear_return_buffer( code=bytes.fromhex("602060008181808035833582525af1503078464500"), balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x421AB4BF2FF9BD61E45075062AEC737A6F1B726D), # noqa: E501 ) # Source: yul # berlin @@ -1460,9 +1452,7 @@ def test_clear_return_buffer( storage={0: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x48DB33B0A06DD1E98DF44D8BEF0DA3F1D948571D), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) tx_data = [ Bytes("048071d3") + Hash(0x11F0) + Hash(0xF3F3) + Hash(0x20), diff --git a/tests/ported_static/stReturnDataTest/test_create_callprecompile_returndatasize.py b/tests/ported_static/stReturnDataTest/test_create_callprecompile_returndatasize.py index c724da2953d..b220fda28c6 100644 --- a/tests/ported_static/stReturnDataTest/test_create_callprecompile_returndatasize.py +++ b/tests/ported_static/stReturnDataTest/test_create_callprecompile_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_callprecompile_returndatasize( ) -> None: """Test_create_callprecompile_returndatasize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_create_callprecompile_returndatasize( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x9898DD5E5C526B55EC49B1047E298705C13279F1), # noqa: E501 ) # Source: lll # { (seq (CREATE 0 0 (lll (seq (mstore 0 0x112233) (CALL 0x9000 4 0 0 32 0 32) (SSTORE 0 (RETURNDATASIZE)) (RETURN 0 32) (STOP) ) 0)) (SSTORE 0 (RETURNDATASIZE)) (STOP) )} # noqa: E501 @@ -87,9 +83,7 @@ def test_create_callprecompile_returndatasize( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0xA2412B1E2A1E23E8FD87F52566C8A89F48682676), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_modexp_modsize0_returndatasize.py b/tests/ported_static/stReturnDataTest/test_modexp_modsize0_returndatasize.py index 9209d1f3b21..b5f159459d4 100644 --- a/tests/ported_static/stReturnDataTest/test_modexp_modsize0_returndatasize.py +++ b/tests/ported_static/stReturnDataTest/test_modexp_modsize0_returndatasize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -77,9 +76,7 @@ def test_modexp_modsize0_returndatasize( ) -> None: """Test_modexp_modsize0_returndatasize.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -111,9 +108,7 @@ def test_modexp_modsize0_returndatasize( + Op.STOP, storage={3: 0xFFFFFFFF}, nonce=0, - address=Address(0x4263C26963E4C1DD1CB69C116009E749F9E4EEC2), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_0_0_following_successful_create.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_0_0_following_successful_create.py index d6ff2c451ff..c964d6505be 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_0_0_following_successful_create.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_0_0_following_successful_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_returndatacopy_0_0_following_successful_create( """Test_returndatacopy_0_0_following_successful_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_returndatacopy_0_0_following_successful_create( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_callcode.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_callcode.py index 877fbe70c32..cc1baaf8c72 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_callcode.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_callcode.py @@ -50,13 +50,22 @@ def test_returndatacopy_after_failing_callcode( ) pre[addr] = Account(balance=0x10000000) + pre[sender] = Account(balance=0x6400000000) + # Source: raw + # 0xfd + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.REVERT, + balance=0x6400000000, + nonce=0, + address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 + ) # Source: lll # { (CALLCODE 0 0 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) (SSTORE 0 (MLOAD 0))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0x0, - address=0x665521FD750490FD880EE369C267FCA44ED8A078, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -71,15 +80,6 @@ def test_returndatacopy_after_failing_callcode( nonce=0, address=Address(0x24878B81DD27C2D76258B421ACDDF26835BC1484), # noqa: E501 ) - # Source: raw - # 0xfd - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.REVERT, - balance=0x6400000000, - nonce=0, - address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 - ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_create.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_create.py index 46b78f692c5..027801052a2 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_create.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatacopy_after_failing_create( ) -> None: """Returndatacopy after failing create case due to 0xfd code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_returndatacopy_after_failing_create( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x1F2642DD423C1BAC7E318EE8DF07608C3216D725), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_delegatecall.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_delegatecall.py index 52902c450df..0ae7ed51e33 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_delegatecall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_delegatecall.py @@ -50,13 +50,22 @@ def test_returndatacopy_after_failing_delegatecall( ) pre[addr] = Account(balance=0x100000) + pre[sender] = Account(balance=0x6400000000) + # Source: raw + # 0xfd + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.REVERT, + balance=0x6400000000, + nonce=0, + address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 + ) # Source: lll # { (DELEGATECALL 10000 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) ( SSTORE 0 (MLOAD 0))} # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0x2710, - address=0x665521FD750490FD880EE369C267FCA44ED8A078, + address=addr_3, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -72,15 +81,6 @@ def test_returndatacopy_after_failing_delegatecall( nonce=0, address=Address(0x5242F2AD00427020024F504AE629E0576CA6A01A), # noqa: E501 ) - # Source: raw - # 0xfd - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.REVERT, - balance=0x6400000000, - nonce=0, - address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 - ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_staticcall.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_staticcall.py index 141faf2ddfb..909dbeba72b 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_staticcall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_failing_staticcall.py @@ -50,13 +50,24 @@ def test_returndatacopy_after_failing_staticcall( ) pre[addr] = Account(balance=0x100000) + pre[sender] = Account(balance=0x6400000000) + # Source: lll + # { (MSTORE 0x0 (CALLER)) (RETURN 0 32) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLER) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=0x6400000000, + nonce=0, + address=Address(0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD), # noqa: E501 + ) # Source: lll # { (STATICCALL 0 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) ( SSTORE 0 (MLOAD 0))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0x0, - address=0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -72,17 +83,6 @@ def test_returndatacopy_after_failing_staticcall( nonce=0, address=Address(0x7ACAE812141B61313BEA3D8B33B2F9C69F4E6720), # noqa: E501 ) - # Source: lll - # { (MSTORE 0x0 (CALLER)) (RETURN 0 32) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLER) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD), # noqa: E501 - ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_revert_in_staticcall.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_revert_in_staticcall.py index 042cbcb5917..ef29d6c7990 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_revert_in_staticcall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_revert_in_staticcall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_returndatacopy_after_revert_in_staticcall( ) -> None: """Test_returndatacopy_after_revert_in_staticcall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x6C7410DA158FA432392FCAD5989E1B28280F99D8) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,23 @@ def test_returndatacopy_after_revert_in_staticcall( gas_limit=111669149696, ) - pre[addr] = Account(balance=0x1000000) + addr = pre.fund_eoa(amount=0x1000000) # noqa: F841 + # Source: lll + # { (MSTORE 0x0 (CALLER)) (REVERT 0 32) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLER) + + Op.REVERT(offset=0x0, size=0x20) + + Op.STOP, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (STATICCALL 60000 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) ( SSTORE 0 (MLOAD 0))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0xEA60, - address=0x3706580D60F246111E3848FFBA4F4AB76C9A01E8, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,19 +75,7 @@ def test_returndatacopy_after_revert_in_staticcall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0x4BEDF636CB41E5DCF09D038DE843004824DFBB3A), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0x0 (CALLER)) (REVERT 0 32) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLER) - + Op.REVERT(offset=0x0, size=0x20) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x3706580D60F246111E3848FFBA4F4AB76C9A01E8), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, @@ -91,10 +84,6 @@ def test_returndatacopy_after_revert_in_staticcall( gas_limit=100000, ) - post = { - target: Account( - storage={0: 0x4BEDF636CB41E5DCF09D038DE843004824DFBB3A}, - ), - } + post = {target: Account(storage={0: target})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_callcode.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_callcode.py index d1ebd26a452..513523a49f7 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_callcode.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_callcode.py @@ -48,13 +48,27 @@ def test_returndatacopy_after_successful_callcode( gas_limit=111669149696, ) + pre[sender] = Account(balance=0x6400000000) + # Source: lll + # { (MSTORE 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (RETURN 0 32) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=0x6400000000, + nonce=0, + address=Address(0x53B272D553D8179D017AAE6F3BADF0570743593A), # noqa: E501 + ) # Source: lll # { (CALLCODE 60000 0 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) (SSTORE 0 (MLOAD 0))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0xEA60, - address=0x53B272D553D8179D017AAE6F3BADF0570743593A, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,20 +83,6 @@ def test_returndatacopy_after_successful_callcode( nonce=0, address=Address(0x7E319028B16C006ECC1B068CCE1A1C9B0B457B0D), # noqa: E501 ) - # Source: lll - # { (MSTORE 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (RETURN 0 32) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x53B272D553D8179D017AAE6F3BADF0570743593A), # noqa: E501 - ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_delegatecall.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_delegatecall.py index 0aa89b298c5..15043eaf87a 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_delegatecall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_delegatecall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatacopy_after_successful_delegatecall( ) -> None: """Test_returndatacopy_after_successful_delegatecall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,22 @@ def test_returndatacopy_after_successful_delegatecall( gas_limit=111669149696, ) + # Source: lll + # { (MSTORE 0x0 (CALLER)) (RETURN 0 32) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLER) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (DELEGATECALL 60000 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) ( SSTORE 0 (MLOAD 0))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0xEA60, - address=0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,19 +74,7 @@ def test_returndatacopy_after_successful_delegatecall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0xB669C96E9E7CCFD69D0FD0FFCF9260E9D1E6F5C4), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0x0 (CALLER)) (RETURN 0 32) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLER) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, @@ -89,10 +83,6 @@ def test_returndatacopy_after_successful_delegatecall( gas_limit=100000, ) - post = { - target: Account( - storage={0: 0xC102734F6A1E4747310179C0A0FC16E674AA901D}, - ), - } + post = {target: Account(storage={0: sender})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_staticcall.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_staticcall.py index 7bfb2fcf9f3..95a483a7e4a 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_staticcall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_after_successful_staticcall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_returndatacopy_after_successful_staticcall( ) -> None: """Test_returndatacopy_after_successful_staticcall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x6C7410DA158FA432392FCAD5989E1B28280F99D8) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,23 @@ def test_returndatacopy_after_successful_staticcall( gas_limit=111669149696, ) - pre[addr] = Account(balance=0x1000000) + addr = pre.fund_eoa(amount=0x1000000) # noqa: F841 + # Source: lll + # { (MSTORE 0x0 (CALLER)) (RETURN 0 32) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLER) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (STATICCALL 60000 0 0 0 0) (RETURNDATACOPY 0x0 0x0 32) ( SSTORE 0 (MLOAD 0))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0xEA60, - address=0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,19 +75,7 @@ def test_returndatacopy_after_successful_staticcall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0x4BEDF636CB41E5DCF09D038DE843004824DFBB3A), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0x0 (CALLER)) (RETURN 0 32) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLER) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x52FD0CBC013EE33577EEC035031DBC4489A1E0BD), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, @@ -91,10 +84,6 @@ def test_returndatacopy_after_successful_staticcall( gas_limit=100000, ) - post = { - target: Account( - storage={0: 0x4BEDF636CB41E5DCF09D038DE843004824DFBB3A}, - ), - } + post = {target: Account(storage={0: target})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_call.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_call.py index fd8e16e7fd6..68bd5870c13 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_call.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_call.py @@ -46,6 +46,7 @@ def test_returndatacopy_following_call( gas_limit=111669149696, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (seq (MSTORE 0 0x0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff) (RETURN 0 32)) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -64,7 +65,7 @@ def test_returndatacopy_following_call( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x9898DD5E5C526B55EC49B1047E298705C13279F1, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -79,7 +80,6 @@ def test_returndatacopy_following_call( nonce=0, address=Address(0x2FAF9D2A81304665C9A06A42935DDC42B24F488B), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_create.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_create.py index f39d48ec707..80fa6443230 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_create.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatacopy_following_create( ) -> None: """Test_returndatacopy_following_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_returndatacopy_following_create( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x9898DD5E5C526B55EC49B1047E298705C13279F1), # noqa: E501 ) # Source: lll # { (seq (create (STOP)) (RETURNDATACOPY 0 0 32) (SSTORE 0 (MLOAD 0)) )} @@ -79,9 +75,7 @@ def test_returndatacopy_following_create( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0xB2F12F3B77DAD19C11029CB8EE4EECB144E05AD3), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_failing_call.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_failing_call.py index 568faf33ab5..81196af2f6b 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_failing_call.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_failing_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatacopy_following_failing_call( ) -> None: """Test_returndatacopy_following_failing_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -53,7 +50,6 @@ def test_returndatacopy_following_failing_call( addr = pre.deploy_contract( # noqa: F841 code=Op.REVERT, nonce=0, - address=Address(0x3141BB954E8294E47A14EBD08229F30E6294BA83), # noqa: E501 ) # Source: lll # { (CALL 0x0900000000 0 0 0 0 0) (RETURNDATACOPY 0 1 32) (SSTORE 0 (MLOAD 0)) } # noqa: E501 @@ -61,7 +57,7 @@ def test_returndatacopy_following_failing_call( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x3141BB954E8294E47A14EBD08229F30E6294BA83, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -74,9 +70,7 @@ def test_returndatacopy_following_failing_call( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x71A277F82C43FF98682EB8D6DB4A3ECD680407EB), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert.py index a2121b9b101..d9dfc787585 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert.py @@ -48,6 +48,7 @@ def test_returndatacopy_following_revert( gas_limit=111669149696, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (seq (MSTORE 0 0x0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff) (REVERT 0 32)) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -66,7 +67,7 @@ def test_returndatacopy_following_revert( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x2159735BA26480ADC67F0EE9D4A05E5405A5CF83, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -81,7 +82,6 @@ def test_returndatacopy_following_revert( nonce=0, address=Address(0x2FAF9D2A81304665C9A06A42935DDC42B24F488B), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert_in_create.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert_in_create.py index 30ded33f7c6..868ae13c14e 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert_in_create.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_revert_in_create.py @@ -48,6 +48,7 @@ def test_returndatacopy_following_revert_in_create( gas_limit=111669149696, ) + pre[sender] = Account(balance=0x6400000000) # Source: lll # { (seq (CREATE 0 0 (lll (seq (MSTORE 0 0x0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff) (REVERT 0 32) (STOP) ) 0)) (RETURNDATACOPY 0 0 32) (SSTORE 0 (MLOAD 0)) (STOP) )} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,7 +70,6 @@ def test_returndatacopy_following_revert_in_create( nonce=0, address=Address(0x70B8403604734D52990000D1503D165B056DC00A), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_successful_create.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_successful_create.py index 09e5f12003f..997d56258ec 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_successful_create.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_successful_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatacopy_following_successful_create( ) -> None: """Test_returndatacopy_following_successful_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -67,9 +64,7 @@ def test_returndatacopy_following_successful_create( + Op.STOP * 2, storage={0: 2}, nonce=0, - address=Address(0xBABE109963095EFA4C742D15426F841A7033D6AA), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_too_big_transfer.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_too_big_transfer.py index 83a4c8018d6..e3dd5b68dbb 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_following_too_big_transfer.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_following_too_big_transfer.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatacopy_following_too_big_transfer( ) -> None: """Test: tis test tries RETURNDATACOPY with a non-zero size after a CALL...""" # noqa: E501 coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,7 +55,6 @@ def test_returndatacopy_following_too_big_transfer( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x9898DD5E5C526B55EC49B1047E298705C13279F1), # noqa: E501 ) # Source: lll # { (seq (CALL 0x0900000000 10000000 0 0 0 0) (RETURNDATACOPY 0 0 32) (SSTORE 0 200) )} # noqa: E501 @@ -66,7 +62,7 @@ def test_returndatacopy_following_too_big_transfer( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x9898DD5E5C526B55EC49B1047E298705C13279F1, + address=addr, value=0x989680, args_offset=0x0, args_size=0x0, @@ -79,9 +75,7 @@ def test_returndatacopy_following_too_big_transfer( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x386E9FC96C1E60F449C2DF320F37545CCA30F58D), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_initial.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_initial.py index 154bc32035b..57f9089b05f 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_initial.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_initial.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_returndatacopy_initial( ) -> None: """Test_returndatacopy_initial.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -56,9 +53,7 @@ def test_returndatacopy_initial( storage={0: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7D970B9AD2E5F64518FF774031441F22B78BE4C7), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_256.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_256.py index a4b18bb5286..30e351e733b 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_256.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_256.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_returndatacopy_initial_256( ) -> None: """Test_returndatacopy_initial_256.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -88,9 +85,7 @@ def test_returndatacopy_initial_256( storage={0: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x28F194B678152B435B5910DBDF69C091FA056347), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx_data = [ Hash(0x64), diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_big_sum.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_big_sum.py index c9bbeb936d4..02be12ee8d9 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_big_sum.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_initial_big_sum.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_returndatacopy_initial_big_sum( ) -> None: """Test_returndatacopy_initial_big_sum.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -58,9 +55,7 @@ def test_returndatacopy_initial_big_sum( storage={0: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3C975790C6CBB489AE5EAF7AF45202F98DFFCCDF), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatacopy_overrun.py b/tests/ported_static/stReturnDataTest/test_returndatacopy_overrun.py index bc3789859a1..3ba3a5f8f16 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatacopy_overrun.py +++ b/tests/ported_static/stReturnDataTest/test_returndatacopy_overrun.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_returndatacopy_overrun( ) -> None: """Test_returndatacopy_overrun.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -56,7 +53,6 @@ def test_returndatacopy_overrun( + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, nonce=0, - address=Address(0x9898DD5E5C526B55EC49B1047E298705C13279F1), # noqa: E501 ) # Source: lll # { (seq (CALL 0x0900000000 0 0 0 0 0) (RETURNDATACOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc 100) (SSTORE 0 (MLOAD 0)) )} # noqa: E501 @@ -64,7 +60,7 @@ def test_returndatacopy_overrun( code=Op.POP( Op.CALL( gas=0x900000000, - address=0x9898DD5E5C526B55EC49B1047E298705C13279F1, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -81,9 +77,7 @@ def test_returndatacopy_overrun( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x36E328ACF112F37630C605BB27C130C5646D2915), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_callcode.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_callcode.py index bcaf88ed0c1..de632358bed 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_callcode.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_callcode.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_returndatasize_after_failing_callcode( ) -> None: """Test_returndatasize_after_failing_callcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x285D0814904BEBB3B4ADD3B531A07647C2D08F59) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,21 @@ def test_returndatasize_after_failing_callcode( gas_limit=111669149696, ) - pre[addr] = Account(balance=0x10000000) + addr = pre.fund_eoa(amount=0x10000000) # noqa: F841 + # Source: raw + # 0xfd + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.REVERT, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (seq (CALLCODE 100000 0 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0x186A0, - address=0x665521FD750490FD880EE369C267FCA44ED8A078, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -68,17 +71,7 @@ def test_returndatasize_after_failing_callcode( + Op.STOP, storage={0: 0xFFFFFFFF}, nonce=0, - address=Address(0x716E4812F69C442687F8917638E10BBE6EB00592), # noqa: E501 - ) - # Source: raw - # 0xfd - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.REVERT, - balance=0x6400000000, - nonce=0, - address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_delegatecall.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_delegatecall.py index d2d9054921e..0a551cfeadc 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_delegatecall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_delegatecall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_returndatasize_after_failing_delegatecall( ) -> None: """Test_returndatasize_after_failing_delegatecall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x6C7410DA158FA432392FCAD5989E1B28280F99D8) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,21 @@ def test_returndatasize_after_failing_delegatecall( gas_limit=111669149696, ) - pre[addr] = Account(balance=0x1000000) + addr = pre.fund_eoa(amount=0x1000000) # noqa: F841 + # Source: raw + # 0xfd + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.REVERT, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (seq (DELEGATECALL 10000 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0x2710, - address=0x665521FD750490FD880EE369C267FCA44ED8A078, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,17 +72,7 @@ def test_returndatasize_after_failing_delegatecall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0xACB6AD74F94EA8C5A482F1E89D1C0946600A9888), # noqa: E501 - ) - # Source: raw - # 0xfd - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.REVERT, - balance=0x6400000000, - nonce=0, - address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_staticcall.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_staticcall.py index a0900a3eb6a..9b36f269ef6 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_staticcall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_failing_staticcall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_returndatasize_after_failing_staticcall( ) -> None: """Test_returndatasize_after_failing_staticcall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x905C744ACAF4D8F5436C9C5E91E0626D44ADD821) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,21 @@ def test_returndatasize_after_failing_staticcall( gas_limit=111669149696, ) - pre[addr] = Account(balance=0x100000) + addr = pre.fund_eoa(amount=0x100000) # noqa: F841 + # Source: raw + # 0xfd + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.REVERT, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (seq (STATICCALL 60000 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0xEA60, - address=0x665521FD750490FD880EE369C267FCA44ED8A078, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,17 +72,7 @@ def test_returndatasize_after_failing_staticcall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0xB59B41F3A1359DD85455601DB8E79F621D7E63F6), # noqa: E501 - ) - # Source: raw - # 0xfd - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.REVERT, - balance=0x6400000000, - nonce=0, - address=Address(0x665521FD750490FD880EE369C267FCA44ED8A078), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_oog_after_deeper.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_oog_after_deeper.py index e6e10aaf816..ef7389b390c 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_oog_after_deeper.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_oog_after_deeper.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_returndatasize_after_oog_after_deeper( ) -> None: """Transaction calls A (CALL B(CALL C(RETURN) OOG) 'check buffers').""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0xBDA572E15071B6AB42CFEC01423F1FBB1DE68703) - sender = EOA( - key=0x987C63506890B18862BD2304513F21B726A7E35961C9214954326694141FDB46 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -49,28 +45,14 @@ def test_returndatasize_after_oog_after_deeper( gas_limit=111669149696, ) - pre[addr] = Account(balance=0x1000000000) + addr = pre.fund_eoa(amount=0x1000000000) # noqa: F841 # Source: lll - # { (seq (SSTORE 2 (CALL 100000 0 0 0 0 32)) (SSTORE 0 (RETURNDATASIZE))) (SSTORE 1 (MLOAD 0))} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x186A0, - address=0xCB33B9A773995316746A40201081D054635D02DA, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x20, - ), - ) - + Op.SSTORE(key=0x0, value=Op.RETURNDATASIZE) - + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) + # { (seq (MSTORE 0 255) (RETURN 0 32) )} + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0xFF) + + Op.RETURN(offset=0x0, size=0x20) + Op.STOP, - storage={0: 0xFFFFFFFF, 1: 0xFFFFFFFF, 2: 0xFFFFFFFF}, nonce=0, - address=Address(0x58EAA3041AD52C24E38E485222953F1CC19C7484), # noqa: E501 ) # Source: lll # { (seq (CALL 100000 0 0 0 0 0) (while 1 (SSTORE 0 1)) )} # noqa: E501 @@ -78,7 +60,7 @@ def test_returndatasize_after_oog_after_deeper( code=Op.POP( Op.CALL( gas=0x186A0, - address=0x8E0C75135225713D8C9ACBB889ABBA5A5F598920, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x0, @@ -94,17 +76,27 @@ def test_returndatasize_after_oog_after_deeper( + Op.STOP, balance=0x6400000000, nonce=0, - address=Address(0xCB33B9A773995316746A40201081D054635D02DA), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) # Source: lll - # { (seq (MSTORE 0 255) (RETURN 0 32) )} - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0xFF) - + Op.RETURN(offset=0x0, size=0x20) + # { (seq (SSTORE 2 (CALL 100000 0 0 0 0 32)) (SSTORE 0 (RETURNDATASIZE))) (SSTORE 1 (MLOAD 0))} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=0x186A0, + address=addr_2, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x20, + ), + ) + + Op.SSTORE(key=0x0, value=Op.RETURNDATASIZE) + + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x0)) + Op.STOP, + storage={0: 0xFFFFFFFF, 1: 0xFFFFFFFF, 2: 0xFFFFFFFF}, nonce=0, - address=Address(0x8E0C75135225713D8C9ACBB889ABBA5A5F598920), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_callcode.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_callcode.py index 0363ef0790b..e862fa26864 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_callcode.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_callcode.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatasize_after_successful_callcode( ) -> None: """Test_returndatasize_after_successful_callcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,25 @@ def test_returndatasize_after_successful_callcode( gas_limit=111669149696, ) + # Source: lll + # { (MSTORE 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (RETURN 0 6) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.RETURN(offset=0x0, size=0x6) + + Op.STOP, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (seq (CALLCODE 60000 0 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0xEA60, - address=0xC6426EE9B84CE08176D8D295613A7D10C48576B, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,22 +75,7 @@ def test_returndatasize_after_successful_callcode( + Op.STOP, storage={0: 0}, nonce=0, - address=Address(0xC8005FEC752AB6F5F4691BB1A54DCCE7EE3D1EB9), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (RETURN 0 6) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.RETURN(offset=0x0, size=0x6) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x0C6426EE9B84CE08176D8D295613A7D10C48576B), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_delegatecall.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_delegatecall.py index d079b091aa9..fe1909c48d1 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_delegatecall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_delegatecall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatasize_after_successful_delegatecall( ) -> None: """Test_returndatasize_after_successful_delegatecall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,22 @@ def test_returndatasize_after_successful_delegatecall( gas_limit=111669149696, ) + # Source: lll + # { (MSTORE 0x0 (CALLER)) (RETURN 0 20) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLER) + + Op.RETURN(offset=0x0, size=0x14) + + Op.STOP, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (seq (DELEGATECALL 60000 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0xEA60, - address=0x7C17DBBFA29DC8391BFA19022ECB4FDA54FC826A, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -67,19 +73,7 @@ def test_returndatasize_after_successful_delegatecall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0x1C7CCE7753E67952A031524E6505E53F170520BE), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0x0 (CALLER)) (RETURN 0 20) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLER) - + Op.RETURN(offset=0x0, size=0x14) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x7C17DBBFA29DC8391BFA19022ECB4FDA54FC826A), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_staticcall.py b/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_staticcall.py index 10e705d58d5..1725dba694e 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_staticcall.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_after_successful_staticcall.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatasize_after_successful_staticcall( ) -> None: """Test_returndatasize_after_successful_staticcall.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,25 @@ def test_returndatasize_after_successful_staticcall( gas_limit=111669149696, ) + # Source: lll + # { (MSTORE 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (RETURN 0 6) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.RETURN(offset=0x0, size=0x6) + + Op.STOP, + balance=0x6400000000, + nonce=0, + ) # Source: lll # { (seq (STATICCALL 60000 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)))} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0xEA60, - address=0xC6426EE9B84CE08176D8D295613A7D10C48576B, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -67,22 +76,7 @@ def test_returndatasize_after_successful_staticcall( 0: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 }, nonce=0, - address=Address(0xB59B41F3A1359DD85455601DB8E79F621D7E63F6), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0x0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (RETURN 0 6) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.RETURN(offset=0x0, size=0x6) - + Op.STOP, - balance=0x6400000000, - nonce=0, - address=Address(0x0C6426EE9B84CE08176D8D295613A7D10C48576B), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_bug.py b/tests/ported_static/stReturnDataTest/test_returndatasize_bug.py index 70a1ddf41bc..d19f6656947 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_bug.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_bug.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_returndatasize_bug( ) -> None: """RETURNDATASIZE after a failing CALL (due to insufficient balance)...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -47,12 +44,12 @@ def test_returndatasize_bug( ) # Source: lll - # { (CALL 1 50000 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (CALL 10 1 50000 0 0 0 0) (SSTORE 1 1) } + addr = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( - gas=0x1, - address=0xA6DE4978FAA392285CC6411DFE442872304DEB1, + gas=0xA, + address=0x1, value=0xC350, args_offset=0x0, args_size=0x0, @@ -60,20 +57,17 @@ def test_returndatasize_bug( ret_size=0x0, ) ) - + Op.SSTORE(key=0x0, value=Op.RETURNDATASIZE) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - storage={0: 1}, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0D7BC2FBD330F7D4EC71764551A8B9CFB11619F5), # noqa: E501 ) # Source: lll - # { (CALL 10 1 50000 0 0 0 0) (SSTORE 1 1) } - addr = pre.deploy_contract( # noqa: F841 + # { (CALL 1 50000 0 0 0 0) (SSTORE 0 (RETURNDATASIZE)) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( - gas=0xA, - address=0x1, + gas=0x1, + address=addr, value=0xC350, args_offset=0x0, args_size=0x0, @@ -81,12 +75,12 @@ def test_returndatasize_bug( ret_size=0x0, ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.SSTORE(key=0x0, value=Op.RETURNDATASIZE) + Op.STOP, + storage={0: 1}, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0A6DE4978FAA392285CC6411DFE442872304DEB1), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_following_successful_create.py b/tests/ported_static/stReturnDataTest/test_returndatasize_following_successful_create.py index 2ed2ecf0c7a..0fe11d444fb 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_following_successful_create.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_following_successful_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_returndatasize_following_successful_create( ) -> None: """Test_returndatasize_following_successful_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -63,9 +60,7 @@ def test_returndatasize_following_successful_create( + Op.STOP * 2, storage={0: 1}, nonce=0, - address=Address(0xE7E262CA8EF9761ACCA450874326B1F3F483A73F), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_initial.py b/tests/ported_static/stReturnDataTest/test_returndatasize_initial.py index 4bec111f2c0..b347d992e05 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_initial.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_initial.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_returndatasize_initial( ) -> None: """Test_returndatasize_initial.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_returndatasize_initial( storage={0: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3A939FCCA7DA8B1332893BCCA91690406F4B7A82), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_returndatasize_initial_zero_read.py b/tests/ported_static/stReturnDataTest/test_returndatasize_initial_zero_read.py index 82e2eea989d..13248ea8d42 100644 --- a/tests/ported_static/stReturnDataTest/test_returndatasize_initial_zero_read.py +++ b/tests/ported_static/stReturnDataTest/test_returndatasize_initial_zero_read.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,9 +56,7 @@ def test_returndatasize_initial_zero_read( ) -> None: """Test_returndatasize_initial_zero_read.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -79,9 +76,7 @@ def test_returndatasize_initial_zero_read( storage={0: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x537CD1744AF41C3A74D5AA5AE93958D1160CA98F), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stReturnDataTest/test_revert_ret_data_size.py b/tests/ported_static/stReturnDataTest/test_revert_ret_data_size.py index 520ad4a4f47..d5094abc709 100644 --- a/tests/ported_static/stReturnDataTest/test_revert_ret_data_size.py +++ b/tests/ported_static/stReturnDataTest/test_revert_ret_data_size.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -266,9 +265,7 @@ def test_revert_ret_data_size( contract_3 = Address(0x0000000000000000000000000000000000000300) contract_4 = Address(0x0000000000000000000000000000000000000400) contract_5 = Address(0x0000000000000000000000000000000000000500) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -279,6 +276,54 @@ def test_revert_ret_data_size( gas_limit=100000000, ) + # Source: lll + # { + # [0x00] (/ (- 0 1) 2) + # [0x20] (+ @0x00 1) + # + # (return 0 0x40) + # } + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.DIV(Op.SUB(0x0, 0x1), 0x2)) + + Op.MSTORE(offset=0x20, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) + + Op.RETURN(offset=0x0, size=0x40) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000001000), # noqa: E501 + ) + # Source: raw + # 0x5000 + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000000200), # noqa: E501 + ) + # Source: raw + # 0x600056 + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.JUMP(pc=0x0), + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000000300), # noqa: E501 + ) + # Source: raw + # 0x6001600157 + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI(pc=0x1, condition=0x1), + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000000400), # noqa: E501 + ) + # Source: raw + # 0xFE00 + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.INVALID + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000000500), # noqa: E501 + ) # Source: lll # { ; $4 is the type of thing that fails # ; $36 is the failure itself @@ -722,55 +767,6 @@ def test_revert_ret_data_size( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - # Source: lll - # { - # [0x00] (/ (- 0 1) 2) - # [0x20] (+ @0x00 1) - # - # (return 0 0x40) - # } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.DIV(Op.SUB(0x0, 0x1), 0x2)) - + Op.MSTORE(offset=0x20, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) - + Op.RETURN(offset=0x0, size=0x40) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000001000), # noqa: E501 - ) - # Source: raw - # 0x5000 - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000000200), # noqa: E501 - ) - # Source: raw - # 0x600056 - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.JUMP(pc=0x0), - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000000300), # noqa: E501 - ) - # Source: raw - # 0x6001600157 - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI(pc=0x1, condition=0x1), - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000000400), # noqa: E501 - ) - # Source: raw - # 0xFE00 - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.INVALID + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000000500), # noqa: E501 - ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("1a8451e6") + Hash(0xF1) + Hash(0x0), diff --git a/tests/ported_static/stReturnDataTest/test_subcall_return_more_then_expected.py b/tests/ported_static/stReturnDataTest/test_subcall_return_more_then_expected.py index d4f8c030888..1f2141adffe 100644 --- a/tests/ported_static/stReturnDataTest/test_subcall_return_more_then_expected.py +++ b/tests/ported_static/stReturnDataTest/test_subcall_return_more_then_expected.py @@ -46,6 +46,49 @@ def test_subcall_return_more_then_expected( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { + # (MSTORE 0 0x1122334455667788991011121314151617181920212223242526272829303132) # noqa: E501 + # (MSTORE 32 0x3334353637383940414243444546474849505152535455565758596061626364) # noqa: E501 + # (RETURN 0 64) + # } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0x1122334455667788991011121314151617181920212223242526272829303132, # noqa: E501 + ) + + Op.MSTORE( + offset=0x20, + value=0x3334353637383940414243444546474849505152535455565758596061626364, # noqa: E501 + ) + + Op.RETURN(offset=0x0, size=0x40) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xA8592F39B32943F9F464090497722B4F9C15F598), # noqa: E501 + ) + # Source: lll + # { + # (MSTORE 0 0x1122334455667788991011121314151617181920212223242526272829303132) # noqa: E501 + # (MSTORE 32 0x3334353637383940414243444546474849505152535455565758596061626364) # noqa: E501 + # (REVERT 0 64) + # } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0x1122334455667788991011121314151617181920212223242526272829303132, # noqa: E501 + ) + + Op.MSTORE( + offset=0x20, + value=0x3334353637383940414243444546474849505152535455565758596061626364, # noqa: E501 + ) + + Op.REVERT(offset=0x0, size=0x40) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x028CDAFC3D5D27D006FFB88E1ECF2FA4B412EE4F), # noqa: E501 + ) # Source: lll # { # ;; Get returndata from a subcall @@ -79,7 +122,7 @@ def test_subcall_return_more_then_expected( code=Op.POP( Op.CALL( gas=0x30D40, - address=0xA8592F39B32943F9F464090497722B4F9C15F598, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -92,7 +135,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.DELEGATECALL( gas=0x30D40, - address=0xA8592F39B32943F9F464090497722B4F9C15F598, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -104,7 +147,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.STATICCALL( gas=0x30D40, - address=0xA8592F39B32943F9F464090497722B4F9C15F598, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -116,7 +159,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.CALLCODE( gas=0x30D40, - address=0xA8592F39B32943F9F464090497722B4F9C15F598, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -129,7 +172,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.CALL( gas=0x30D40, - address=0x28CDAFC3D5D27D006FFB88E1ECF2FA4B412EE4F, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -142,7 +185,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.DELEGATECALL( gas=0x30D40, - address=0x28CDAFC3D5D27D006FFB88E1ECF2FA4B412EE4F, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -154,7 +197,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.STATICCALL( gas=0x30D40, - address=0x28CDAFC3D5D27D006FFB88E1ECF2FA4B412EE4F, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -166,7 +209,7 @@ def test_subcall_return_more_then_expected( + Op.POP( Op.CALLCODE( gas=0x30D40, - address=0x28CDAFC3D5D27D006FFB88E1ECF2FA4B412EE4F, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -180,49 +223,6 @@ def test_subcall_return_more_then_expected( nonce=0, address=Address(0xCA70835D5E9B8C8E139A9693AB05705D291F86BB), # noqa: E501 ) - # Source: lll - # { - # (MSTORE 0 0x1122334455667788991011121314151617181920212223242526272829303132) # noqa: E501 - # (MSTORE 32 0x3334353637383940414243444546474849505152535455565758596061626364) # noqa: E501 - # (RETURN 0 64) - # } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0x1122334455667788991011121314151617181920212223242526272829303132, # noqa: E501 - ) - + Op.MSTORE( - offset=0x20, - value=0x3334353637383940414243444546474849505152535455565758596061626364, # noqa: E501 - ) - + Op.RETURN(offset=0x0, size=0x40) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xA8592F39B32943F9F464090497722B4F9C15F598), # noqa: E501 - ) - # Source: lll - # { - # (MSTORE 0 0x1122334455667788991011121314151617181920212223242526272829303132) # noqa: E501 - # (MSTORE 32 0x3334353637383940414243444546474849505152535455565758596061626364) # noqa: E501 - # (REVERT 0 64) - # } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0x1122334455667788991011121314151617181920212223242526272829303132, # noqa: E501 - ) - + Op.MSTORE( - offset=0x20, - value=0x3334353637383940414243444546474849505152535455565758596061626364, # noqa: E501 - ) - + Op.REVERT(offset=0x0, size=0x40) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x028CDAFC3D5D27D006FFB88E1ECF2FA4B412EE4F), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stReturnDataTest/test_too_long_return_data_copy.py b/tests/ported_static/stReturnDataTest/test_too_long_return_data_copy.py index 1ff03bc0321..ee261f186bc 100644 --- a/tests/ported_static/stReturnDataTest/test_too_long_return_data_copy.py +++ b/tests/ported_static/stReturnDataTest/test_too_long_return_data_copy.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -191,9 +190,7 @@ def test_too_long_return_data_copy( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4DC42D61413D4DED993826AC4D6ED7A4A970C60335D2B285C60A4274E792FF1 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -228,7 +225,6 @@ def test_too_long_return_data_copy( + Op.PUSH1[0x0] + Op.RETURN, nonce=1, - address=Address(0xA6E4F86617D6AB14D857F9115C2AB9F2787157BA), # noqa: E501 ) # Source: yul # berlin @@ -254,7 +250,6 @@ def test_too_long_return_data_copy( + Op.PUSH1[0x0] + Op.REVERT, nonce=1, - address=Address(0x23EEF957BCFB3738417AEE7FDF4294CF110D7881), # noqa: E501 ) # Source: yul # berlin @@ -307,15 +302,10 @@ def test_too_long_return_data_copy( + Op.PUSH2[0x100] + Op.RETURNDATACOPY + Op.EXTCODECOPY( - address=0xA6E4F86617D6AB14D857F9115C2AB9F2787157BA, + address=addr, dest_offset=Op.DUP1, offset=0x0, - size=Op.ADD( - 0x20, - Op.EXTCODESIZE( - address=0xA6E4F86617D6AB14D857F9115C2AB9F2787157BA - ), - ), + size=Op.ADD(0x20, Op.EXTCODESIZE(address=addr)), ) + Op.CALLDATACOPY( dest_offset=Op.DUP1, offset=0x0, size=Op.ADD(0x20, Op.CALLDATASIZE) @@ -328,9 +318,7 @@ def test_too_long_return_data_copy( storage={0: 24743}, balance=0xDE0B6B3A7640000, nonce=1, - address=Address(0xE4592ED5B9C3A9302D66798E39BFB7DFD44FAFC1), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stRevertTest/test_cost_revert.py b/tests/ported_static/stRevertTest/test_cost_revert.py index c12c2f4a942..7c6fddec42c 100644 --- a/tests/ported_static/stRevertTest/test_cost_revert.py +++ b/tests/ported_static/stRevertTest/test_cost_revert.py @@ -237,6 +237,7 @@ def test_cost_revert( gas_limit=100000000, ) + pre[sender] = Account(balance=0x100000000000) # Source: lll # { # (revert 0 0x10) @@ -469,7 +470,6 @@ def test_cost_revert( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert.py b/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert.py index 71696e7b402..fc4b0089a75 100644 --- a/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert.py +++ b/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_loop_calls_depth_then_revert( ) -> None: """Test_loop_calls_depth_then_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_loop_calls_depth_then_revert( gas_limit=100000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]] (+ (SLOAD 0) 1) (CALL (GAS) 0 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert2.py b/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert2.py index ed6a5e22284..3a2f95fdd05 100644 --- a/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert2.py +++ b/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_loop_calls_depth_then_revert2( """Test_loop_calls_depth_then_revert2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x13426172C74D822B878FE800000000) env = Environment( fee_recipient=coinbase, @@ -49,7 +46,6 @@ def test_loop_calls_depth_then_revert2( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0x13426172C74D822B878FE800000000) # Source: raw # 0x6103ff60005414603f576001600054016000556000600060006000600073a0000000000000000000000000000000000000005af15061041a600054106053575b66600060006002f0600052600760196003f0505b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert3.py b/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert3.py index b00e868bc95..2ebd7d4cec4 100644 --- a/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert3.py +++ b/tests/ported_static/stRevertTest/test_loop_calls_depth_then_revert3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_loop_calls_depth_then_revert3( """Test_loop_calls_depth_then_revert3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x13426172C74D822B878FE800000000) env = Environment( fee_recipient=coinbase, @@ -49,7 +46,6 @@ def test_loop_calls_depth_then_revert3( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0x13426172C74D822B878FE800000000) # Source: raw # 0x6103fe60005414603f576001600054016000556000600060006000600073a0000000000000000000000000000000000000005af15061041a600054106053575b66600060006002f0600052600760196003f0505b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -87,9 +83,10 @@ def test_loop_calls_depth_then_revert3( compute_create_address(address=contract_0, nonce=0): Account( balance=1, nonce=2 ), - Address(0xCD6807039CAFFDDBD1C28A749EC91BEF15F448E5): Account( - balance=2, nonce=1 - ), + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=1, + ): Account(balance=2, nonce=1), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stRevertTest/test_loop_calls_then_revert.py b/tests/ported_static/stRevertTest/test_loop_calls_then_revert.py index 82f49a403f8..c64f15352a7 100644 --- a/tests/ported_static/stRevertTest/test_loop_calls_then_revert.py +++ b/tests/ported_static/stRevertTest/test_loop_calls_then_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_loop_calls_then_revert( ) -> None: """Test_loop_calls_then_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,13 @@ def test_loop_calls_then_revert( gas_limit=100000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { [[0]] (ADD 1 (SLOAD 0)) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) # Source: raw # 0x5b600160005403600055600060006000600060007361c350f150600054600057 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +58,7 @@ def test_loop_calls_then_revert( + Op.POP( Op.CALL( gas=0xC350, - address=0xC47BCBF49DD735566CFDE927821E938D5B33014C, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,15 +69,6 @@ def test_loop_calls_then_revert( + Op.JUMPI(pc=0x0, condition=Op.SLOAD(key=0x0)), storage={0: 850}, nonce=0, - address=Address(0x0347AFF20D9D3C574E18F3B17DC267DDCD2D75CA), # noqa: E501 - ) - # Source: lll - # { [[0]] (ADD 1 (SLOAD 0)) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0xC47BCBF49DD735566CFDE927821E938D5B33014C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_loop_delegate_calls_depth_then_revert.py b/tests/ported_static/stRevertTest/test_loop_delegate_calls_depth_then_revert.py index 39bc63f8f88..1be3fb70d90 100644 --- a/tests/ported_static/stRevertTest/test_loop_delegate_calls_depth_then_revert.py +++ b/tests/ported_static/stRevertTest/test_loop_delegate_calls_depth_then_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_loop_delegate_calls_depth_then_revert( ) -> None: """Test_loop_delegate_calls_depth_then_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_loop_delegate_calls_depth_then_revert( gas_limit=100000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]] (+ (SLOAD 0) 1) (DELEGATECALL (GAS) 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stRevertTest/test_nashatyrev_suicide_revert.py b/tests/ported_static/stRevertTest/test_nashatyrev_suicide_revert.py index 3d38439d3a7..64f7fb297d5 100644 --- a/tests/ported_static/stRevertTest/test_nashatyrev_suicide_revert.py +++ b/tests/ported_static/stRevertTest/test_nashatyrev_suicide_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -32,9 +31,7 @@ def test_nashatyrev_suicide_revert( ) -> None: """Test_nashatyrev_suicide_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -45,7 +42,6 @@ def test_nashatyrev_suicide_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: raw # 0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680639c3674fc14610049578063c040622614610058575b610000565b3461000057610056610067565b005b3461000057610065610147565b005b600060405160a680610200833901809050604051809103906000f080156100005790508073ffffffffffffffffffffffffffffffffffffffff1660405180807f6628290000000000000000000000000000000000000000000000000000000000815250600301905060405180910390207c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018090506000604051808303816000876161da5a03f19250505050610000565b50565b3073ffffffffffffffffffffffffffffffffffffffff1660405180807f6261642829000000000000000000000000000000000000000000000000000000815250600501905060405180910390207c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018090506000604051808303816000876161da5a03f192505050505b56006060604052346000575b608f806100176000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806326121ff014603c575b6000565b3460005760466048565b005b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5600a165627a7a723058203d1a897befde21eff26abc325fb3da2f526bbc99de1c5c857d1835f673744ebd0029a165627a7a72305820850a52b31ec4745b7af15ba3bffdb1ba17f5d9a00a5f263ee287a92b568f534c0029 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +49,6 @@ def test_nashatyrev_suicide_revert( "60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680639c3674fc14610049578063c040622614610058575b610000565b3461000057610056610067565b005b3461000057610065610147565b005b600060405160a680610200833901809050604051809103906000f080156100005790508073ffffffffffffffffffffffffffffffffffffffff1660405180807f6628290000000000000000000000000000000000000000000000000000000000815250600301905060405180910390207c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018090506000604051808303816000876161da5a03f19250505050610000565b50565b3073ffffffffffffffffffffffffffffffffffffffff1660405180807f6261642829000000000000000000000000000000000000000000000000000000815250600501905060405180910390207c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018090506000604051808303816000876161da5a03f192505050505b56006060604052346000575b608f806100176000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806326121ff014603c575b6000565b3460005760466048565b005b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5600a165627a7a723058203d1a897befde21eff26abc325fb3da2f526bbc99de1c5c857d1835f673744ebd0029a165627a7a72305820850a52b31ec4745b7af15ba3bffdb1ba17f5d9a00a5f263ee287a92b568f534c0029" # noqa: E501 ), nonce=0, - address=Address(0xD926BBC3745F0070528FC04CBFD3A2C9F9CA6A19), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_python_revert_test_tue201814_minus_1430.py b/tests/ported_static/stRevertTest/test_python_revert_test_tue201814_minus_1430.py index 72570819b28..f387b5eeabb 100644 --- a/tests/ported_static/stRevertTest/test_python_revert_test_tue201814_minus_1430.py +++ b/tests/ported_static/stRevertTest/test_python_revert_test_tue201814_minus_1430.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_python_revert_test_tue201814_minus_1430( ) -> None: """A random test that had failed in Python ethereum implementation.""" coinbase = Address(0xF7B2E80637A148B5E46945E29388928DAFD5AA25) - sender = EOA( - key=0x3E297DF41E49C542F54718BBEE92D449778686880729C852F6D2C3C40D135341 - ) + sender = pre.fund_eoa(amount=0xAB56295C9D120548) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,100 @@ def test_python_revert_test_tue201814_minus_1430( gas_limit=5805800386153628, ) + # Source: raw + # 0x601361019f6101013e6f338db2b1165b4918f178852663192a956d79a68b50eefdc639ca0b62ab4d52771db054ccc801c0666b34b3c6242bbfc5e98f20c14fb95e016718be9ad033d50e21675ff59297861847ea6a911a6a9d135e2f826dc6037d850e0db21d105b8732a34b873c7d943050b8659794f0bd3e841d35a2231e65f697f8cde1176728fa2051e87933cf66858e4e5e91baa7764fc1e9ffe4c7b15ba600e88f095989dc68f47ed704be2b99601761021563200fbd63f07e41c7f86732f4d5419b41e6887cca98e0943f141a5c66df98bd0c6d6c4cec657893afaa8ce1769c96cd0751aa76a98c8196fa8c92e70d7bda176299c91c3e7a7f05de3181109b8194387746f9ec15a6e0233f759e43360bd4e0a06e4e9f395117afcd072774ce12d13dc761016152303a683305858002a92140b678508e3a3be377d4825dbf618a393c7c061e75a8a496a33afe0f72017f2e33549e321838b083d48893f23dced4597e2e9ea08fe3f80970d6334b6c6f1fde8bcc81d03a7ccc244231cb6606dba6d06ec1c5158ef0db6994192acbd4cac6ab6ac8449d80fc2c32471946e071d9606bd390266d7f712766f4765076283ad6687450d7ab4df6f3f6ee9661014a70b802ec9d7ed96dc0b9ce7bd14b193dc1f05376d11ce19283c7f651d4d2e7c180715ff7fcbc995ea8b2766213cc517d6dad16d17f29a93220ce0ddb0a65d3d474dbc39cba5bcb3d4fcf9fef1910607d64c04511df277f522ab2475fbb2ba0720711a903dbecfa0429bf11e6e90cbb0f13d4ee050c52c87365e0216b4096186fc604fb563fa59f1263ee91d5695e407fdffe82ca1558f7876a93f3a218dd9ba6901fdea93d6be498f0b0e1874331115e31aa6fad4d87227362a9ec3e1c1be11cdb2309697bbc0c692eeadfa9161669b8aec24564487dc74f8e7d17e6a133b5dbe576838697de73f856197203ef1a3a54f7edb0dbd60f9d5274db6b5c1477169b77f0d817ed731a20db4b9e5b83d2786bffefab084a31c4afda168156612f281da0be688e5bdb1f3176ed78bc62343a7665abad6573482449e68b3acfe820993d77df5785384d51aaa0612dab5ddbf2a9bf550736ad422933878861011961023ffd608f61022d61021661036e635af7465b73ffffffffffffffffffffffffffffffffffffffff63792c6916f16ed70693587df6ccfae5218d01559bac60156102006101adfd # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.RETURNDATACOPY(dest_offset=0x101, offset=0x19F, size=0x13) + + Op.PUSH16[0x338DB2B1165B4918F178852663192A95] + + Op.PUSH14[0x79A68B50EEFDC639CA0B62AB4D52] + + Op.PUSH24[0x1DB054CCC801C0666B34B3C6242BBFC5E98F20C14FB95E01] + + Op.PUSH8[0x18BE9AD033D50E21] + + Op.PUSH8[0x5FF59297861847EA] + + Op.PUSH11[0x911A6A9D135E2F826DC603] + + Op.PUSH30[ + 0x850E0DB21D105B8732A34B873C7D943050B8659794F0BD3E841D35A2231E + ] + + Op.PUSH6[0xF697F8CDE117] + + Op.PUSH8[0x28FA2051E87933CF] + + Op.PUSH7[0x858E4E5E91BAA7] + + Op.PUSH23[0x4FC1E9FFE4C7B15BA600E88F095989DC68F47ED704BE2B] + + Op.SWAP10 + + Op.CREATE(value=0x200FBD63, offset=0x215, size=0x17) + + Op.RETURNDATACOPY( + dest_offset=0x99C91C, + offset=0x93AFAA8CE1769C96CD0751AA76A98C8196FA8C92E70D7BDA17, + size=0x41C7F86732F4D5419B41E6887CCA98E0943F141A5C66DF98BD0C6D6C4CEC65, # noqa: E501 + ) + + Op.PUSH27[0x7F05DE3181109B8194387746F9EC15A6E0233F759E43360BD4E0A0] + + Op.MSTORE(offset=0x161, value=0x4E9F395117AFCD072774CE12D13DC7) + + Op.ADDRESS + + Op.GASPRICE + + Op.PUSH9[0x3305858002A92140B6] + + Op.PUSH25[0x508E3A3BE377D4825DBF618A393C7C061E75A8A496A33AFE0F] + + Op.PUSH19[0x17F2E33549E321838B083D48893F23DCED459] + + Op.PUSH31[ + 0x2E9EA08FE3F80970D6334B6C6F1FDE8BCC81D03A7CCC244231CB6606DBA6D0 + ] + + Op.PUSH15[0xC1C5158EF0DB6994192ACBD4CAC6AB] + + Op.PUSH11[0xC8449D80FC2C32471946E0] + + Op.PUSH18[0xD9606BD390266D7F712766F4765076283AD6] + + Op.PUSH9[0x7450D7AB4DF6F3F6EE] + + Op.SWAP7 + + Op.MSTORE8(offset=0xB802EC9D7ED96DC0B9CE7BD14B193DC1F0, value=0x14A) + + Op.PUSH23[0xD11CE19283C7F651D4D2E7C180715FF7FCBC995EA8B276] + + Op.PUSH3[0x13CC51] + + Op.PUSH30[ + 0x6DAD16D17F29A93220CE0DDB0A65D3D474DBC39CBA5BCB3D4FCF9FEF1910 + ] + + Op.PUSH1[0x7D] + + Op.PUSH5[0xC04511DF27] + + Op.PUSH32[ + 0x522AB2475FBB2BA0720711A903DBECFA0429BF11E6E90CBB0F13D4EE050C52C8 + ] + + Op.PUSH20[0x65E0216B4096186FC604FB563FA59F1263EE91D5] + + Op.PUSH10[0x5E407FDFFE82CA1558F7] + + Op.DUP8 + + Op.PUSH11[0x93F3A218DD9BA6901FDEA9] + + Op.RETURNDATASIZE + + Op.PUSH12[0xE498F0B0E1874331115E31AA] + + Op.PUSH16[0xAD4D87227362A9EC3E1C1BE11CDB2309] + + Op.PUSH10[0x7BBC0C692EEADFA91616] + + Op.PUSH10[0xB8AEC24564487DC74F8E] + + Op.PUSH30[ + 0x17E6A133B5DBE576838697DE73F856197203EF1A3A54F7EDB0DBD60F9D52 + ] + + Op.PUSH21[0xDB6B5C1477169B77F0D817ED731A20DB4B9E5B83D2] + + Op.PUSH25[0x6BFFEFAB084A31C4AFDA168156612F281DA0BE688E5BDB1F31] + + Op.PUSH23[0xED78BC62343A7665ABAD6573482449E68B3ACFE820993D] + + Op.PUSH24[0xDF5785384D51AAA0612DAB5DDBF2A9BF550736AD42293387] + + Op.DUP9 + + Op.REVERT(offset=0x23F, size=0x119) + + Op.CALL( + gas=0x792C6916, + address=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + value=0x5AF7465B, + args_offset=0x36E, + args_size=0x216, + ret_offset=0x22D, + ret_size=0x8F, + ) + + Op.PUSH15[0xD70693587DF6CCFAE5218D01559BAC] + + Op.PUSH1[0x15] + + Op.REVERT(offset=0x1AD, size=0x200), + balance=0x5B1936A53E6E440F, + nonce=21, + address=Address(0xE7E620C9CF6045209EDCAD4D6EF43413BEDF0949), # noqa: E501 + ) + # Source: raw + # 0x610326610100f379c940b5f2046740058558468f238b85db7f6bbe3f3d51e92a3e3268b7f7c4147541c695f376705288410b81b217e80726fb9e4c5c7b4c49eca0c1b6b97e117c16c26c9816459f38396ffc36da48d65defdc7d055cbc846c07e81cfab0fb607c6cbc968774d4de7df8e3236f581e688cc2081a96b1cad9e0609b70f4fddda49ae97714e7d325ceab23acd5f46ba15b5210474116121921a04f68f3f933b9ad91b735bf71bfe41da706499c5d47b6de1fe398cb91fdf66481cbb8661d71d457cf3cef75dabf5ea496d7012f4c56b9fe70e6c4204720e3ce66874cead08499d57a547b97d37744ce205e051f296fb116fc9e5f3c280919aff3c93c5d5cefff9a6102d86103ca6364b68c8ef07d # noqa: E501 + coinbase = pre.deploy_contract( # noqa: F841 + code=bytes.fromhex( + "610326610100f379c940b5f2046740058558468f238b85db7f6bbe3f3d51e92a3e3268b7f7c4147541c695f376705288410b81b217e80726fb9e4c5c7b4c49eca0c1b6b97e117c16c26c9816459f38396ffc36da48d65defdc7d055cbc846c07e81cfab0fb607c6cbc968774d4de7df8e3236f581e688cc2081a96b1cad9e0609b70f4fddda49ae97714e7d325ceab23acd5f46ba15b5210474116121921a04f68f3f933b9ad91b735bf71bfe41da706499c5d47b6de1fe398cb91fdf66481cbb8661d71d457cf3cef75dabf5ea496d7012f4c56b9fe70e6c4204720e3ce66874cead08499d57a547b97d37744ce205e051f296fb116fc9e5f3c280919aff3c93c5d5cefff9a6102d86103ca6364b68c8ef07d" # noqa: E501 + ), + balance=0x54C814F188394C8, + nonce=29, + address=Address(0xF7B2E80637A148B5E46945E29388928DAFD5AA25), # noqa: E501 + ) # Source: raw # 0x6102fa60ff60f561014873630277795afa689497edb6a665eae52f3d625249756103a55260a860fb60cb3e6102dd6103e0fd6f568a159c0cae9044d258c55b10f4d100628d29ab781df7fcebb789e2a8cdbaa9c67c42cd1ebe81716ead0e94c7216d279dd3a0b3de311596d54729287873449ccce511e6991b3dc636a178159a3d9a06227462cd9a6768ccba17c2cb06de468e95730bf78e55af17e19973f2c3f5d4c21c169890b9a9672491f91aa1e7142667060d385ed594e21b6d02b23a6c4c50e7ab6a3ef66f83a2927f9845b4ba85c4fdfbd0054a0123ad93eff4b525b0f4b08d285f36f3bcac6a985b66906c348472b7cb047bc5a02e618666f0c50eecdc11f20fc1dc41c2fd957752e55ede4e56f469f536a04d436ad418a1ca7a44c0173c10f1806ba284f9c9c7c13670005de594dec538cd56c2746b3bfdfa7683ae0df68bbcb5347d61be606ef617322e6448e3e4124dbe061257a8f486529de397f08ce92502a37b957f855818082b5b5b49e36de5a83e8a270663088571bf2fdf8f5f2961031452326fb9499741e3859928a237f5e5df84c13c6043556b1e82328f9093e64defbdd07d7774d84835800999791abc41260472d96f604d07198e859adc0b70806beae7200cf116d2b55e89ddd564abc36d900e69a68b0f0e9e4f129987288153605d7d01c42f3b109ed2bd72a6cf13500241c2a5e5c4e17ea9ed9b05ba9b57d70d63d270ece77f6ecf21d3a41ad554f79584dcab761d4c8437774cad4bb13b2bece140358df93e76c0f49abe102cd44e474ab71c0237247865fa2add74c8b2a33d6f7041c5718a2554a72662720296dff5b377b559df4558b8a5b2c9e7d15eb3947a70064f935c8fdf0a4e726f644aa31b42c10280e50ea92a366c3d060c1270c6a16a75522fbeb3d7cca702807f5217816eab9cceb9e237ee8fde4ed3a23d3ec87adb334ac1caa7e06523b0132dd615cf3fc16140d34c191617823c3a7bf47c42bc36b69cb4385463595c7f6f9ea451e05303603e0cd401e13d6ff744e2a673824d943941551704ff14df7fa8646efbb2d8abc4ac6e258e9924924b8001f8f0650d66b37411d484b18f41e77c792bd1c169fa52bbfc8af4a45f20acb0ef95db2ecbc0d4eadbbbf6732f648bd33b36336dc0faf0cf1970bcd38093a50a44fd6b253b0e74f2706239c499217b8c3263dae332e254711d5d5e7e795c998cceed14cf46977e7d3cbb35783c79ef0530c3a8ac3fd8d49f10bb0ae919fa149adead67dae035627de430622813ac6271b518733c7fb9ba628e056e0e87e029b8e5f42821d775338e6774301ecb428b3938236ee22b7d0b5edf2ad6997869f427ba0672a7168614233e85f61dae5ed4283a53f60570116dad586dce62833a62ca8c914c641f8660526101d761010761031c736333d3d55ff4611a5b631c4ea729816102566103ce6101c161014a73000000000000000000000000000000000000000663202b2ea8f4610221610106602e3e648a95029ecb72849fe0943cb9d854c7d50ad04cfdfe648e286876b8f2b53e55fe01a152c8496cbcc6997447062b734cebde04796c6452e9efc4aba5bf071cbff56208a525a8ef5f52399b4f33697bd988884f58166d734881774eff46d77bb189c89c55b1c6591f178d2d7c21bf2b023adf9bc5b8621235e3346d98d56047a3f71241fd5a24abbb0c73fc463fb8a5e67e32055696fe51258dd07526ebd87e439bcebb514ae26dc12d653a5c1263705109097ec5dcdb3918ab114985f7097fd3003b50e58fba91007825a6b800f644eaa306051808460fc3b2d8e276b2187c7b583ff29ee0b0c34f9ee57bac9ebb996402e3300ddf06c760fc5f531f746b1e2beda7a15c07f90f92422822e8d33c5d2409ea7375197f7cd6d61770eddb078206cfc7c5006cd0e97da9ec65fa4fc683da22cfaf6dfc995feb5f8386a052851fc502f32e7ef9346e3d4633def4c0a4b9be12f2cd7c646062e14ca37cfb977524f677714c3d994ea05f1997a2462fc0ab20ed2a5958f37126029b6102056102c9605d6103a1736302e83dbef4 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -328,101 +419,6 @@ def test_python_revert_test_tue201814_minus_1430( nonce=29, address=Address(0x69859649E8A52DE717592B881508371F8A8ED6B9), # noqa: E501 ) - pre[sender] = Account(balance=0xAB56295C9D120548) - # Source: raw - # 0x601361019f6101013e6f338db2b1165b4918f178852663192a956d79a68b50eefdc639ca0b62ab4d52771db054ccc801c0666b34b3c6242bbfc5e98f20c14fb95e016718be9ad033d50e21675ff59297861847ea6a911a6a9d135e2f826dc6037d850e0db21d105b8732a34b873c7d943050b8659794f0bd3e841d35a2231e65f697f8cde1176728fa2051e87933cf66858e4e5e91baa7764fc1e9ffe4c7b15ba600e88f095989dc68f47ed704be2b99601761021563200fbd63f07e41c7f86732f4d5419b41e6887cca98e0943f141a5c66df98bd0c6d6c4cec657893afaa8ce1769c96cd0751aa76a98c8196fa8c92e70d7bda176299c91c3e7a7f05de3181109b8194387746f9ec15a6e0233f759e43360bd4e0a06e4e9f395117afcd072774ce12d13dc761016152303a683305858002a92140b678508e3a3be377d4825dbf618a393c7c061e75a8a496a33afe0f72017f2e33549e321838b083d48893f23dced4597e2e9ea08fe3f80970d6334b6c6f1fde8bcc81d03a7ccc244231cb6606dba6d06ec1c5158ef0db6994192acbd4cac6ab6ac8449d80fc2c32471946e071d9606bd390266d7f712766f4765076283ad6687450d7ab4df6f3f6ee9661014a70b802ec9d7ed96dc0b9ce7bd14b193dc1f05376d11ce19283c7f651d4d2e7c180715ff7fcbc995ea8b2766213cc517d6dad16d17f29a93220ce0ddb0a65d3d474dbc39cba5bcb3d4fcf9fef1910607d64c04511df277f522ab2475fbb2ba0720711a903dbecfa0429bf11e6e90cbb0f13d4ee050c52c87365e0216b4096186fc604fb563fa59f1263ee91d5695e407fdffe82ca1558f7876a93f3a218dd9ba6901fdea93d6be498f0b0e1874331115e31aa6fad4d87227362a9ec3e1c1be11cdb2309697bbc0c692eeadfa9161669b8aec24564487dc74f8e7d17e6a133b5dbe576838697de73f856197203ef1a3a54f7edb0dbd60f9d5274db6b5c1477169b77f0d817ed731a20db4b9e5b83d2786bffefab084a31c4afda168156612f281da0be688e5bdb1f3176ed78bc62343a7665abad6573482449e68b3acfe820993d77df5785384d51aaa0612dab5ddbf2a9bf550736ad422933878861011961023ffd608f61022d61021661036e635af7465b73ffffffffffffffffffffffffffffffffffffffff63792c6916f16ed70693587df6ccfae5218d01559bac60156102006101adfd # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.RETURNDATACOPY(dest_offset=0x101, offset=0x19F, size=0x13) - + Op.PUSH16[0x338DB2B1165B4918F178852663192A95] - + Op.PUSH14[0x79A68B50EEFDC639CA0B62AB4D52] - + Op.PUSH24[0x1DB054CCC801C0666B34B3C6242BBFC5E98F20C14FB95E01] - + Op.PUSH8[0x18BE9AD033D50E21] - + Op.PUSH8[0x5FF59297861847EA] - + Op.PUSH11[0x911A6A9D135E2F826DC603] - + Op.PUSH30[ - 0x850E0DB21D105B8732A34B873C7D943050B8659794F0BD3E841D35A2231E - ] - + Op.PUSH6[0xF697F8CDE117] - + Op.PUSH8[0x28FA2051E87933CF] - + Op.PUSH7[0x858E4E5E91BAA7] - + Op.PUSH23[0x4FC1E9FFE4C7B15BA600E88F095989DC68F47ED704BE2B] - + Op.SWAP10 - + Op.CREATE(value=0x200FBD63, offset=0x215, size=0x17) - + Op.RETURNDATACOPY( - dest_offset=0x99C91C, - offset=0x93AFAA8CE1769C96CD0751AA76A98C8196FA8C92E70D7BDA17, - size=0x41C7F86732F4D5419B41E6887CCA98E0943F141A5C66DF98BD0C6D6C4CEC65, # noqa: E501 - ) - + Op.PUSH27[0x7F05DE3181109B8194387746F9EC15A6E0233F759E43360BD4E0A0] - + Op.MSTORE(offset=0x161, value=0x4E9F395117AFCD072774CE12D13DC7) - + Op.ADDRESS - + Op.GASPRICE - + Op.PUSH9[0x3305858002A92140B6] - + Op.PUSH25[0x508E3A3BE377D4825DBF618A393C7C061E75A8A496A33AFE0F] - + Op.PUSH19[0x17F2E33549E321838B083D48893F23DCED459] - + Op.PUSH31[ - 0x2E9EA08FE3F80970D6334B6C6F1FDE8BCC81D03A7CCC244231CB6606DBA6D0 - ] - + Op.PUSH15[0xC1C5158EF0DB6994192ACBD4CAC6AB] - + Op.PUSH11[0xC8449D80FC2C32471946E0] - + Op.PUSH18[0xD9606BD390266D7F712766F4765076283AD6] - + Op.PUSH9[0x7450D7AB4DF6F3F6EE] - + Op.SWAP7 - + Op.MSTORE8(offset=0xB802EC9D7ED96DC0B9CE7BD14B193DC1F0, value=0x14A) - + Op.PUSH23[0xD11CE19283C7F651D4D2E7C180715FF7FCBC995EA8B276] - + Op.PUSH3[0x13CC51] - + Op.PUSH30[ - 0x6DAD16D17F29A93220CE0DDB0A65D3D474DBC39CBA5BCB3D4FCF9FEF1910 - ] - + Op.PUSH1[0x7D] - + Op.PUSH5[0xC04511DF27] - + Op.PUSH32[ - 0x522AB2475FBB2BA0720711A903DBECFA0429BF11E6E90CBB0F13D4EE050C52C8 - ] - + Op.PUSH20[0x65E0216B4096186FC604FB563FA59F1263EE91D5] - + Op.PUSH10[0x5E407FDFFE82CA1558F7] - + Op.DUP8 - + Op.PUSH11[0x93F3A218DD9BA6901FDEA9] - + Op.RETURNDATASIZE - + Op.PUSH12[0xE498F0B0E1874331115E31AA] - + Op.PUSH16[0xAD4D87227362A9EC3E1C1BE11CDB2309] - + Op.PUSH10[0x7BBC0C692EEADFA91616] - + Op.PUSH10[0xB8AEC24564487DC74F8E] - + Op.PUSH30[ - 0x17E6A133B5DBE576838697DE73F856197203EF1A3A54F7EDB0DBD60F9D52 - ] - + Op.PUSH21[0xDB6B5C1477169B77F0D817ED731A20DB4B9E5B83D2] - + Op.PUSH25[0x6BFFEFAB084A31C4AFDA168156612F281DA0BE688E5BDB1F31] - + Op.PUSH23[0xED78BC62343A7665ABAD6573482449E68B3ACFE820993D] - + Op.PUSH24[0xDF5785384D51AAA0612DAB5DDBF2A9BF550736AD42293387] - + Op.DUP9 - + Op.REVERT(offset=0x23F, size=0x119) - + Op.CALL( - gas=0x792C6916, - address=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, - value=0x5AF7465B, - args_offset=0x36E, - args_size=0x216, - ret_offset=0x22D, - ret_size=0x8F, - ) - + Op.PUSH15[0xD70693587DF6CCFAE5218D01559BAC] - + Op.PUSH1[0x15] - + Op.REVERT(offset=0x1AD, size=0x200), - balance=0x5B1936A53E6E440F, - nonce=21, - address=Address(0xE7E620C9CF6045209EDCAD4D6EF43413BEDF0949), # noqa: E501 - ) - # Source: raw - # 0x610326610100f379c940b5f2046740058558468f238b85db7f6bbe3f3d51e92a3e3268b7f7c4147541c695f376705288410b81b217e80726fb9e4c5c7b4c49eca0c1b6b97e117c16c26c9816459f38396ffc36da48d65defdc7d055cbc846c07e81cfab0fb607c6cbc968774d4de7df8e3236f581e688cc2081a96b1cad9e0609b70f4fddda49ae97714e7d325ceab23acd5f46ba15b5210474116121921a04f68f3f933b9ad91b735bf71bfe41da706499c5d47b6de1fe398cb91fdf66481cbb8661d71d457cf3cef75dabf5ea496d7012f4c56b9fe70e6c4204720e3ce66874cead08499d57a547b97d37744ce205e051f296fb116fc9e5f3c280919aff3c93c5d5cefff9a6102d86103ca6364b68c8ef07d # noqa: E501 - coinbase = pre.deploy_contract( # noqa: F841 - code=bytes.fromhex( - "610326610100f379c940b5f2046740058558468f238b85db7f6bbe3f3d51e92a3e3268b7f7c4147541c695f376705288410b81b217e80726fb9e4c5c7b4c49eca0c1b6b97e117c16c26c9816459f38396ffc36da48d65defdc7d055cbc846c07e81cfab0fb607c6cbc968774d4de7df8e3236f581e688cc2081a96b1cad9e0609b70f4fddda49ae97714e7d325ceab23acd5f46ba15b5210474116121921a04f68f3f933b9ad91b735bf71bfe41da706499c5d47b6de1fe398cb91fdf66481cbb8661d71d457cf3cef75dabf5ea496d7012f4c56b9fe70e6c4204720e3ce66874cead08499d57a547b97d37744ce205e051f296fb116fc9e5f3c280919aff3c93c5d5cefff9a6102d86103ca6364b68c8ef07d" # noqa: E501 - ), - balance=0x54C814F188394C8, - nonce=29, - address=Address(0xF7B2E80637A148B5E46945E29388928DAFD5AA25), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRevertTest/test_revert_depth2.py b/tests/ported_static/stRevertTest/test_revert_depth2.py index b1911b948b5..672da622c5c 100644 --- a/tests/ported_static/stRevertTest/test_revert_depth2.py +++ b/tests/ported_static/stRevertTest/test_revert_depth2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -55,9 +54,7 @@ def test_revert_depth2( ) -> None: """Test_revert_depth2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -68,28 +65,22 @@ def test_revert_depth2( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (CALL 150000 0 0 0 0 0) [[2]] (CALL 150000 0 0 0 0 0)} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { [[0]] (ADD 1 (SLOAD 0)) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (CALL 50000 0 0 0 0 0) [[2]] (GAS)} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + Op.SSTORE( key=0x1, value=Op.CALL( - gas=0x249F0, - address=0x707F29673F05E46FEEB7C4766419A222010AE45, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.SSTORE( - key=0x2, - value=Op.CALL( - gas=0x249F0, - address=0x78ED2EB0809CD080C7837DC83AFC388A2B98D200, + gas=0xC350, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -97,9 +88,9 @@ def test_revert_depth2( ret_size=0x0, ), ) + + Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x68EA09E164A8B66DE117A2C306B3966E6D71CA93), # noqa: E501 ) # Source: lll # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (CALL 50000 0 0 0 0 0)} # noqa: E501 @@ -109,7 +100,7 @@ def test_revert_depth2( key=0x1, value=Op.CALL( gas=0xC350, - address=0xC47BCBF49DD735566CFDE927821E938D5B33014C, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -119,25 +110,28 @@ def test_revert_depth2( ) + Op.STOP, nonce=0, - address=Address(0x0707F29673F05E46FEEB7C4766419A222010AE45), # noqa: E501 ) # Source: lll - # { [[0]] (ADD 1 (SLOAD 0)) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.STOP, - nonce=0, - address=Address(0xC47BCBF49DD735566CFDE927821E938D5B33014C), # noqa: E501 - ) - # Source: lll - # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (CALL 50000 0 0 0 0 0) [[2]] (GAS)} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (CALL 150000 0 0 0 0 0) [[2]] (CALL 150000 0 0 0 0 0)} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + Op.SSTORE( key=0x1, value=Op.CALL( - gas=0xC350, - address=0xC47BCBF49DD735566CFDE927821E938D5B33014C, + gas=0x249F0, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.SSTORE( + key=0x2, + value=Op.CALL( + gas=0x249F0, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x0, @@ -145,10 +139,8 @@ def test_revert_depth2( ret_size=0x0, ), ) - + Op.SSTORE(key=0x2, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x78ED2EB0809CD080C7837DC83AFC388A2B98D200), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stRevertTest/test_revert_depth_create_address_collision.py b/tests/ported_static/stRevertTest/test_revert_depth_create_address_collision.py index 12681db6341..21dfadc052b 100644 --- a/tests/ported_static/stRevertTest/test_revert_depth_create_address_collision.py +++ b/tests/ported_static/stRevertTest/test_revert_depth_create_address_collision.py @@ -109,6 +109,16 @@ def test_revert_depth_create_address_collision( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll + # { [[2]] 8 (CREATE 0 0 0) [[3]] 12} + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x8) + + Op.POP(Op.CREATE(value=0x0, offset=0x0, size=0x0)) + + Op.SSTORE(key=0x3, value=0xC) + + Op.STOP, + nonce=0, + address=Address(0xB1B49241A4ECF7860872E686090781C906B1B437), # noqa: E501 + ) + # Source: lll # { [[0]] 1 [[1]] (CALL (CALLDATALOAD 0) 0 0 0 0 0) [[4]] 12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -130,16 +140,6 @@ def test_revert_depth_create_address_collision( nonce=54, address=Address(0x97E33A176B7C8D61B356D1C170AC2119D28867DF), # noqa: E501 ) - # Source: lll - # { [[2]] 8 (CREATE 0 0 0) [[3]] 12} - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x8) - + Op.POP(Op.CREATE(value=0x0, offset=0x0, size=0x0)) - + Op.SSTORE(key=0x3, value=0xC) - + Op.STOP, - nonce=0, - address=Address(0xB1B49241A4ECF7860872E686090781C906B1B437), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stRevertTest/test_revert_depth_create_oog.py b/tests/ported_static/stRevertTest/test_revert_depth_create_oog.py index ffb39b2905f..12dadbe7ce4 100644 --- a/tests/ported_static/stRevertTest/test_revert_depth_create_oog.py +++ b/tests/ported_static/stRevertTest/test_revert_depth_create_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -97,9 +96,7 @@ def test_revert_depth_create_oog( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA000000000000000000000000000000000000000) contract_1 = Address(0xB000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -110,7 +107,15 @@ def test_revert_depth_create_oog( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { [[2]] 8 (CREATE 0 0 0) [[3]] 12} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x8) + + Op.POP(Op.CREATE(value=0x0, offset=0x0, size=0x0)) + + Op.SSTORE(key=0x3, value=0xC) + + Op.STOP, + nonce=0, + ) # Source: lll # { [[0]] 1 [[1]] (CALL (CALLDATALOAD 0) 0xb000000000000000000000000000000000000000 0 0 0 0 0) [[4]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -119,7 +124,7 @@ def test_revert_depth_create_oog( key=0x1, value=Op.CALL( gas=Op.CALLDATALOAD(offset=0x0), - address=0xB000000000000000000000000000000000000000, + address=contract_1, value=0x0, args_offset=0x0, args_size=0x0, @@ -131,17 +136,6 @@ def test_revert_depth_create_oog( + Op.STOP, balance=5, nonce=54, - address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { [[2]] 8 (CREATE 0 0 0) [[3]] 12} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x8) - + Op.POP(Op.CREATE(value=0x0, offset=0x0, size=0x0)) - + Op.SSTORE(key=0x3, value=0xC) - + Op.STOP, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_in_call_code.py b/tests/ported_static/stRevertTest/test_revert_in_call_code.py index 445c7143457..77e8cdafda8 100644 --- a/tests/ported_static/stRevertTest/test_revert_in_call_code.py +++ b/tests/ported_static/stRevertTest/test_revert_in_call_code.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_revert_in_call_code( ) -> None: """Test_revert_in_call_code.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_revert_in_call_code( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0x2232) (REVERT 0 32) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x2232) + + Op.REVERT(offset=0x0, size=0x20) + + Op.STOP, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALLCODE 50000 1000 0 64 0 64 ) [[ 1 ]] (RETURNDATASIZE) (RETURNDATACOPY 64 0 32) [[ 2 ]] (MLOAD 64) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +58,7 @@ def test_revert_in_call_code( key=0x0, value=Op.CALLCODE( gas=0xC350, - address=0x26BC42B8191CCB142CB8CBC3490BD3BDCE465591, + address=addr, value=0x3E8, args_offset=0x0, args_size=0x40, @@ -67,18 +72,7 @@ def test_revert_in_call_code( + Op.STOP, balance=1000, nonce=0, - address=Address(0x5E1D76D7BADBAD41710E47410DBA9226C255D229), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0x2232) (REVERT 0 32) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x2232) - + Op.REVERT(offset=0x0, size=0x20) - + Op.STOP, - nonce=0, - address=Address(0x26BC42B8191CCB142CB8CBC3490BD3BDCE465591), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRevertTest/test_revert_in_delegate_call.py b/tests/ported_static/stRevertTest/test_revert_in_delegate_call.py index 97d01bf7273..85992148486 100644 --- a/tests/ported_static/stRevertTest/test_revert_in_delegate_call.py +++ b/tests/ported_static/stRevertTest/test_revert_in_delegate_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_revert_in_delegate_call( ) -> None: """Test_revert_in_delegate_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_revert_in_delegate_call( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 32 10) (REVERT 32 32) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x20, value=0xA) + + Op.REVERT(offset=0x20, size=0x20) + + Op.STOP, + nonce=0, + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 50000 0 64 0 64 ) [[ 1 ]] (RETURNDATASIZE) (RETURNDATACOPY 63 0 32) [[2]](MLOAD 63)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +58,7 @@ def test_revert_in_delegate_call( key=0x0, value=Op.DELEGATECALL( gas=0xC350, - address=0xC3ECFE24C185AD3C946EBFF4624131E8AF5220A2, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -66,18 +71,7 @@ def test_revert_in_delegate_call( + Op.STOP, balance=1000, nonce=0, - address=Address(0x23EA33DC3AA11F5A1DA3643BB13956382B9B6767), # noqa: E501 - ) - # Source: lll - # { (MSTORE 32 10) (REVERT 32 32) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x20, value=0xA) - + Op.REVERT(offset=0x20, size=0x20) - + Op.STOP, - nonce=0, - address=Address(0xC3ECFE24C185AD3C946EBFF4624131E8AF5220A2), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRevertTest/test_revert_in_static_call.py b/tests/ported_static/stRevertTest/test_revert_in_static_call.py index 1e4a9eeba00..929e0272517 100644 --- a/tests/ported_static/stRevertTest/test_revert_in_static_call.py +++ b/tests/ported_static/stRevertTest/test_revert_in_static_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_revert_in_static_call( ) -> None: """Test_revert_in_static_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,12 @@ def test_revert_in_static_call( gas_limit=1000000, ) + # Source: lll + # { (REVERT 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.REVERT(offset=0x0, size=0x0) + Op.STOP, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 50000 0 64 0 64 )} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +56,7 @@ def test_revert_in_static_call( key=0x0, value=Op.STATICCALL( gas=0xC350, - address=0x33FCF0576AB8B4527C9426094E2E355A7FFC7E71, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,16 +66,7 @@ def test_revert_in_static_call( + Op.STOP, balance=1000, nonce=0, - address=Address(0x30F7398D20AFE518491069C036185CAF69D5AAE9), # noqa: E501 - ) - # Source: lll - # { (REVERT 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.REVERT(offset=0x0, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x33FCF0576AB8B4527C9426094E2E355A7FFC7E71), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRevertTest/test_revert_on_empty_stack.py b/tests/ported_static/stRevertTest/test_revert_on_empty_stack.py index 15e2b17b1d7..6809ead9e64 100644 --- a/tests/ported_static/stRevertTest/test_revert_on_empty_stack.py +++ b/tests/ported_static/stRevertTest/test_revert_on_empty_stack.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_revert_on_empty_stack( ) -> None: """Calling a runtime code that contains only a single `REVERT` should...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x3327048BBC0B8C348A6352BE62994144E64B8FF2CEC68D9FF4CA4E911ECD5D22 - ) + sender = pre.fund_eoa(amount=0x5AF3107A4000) env = Environment( fee_recipient=coinbase, @@ -46,13 +43,11 @@ def test_revert_on_empty_stack( gas_limit=10000000, ) - pre[sender] = Account(balance=0x5AF3107A4000) # Source: raw # 0xfd target = pre.deploy_contract( # noqa: F841 code=Op.REVERT, nonce=0, - address=Address(0x3141BB954E8294E47A14EBD08229F30E6294BA83), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_opcode.py b/tests/ported_static/stRevertTest/test_revert_opcode.py index 58f0e64e247..e76a7ee25f2 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -70,9 +69,7 @@ def test_revert_opcode( ) -> None: """Test_revert_opcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -83,7 +80,6 @@ def test_revert_opcode( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: raw # 0x600160005560016000fd6011600155 target = pre.deploy_contract( # noqa: F841 @@ -91,7 +87,6 @@ def test_revert_opcode( + Op.REVERT(offset=0x0, size=0x1) + Op.SSTORE(key=0x1, value=0x11), nonce=0, - address=Address(0xF5EAF70F313AB7C223DED96F5A804ABC49BF804A), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_calls.py b/tests/ported_static/stRevertTest/test_revert_opcode_calls.py index d5e7373d93d..1ac94a6d4f7 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_calls.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -94,9 +93,7 @@ def test_revert_opcode_calls( ) -> None: """Test_revert_opcode_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_revert_opcode_calls( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[10]] (CALL 260000 (CALLDATALOAD 0) 0 0 0 0 0)} target = pre.deploy_contract( # noqa: F841 @@ -129,10 +125,21 @@ def test_revert_opcode_calls( address=Address(0x1ADA72179309FD8A562E308928E38763A543ED6C), # noqa: E501 ) # Source: lll - # { [[0]] (CALL 50000 0 0 0 0 0) [[2]] 14 } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { [[1]] 12 (REVERT 0 1) [[3]] 13 } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + + Op.REVERT(offset=0x0, size=0x1) + + Op.SSTORE(key=0x3, value=0xD) + + Op.STOP, + balance=1, + nonce=0, + address=Address(0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B), # noqa: E501 + ) + # Source: lll + # { [[4]] (CALL 50000 0 0 0 0 0) [[5]] 14 } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x4, value=Op.CALL( gas=0xC350, address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, @@ -143,18 +150,18 @@ def test_revert_opcode_calls( ret_size=0x0, ), ) - + Op.SSTORE(key=0x2, value=0xE) + + Op.SSTORE(key=0x5, value=0xE) + Op.STOP, balance=1, nonce=0, - address=Address(0xCEB48D108C874B5B014ACDD1A2466D65A3D01DE6), # noqa: E501 + address=Address(0x652761B88018EA027F6F27E456FE55C2DC5D6A91), # noqa: E501 ) # Source: lll - # { [[0]] (CALLCODE 50000 0 0 0 0 0) [[2]] 14 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[0]] (CALL 50000 0 0 0 0 0) [[2]] 14 } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, - value=Op.CALLCODE( + value=Op.CALL( gas=0xC350, address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, value=0x0, @@ -168,7 +175,7 @@ def test_revert_opcode_calls( + Op.STOP, balance=1, nonce=0, - address=Address(0x737F82ED94146E759790D925492DF5A8CED35885), # noqa: E501 + address=Address(0xCEB48D108C874B5B014ACDD1A2466D65A3D01DE6), # noqa: E501 ) # Source: lll # { [[0]] (DELEGATECALL 50000 0 0 0 0) [[2]] 14 } # noqa: E501 @@ -191,13 +198,13 @@ def test_revert_opcode_calls( address=Address(0x6B8268AC8921E6A6E59A4B1D51A76F4E807E17AF), # noqa: E501 ) # Source: lll - # { [[0]] (CALL 100000 0 0 0 0 0) [[2]] 14 } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { [[0]] (CALLCODE 50000 0 0 0 0 0) [[2]] 14 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, - value=Op.CALL( - gas=0x186A0, - address=0x652761B88018EA027F6F27E456FE55C2DC5D6A91, + value=Op.CALLCODE( + gas=0xC350, + address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, value=0x0, args_offset=0x0, args_size=0x0, @@ -209,16 +216,16 @@ def test_revert_opcode_calls( + Op.STOP, balance=1, nonce=0, - address=Address(0xBF3FC188D9C8D699FFA12F0369E3B2BCF8428F7C), # noqa: E501 + address=Address(0x737F82ED94146E759790D925492DF5A8CED35885), # noqa: E501 ) # Source: lll - # { [[4]] (CALL 50000 0 0 0 0 0) [[5]] 14 } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 + # { [[0]] (CALL 100000 0 0 0 0 0) [[2]] 14 } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x4, + key=0x0, value=Op.CALL( - gas=0xC350, - address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, + gas=0x186A0, + address=0x652761B88018EA027F6F27E456FE55C2DC5D6A91, value=0x0, args_offset=0x0, args_size=0x0, @@ -226,22 +233,11 @@ def test_revert_opcode_calls( ret_size=0x0, ), ) - + Op.SSTORE(key=0x5, value=0xE) - + Op.STOP, - balance=1, - nonce=0, - address=Address(0x652761B88018EA027F6F27E456FE55C2DC5D6A91), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 (REVERT 0 1) [[3]] 13 } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) - + Op.REVERT(offset=0x0, size=0x1) - + Op.SSTORE(key=0x3, value=0xD) + + Op.SSTORE(key=0x2, value=0xE) + Op.STOP, balance=1, nonce=0, - address=Address(0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B), # noqa: E501 + address=Address(0xBF3FC188D9C8D699FFA12F0369E3B2BCF8428F7C), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_create.py b/tests/ported_static/stRevertTest/test_revert_opcode_create.py index f8fbd1a67fa..2672aa489e8 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_create.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_revert_opcode_create( """Test_revert_opcode_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_revert_opcode_create( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 0 0x600160005560016000fd6011600155 ) [[1]](CREATE 1 17 15) [[0]] 12 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -83,7 +79,6 @@ def test_revert_opcode_create( + Op.STOP, balance=1, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_direct_call.py b/tests/ported_static/stRevertTest/test_revert_opcode_direct_call.py index dbf05069936..76b0eb62908 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_direct_call.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_direct_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_revert_opcode_direct_call( ) -> None: """Test_revert_opcode_direct_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -71,7 +68,6 @@ def test_revert_opcode_direct_call( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[10]] (CALL 60000 (CALLDATALOAD 0) 0 0 0 0 0)} addr = pre.deploy_contract( # noqa: F841 @@ -93,6 +89,17 @@ def test_revert_opcode_direct_call( address=Address(0xF94D87FAF19D8C731E70E1B0A25F9668718F6E17), # noqa: E501 ) # Source: lll + # { [[1]] 12 (REVERT 0 1) [[3]] 13 } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + + Op.REVERT(offset=0x0, size=0x1) + + Op.SSTORE(key=0x3, value=0xD) + + Op.STOP, + balance=1, + nonce=0, + address=Address(0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B), # noqa: E501 + ) + # Source: lll # { [[0]] (CALL 50000 0 0 0 0 0) [[2]] 14 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( @@ -113,17 +120,6 @@ def test_revert_opcode_direct_call( nonce=0, address=Address(0xCEB48D108C874B5B014ACDD1A2466D65A3D01DE6), # noqa: E501 ) - # Source: lll - # { [[1]] 12 (REVERT 0 1) [[3]] 13 } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) - + Op.REVERT(offset=0x0, size=0x1) - + Op.SSTORE(key=0x3, value=0xD) - + Op.STOP, - balance=1, - nonce=0, - address=Address(0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_in_calls_on_non_empty_return_data.py b/tests/ported_static/stRevertTest/test_revert_opcode_in_calls_on_non_empty_return_data.py index 2d520c359c8..83e34b96b21 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_in_calls_on_non_empty_return_data.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_in_calls_on_non_empty_return_data.py @@ -111,8 +111,29 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (CALL 0 0 0 0 0 0) [[10]] (CALL 260000 (CALLDATALOAD 0) 0 0 0 0 0)} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { [[1]] 12 (REVERT 0 1) [[3]] 13 } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + + Op.REVERT(offset=0x0, size=0x1) + + Op.SSTORE(key=0x3, value=0xD) + + Op.STOP, + balance=1, + nonce=0, + address=Address(0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B), # noqa: E501 + ) + # Source: lll + # { [1] 12 (RETURN 0 64) } + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0xC) + + Op.RETURN(offset=0x0, size=0x40) + + Op.STOP, + balance=1, + nonce=0, + address=Address(0x127EAF7E31D691A8393B7A2F84A6E94372190C01), # noqa: E501 + ) + # Source: lll + # { (CALL 0 0 0 0 0 0) [[0]] (DELEGATECALL 50000 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, @@ -125,26 +146,25 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ) ) + Op.SSTORE( - key=0xA, - value=Op.CALL( - gas=0x3F7A0, - address=Op.CALLDATALOAD(offset=0x0), - value=0x0, + key=0x0, + value=Op.DELEGATECALL( + gas=0xC350, + address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, args_offset=0x0, args_size=0x0, ret_offset=0x0, ret_size=0x0, ), ) + + Op.SSTORE(key=0x2, value=Op.RETURNDATASIZE) + Op.STOP, - storage={10: 255}, balance=1, nonce=0, - address=Address(0x172A8F572404293AA810685DFDC6F740C300CC4B), # noqa: E501 + address=Address(0xF20CCAF271BEAA36E7CF4C9CED2867FAC9558F14), # noqa: E501 ) # Source: lll - # { (CALL 0 0 0 0 0 0) [[0]] (CALL 50000 0 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (CALL 0 0 0 0 0 0) [[0]] (CALLCODE 50000 0 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, @@ -158,7 +178,7 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ) + Op.SSTORE( key=0x0, - value=Op.CALL( + value=Op.CALLCODE( gas=0xC350, address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, value=0x0, @@ -172,11 +192,11 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( + Op.STOP, balance=1, nonce=0, - address=Address(0xE73611B5B479B30C93AC377AEB3BFB199764F3C3), # noqa: E501 + address=Address(0xC9DA6CD8413F64323F12CD44C99671F280F15E1C), # noqa: E501 ) # Source: lll - # { (CALL 0 0 0 0 0 0) [[0]] (CALLCODE 50000 0 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (CALL 0 0 0 0 0 0) [[4]] (CALL 50000 0 0 0 0 0) [[5]] (RETURNDATASIZE) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, @@ -189,8 +209,8 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ) ) + Op.SSTORE( - key=0x0, - value=Op.CALLCODE( + key=0x4, + value=Op.CALL( gas=0xC350, address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, value=0x0, @@ -200,15 +220,15 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ret_size=0x0, ), ) - + Op.SSTORE(key=0x2, value=Op.RETURNDATASIZE) + + Op.SSTORE(key=0x5, value=Op.RETURNDATASIZE) + Op.STOP, balance=1, nonce=0, - address=Address(0xC9DA6CD8413F64323F12CD44C99671F280F15E1C), # noqa: E501 + address=Address(0xEA519C47889074E6378B0D83747F2C3EA0B9CBC9), # noqa: E501 ) # Source: lll - # { (CALL 0 0 0 0 0 0) [[0]] (DELEGATECALL 50000 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (CALL 0 0 0 0 0 0) [[0]] (CALL 50000 0 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, @@ -222,9 +242,10 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ) + Op.SSTORE( key=0x0, - value=Op.DELEGATECALL( + value=Op.CALL( gas=0xC350, address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, + value=0x0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -235,11 +256,11 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( + Op.STOP, balance=1, nonce=0, - address=Address(0xF20CCAF271BEAA36E7CF4C9CED2867FAC9558F14), # noqa: E501 + address=Address(0xE73611B5B479B30C93AC377AEB3BFB199764F3C3), # noqa: E501 ) # Source: lll - # { (CALL 0 0 0 0 0 0) [[0]] (CALL 100000 0 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { (CALL 0 0 0 0 0 0) [[10]] (CALL 260000 (CALLDATALOAD 0) 0 0 0 0 0)} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, @@ -252,10 +273,10 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ) ) + Op.SSTORE( - key=0x0, + key=0xA, value=Op.CALL( - gas=0x186A0, - address=0xEA519C47889074E6378B0D83747F2C3EA0B9CBC9, + gas=0x3F7A0, + address=Op.CALLDATALOAD(offset=0x0), value=0x0, args_offset=0x0, args_size=0x0, @@ -263,15 +284,15 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ret_size=0x0, ), ) - + Op.SSTORE(key=0x2, value=Op.RETURNDATASIZE) + Op.STOP, + storage={10: 255}, balance=1, nonce=0, - address=Address(0x6BACDFA8216DBB2A09819F8739E57AE3574C9FFF), # noqa: E501 + address=Address(0x172A8F572404293AA810685DFDC6F740C300CC4B), # noqa: E501 ) # Source: lll - # { (CALL 0 0 0 0 0 0) [[4]] (CALL 50000 0 0 0 0 0) [[5]] (RETURNDATASIZE) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 + # { (CALL 0 0 0 0 0 0) [[0]] (CALL 100000 0 0 0 0 0) [[2]] (RETURNDATASIZE) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x0, @@ -284,10 +305,10 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ) ) + Op.SSTORE( - key=0x4, + key=0x0, value=Op.CALL( - gas=0xC350, - address=0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B, + gas=0x186A0, + address=0xEA519C47889074E6378B0D83747F2C3EA0B9CBC9, value=0x0, args_offset=0x0, args_size=0x0, @@ -295,32 +316,11 @@ def test_revert_opcode_in_calls_on_non_empty_return_data( ret_size=0x0, ), ) - + Op.SSTORE(key=0x5, value=Op.RETURNDATASIZE) - + Op.STOP, - balance=1, - nonce=0, - address=Address(0xEA519C47889074E6378B0D83747F2C3EA0B9CBC9), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 (REVERT 0 1) [[3]] 13 } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) - + Op.REVERT(offset=0x0, size=0x1) - + Op.SSTORE(key=0x3, value=0xD) - + Op.STOP, - balance=1, - nonce=0, - address=Address(0x93A599BDE9A3B6390AFDB06952AA5EC0B8C44F3B), # noqa: E501 - ) - # Source: lll - # { [1] 12 (RETURN 0 64) } - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0xC) - + Op.RETURN(offset=0x0, size=0x40) + + Op.SSTORE(key=0x2, value=Op.RETURNDATASIZE) + Op.STOP, balance=1, nonce=0, - address=Address(0x127EAF7E31D691A8393B7A2F84A6E94372190C01), # noqa: E501 + address=Address(0x6BACDFA8216DBB2A09819F8739E57AE3574C9FFF), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_in_create_returns.py b/tests/ported_static/stRevertTest/test_revert_opcode_in_create_returns.py index 4b74185f565..8a64f8f6529 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_in_create_returns.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_in_create_returns.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_revert_opcode_in_create_returns( ) -> None: """Test_revert_opcode_in_create_returns.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x834185262E53584684BF2B72C64E510013C235D0F45E462DB65900455DF45A35 - ) + sender = pre.fund_eoa(amount=0x6400000000) env = Environment( fee_recipient=coinbase, @@ -61,9 +58,7 @@ def test_revert_opcode_in_create_returns( + Op.STOP, storage={0: 1}, nonce=0, - address=Address(0x910073CEED5C2372DC67FFD941B0F148DC4EBAF5), # noqa: E501 ) - pre[sender] = Account(balance=0x6400000000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_in_init.py b/tests/ported_static/stRevertTest/test_revert_opcode_in_init.py index d6997f18cdb..c5c7e8af07d 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_in_init.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_in_init.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -44,7 +43,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_revert_opcode_in_init( state_test: StateTestFiller, pre: Alloc, @@ -55,9 +53,7 @@ def test_revert_opcode_in_init( ) -> None: """TODO revertOpcodeInInit followed by OOG.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -68,8 +64,6 @@ def test_revert_opcode_in_init( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - tx_data = [ Op.SSTORE(key=0x0, value=0x1) + Op.REVERT(offset=0x0, size=0x1) diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_multiple_sub_calls.py b/tests/ported_static/stRevertTest/test_revert_opcode_multiple_sub_calls.py index da763d19f8b..4cb54d7251c 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_multiple_sub_calls.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_multiple_sub_calls.py @@ -269,11 +269,38 @@ def test_revert_opcode_multiple_sub_calls( address=Address(0x89AB420962193A25593B5663462B75C083D56148), # noqa: E501 ) # Source: lll - # { [[10]](CALL 50000 0 0 0 0 0) [[11]](CALL 50000 0 0 0 0 0) [[12]](CALL 50000 0 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { [[1]] 12 (REVERT 0 1) } + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0xC) + + Op.REVERT(offset=0x0, size=0x1) + + Op.STOP, + nonce=0, + address=Address(0x86C575F296A8A021A2A64972E57A20B06FE8B897), # noqa: E501 + ) + # Source: lll + # { [[2]] 12 (REVERT 0 1) } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0xC) + + Op.REVERT(offset=0x0, size=0x1) + + Op.STOP, + nonce=0, + address=Address(0x3D2496D905CF0E9C77473CBFB6E100062B5AF57F), # noqa: E501 + ) + # Source: lll + # { [[3]] 12 (REVERT 0 1) } + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0xC) + + Op.REVERT(offset=0x0, size=0x1) + + Op.STOP, + nonce=0, + address=Address(0x83BAC26DD305C061381C042D0BAC07B08D15BBCE), # noqa: E501 + ) + # Source: lll + # { [[10]](CALLCODE 50000 0 0 0 0 0) [[11]](CALLCODE 50000 0 0 0 0 0) [[12]](CALLCODE 50000 0 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0xA, - value=Op.CALL( + value=Op.CALLCODE( gas=0xC350, address=0x86C575F296A8A021A2A64972E57A20B06FE8B897, value=0x0, @@ -285,7 +312,7 @@ def test_revert_opcode_multiple_sub_calls( ) + Op.SSTORE( key=0xB, - value=Op.CALL( + value=Op.CALLCODE( gas=0xC350, address=0x3D2496D905CF0E9C77473CBFB6E100062B5AF57F, value=0x0, @@ -297,7 +324,7 @@ def test_revert_opcode_multiple_sub_calls( ) + Op.SSTORE( key=0xC, - value=Op.CALL( + value=Op.CALLCODE( gas=0xC350, address=0x83BAC26DD305C061381C042D0BAC07B08D15BBCE, value=0x0, @@ -311,14 +338,14 @@ def test_revert_opcode_multiple_sub_calls( + Op.SSTORE(key=0x5, value=0xC) + Op.STOP, nonce=0, - address=Address(0xD7E294F032A5CC430E9E6C4148220867E9704DCD), # noqa: E501 + address=Address(0xEE88DFD8455D7D9D6D33231F3DAF6D9A4526D5CF), # noqa: E501 ) # Source: lll - # { [[10]](CALLCODE 50000 0 0 0 0 0) [[11]](CALLCODE 50000 0 0 0 0 0) [[12]](CALLCODE 50000 0 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[10]](CALL 50000 0 0 0 0 0) [[11]](DELEGATECALL 50000 0 0 0 0) [[12]](CALLCODE 50000 0 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0xA, - value=Op.CALLCODE( + value=Op.CALL( gas=0xC350, address=0x86C575F296A8A021A2A64972E57A20B06FE8B897, value=0x0, @@ -330,10 +357,9 @@ def test_revert_opcode_multiple_sub_calls( ) + Op.SSTORE( key=0xB, - value=Op.CALLCODE( + value=Op.DELEGATECALL( gas=0xC350, address=0x3D2496D905CF0E9C77473CBFB6E100062B5AF57F, - value=0x0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -356,7 +382,7 @@ def test_revert_opcode_multiple_sub_calls( + Op.SSTORE(key=0x5, value=0xC) + Op.STOP, nonce=0, - address=Address(0xEE88DFD8455D7D9D6D33231F3DAF6D9A4526D5CF), # noqa: E501 + address=Address(0x1302FD3B212E7E634F82ED6D00AC14544E8B1CAB), # noqa: E501 ) # Source: lll # { [[10]](DELEGATECALL 50000 0 0 0 0) [[11]](DELEGATECALL 50000 0 0 0 0) [[12]](DELEGATECALL 50000 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 @@ -401,8 +427,8 @@ def test_revert_opcode_multiple_sub_calls( address=Address(0x68CF97C6CA41ECFC5623D8A7E9B6F72068213E95), # noqa: E501 ) # Source: lll - # { [[10]](CALL 50000 0 0 0 0 0) [[11]](DELEGATECALL 50000 0 0 0 0) [[12]](CALLCODE 50000 0 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { [[10]](CALL 50000 0 0 0 0 0) [[11]](CALL 50000 0 0 0 0 0) [[12]](CALL 50000 0 0 0 0 0) [[4]]12 [[5]]12 } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0xA, value=Op.CALL( @@ -417,9 +443,10 @@ def test_revert_opcode_multiple_sub_calls( ) + Op.SSTORE( key=0xB, - value=Op.DELEGATECALL( + value=Op.CALL( gas=0xC350, address=0x3D2496D905CF0E9C77473CBFB6E100062B5AF57F, + value=0x0, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -428,7 +455,7 @@ def test_revert_opcode_multiple_sub_calls( ) + Op.SSTORE( key=0xC, - value=Op.CALLCODE( + value=Op.CALL( gas=0xC350, address=0x83BAC26DD305C061381C042D0BAC07B08D15BBCE, value=0x0, @@ -442,34 +469,7 @@ def test_revert_opcode_multiple_sub_calls( + Op.SSTORE(key=0x5, value=0xC) + Op.STOP, nonce=0, - address=Address(0x1302FD3B212E7E634F82ED6D00AC14544E8B1CAB), # noqa: E501 - ) - # Source: lll - # { [[1]] 12 (REVERT 0 1) } - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0xC) - + Op.REVERT(offset=0x0, size=0x1) - + Op.STOP, - nonce=0, - address=Address(0x86C575F296A8A021A2A64972E57A20B06FE8B897), # noqa: E501 - ) - # Source: lll - # { [[2]] 12 (REVERT 0 1) } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0xC) - + Op.REVERT(offset=0x0, size=0x1) - + Op.STOP, - nonce=0, - address=Address(0x3D2496D905CF0E9C77473CBFB6E100062B5AF57F), # noqa: E501 - ) - # Source: lll - # { [[3]] 12 (REVERT 0 1) } - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0xC) - + Op.REVERT(offset=0x0, size=0x1) - + Op.STOP, - nonce=0, - address=Address(0x83BAC26DD305C061381C042D0BAC07B08D15BBCE), # noqa: E501 + address=Address(0xD7E294F032A5CC430E9E6C4148220867E9704DCD), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_opcode_with_big_output_in_init.py b/tests/ported_static/stRevertTest/test_revert_opcode_with_big_output_in_init.py index 96e57fe4b56..a50d18f316a 100644 --- a/tests/ported_static/stRevertTest/test_revert_opcode_with_big_output_in_init.py +++ b/tests/ported_static/stRevertTest/test_revert_opcode_with_big_output_in_init.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -44,7 +43,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_revert_opcode_with_big_output_in_init( state_test: StateTestFiller, pre: Alloc, @@ -55,9 +53,7 @@ def test_revert_opcode_with_big_output_in_init( ) -> None: """A REVERT with a big output should not be confused with a big code...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -68,8 +64,6 @@ def test_revert_opcode_with_big_output_in_init( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - tx_data = [ Op.SSTORE(key=0x0, value=0x1) + Op.REVERT(offset=0x0, size=0x1) diff --git a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py index 9860ca0eaca..ff07e21b0d5 100644 --- a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -624,17 +623,15 @@ def test_revert_precompiled_touch_exact_oog_paris( ) -> None: """Test_revert_precompiled_touch_exact_oog_paris.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - addr_5 = Address(0x6EB9AFCB5D985B12549B7AC2E65C093F7113A0C7) - addr_6 = Address(0xF07A794E0F8AAB4242B86368503D3C1DE15481F8) - addr_7 = Address(0x9E6C35DECED6E05EB21D3465B5BBBB57B9CD57D6) - addr_8 = Address(0x1688023D9AE9E25EA02A2447A77B9CC9D22CE57B) - addr_9 = Address(0xD085AB47BC36D1238FC092679B21B10792746640) - addr_10 = Address(0xAD3DF2901B7C6642E397C35E0E9F3DEA5D098238) - addr_11 = Address(0xBE44B82021B08CFECC33A2E57FF5ADCB7FE3B049) - addr_12 = Address(0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA) - sender = EOA( - key=0xFF8D58222F34F6890DDAA468C023B77D6691ED7D3C4DCDDAE38336212FAF54B - ) + addr_5 = Address(0x0000000000000000000000000000000000000001) + addr_6 = Address(0x0000000000000000000000000000000000000002) + addr_7 = Address(0x0000000000000000000000000000000000000003) + addr_8 = Address(0x0000000000000000000000000000000000000004) + addr_9 = Address(0x0000000000000000000000000000000000000005) + addr_10 = Address(0x0000000000000000000000000000000000000006) + addr_11 = Address(0x0000000000000000000000000000000000000007) + addr_12 = Address(0x0000000000000000000000000000000000000008) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -645,6 +642,14 @@ def test_revert_precompiled_touch_exact_oog_paris( gas_limit=4012015, ) + pre[addr_5] = Account(balance=1) + pre[addr_6] = Account(balance=1) + pre[addr_7] = Account(balance=1) + pre[addr_8] = Account(balance=1) + pre[addr_9] = Account(balance=1) + pre[addr_10] = Account(balance=1) + pre[addr_11] = Account(balance=1) + pre[addr_12] = Account(balance=1) # Source: lll # { (CALLCODE (GAS) (CALLDATALOAD 0) 0 0 (CALLDATALOAD 32) 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -723,15 +728,6 @@ def test_revert_precompiled_touch_exact_oog_paris( nonce=0, address=Address(0xC02FFF115E5EEE4FF4420EBA1CB7CB8772E0598E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[addr_5] = Account(balance=1) - pre[addr_6] = Account(balance=1) - pre[addr_7] = Account(balance=1) - pre[addr_8] = Account(balance=1) - pre[addr_9] = Account(balance=1) - pre[addr_10] = Account(balance=1) - pre[addr_11] = Account(balance=1) - pre[addr_12] = Account(balance=1) expect_entries_: list[dict] = [ { @@ -864,38 +860,70 @@ def test_revert_precompiled_touch_exact_oog_paris( post, _exc = resolve_expect_post(expect_entries_, d, g, v, fork) tx_data = [ - Hash(0x1000000000000000000000000000000000000000) + Hash(0x1), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x2), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x3), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x4), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x5), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x6), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x7), - Hash(0x1000000000000000000000000000000000000000) + Hash(0x8), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x1), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x2), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x3), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x4), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x5), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x6), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x7), - Hash(0x2000000000000000000000000000000000000000) + Hash(0x8), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x1), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x2), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x3), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x4), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x5), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x6), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x7), - Hash(0x3000000000000000000000000000000000000000) + Hash(0x8), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x1), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x2), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x3), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x4), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x5), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x6), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x7), - Hash(0x4000000000000000000000000000000000000000) + Hash(0x8), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_5, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_6, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_7, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_8, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_9, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_10, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_11, left_padding=True), + Hash(0x1000000000000000000000000000000000000000) + + Hash(addr_12, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_5, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_6, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_7, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_8, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_9, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_10, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_11, left_padding=True), + Hash(0x2000000000000000000000000000000000000000) + + Hash(addr_12, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_5, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_6, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_7, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_8, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_9, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_10, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_11, left_padding=True), + Hash(0x3000000000000000000000000000000000000000) + + Hash(addr_12, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_5, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_6, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_7, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_8, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_9, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_10, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_11, left_padding=True), + Hash(0x4000000000000000000000000000000000000000) + + Hash(addr_12, left_padding=True), ] tx_gas = [22500, 120000, 69000] diff --git a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_nonce.py b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_nonce.py index 0e607516f42..56cc3c019bf 100644 --- a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_nonce.py +++ b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_nonce.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -67,17 +66,15 @@ def test_revert_precompiled_touch_nonce( ) -> None: """Test_revert_precompiled_touch_nonce.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - addr_5 = Address(0xB478E245708BE95C33C6C35DEA161C0429D02DD2) - addr_6 = Address(0x6A22458E937F487E2DAFFA193B9C5FB610DC4789) - addr_7 = Address(0x8D1D883976DF004B96C383782A828DC5BC82EF9D) - addr_8 = Address(0x05A4FAF1EDE8E96AAE92AE51915074E42787F868) - addr_9 = Address(0xF8F0AEC70F4BBDADCE829783A0AFFF43F384C640) - addr_10 = Address(0x4BA6259BB96E9D7822A5FB3A1F8037BC68A08D43) - addr_11 = Address(0xBEB47E021A70649B079C4BDF150108C0D8C6ACCB) - addr_12 = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xFF8D58222F34F6890DDAA468C023B77D6691ED7D3C4DCDDAE38336212FAF54B - ) + addr_5 = Address(0x0000000000000000000000000000000000000001) + addr_6 = Address(0x0000000000000000000000000000000000000002) + addr_7 = Address(0x0000000000000000000000000000000000000003) + addr_8 = Address(0x0000000000000000000000000000000000000004) + addr_9 = Address(0x0000000000000000000000000000000000000005) + addr_10 = Address(0x0000000000000000000000000000000000000006) + addr_11 = Address(0x0000000000000000000000000000000000000007) + addr_12 = Address(0x0000000000000000000000000000000000000008) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -88,6 +85,14 @@ def test_revert_precompiled_touch_nonce( gas_limit=4012015, ) + pre[addr_5] = Account(balance=0, nonce=1) + pre[addr_6] = Account(balance=0, nonce=1) + pre[addr_7] = Account(balance=0, nonce=1) + pre[addr_8] = Account(balance=0, nonce=1) + pre[addr_9] = Account(balance=0, nonce=1) + pre[addr_10] = Account(balance=0, nonce=1) + pre[addr_11] = Account(balance=0, nonce=1) + pre[addr_12] = Account(balance=0, nonce=1) # Source: lll # { (CALLCODE (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -480,15 +485,6 @@ def test_revert_precompiled_touch_nonce( nonce=0, address=Address(0x10EF6D6218ADA53728683CEC4D5160C8C72159BD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[addr_5] = Account(balance=0, nonce=1) - pre[addr_6] = Account(balance=0, nonce=1) - pre[addr_7] = Account(balance=0, nonce=1) - pre[addr_8] = Account(balance=0, nonce=1) - pre[addr_9] = Account(balance=0, nonce=1) - pre[addr_10] = Account(balance=0, nonce=1) - pre[addr_11] = Account(balance=0, nonce=1) - pre[addr_12] = Account(balance=0, nonce=1) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_noncestorage.py b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_noncestorage.py index 0c42b17c3e1..749bb8a785d 100644 --- a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_noncestorage.py +++ b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_noncestorage.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -69,17 +68,15 @@ def test_revert_precompiled_touch_noncestorage( ) -> None: """Test_revert_precompiled_touch_noncestorage.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - addr_5 = Address(0xB0A7B7B80BC0F95F8890E6E2070DDC906BBFDBCD) - addr_6 = Address(0xE2041123687B446E6F4BA274BFED4CE0206D4C8E) - addr_7 = Address(0x0D6D2DA01A9DA2C336E2AFFE3E6A9D0787069B56) - addr_8 = Address(0x1E28DB5341D617CCE6178F0BBCCB352C51C5909D) - addr_9 = Address(0xAE321AB38D9488985A884ED293F2C1466D2C806B) - addr_10 = Address(0xF6165BB84BEB5028557005861FAA9B085C1381D9) - addr_11 = Address(0x9BCE9E56A0A95F42D0B6A7B550E26604D7C5299F) - addr_12 = Address(0x0E145EDEA519E730A2C24124733E22E8B8DE1202) - sender = EOA( - key=0xFF8D58222F34F6890DDAA468C023B77D6691ED7D3C4DCDDAE38336212FAF54B - ) + addr_5 = Address(0x0000000000000000000000000000000000000001) + addr_6 = Address(0x0000000000000000000000000000000000000002) + addr_7 = Address(0x0000000000000000000000000000000000000003) + addr_8 = Address(0x0000000000000000000000000000000000000004) + addr_9 = Address(0x0000000000000000000000000000000000000005) + addr_10 = Address(0x0000000000000000000000000000000000000006) + addr_11 = Address(0x0000000000000000000000000000000000000007) + addr_12 = Address(0x0000000000000000000000000000000000000008) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -90,6 +87,14 @@ def test_revert_precompiled_touch_noncestorage( gas_limit=4012015, ) + pre[addr_5] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_6] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_7] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_8] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_9] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_10] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_11] = Account(balance=0, nonce=1, storage={0: addr_5}) + pre[addr_12] = Account(balance=0, nonce=1, storage={0: addr_5}) # Source: lll # { (CALLCODE (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -482,15 +487,6 @@ def test_revert_precompiled_touch_noncestorage( nonce=0, address=Address(0x10EF6D6218ADA53728683CEC4D5160C8C72159BD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[addr_5] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_6] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_7] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_8] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_9] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_10] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_11] = Account(balance=0, nonce=1, storage={0: 1}) - pre[addr_12] = Account(balance=0, nonce=1, storage={0: 1}) tx_data = [ Hash(addr, left_padding=True), @@ -509,14 +505,14 @@ def test_revert_precompiled_touch_noncestorage( ) post = { - addr_5: Account(storage={0: 1}, nonce=1), - addr_6: Account(storage={0: 1}, nonce=1), - addr_7: Account(storage={0: 1}, nonce=1), - addr_8: Account(storage={0: 1}, nonce=1), - addr_9: Account(storage={0: 1}, nonce=1), - addr_10: Account(storage={0: 1}, nonce=1), - addr_11: Account(storage={0: 1}, nonce=1), - addr_12: Account(storage={0: 1}, nonce=1), + addr_5: Account(storage={0: addr_5}, nonce=1), + addr_6: Account(storage={0: addr_5}, nonce=1), + addr_7: Account(storage={0: addr_5}, nonce=1), + addr_8: Account(storage={0: addr_5}, nonce=1), + addr_9: Account(storage={0: addr_5}, nonce=1), + addr_10: Account(storage={0: addr_5}, nonce=1), + addr_11: Account(storage={0: addr_5}, nonce=1), + addr_12: Account(storage={0: addr_5}, nonce=1), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_paris.py b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_paris.py index 2e938522306..5e3ebc1ede5 100644 --- a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_paris.py @@ -70,14 +70,14 @@ def test_revert_precompiled_touch_paris( ) -> None: """Test_revert_precompiled_touch_paris.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - addr_5 = Address(0x6EB9AFCB5D985B12549B7AC2E65C093F7113A0C7) - addr_6 = Address(0xF07A794E0F8AAB4242B86368503D3C1DE15481F8) - addr_7 = Address(0x9E6C35DECED6E05EB21D3465B5BBBB57B9CD57D6) - addr_8 = Address(0x1688023D9AE9E25EA02A2447A77B9CC9D22CE57B) - addr_9 = Address(0xD085AB47BC36D1238FC092679B21B10792746640) - addr_10 = Address(0xAD3DF2901B7C6642E397C35E0E9F3DEA5D098238) - addr_11 = Address(0xBE44B82021B08CFECC33A2E57FF5ADCB7FE3B049) - addr_12 = Address(0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA) + addr_5 = Address(0x0000000000000000000000000000000000000001) + addr_6 = Address(0x0000000000000000000000000000000000000002) + addr_7 = Address(0x0000000000000000000000000000000000000003) + addr_8 = Address(0x0000000000000000000000000000000000000004) + addr_9 = Address(0x0000000000000000000000000000000000000005) + addr_10 = Address(0x0000000000000000000000000000000000000006) + addr_11 = Address(0x0000000000000000000000000000000000000007) + addr_12 = Address(0x0000000000000000000000000000000000000008) sender = EOA( key=0xFF8D58222F34F6890DDAA468C023B77D6691ED7D3C4DCDDAE38336212FAF54B ) @@ -91,6 +91,15 @@ def test_revert_precompiled_touch_paris( gas_limit=4012015, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) + pre[addr_5] = Account(balance=1) + pre[addr_6] = Account(balance=1) + pre[addr_7] = Account(balance=1) + pre[addr_8] = Account(balance=1) + pre[addr_9] = Account(balance=1) + pre[addr_10] = Account(balance=1) + pre[addr_11] = Account(balance=1) + pre[addr_12] = Account(balance=1) # Source: lll # { (CALLCODE (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -483,15 +492,6 @@ def test_revert_precompiled_touch_paris( nonce=0, address=Address(0x10EF6D6218ADA53728683CEC4D5160C8C72159BD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[addr_5] = Account(balance=1) - pre[addr_6] = Account(balance=1) - pre[addr_7] = Account(balance=1) - pre[addr_8] = Account(balance=1) - pre[addr_9] = Account(balance=1) - pre[addr_10] = Account(balance=1) - pre[addr_11] = Account(balance=1) - pre[addr_12] = Account(balance=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_storage_paris.py b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_storage_paris.py index cd8295af53c..25d6fe6394e 100644 --- a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_storage_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_storage_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -72,17 +71,15 @@ def test_revert_precompiled_touch_storage_paris( ) -> None: """Test_revert_precompiled_touch_storage_paris.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - addr_5 = Address(0x9DEB46A3B3E955BD56ECC4072DA4B42BD9B5DB2C) - addr_6 = Address(0xA8FD4CB9C2C538ED7FF94C3B711B2E08A08C7FB8) - addr_7 = Address(0x6D15138CE372D9B89EE38FC3973B715477426F11) - addr_8 = Address(0x46AC2E7E1550D911E5A72FBC51C15CA817DBB1D5) - addr_9 = Address(0x0DC4B229346287FE9FA441960081A9886B71C42D) - addr_10 = Address(0x3A3EEE808C401A574F92824DC64D89EDB05FAFE4) - addr_11 = Address(0xDA7F8ADD6896B7E58F28331A97B315DDE5FB8CD1) - addr_12 = Address(0x4757608F18B70777AE788DD4056EEED52F7AA68F) - sender = EOA( - key=0xFF8D58222F34F6890DDAA468C023B77D6691ED7D3C4DCDDAE38336212FAF54B - ) + addr_5 = Address(0x0000000000000000000000000000000000000001) + addr_6 = Address(0x0000000000000000000000000000000000000002) + addr_7 = Address(0x0000000000000000000000000000000000000003) + addr_8 = Address(0x0000000000000000000000000000000000000004) + addr_9 = Address(0x0000000000000000000000000000000000000005) + addr_10 = Address(0x0000000000000000000000000000000000000006) + addr_11 = Address(0x0000000000000000000000000000000000000007) + addr_12 = Address(0x0000000000000000000000000000000000000008) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -93,6 +90,14 @@ def test_revert_precompiled_touch_storage_paris( gas_limit=4012015, ) + pre[addr_5] = Account(balance=10, storage={0: addr_5}) + pre[addr_6] = Account(balance=10, storage={0: addr_5}) + pre[addr_7] = Account(balance=10, storage={0: addr_5}) + pre[addr_8] = Account(balance=10, storage={0: addr_5}) + pre[addr_9] = Account(balance=10, storage={0: addr_5}) + pre[addr_10] = Account(balance=10, storage={0: addr_5}) + pre[addr_11] = Account(balance=10, storage={0: addr_5}) + pre[addr_12] = Account(balance=10, storage={0: addr_5}) # Source: lll # { (CALLCODE (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -485,43 +490,34 @@ def test_revert_precompiled_touch_storage_paris( nonce=0, address=Address(0x10EF6D6218ADA53728683CEC4D5160C8C72159BD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[addr_5] = Account(balance=10, storage={0: 1}) - pre[addr_6] = Account(balance=10, storage={0: 1}) - pre[addr_7] = Account(balance=10, storage={0: 1}) - pre[addr_8] = Account(balance=10, storage={0: 1}) - pre[addr_9] = Account(balance=10, storage={0: 1}) - pre[addr_10] = Account(balance=10, storage={0: 1}) - pre[addr_11] = Account(balance=10, storage={0: 1}) - pre[addr_12] = Account(balance=10, storage={0: 1}) expect_entries_: list[dict] = [ { "indexes": {"data": [0, 3], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - addr_5: Account(storage={0: 1}), - addr_6: Account(storage={0: 1}), + addr_5: Account(storage={0: addr_5}), + addr_6: Account(storage={0: addr_5}), addr_7: Account(balance=10), - addr_8: Account(storage={0: 1}), - addr_9: Account(storage={0: 1}), - addr_10: Account(storage={0: 1}), - addr_11: Account(storage={0: 1}), - addr_12: Account(storage={0: 1}), + addr_8: Account(storage={0: addr_5}), + addr_9: Account(storage={0: addr_5}), + addr_10: Account(storage={0: addr_5}), + addr_11: Account(storage={0: addr_5}), + addr_12: Account(storage={0: addr_5}), }, }, { "indexes": {"data": [1, 2], "gas": -1, "value": -1}, "network": [">=Cancun"], "result": { - addr_5: Account(storage={0: 1}), - addr_6: Account(storage={0: 1}), - addr_7: Account(storage={0: 1}), - addr_8: Account(storage={0: 1}), - addr_9: Account(storage={0: 1}), - addr_10: Account(storage={0: 1}), - addr_11: Account(storage={0: 1}), - addr_12: Account(storage={0: 1}), + addr_5: Account(storage={0: addr_5}), + addr_6: Account(storage={0: addr_5}), + addr_7: Account(storage={0: addr_5}), + addr_8: Account(storage={0: addr_5}), + addr_9: Account(storage={0: addr_5}), + addr_10: Account(storage={0: addr_5}), + addr_11: Account(storage={0: addr_5}), + addr_12: Account(storage={0: addr_5}), }, }, ] diff --git a/tests/ported_static/stRevertTest/test_revert_prefound_call.py b/tests/ported_static/stRevertTest/test_revert_prefound_call.py index 6edd7015083..6a0f2e314e3 100644 --- a/tests/ported_static/stRevertTest/test_revert_prefound_call.py +++ b/tests/ported_static/stRevertTest/test_revert_prefound_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_revert_prefound_call( ) -> None: """Test_revert_prefound_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_revert_prefound_call( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=1) + addr = pre.fund_eoa(amount=1) # noqa: F841 # Source: lll # { [[0]] (CALL 50000 0 0 32 0 32) [[1]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +51,7 @@ def test_revert_prefound_call( key=0x0, value=Op.CALL( gas=0xC350, - address=0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA, + address=addr, value=0x0, args_offset=0x0, args_size=0x20, @@ -68,7 +63,6 @@ def test_revert_prefound_call( + Op.STOP, balance=1, nonce=0, - address=Address(0x10E193907AA28773CC8F835C3B27BB02D064CE8C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_prefound_call_oog.py b/tests/ported_static/stRevertTest/test_revert_prefound_call_oog.py index 43f6cb9ff10..dfceed27321 100644 --- a/tests/ported_static/stRevertTest/test_revert_prefound_call_oog.py +++ b/tests/ported_static/stRevertTest/test_revert_prefound_call_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_revert_prefound_call_oog( ) -> None: """Test_revert_prefound_call_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_revert_prefound_call_oog( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=1) + addr = pre.fund_eoa(amount=1) # noqa: F841 # Source: lll # { [[0]] (CALL 50000 0 0 32 0 32) [[1]]12 [[2]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +51,7 @@ def test_revert_prefound_call_oog( key=0x0, value=Op.CALL( gas=0xC350, - address=0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA, + address=addr, value=0x0, args_offset=0x0, args_size=0x20, @@ -69,7 +64,6 @@ def test_revert_prefound_call_oog( + Op.STOP, balance=1, nonce=0, - address=Address(0xF679BFE5F61E7640B9A66DB191D5D86ABC7B5C0A), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_oog_paris.py b/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_oog_paris.py index 9b1d30c4405..53b3b0a41b2 100644 --- a/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_oog_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_oog_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_revert_prefound_empty_call_oog_paris( ) -> None: """Test_revert_prefound_empty_call_oog_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_revert_prefound_empty_call_oog_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]] (CALL 50000 0 0 32 0 32) [[1]]12 [[2]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +51,7 @@ def test_revert_prefound_empty_call_oog_paris( key=0x0, value=Op.CALL( gas=0xC350, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x20, @@ -69,7 +64,6 @@ def test_revert_prefound_empty_call_oog_paris( + Op.STOP, balance=1, nonce=0, - address=Address(0xF679BFE5F61E7640B9A66DB191D5D86ABC7B5C0A), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_paris.py b/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_paris.py index 1d991f29514..83e7110f8cf 100644 --- a/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_prefound_empty_call_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_revert_prefound_empty_call_paris( ) -> None: """Test_revert_prefound_empty_call_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_revert_prefound_empty_call_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]] (CALL 50000 0 0 32 0 32) [[1]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +51,7 @@ def test_revert_prefound_empty_call_paris( key=0x0, value=Op.CALL( gas=0xC350, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x20, @@ -68,7 +63,6 @@ def test_revert_prefound_empty_call_paris( + Op.STOP, balance=1, nonce=0, - address=Address(0x10E193907AA28773CC8F835C3B27BB02D064CE8C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_prefound_empty_oog_paris.py b/tests/ported_static/stRevertTest/test_revert_prefound_empty_oog_paris.py index a60de2e277b..230847cde3b 100644 --- a/tests/ported_static/stRevertTest/test_revert_prefound_empty_oog_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_prefound_empty_oog_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_revert_prefound_empty_oog_paris( ) -> None: """Test_revert_prefound_empty_oog_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_revert_prefound_empty_oog_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]] (CREATE 0 0 32) (KECCAK256 0x00 0x2fffff) } target = pre.deploy_contract( # noqa: F841 @@ -59,7 +54,6 @@ def test_revert_prefound_empty_oog_paris( + Op.STOP, balance=1, nonce=0, - address=Address(0x35B3F8CA79C46F2CBC3DB596A2162ADE570B0ADD), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_prefound_oog.py b/tests/ported_static/stRevertTest/test_revert_prefound_oog.py index 4b1599d2595..7f1e1984a35 100644 --- a/tests/ported_static/stRevertTest/test_revert_prefound_oog.py +++ b/tests/ported_static/stRevertTest/test_revert_prefound_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_revert_prefound_oog( ) -> None: """Test_revert_prefound_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x85FDDE91FD0CE22A2968E1F1B2EBB9F9E5A180BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_revert_prefound_oog( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=1) + addr = pre.fund_eoa(amount=1) # noqa: F841 # Source: lll # { [[0]] (CREATE 0 0 32) (KECCAK256 0x00 0x2fffff) } target = pre.deploy_contract( # noqa: F841 @@ -59,7 +54,6 @@ def test_revert_prefound_oog( + Op.STOP, balance=1, nonce=0, - address=Address(0x35B3F8CA79C46F2CBC3DB596A2162ADE570B0ADD), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog.py b/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog.py index 1c937b7f41a..db8c009d780 100644 --- a/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog.py +++ b/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -69,9 +68,7 @@ def test_revert_sub_call_storage_oog( ) -> None: """Test_revert_sub_call_storage_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -82,7 +79,6 @@ def test_revert_sub_call_storage_oog( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: raw # 0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b28175c4146046578063c0406226146052575b6000565b3460005760506076565b005b34600057605c6081565b604051808215151515815260200191505060405180910390f35b600c6000819055505b565b600060896076565b600d600181905550600e600281905550600190505b905600a165627a7a723058202a8a75d7d795b5bcb9042fb18b283daa90b999a11ddec892f548732235342eb60029 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -91,7 +87,6 @@ def test_revert_sub_call_storage_oog( ), balance=1, nonce=0, - address=Address(0xDFA0378009E95C6B0E668DB83477627C9B1E5D01), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog2.py b/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog2.py index 3b7e394193f..6b5bf707e63 100644 --- a/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog2.py +++ b/tests/ported_static/stRevertTest/test_revert_sub_call_storage_oog2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -69,9 +68,7 @@ def test_revert_sub_call_storage_oog2( ) -> None: """Test_revert_sub_call_storage_oog2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -82,7 +79,6 @@ def test_revert_sub_call_storage_oog2( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: raw # 0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b28175c4146046578063c0406226146052575b6000565b3460005760506076565b005b34600057605c6081565b604051808215151515815260200191505060405180910390f35b600c6000819055505b565b600060896076565b600d600081905550600e6001819055505b905600a165627a7a72305820b7c6987c21e63fed8a74d899557744a3be8d3fda191ce0f56cf261d6b860f6b40029 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -91,7 +87,6 @@ def test_revert_sub_call_storage_oog2( ), balance=1, nonce=0, - address=Address(0x48BC00BE37FE77BD0F7B7B8009F908FC534A028B), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stRevertTest/test_state_revert.py b/tests/ported_static/stRevertTest/test_state_revert.py index 3b215dcea25..85f9817b996 100644 --- a/tests/ported_static/stRevertTest/test_state_revert.py +++ b/tests/ported_static/stRevertTest/test_state_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -86,9 +85,7 @@ def test_state_revert( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA62D63F95900B04CCD3FEE13360DE78966F24695945E8B2C09E646352BC5AF94 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -274,7 +271,6 @@ def test_state_revert( nonce=0, address=Address(0x3559AFE49654B532B7E67E6ACD87DEB8C569E7AD), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert2_paris.py b/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert2_paris.py index a47979fd9d7..29bd0114ae8 100644 --- a/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert2_paris.py +++ b/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert2_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_touch_to_empty_account_revert2_paris( ) -> None: """Test_touch_to_empty_account_revert2_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,16 +43,15 @@ def test_touch_to_empty_account_revert2_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll - # { [[0]](CALL 130000 0 0 0 0 0) [[1]](CALL 130000 0 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { [[2]](CALL 130000 0 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( gas=0x1FBD0, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -64,11 +59,18 @@ def test_touch_to_empty_account_revert2_paris( ret_size=0x0, ), ) - + Op.SSTORE( - key=0x1, + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[0]](CALL 130000 0 0 0 0 0) [[1]](CALL 130000 0 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALL( gas=0x1FBD0, - address=0xFC4D79463BC948EB3FE54196270DE2B78C201506, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -76,18 +78,11 @@ def test_touch_to_empty_account_revert2_paris( ret_size=0x0, ), ) - + Op.STOP, - nonce=0, - address=Address(0x0982DE98D43928669EC4ED9FEA05F2B852BBEC41), # noqa: E501 - ) - # Source: lll - # { [[2]](CALL 130000 0 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x2, + + Op.SSTORE( + key=0x1, value=Op.CALL( gas=0x1FBD0, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -95,10 +90,8 @@ def test_touch_to_empty_account_revert2_paris( ret_size=0x0, ), ) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xFC4D79463BC948EB3FE54196270DE2B78C201506), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert3_paris.py b/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert3_paris.py index 4aba629a847..842d8334f4b 100644 --- a/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert3_paris.py +++ b/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert3_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_touch_to_empty_account_revert3_paris( ) -> None: """Test_touch_to_empty_account_revert3_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,16 +43,27 @@ def test_touch_to_empty_account_revert3_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll - # { [[0]](CALL 130000 0 0 0 0 0) [[1]](CALL 130000 0 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { (SELFDESTRUCT ) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=addr) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (SELFDESTRUCT ) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=addr) + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[2]](CALL 100000 0 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x2, value=Op.CALL( - gas=0x1FBD0, - address=0x51CD6399DE7E11930D3AA146D45A2E327B5894B9, + gas=0x186A0, + address=addr_4, value=0x0, args_offset=0x0, args_size=0x0, @@ -64,11 +71,18 @@ def test_touch_to_empty_account_revert3_paris( ret_size=0x0, ), ) - + Op.SSTORE( - key=0x1, + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[0]](CALL 130000 0 0 0 0 0) [[1]](CALL 130000 0 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, value=Op.CALL( gas=0x1FBD0, - address=0x2620916B2F3D6B185F4D9DD1ECEE4A1F665D5C36, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x0, @@ -76,18 +90,11 @@ def test_touch_to_empty_account_revert3_paris( ret_size=0x0, ), ) - + Op.STOP, - nonce=0, - address=Address(0xCD48E0C45933CFA7AA1345807CF2D6B02875F627), # noqa: E501 - ) - # Source: lll - # { [[2]](CALL 100000 0 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x2, + + Op.SSTORE( + key=0x1, value=Op.CALL( - gas=0x186A0, - address=0x28207E524CCB9DBC79BB3044819ACD87D630F27A, + gas=0x1FBD0, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -95,30 +102,8 @@ def test_touch_to_empty_account_revert3_paris( ret_size=0x0, ), ) - + Op.SHA3(offset=0x0, size=0x2FFFFF) - + Op.STOP, - nonce=0, - address=Address(0x2620916B2F3D6B185F4D9DD1ECEE4A1F665D5C36), # noqa: E501 - ) - # Source: lll - # { (SELFDESTRUCT ) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x76FAE819612A29489A1A43208613D8F8557B8898 - ) - + Op.STOP, - nonce=0, - address=Address(0x51CD6399DE7E11930D3AA146D45A2E327B5894B9), # noqa: E501 - ) - # Source: lll - # { (SELFDESTRUCT ) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x76FAE819612A29489A1A43208613D8F8557B8898 - ) + Op.STOP, nonce=0, - address=Address(0x28207E524CCB9DBC79BB3044819ACD87D630F27A), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert_paris.py b/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert_paris.py index 956e446364b..8f01e8ee6c1 100644 --- a/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert_paris.py +++ b/tests/ported_static/stRevertTest/test_touch_to_empty_account_revert_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_touch_to_empty_account_revert_paris( ) -> None: """Test_touch_to_empty_account_revert_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,16 +43,15 @@ def test_touch_to_empty_account_revert_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll - # { [[0]](CALL 30000 0 0 0 0 0) [[2]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 + # { [[1]](CALL 30000 0 0 0 0 0) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x0, + key=0x1, value=Op.CALL( gas=0x7530, - address=0xBA4D09EB64FDDCEC11D7587E1F51AC0B07C5069C, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -64,19 +59,17 @@ def test_touch_to_empty_account_revert_paris( ret_size=0x0, ), ) - + Op.SSTORE(key=0x2, value=0x1) + Op.STOP, nonce=0, - address=Address(0x68B5E303DA0AD3DFBA8B2134BAB64274DE666F37), # noqa: E501 ) # Source: lll - # { [[1]](CALL 30000 0 0 0 0 0) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { [[0]](CALL 30000 0 0 0 0 0) [[2]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( - key=0x1, + key=0x0, value=Op.CALL( gas=0x7530, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr_2, value=0x0, args_offset=0x0, args_size=0x0, @@ -84,9 +77,9 @@ def test_touch_to_empty_account_revert_paris( ret_size=0x0, ), ) + + Op.SSTORE(key=0x2, value=0x1) + Op.STOP, nonce=0, - address=Address(0xBA4D09EB64FDDCEC11D7587E1F51AC0B07C5069C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stSStoreTest/test_sstore_call_to_self_sub_refund_below_zero.py b/tests/ported_static/stSStoreTest/test_sstore_call_to_self_sub_refund_below_zero.py index d0363ffc99a..71052640eb1 100644 --- a/tests/ported_static/stSStoreTest/test_sstore_call_to_self_sub_refund_below_zero.py +++ b/tests/ported_static/stSStoreTest/test_sstore_call_to_self_sub_refund_below_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sstore_call_to_self_sub_refund_below_zero( ) -> None: """Test where accnt has slot 1 value of '2', is cleared, then calls...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xAF50993BA9FD52F2A61FCD1DC6D59A44E7AF39F4289201CC19EA7D30E8E27E83 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -66,9 +63,7 @@ def test_sstore_call_to_self_sub_refund_below_zero( + Op.STOP, storage={1: 2}, nonce=0, - address=Address(0xB48023055B6C3D565A6F5488459D64EFAB79B6C7), # noqa: E501 ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSStoreTest/test_sstore_gas.py b/tests/ported_static/stSStoreTest/test_sstore_gas.py index 059c539c049..975d3765c56 100644 --- a/tests/ported_static/stSStoreTest/test_sstore_gas.py +++ b/tests/ported_static/stSStoreTest/test_sstore_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sstore_gas( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x48DC5A9F099CAAAA557742CA3A990A94BE45B9969126A1BC74E5E8BE5A2B5B47 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE, nonce=1) env = Environment( fee_recipient=coinbase, @@ -164,9 +161,7 @@ def test_sstore_gas( storage={0: 24743, 1: 24743}, balance=0xBA1A9CE0BA1A9CE, nonce=1, - address=Address(0x84E1DC6705B8B9B7FFACA256C9266792BDD0943B), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSelfBalance/test_self_balance.py b/tests/ported_static/stSelfBalance/test_self_balance.py index 23828020906..af929bf08c8 100644 --- a/tests/ported_static/stSelfBalance/test_self_balance.py +++ b/tests/ported_static/stSelfBalance/test_self_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_self_balance( ) -> None: """Test_self_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_self_balance( code=Op.SSTORE(key=0x1, value=Op.SELFBALANCE) + Op.STOP, balance=500, nonce=0, - address=Address(0xC4686D898FAA85A20D23378B84956C9E10295DB5), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSelfBalance/test_self_balance_call_types.py b/tests/ported_static/stSelfBalance/test_self_balance_call_types.py index d28cf8016a1..fb8f5d29929 100644 --- a/tests/ported_static/stSelfBalance/test_self_balance_call_types.py +++ b/tests/ported_static/stSelfBalance/test_self_balance_call_types.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,9 +63,7 @@ def test_self_balance_call_types( ) -> None: """SELFBALANCE tests inside CALL, DELEGATECALL, and CALLCODE.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -199,17 +196,11 @@ def test_self_balance_call_types( + Op.JUMP(pc=0x5) + Op.JUMPDEST + Op.STOP, - storage={ - 0: 0xA590BBF1B07B00FED987724E1DB1BF206C2BC37C, - 1: 0x76BAC61EE2056F42F6CC29F5400ADAE3E5705237, - 2: 0x8537CE29429EA557E3903C255EE6554DD8D21D26, - 3: 0xE1CE93B3251FB38AE74D41AF9F865978C572CF63, - }, + storage={0: addr, 1: addr_2, 2: addr_3, 3: addr_4}, balance=8192, nonce=0, address=Address(0x84BF87FBEF135AFEA15330FDF5847EB504CFF901), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) expect_entries_: list[dict] = [ { @@ -228,10 +219,10 @@ def test_self_balance_call_types( "result": { target: Account( storage={ - 0: 0xA590BBF1B07B00FED987724E1DB1BF206C2BC37C, - 1: 0x76BAC61EE2056F42F6CC29F5400ADAE3E5705237, - 2: 0x8537CE29429EA557E3903C255EE6554DD8D21D26, - 3: 0xE1CE93B3251FB38AE74D41AF9F865978C572CF63, + 0: addr, + 1: addr_2, + 2: addr_3, + 3: addr_4, 17: 1, 33: 8192, 49: 5, diff --git a/tests/ported_static/stSelfBalance/test_self_balance_equals_balance.py b/tests/ported_static/stSelfBalance/test_self_balance_equals_balance.py index b5b52153141..c4e11a686d2 100644 --- a/tests/ported_static/stSelfBalance/test_self_balance_equals_balance.py +++ b/tests/ported_static/stSelfBalance/test_self_balance_equals_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_self_balance_equals_balance( ) -> None: """Test_self_balance_equals_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -56,9 +53,7 @@ def test_self_balance_equals_balance( + Op.STOP, balance=500, nonce=0, - address=Address(0x2F9DC2C2519CFD4FF8F7F296575C59DBE303D452), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSelfBalance/test_self_balance_gas_cost.py b/tests/ported_static/stSelfBalance/test_self_balance_gas_cost.py index 550b06f00cd..7d45e07fe17 100644 --- a/tests/ported_static/stSelfBalance/test_self_balance_gas_cost.py +++ b/tests/ported_static/stSelfBalance/test_self_balance_gas_cost.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_self_balance_gas_cost( ) -> None: """Test_self_balance_gas_cost.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -61,9 +58,7 @@ def test_self_balance_gas_cost( + Op.SSTORE(key=0x1, value=Op.SUB) + Op.STOP, nonce=0, - address=Address(0x20005B9A765D12C8F6AC08C2673B00FA6BE00486), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSelfBalance/test_self_balance_update.py b/tests/ported_static/stSelfBalance/test_self_balance_update.py index 79deaf3c9d2..549903be9d1 100644 --- a/tests/ported_static/stSelfBalance/test_self_balance_update.py +++ b/tests/ported_static/stSelfBalance/test_self_balance_update.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_self_balance_update( ) -> None: """Test_self_balance_update.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x897B12D02D588D8A4FE16FF831CBD4459C6F62F8C845B0CCDD31CAF068C84A26 - ) + sender = pre.fund_eoa(amount=0x3635C9ADC5DEA00000) env = Environment( fee_recipient=coinbase, @@ -69,9 +66,7 @@ def test_self_balance_update( + Op.STOP, balance=500, nonce=0, - address=Address(0xFF44472F5FFDD079C61153F097871F57C1F689CA), # noqa: E501 ) - pre[sender] = Account(balance=0x3635C9ADC5DEA00000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar00.py b/tests/ported_static/stShift/test_sar00.py index bab4d933456..14480fdf678 100644 --- a/tests/ported_static/stShift/test_sar00.py +++ b/tests/ported_static/stShift/test_sar00.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar00( ) -> None: """Test_sar00.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_sar00( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9AD94489822593B54793E82913F291C9207D1310), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar01.py b/tests/ported_static/stShift/test_sar01.py index 299444854af..a80bacfb039 100644 --- a/tests/ported_static/stShift/test_sar01.py +++ b/tests/ported_static/stShift/test_sar01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar01( ) -> None: """Test_sar01.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_sar01( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2DDE5F71C0D0ECC67A9AE94C2CAFA14FBB93B84C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar10.py b/tests/ported_static/stShift/test_sar10.py index 3f76aa5730a..8073e9ba4a0 100644 --- a/tests/ported_static/stShift/test_sar10.py +++ b/tests/ported_static/stShift/test_sar10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar10( ) -> None: """Test_sar10.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_sar10( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA3460B99A5BCB7697BEFBFFF895F60BDF7984363), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar11.py b/tests/ported_static/stShift/test_sar11.py index 0d593ab415d..3663b7b651d 100644 --- a/tests/ported_static/stShift/test_sar11.py +++ b/tests/ported_static/stShift/test_sar11.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar11( ) -> None: """Test_sar11.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_sar11( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7362D25017F41B7D56BC5878CBB1FB9B03C39E26), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_0_256_minus_1.py b/tests/ported_static/stShift/test_sar_0_256_minus_1.py index 2072027865b..5d4794477c7 100644 --- a/tests/ported_static/stShift/test_sar_0_256_minus_1.py +++ b/tests/ported_static/stShift/test_sar_0_256_minus_1.py @@ -46,6 +46,7 @@ def test_sar_0_256_minus_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (SSTORE 0 (SAR 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,7 +63,6 @@ def test_sar_0_256_minus_1( nonce=0, address=Address(0xD1E074895679E6AFB7A9F3CB1AC3FFA300D2A5E8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_254_254.py b/tests/ported_static/stShift/test_sar_2_254_254.py index 77350fa415e..1e56f56b8cf 100644 --- a/tests/ported_static/stShift/test_sar_2_254_254.py +++ b/tests/ported_static/stShift/test_sar_2_254_254.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar_2_254_254( ) -> None: """Test_sar_2_254_254.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_sar_2_254_254( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6F6A7E06C68B63202842C646A7EB4F01880D8AF0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_1.py b/tests/ported_static/stShift/test_sar_2_255_1.py index 0019f19ade1..c6903037aee 100644 --- a/tests/ported_static/stShift/test_sar_2_255_1.py +++ b/tests/ported_static/stShift/test_sar_2_255_1.py @@ -46,6 +46,7 @@ def test_sar_2_255_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f800000000000000000000000000000000000000000000000000000000000000060011d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_255_1( nonce=0, address=Address(0xB6587B163F780EAAA5C216DD3DDF2E381FEAA96C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_255.py b/tests/ported_static/stShift/test_sar_2_255_255.py index 935617c7ad9..b250ba79a06 100644 --- a/tests/ported_static/stShift/test_sar_2_255_255.py +++ b/tests/ported_static/stShift/test_sar_2_255_255.py @@ -46,6 +46,7 @@ def test_sar_2_255_255( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f800000000000000000000000000000000000000000000000000000000000000060ff1d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_255_255( nonce=0, address=Address(0xED3A766218E6436FD80F97075B08DF750F226F0D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_256.py b/tests/ported_static/stShift/test_sar_2_255_256.py index d4d2eb6db16..1939c68afef 100644 --- a/tests/ported_static/stShift/test_sar_2_255_256.py +++ b/tests/ported_static/stShift/test_sar_2_255_256.py @@ -46,6 +46,7 @@ def test_sar_2_255_256( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f80000000000000000000000000000000000000000000000000000000000000006101001d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_255_256( nonce=0, address=Address(0xAF9B43858D7F35038AEA2ACF1FFFEA3DF1AB4BCC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_257.py b/tests/ported_static/stShift/test_sar_2_255_257.py index 4572c012fbc..be83634889e 100644 --- a/tests/ported_static/stShift/test_sar_2_255_257.py +++ b/tests/ported_static/stShift/test_sar_2_255_257.py @@ -46,6 +46,7 @@ def test_sar_2_255_257( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f80000000000000000000000000000000000000000000000000000000000000006101011d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_255_257( nonce=0, address=Address(0xF1B108EB4DE4C7A4C0B2258442C550D23DF640A0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_minus_1_248.py b/tests/ported_static/stShift/test_sar_2_255_minus_1_248.py index f8ea1bb304b..6b17e228638 100644 --- a/tests/ported_static/stShift/test_sar_2_255_minus_1_248.py +++ b/tests/ported_static/stShift/test_sar_2_255_minus_1_248.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar_2_255_minus_1_248( ) -> None: """Test_sar_2_255_minus_1_248.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_sar_2_255_minus_1_248( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xACA270CA7F9E766B84A13DE48F52DAFC92B80F8E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_minus_1_254.py b/tests/ported_static/stShift/test_sar_2_255_minus_1_254.py index 4b7bcca5a1b..8c5b0743ac9 100644 --- a/tests/ported_static/stShift/test_sar_2_255_minus_1_254.py +++ b/tests/ported_static/stShift/test_sar_2_255_minus_1_254.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar_2_255_minus_1_254( ) -> None: """Test_sar_2_255_minus_1_254.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_sar_2_255_minus_1_254( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x21F937F03A969139CFD6A0C20959317D0A4AE6BA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_minus_1_255.py b/tests/ported_static/stShift/test_sar_2_255_minus_1_255.py index 657353f00bb..d6b7bee6ae0 100644 --- a/tests/ported_static/stShift/test_sar_2_255_minus_1_255.py +++ b/tests/ported_static/stShift/test_sar_2_255_minus_1_255.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar_2_255_minus_1_255( ) -> None: """Test_sar_2_255_minus_1_255.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_sar_2_255_minus_1_255( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x38EF04946EAFCF6E172CC1AB51F731A7DF62AE9C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_255_minus_1_256.py b/tests/ported_static/stShift/test_sar_2_255_minus_1_256.py index 1cecc9bd5db..fcf388e727d 100644 --- a/tests/ported_static/stShift/test_sar_2_255_minus_1_256.py +++ b/tests/ported_static/stShift/test_sar_2_255_minus_1_256.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar_2_255_minus_1_256( ) -> None: """Test_sar_2_255_minus_1_256.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_sar_2_255_minus_1_256( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2FC6CB11C70CD31A1BB03C5149F434D6C9C553AA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_256_minus_1_0.py b/tests/ported_static/stShift/test_sar_2_256_minus_1_0.py index 4b743fc4888..76f07ec032e 100644 --- a/tests/ported_static/stShift/test_sar_2_256_minus_1_0.py +++ b/tests/ported_static/stShift/test_sar_2_256_minus_1_0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sar_2_256_minus_1_0( ) -> None: """Test_sar_2_256_minus_1_0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,9 +57,7 @@ def test_sar_2_256_minus_1_0( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x488DE231F3302A744E2D40ECC611A66F21B4DB06), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_256_minus_1_1.py b/tests/ported_static/stShift/test_sar_2_256_minus_1_1.py index 7a534b8e955..6956a3d508b 100644 --- a/tests/ported_static/stShift/test_sar_2_256_minus_1_1.py +++ b/tests/ported_static/stShift/test_sar_2_256_minus_1_1.py @@ -46,6 +46,7 @@ def test_sar_2_256_minus_1_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60011d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_256_minus_1_1( nonce=0, address=Address(0x37A6DF595C7AE4907CF940CE2ED9301836379BE0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_256_minus_1_255.py b/tests/ported_static/stShift/test_sar_2_256_minus_1_255.py index 8b81faafff7..bf1335a9f18 100644 --- a/tests/ported_static/stShift/test_sar_2_256_minus_1_255.py +++ b/tests/ported_static/stShift/test_sar_2_256_minus_1_255.py @@ -46,6 +46,7 @@ def test_sar_2_256_minus_1_255( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60ff1d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_256_minus_1_255( nonce=0, address=Address(0xD7953AA3795F1835AC719193B028850319F530EB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_sar_2_256_minus_1_256.py b/tests/ported_static/stShift/test_sar_2_256_minus_1_256.py index 715e5efbbb8..fac94aaf67a 100644 --- a/tests/ported_static/stShift/test_sar_2_256_minus_1_256.py +++ b/tests/ported_static/stShift/test_sar_2_256_minus_1_256.py @@ -46,6 +46,7 @@ def test_sar_2_256_minus_1_256( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101001d600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_sar_2_256_minus_1_256( nonce=0, address=Address(0x3E8CC6A056C48EDCE9E2ABB7F1857F69318ADD34), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shift_signed_combinations.py b/tests/ported_static/stShift/test_shift_signed_combinations.py index ead97a9b356..20e54feebf5 100644 --- a/tests/ported_static/stShift/test_shift_signed_combinations.py +++ b/tests/ported_static/stShift/test_shift_signed_combinations.py @@ -47,6 +47,7 @@ def test_shift_signed_combinations( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # (def 'sstore_n 0) @@ -310,7 +311,6 @@ def test_shift_signed_combinations( nonce=0, address=Address(0x6C08B7236EE4784E5499B9A576902679D8F863D5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl01.py b/tests/ported_static/stShift/test_shl01.py index aa480116f36..01f8cfd4069 100644 --- a/tests/ported_static/stShift/test_shl01.py +++ b/tests/ported_static/stShift/test_shl01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shl01( ) -> None: """Test_shl01.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shl01( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD968E3655CBD1FA49753B38AF57F8F335062470F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl01_minus_0100.py b/tests/ported_static/stShift/test_shl01_minus_0100.py index da671796802..d269b6d435c 100644 --- a/tests/ported_static/stShift/test_shl01_minus_0100.py +++ b/tests/ported_static/stShift/test_shl01_minus_0100.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shl01_minus_0100( ) -> None: """Test_shl01_minus_0100.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shl01_minus_0100( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA90096F3CEEE40E87EC1AFC1052BBBC98616E3E9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl01_minus_0101.py b/tests/ported_static/stShift/test_shl01_minus_0101.py index c4c2fc59590..039c045a6f3 100644 --- a/tests/ported_static/stShift/test_shl01_minus_0101.py +++ b/tests/ported_static/stShift/test_shl01_minus_0101.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shl01_minus_0101( ) -> None: """Test_shl01_minus_0101.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shl01_minus_0101( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0AD09D9167B6FD7013F4A95E9A67DAA83FBDF6FE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl01_minus_ff.py b/tests/ported_static/stShift/test_shl01_minus_ff.py index 809390060d6..278d2f2ac8d 100644 --- a/tests/ported_static/stShift/test_shl01_minus_ff.py +++ b/tests/ported_static/stShift/test_shl01_minus_ff.py @@ -46,6 +46,7 @@ def test_shl01_minus_ff( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x600160ff1b600055 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +56,6 @@ def test_shl01_minus_ff( nonce=0, address=Address(0x6750CCB18BD2D092093F25BF1EAEBE77F4ECB9A2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl10.py b/tests/ported_static/stShift/test_shl10.py index 1a9c9ee33f9..dc3ff71839e 100644 --- a/tests/ported_static/stShift/test_shl10.py +++ b/tests/ported_static/stShift/test_shl10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shl10( ) -> None: """Test_shl10.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shl10( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8162885EED8441D008AAEC61134E7B159360A9CB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl11.py b/tests/ported_static/stShift/test_shl11.py index 074955f3da6..330c5034512 100644 --- a/tests/ported_static/stShift/test_shl11.py +++ b/tests/ported_static/stShift/test_shl11.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shl11( ) -> None: """Test_shl11.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shl11( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x470AF4E9738D2348BF28D09F712BB06A118F6146), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl_2_255_minus_1_1.py b/tests/ported_static/stShift/test_shl_2_255_minus_1_1.py index 034bdaf3ace..dcae03b38f5 100644 --- a/tests/ported_static/stShift/test_shl_2_255_minus_1_1.py +++ b/tests/ported_static/stShift/test_shl_2_255_minus_1_1.py @@ -46,6 +46,7 @@ def test_shl_2_255_minus_1_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60011b600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shl_2_255_minus_1_1( nonce=0, address=Address(0x3CE647DC9F67841B40DF3DDD90FEF6FA3C44CCBC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl_minus_1_0.py b/tests/ported_static/stShift/test_shl_minus_1_0.py index 24d77d8c6b2..1ed996b4e72 100644 --- a/tests/ported_static/stShift/test_shl_minus_1_0.py +++ b/tests/ported_static/stShift/test_shl_minus_1_0.py @@ -46,6 +46,7 @@ def test_shl_minus_1_0( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shl_minus_1_0( nonce=0, address=Address(0x0630E2AC09069A9263D8D96BCB426B35D3E29A6A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl_minus_1_1.py b/tests/ported_static/stShift/test_shl_minus_1_1.py index 95730ca0366..455e23e905a 100644 --- a/tests/ported_static/stShift/test_shl_minus_1_1.py +++ b/tests/ported_static/stShift/test_shl_minus_1_1.py @@ -46,6 +46,7 @@ def test_shl_minus_1_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60011b600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shl_minus_1_1( nonce=0, address=Address(0xBCA8D83175FB98FAAE32481A974BBFEE99B931F3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl_minus_1_255.py b/tests/ported_static/stShift/test_shl_minus_1_255.py index 5a24b4fc2d0..403433f6bc1 100644 --- a/tests/ported_static/stShift/test_shl_minus_1_255.py +++ b/tests/ported_static/stShift/test_shl_minus_1_255.py @@ -46,6 +46,7 @@ def test_shl_minus_1_255( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60ff1b600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shl_minus_1_255( nonce=0, address=Address(0x09718BD7395AAFDC3E1AF2B747902980B036BEA8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shl_minus_1_256.py b/tests/ported_static/stShift/test_shl_minus_1_256.py index 7031ae2dd97..75c679ab014 100644 --- a/tests/ported_static/stShift/test_shl_minus_1_256.py +++ b/tests/ported_static/stShift/test_shl_minus_1_256.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shl_minus_1_256( ) -> None: """Test_shl_minus_1_256.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_shl_minus_1_256( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFC4F633F1E963E8685A1E9F4A70AB46901B51FB3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr01.py b/tests/ported_static/stShift/test_shr01.py index 1d66e665952..440b1720d94 100644 --- a/tests/ported_static/stShift/test_shr01.py +++ b/tests/ported_static/stShift/test_shr01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr01( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shr01( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x16408314E05C2677E2AC6A3A832D740AA9E1E99F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr10.py b/tests/ported_static/stShift/test_shr10.py index e88087f4dd5..f530f482917 100644 --- a/tests/ported_static/stShift/test_shr10.py +++ b/tests/ported_static/stShift/test_shr10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr10( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shr10( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEBFE51D0BD88B6EFF720C820FB552E868F78C681), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr11.py b/tests/ported_static/stShift/test_shr11.py index 113120c289e..f63d0c0da5f 100644 --- a/tests/ported_static/stShift/test_shr11.py +++ b/tests/ported_static/stShift/test_shr11.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr11( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,9 +50,7 @@ def test_shr11( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCD5C8D543415CCD7AC98C6FB1E8A64E2BB9EF8AC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_2_255_1.py b/tests/ported_static/stShift/test_shr_2_255_1.py index a53132eb96a..e5098e15523 100644 --- a/tests/ported_static/stShift/test_shr_2_255_1.py +++ b/tests/ported_static/stShift/test_shr_2_255_1.py @@ -46,6 +46,7 @@ def test_shr_2_255_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7f800000000000000000000000000000000000000000000000000000000000000060011c600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shr_2_255_1( nonce=0, address=Address(0xA389B98748A90663FA4E2B16D2AE848EBC2069D2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_2_255_255.py b/tests/ported_static/stShift/test_shr_2_255_255.py index b96fc123e30..32b6c243015 100644 --- a/tests/ported_static/stShift/test_shr_2_255_255.py +++ b/tests/ported_static/stShift/test_shr_2_255_255.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr_2_255_255( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_shr_2_255_255( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAD48C928474B5D7BC2AD4C8E769133BCD5988894), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_2_255_256.py b/tests/ported_static/stShift/test_shr_2_255_256.py index cda32d8de64..e94dd6b51b0 100644 --- a/tests/ported_static/stShift/test_shr_2_255_256.py +++ b/tests/ported_static/stShift/test_shr_2_255_256.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr_2_255_256( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_shr_2_255_256( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x634045B2E9EF0249256F6C175BEDDB252CCDCC65), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_2_255_257.py b/tests/ported_static/stShift/test_shr_2_255_257.py index 06826a861d2..eb5e71253f3 100644 --- a/tests/ported_static/stShift/test_shr_2_255_257.py +++ b/tests/ported_static/stShift/test_shr_2_255_257.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr_2_255_257( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_shr_2_255_257( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x00FE70B13953D2DAB2D13CE453CC42C47E3AB8CA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_minus_1_0.py b/tests/ported_static/stShift/test_shr_minus_1_0.py index 9c78c1d9238..340c476af04 100644 --- a/tests/ported_static/stShift/test_shr_minus_1_0.py +++ b/tests/ported_static/stShift/test_shr_minus_1_0.py @@ -46,6 +46,7 @@ def test_shr_minus_1_0( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001c600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shr_minus_1_0( nonce=0, address=Address(0xCB148BF8DF8A38A6478678824EEB7EADD61E3E59), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_minus_1_1.py b/tests/ported_static/stShift/test_shr_minus_1_1.py index 54892484c65..aff1657f6c4 100644 --- a/tests/ported_static/stShift/test_shr_minus_1_1.py +++ b/tests/ported_static/stShift/test_shr_minus_1_1.py @@ -46,6 +46,7 @@ def test_shr_minus_1_1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60011c600055 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_shr_minus_1_1( nonce=0, address=Address(0x3610B43FF3BAB81BD5772E01915AC9CBB67782B9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_minus_1_255.py b/tests/ported_static/stShift/test_shr_minus_1_255.py index c4ec6e09447..7bba31f619b 100644 --- a/tests/ported_static/stShift/test_shr_minus_1_255.py +++ b/tests/ported_static/stShift/test_shr_minus_1_255.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr_minus_1_255( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_shr_minus_1_255( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCBA06AF5AF94BE2ECF98FCE20D1D965296D6FA02), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stShift/test_shr_minus_1_256.py b/tests/ported_static/stShift/test_shr_minus_1_256.py index 01c3fa3e930..4d519360577 100644 --- a/tests/ported_static/stShift/test_shr_minus_1_256.py +++ b/tests/ported_static/stShift/test_shr_minus_1_256.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_shr_minus_1_256( ) -> None: """Taken from https://github.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -59,9 +56,7 @@ def test_shr_minus_1_256( storage={0: 3}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF703BF410C7F3337C04F281F6EB8E44D83323F55), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_ambiguous_method.py b/tests/ported_static/stSolidityTest/test_ambiguous_method.py index 0d09857e7a9..fa6f1e8de36 100644 --- a/tests/ported_static/stSolidityTest/test_ambiguous_method.py +++ b/tests/ported_static/stSolidityTest/test_ambiguous_method.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_ambiguous_method( ) -> None: """Test_ambiguous_method.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA9AE12CB2700C0214F86B9796881BC03A1FD5605D0E76D2DA2CA592E62D53E52 - ) + sender = pre.fund_eoa(amount=0x12A05F200) env = Environment( fee_recipient=coinbase, @@ -70,9 +67,7 @@ def test_ambiguous_method( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0x235C9320B0F4D30204334C1DDB008DFE1D75B1B9), # noqa: E501 ) - pre[sender] = Account(balance=0x12A05F200) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_by_zero.py b/tests/ported_static/stSolidityTest/test_by_zero.py index 4d58b14d717..5fc45ecfe07 100644 --- a/tests/ported_static/stSolidityTest/test_by_zero.py +++ b/tests/ported_static/stSolidityTest/test_by_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,7 +55,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_by_zero( state_test: StateTestFiller, pre: Alloc, @@ -67,9 +65,7 @@ def test_by_zero( ) -> None: """DIV/SDIV/MOD/SMOD by zero tests.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x8AC7230489E80000) env = Environment( fee_recipient=coinbase, @@ -80,8 +76,6 @@ def test_by_zero( gas_limit=1000000, ) - pre[sender] = Account(balance=0x8AC7230489E80000) - tx_data = [ Op.SSTORE(key=Op.DIV(0x1, 0x0), value=0x1) + Op.STOP, Op.SSTORE(key=Op.SDIV(0x1, 0x0), value=0x1) + Op.STOP, diff --git a/tests/ported_static/stSolidityTest/test_call_infinite_loop.py b/tests/ported_static/stSolidityTest/test_call_infinite_loop.py index dca1b0e5172..a1a00522ae6 100644 --- a/tests/ported_static/stSolidityTest/test_call_infinite_loop.py +++ b/tests/ported_static/stSolidityTest/test_call_infinite_loop.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_infinite_loop( ) -> None: """Test_call_infinite_loop.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0x96C07046493EC8728482079AB999D2994420D9CF4D3491DFD06871B106D9D87B - ) + sender = pre.fund_eoa(amount=0x1DCD6500) env = Environment( fee_recipient=coinbase, @@ -90,9 +87,7 @@ def test_call_infinite_loop( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0xF9B9CCB6160CE3574DF5D096CA9FD12BA81D97EE), # noqa: E501 ) - pre[sender] = Account(balance=0x1DCD6500) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_call_low_level_creates_solidity.py b/tests/ported_static/stSolidityTest/test_call_low_level_creates_solidity.py index 6e9485f4a07..506bac4b786 100644 --- a/tests/ported_static/stSolidityTest/test_call_low_level_creates_solidity.py +++ b/tests/ported_static/stSolidityTest/test_call_low_level_creates_solidity.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_low_level_creates_solidity( ) -> None: """Test_call_low_level_creates_solidity.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -156,7 +153,6 @@ def test_call_low_level_creates_solidity( nonce=0, address=Address(0x5DA6FBE439A0C3AB33F813671A4E7767EE0A263B), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, @@ -166,14 +162,6 @@ def test_call_low_level_creates_solidity( value=1, ) - post = { - target: Account( - storage={ - 0: 225, - 1: 0x5DA6FBE439A0C3AB33F813671A4E7767EE0A263B, - }, - nonce=1, - ), - } + post = {target: Account(storage={0: 225, 1: target}, nonce=1)} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stSolidityTest/test_call_recursive_methods.py b/tests/ported_static/stSolidityTest/test_call_recursive_methods.py index eafae5d0d5e..bb578a72397 100644 --- a/tests/ported_static/stSolidityTest/test_call_recursive_methods.py +++ b/tests/ported_static/stSolidityTest/test_call_recursive_methods.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_recursive_methods( ) -> None: """Test_call_recursive_methods.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xA9AE12CB2700C0214F86B9796881BC03A1FD5605D0E76D2DA2CA592E62D53E52 - ) + sender = pre.fund_eoa(amount=0x12A05F200) env = Environment( fee_recipient=coinbase, @@ -90,9 +87,7 @@ def test_call_recursive_methods( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0xC7C7851C7F3291BED1039BB4FFA166C290A605A9), # noqa: E501 ) - pre[sender] = Account(balance=0x12A05F200) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_contract_inheritance.py b/tests/ported_static/stSolidityTest/test_contract_inheritance.py index 080b62b5a9d..d0b8c2f3cd5 100644 --- a/tests/ported_static/stSolidityTest/test_contract_inheritance.py +++ b/tests/ported_static/stSolidityTest/test_contract_inheritance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_contract_inheritance( ) -> None: """Test_contract_inheritance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA9AE12CB2700C0214F86B9796881BC03A1FD5605D0E76D2DA2CA592E62D53E52 - ) + sender = pre.fund_eoa(amount=0x12A05F200) env = Environment( fee_recipient=coinbase, @@ -206,9 +203,7 @@ def test_contract_inheritance( + Op.RETURN, balance=0x186A0, nonce=0, - address=Address(0x3809B123C157B2D0D3B998255F35B5F8B8AE4789), # noqa: E501 ) - pre[sender] = Account(balance=0x12A05F200) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_create_contract_from_method.py b/tests/ported_static/stSolidityTest/test_create_contract_from_method.py index 827cdb3ff7c..c53bad1118b 100644 --- a/tests/ported_static/stSolidityTest/test_create_contract_from_method.py +++ b/tests/ported_static/stSolidityTest/test_create_contract_from_method.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_contract_from_method( """Test_create_contract_from_method.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -125,9 +122,7 @@ def test_create_contract_from_method( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_recursive_create_contracts.py b/tests/ported_static/stSolidityTest/test_recursive_create_contracts.py index 0c335e0368c..836f16024d1 100644 --- a/tests/ported_static/stSolidityTest/test_recursive_create_contracts.py +++ b/tests/ported_static/stSolidityTest/test_recursive_create_contracts.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_recursive_create_contracts( """Test_recursive_create_contracts.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x1DCD6500) env = Environment( fee_recipient=coinbase, @@ -248,7 +245,6 @@ def test_recursive_create_contracts( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x1DCD6500) tx = Transaction( sender=sender, @@ -260,10 +256,7 @@ def test_recursive_create_contracts( post = { contract_0: Account( - storage={ - 0: 0x95E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87, - 1: 772, - }, + storage={0: contract_0, 1: 772}, balance=0x314DC6448D9338C15B0A00000001, nonce=1, ), diff --git a/tests/ported_static/stSolidityTest/test_recursive_create_contracts_create4_contracts.py b/tests/ported_static/stSolidityTest/test_recursive_create_contracts_create4_contracts.py index 31f06f4e2e2..8c88bdf7583 100644 --- a/tests/ported_static/stSolidityTest/test_recursive_create_contracts_create4_contracts.py +++ b/tests/ported_static/stSolidityTest/test_recursive_create_contracts_create4_contracts.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -38,9 +37,7 @@ def test_recursive_create_contracts_create4_contracts( """Test_recursive_create_contracts_create4_contracts.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x1DCD6500) env = Environment( fee_recipient=coinbase, @@ -250,7 +247,6 @@ def test_recursive_create_contracts_create4_contracts( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x1DCD6500) tx = Transaction( sender=sender, @@ -261,16 +257,11 @@ def test_recursive_create_contracts_create4_contracts( ) post = { - contract_0: Account( - storage={ - 0: 0x95E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87, - 1: 4, - }, - nonce=3, - ), - Address(0x2B25AE4B13CB6E06869F694D29DE45E7614EBD97): Account( - storage={0: 1}, nonce=1 - ), + contract_0: Account(storage={0: contract_0, 1: 4}, nonce=3), + compute_create_address( + address=compute_create_address(address=contract_0, nonce=1), + nonce=1, + ): Account(storage={0: 1}, nonce=1), compute_create_address(address=contract_0, nonce=2): Account( balance=2, nonce=1 ), diff --git a/tests/ported_static/stSolidityTest/test_test_block_and_transaction_properties.py b/tests/ported_static/stSolidityTest/test_test_block_and_transaction_properties.py index 2bec0c9098c..0bcbd18e2f1 100644 --- a/tests/ported_static/stSolidityTest/test_test_block_and_transaction_properties.py +++ b/tests/ported_static/stSolidityTest/test_test_block_and_transaction_properties.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_test_block_and_transaction_properties( ) -> None: """Test_test_block_and_transaction_properties.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -145,7 +142,7 @@ def test_test_block_and_transaction_properties( 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, Op.COINBASE, ), - 0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA, + coinbase, ) ) ), @@ -195,7 +192,7 @@ def test_test_block_and_transaction_properties( 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, Op.CALLER, ), - 0x7F3F285918D9B5E764174551E10B7539B97BBB27, + sender, ) ) ), @@ -230,7 +227,7 @@ def test_test_block_and_transaction_properties( 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, Op.ORIGIN, ), - 0x7F3F285918D9B5E764174551E10B7539B97BBB27, + sender, ) ) ), @@ -244,9 +241,7 @@ def test_test_block_and_transaction_properties( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0xAD24D212286AB785EFE98AB6F5A3ECDE73054EE5), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_contract_interaction.py b/tests/ported_static/stSolidityTest/test_test_contract_interaction.py index 16b73bd74bf..0bcc63132a1 100644 --- a/tests/ported_static/stSolidityTest/test_test_contract_interaction.py +++ b/tests/ported_static/stSolidityTest/test_test_contract_interaction.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_test_contract_interaction( ) -> None: """Test_test_contract_interaction.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -162,9 +159,7 @@ def test_test_contract_interaction( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0x087DFEC56D6DA95FD3A1BCF8CCF995EE51645950), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_contract_suicide.py b/tests/ported_static/stSolidityTest/test_test_contract_suicide.py index b1d73f75b60..1dd26ffea76 100644 --- a/tests/ported_static/stSolidityTest/test_test_contract_suicide.py +++ b/tests/ported_static/stSolidityTest/test_test_contract_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_test_contract_suicide( ) -> None: """Test_test_contract_suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -184,9 +181,7 @@ def test_test_contract_suicide( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0xFE34831DF57F026AFBFFFD7E7B51B4ADBFE135E1), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_cryptographic_functions.py b/tests/ported_static/stSolidityTest/test_test_cryptographic_functions.py index 0cfc59089a0..deec53219f6 100644 --- a/tests/ported_static/stSolidityTest/test_test_cryptographic_functions.py +++ b/tests/ported_static/stSolidityTest/test_test_cryptographic_functions.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_test_cryptographic_functions( """Test_test_cryptographic_functions.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x12A05F200) env = Environment( fee_recipient=coinbase, @@ -241,9 +238,7 @@ def test_test_cryptographic_functions( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x12A05F200) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_keywords.py b/tests/ported_static/stSolidityTest/test_test_keywords.py index 08468d531de..5772cd6d269 100644 --- a/tests/ported_static/stSolidityTest/test_test_keywords.py +++ b/tests/ported_static/stSolidityTest/test_test_keywords.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_test_keywords( ) -> None: """Test_test_keywords.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -143,9 +140,7 @@ def test_test_keywords( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0xE7DCB339943A6DB535FFE618EC32D1E4E5A50F37), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_overflow.py b/tests/ported_static/stSolidityTest/test_test_overflow.py index 2ad61a23289..dcfb038159d 100644 --- a/tests/ported_static/stSolidityTest/test_test_overflow.py +++ b/tests/ported_static/stSolidityTest/test_test_overflow.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_test_overflow( ) -> None: """Test_test_overflow.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA9AE12CB2700C0214F86B9796881BC03A1FD5605D0E76D2DA2CA592E62D53E52 - ) + sender = pre.fund_eoa(amount=0x12A05F200) env = Environment( fee_recipient=coinbase, @@ -156,9 +153,7 @@ def test_test_overflow( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0x1A5A251A7E18EBC1A8EBFC47E3F36D9BE03F1627), # noqa: E501 ) - pre[sender] = Account(balance=0x12A05F200) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_store_gas_prices.py b/tests/ported_static/stSolidityTest/test_test_store_gas_prices.py index e896aeafc40..6cea8d54e29 100644 --- a/tests/ported_static/stSolidityTest/test_test_store_gas_prices.py +++ b/tests/ported_static/stSolidityTest/test_test_store_gas_prices.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_test_store_gas_prices( ) -> None: """Test_test_store_gas_prices.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x185FBEA9F643C40E33475353B07FA51D0695CA94789492166B67D60FDB6EF7FB - ) + sender = pre.fund_eoa(amount=0x746A528800) env = Environment( fee_recipient=coinbase, @@ -102,9 +99,7 @@ def test_test_store_gas_prices( + Op.JUMP, balance=0x186A0, nonce=0, - address=Address(0xFE58F48415DCF9D527F770E3148B769A76EF83F1), # noqa: E501 ) - pre[sender] = Account(balance=0x746A528800) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSolidityTest/test_test_structures_and_variabless.py b/tests/ported_static/stSolidityTest/test_test_structures_and_variabless.py index 554d8927291..d60edc74363 100644 --- a/tests/ported_static/stSolidityTest/test_test_structures_and_variabless.py +++ b/tests/ported_static/stSolidityTest/test_test_structures_and_variabless.py @@ -46,6 +46,7 @@ def test_test_structures_and_variabless( gas_limit=9223372036854775807, ) + pre[sender] = Account(balance=0x2540BE400) # Source: raw # 0x7c010000000000000000000000000000000000000000000000000000000060003504632a9afb838114610039578063c04062261461004b57005b61004161005d565b8060005260206000f35b61005361016c565b8060005260206000f35b600160ff8154141561006e57610076565b506000610169565b60015460035414156100875761008f565b506000610169565b7373ffffffffffffffffffffffffffffffffffffffff60016002540481161614156100cd576100d5565b506000610169565b7f676c6f62616c2064617461203332206c656e67746820737472696e670000000060045414156101045761010c565b506000610169565b6005600080815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673141561016057610168565b506000610169565b5b90565b600060ff8060015550736002805473ffffffffffffffffffffffffffffffffffffffff1916821790555060ff80600355507f676c6f62616c2064617461203332206c656e67746820737472696e67000000008060045550736005600080815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff0219169083021790555061022f61005d565b600060006101000a81548160ff0219169083021790555060ff6001600054041690509056 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -98,7 +99,7 @@ def test_test_structures_and_variabless( Op.AND(Op.DUP2, Op.DIV(Op.SLOAD(key=0x2), 0x1)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ), - 0xD96ED4431B417993AB4F4D4A656959D13C66E1DC, + sender, ) ), ) @@ -144,7 +145,7 @@ def test_test_structures_and_variabless( pc=0x160, condition=Op.ISZERO( Op.EQ( - 0xD96ED4431B417993AB4F4D4A656959D13C66E1DC, + sender, Op.AND(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, Op.DIV), ) ), @@ -225,7 +226,6 @@ def test_test_structures_and_variabless( nonce=0, address=Address(0x53D3DBDFD3AE109712A4771F7F37A6B1CDA7B864), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) tx = Transaction( sender=sender, @@ -240,10 +240,10 @@ def test_test_structures_and_variabless( storage={ 0: 1, 1: 255, - 2: 0xD96ED4431B417993AB4F4D4A656959D13C66E1DC, + 2: sender, 3: 255, 4: 0x676C6F62616C2064617461203332206C656E67746820737472696E6700000000, # noqa: E501 - 0x5B8CCBB9D4D8FB16EA74CE3C29A41F1B461FBDAFF4714A0D9A8EB05499746BC: 0xD96ED4431B417993AB4F4D4A656959D13C66E1DC, # noqa: E501 + 0x5B8CCBB9D4D8FB16EA74CE3C29A41F1B461FBDAFF4714A0D9A8EB05499746BC: sender, # noqa: E501 }, ), } diff --git a/tests/ported_static/stSpecialTest/test_block504980.py b/tests/ported_static/stSpecialTest/test_block504980.py index de0856afa03..ecf3d159cfa 100644 --- a/tests/ported_static/stSpecialTest/test_block504980.py +++ b/tests/ported_static/stSpecialTest/test_block504980.py @@ -59,6 +59,7 @@ def test_block504980( gas_limit=3141592, ) + pre[sender] = Account(balance=0xD8D726B7177A800000) # Source: hex # 0x contract_0 = pre.deploy_contract( # noqa: F841 @@ -99,37 +100,30 @@ def test_block504980( nonce=0, address=Address(0x0000000000000000000000000000000000000004), # noqa: E501 ) + # Source: hex + # 0x + coinbase = pre.deploy_contract( # noqa: F841 + code="", + balance=1, + nonce=0, + address=Address(0x1CDC8315BDB1362DE8B7B2FA9EE75DC873037179), # noqa: E501 + ) # Source: raw - # 0x600061289f537c01000000000000000000000000000000000000000000000000000000006000350473c9ae5868651bf7b7db6e360217db49ce4e69c07e60205263c4982a8581141561012757600435606052602435608052608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460a05260a051806020026020015990590160009052818152602081019050905060e0526000610140525b60a05161014051121561010b5760a060a0599059016000905260008152606051816020015260805181604001526001816060015261014051816080015280905020546101405160200260e051015260016101405101610140526100ad565b60e05160206040820352602060208203510260400160408203f3505b63cc1c944e8114156101765760043560605260243560805260806080599059016000905260008152606051816020015260805181604001526000816060015280905020546101a05260206101a0f35b6395a405b98114156101d5576004356060526024356080526044356101e05260a060a059905901600090526000815260605181602001526080518160400152600181606001526101e05181608001528090502054610200526020610200f35b6371ebb662811415610224576004356060526024356080526080608059905901600090526000815260605181602001526080518160400152600281606001528090502054610240526020610240f35b637a57a3db811415610325576004356060526024356080526044356102805260c060c0599059016000905260008152606051816020015260805181604001526003816060015261028051816080015260008160a0015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156102e95780840154816020028301526001810190506102c8565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63f73dc690811415610394576004356060526024356080526044356103c0526064356103e05260c060c059905901600090526000815260605181602001526080518160400152600381606001526103c05181608001526103e0518160a001528090502054610400526020610400f35b6354cc61098114156103f3576004356060526024356080526044356103c05260a060a059905901600090526000815260605181602001526080518160400152600481606001526103c05181608001528090502054610440526020610440f35b63c63ef546811415610442576004356060526024356080526080608059905901600090526000815260605181602001526080518160400152600581606001528090502054610480526020610480f35b639381779b8114156105335760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600681606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156104f75780840154816020028301526001810190506104d6565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b634f9c6eeb8114156106245760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600781606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156105e85780840154816020028301526001810190506105c7565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b637dc121958114156107155760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600881606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156106d95780840154816020028301526001810190506106b8565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63fa9832d18114156108065760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600981606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156107ca5780840154816020028301526001810190506107a9565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b632c5a40d58114156108f75760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600a81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156108bb57808401548160200283015260018101905061089a565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63e05dcb568114156109eb5760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600b81606001526000816080015280905020600260806080599059016000905260008152606051816020015260805181604001526000816060015280905020546020020180806020015990590160009052818152602081019050905060005b602083048112156109af57808401548160200283015260018101905061098e565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63586b5be0811415610a3a576004356060526024356080526080608059905901600090526000815260605181602001526080518160400152600c81606001528090502054610b80526020610b80f35b63eb8af5aa811415610b585760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600d81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215610b1c578084015481602002830152600181019050610afb565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b637ab6ea8a811415610c765760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600e81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215610c3a578084015481602002830152600181019050610c19565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b632b810cb9811415610d945760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600f81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215610d58578084015481602002830152600181019050610d37565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b637fb42e46811415610e855760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601081606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b60208304811215610e49578084015481602002830152600181019050610e28565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63734fa727811415610f765760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601181606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b60208304811215610f3a578084015481602002830152600181019050610f19565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63c67fa8578114156110675760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601281606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b6020830481121561102b57808401548160200283015260018101905061100a565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b635ed853e48114156111855760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601381606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215611149578084015481602002830152600181019050611128565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63b86f51258114156112a35760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601481606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215611267578084015481602002830152600181019050611246565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63bc3d7d858114156113945760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601581606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b60208304811215611358578084015481602002830152600181019050611337565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63a2302f2f81141561148157600435606052602435611680526044356116a0526116a05160a060a0599059016000905260008152606051816020015261168051816040015260018160600152608060805990590160009052600081526060518160200152611680518160400152600081606001528090502054816080015280905020556001608060805990590160009052600081526060518160200152611680518160400152600081606001528090502054016080608059905901600090526000815260605181602001526116805181604001526000816060015280905020556001611740526020611740f35b63058ca2bc8114156114dd576004356060526024356080526044356117605261176051608060805990590160009052600081526060518160200152608051816040015260028160600152809050205560016117a05260206117a0f35b635d3b965b8114156116175736599059016000905236600482376004356060526024356080526044356102805260643560208201016117e052608435611800525060c060c0599059016000905260008152606051816020015260805181604001526003816060015261028051816080015260008160a001528090502060206117e05103516020026020810460005b8181121561158c57806020026117e05101518482015560018101905061156b565b602083066020036101000a600003816020026117e05101511684820155505050506118005160806080599059016000905260008152606051816020015260805181604001526002816060015280905020540160806080599059016000905260008152606051816020015260805181604001526002816060015280905020556001611900526020611900f35b63b0e14f0f81141561167357600435606052602435608052604435611920526119205160806080599059016000905260008152606051816020015260805181604001526005816060015280905020556001611960526020611960f35b636acccdbc8114156117395736599059016000905236600482376004356060526024356080526044356020820101611980525060a060a05990590160009052600081526060518160200152608051816040015260068160600152600081608001528090502060206119805103516020026020810460005b8181121561170b5780602002611980510151848201556001810190506116ea565b602083066020036101000a600003816020026119805101511684820155505050506001611a40526020611a40f35b63a1fa51f98114156117ff5736599059016000905236600482376004356060526024356080526044356020820101611a60525060a060a0599059016000905260008152606051816020015260805181604001526007816060015260008160800152809050206020611a605103516020026020810460005b818112156117d15780602002611a60510151848201556001810190506117b0565b602083066020036101000a60000381602002611a605101511684820155505050506001611b20526020611b20f35b63cd87f43a8114156118c55736599059016000905236600482376004356060526024356080526044356020820101611b40525060a060a0599059016000905260008152606051816020015260805181604001526008816060015260008160800152809050206020611b405103516020026020810460005b818112156118975780602002611b4051015184820155600181019050611876565b602083066020036101000a60000381602002611b405101511684820155505050506001611c00526020611c00f35b63222a866381141561198b5736599059016000905236600482376004356060526024356080526044356020820101611c20525060a060a0599059016000905260008152606051816020015260805181604001526009816060015260008160800152809050206020611c205103516020026020810460005b8181121561195d5780602002611c205101518482015560018101905061193c565b602083066020036101000a60000381602002611c205101511684820155505050506001611ce0526020611ce0f35b63b39e1faa811415611a515736599059016000905236600482376004356060526024356080526044356020820101611d00525060a060a059905901600090526000815260605181602001526080518160400152600a816060015260008160800152809050206020611d005103516020026020810460005b81811215611a235780602002611d0051015184820155600181019050611a02565b602083066020036101000a60000381602002611d005101511684820155505050506001611dc0526020611dc0f35b63e365736b811415611b175736599059016000905236600482376004356060526024356080526044356020820101611de0525060a060a059905901600090526000815260605181602001526080518160400152600b816060015260008160800152809050206020611de05103516020026020810460005b81811215611ae95780602002611de051015184820155600181019050611ac8565b602083066020036101000a60000381602002611de05101511684820155505050506001611ea0526020611ea0f35b63aad7d6e3811415611b7357600435606052602435608052604435611ec052611ec0516080608059905901600090526000815260605181602001526080518160400152600c816060015280905020556001611f00526020611f00f35b6301112b27811415611c395736599059016000905236600482376004356060526024356080526044356020820101611f20525060a060a059905901600090526000815260605181602001526080518160400152600d816060015260008160800152809050206020611f205103516020026020810460005b81811215611c0b5780602002611f2051015184820155600181019050611bea565b602083066020036101000a60000381602002611f205101511684820155505050506001611fe0526020611fe0f35b63bdbb239b811415611cff5736599059016000905236600482376004356060526024356080526044356020820101612000525060a060a059905901600090526000815260605181602001526080518160400152600e8160600152600081608001528090502060206120005103516020026020810460005b81811215611cd1578060200261200051015184820155600181019050611cb0565b602083066020036101000a6000038160200261200051015116848201555050505060016120c05260206120c0f35b6305a0cd48811415611dc557365990590160009052366004823760043560605260243560805260443560208201016120e0525060a060a059905901600090526000815260605181602001526080518160400152600f8160600152600081608001528090502060206120e05103516020026020810460005b81811215611d9757806020026120e051015184820155600181019050611d76565b602083066020036101000a600003816020026120e051015116848201555050505060016121a05260206121a0f35b63aaa1fe35811415611e8b57365990590160009052366004823760043560605260243560805260443560208201016121c0525060a060a05990590160009052600081526060518160200152608051816040015260108160600152600081608001528090502060206121c05103516020026020810460005b81811215611e5d57806020026121c051015184820155600181019050611e3c565b602083066020036101000a600003816020026121c05101511684820155505050506001612280526020612280f35b632be4935d811415611f5157365990590160009052366004823760043560605260243560805260443560208201016122a0525060a060a05990590160009052600081526060518160200152608051816040015260118160600152600081608001528090502060206122a05103516020026020810460005b81811215611f2357806020026122a051015184820155600181019050611f02565b602083066020036101000a600003816020026122a05101511684820155505050506001612360526020612360f35b6313a8350d8114156120175736599059016000905236600482376004356060526024356080526044356020820101612380525060a060a05990590160009052600081526060518160200152608051816040015260128160600152600081608001528090502060206123805103516020026020810460005b81811215611fe9578060200261238051015184820155600181019050611fc8565b602083066020036101000a600003816020026123805101511684820155505050506001612440526020612440f35b63cb540b458114156120dd5736599059016000905236600482376004356060526024356080526044356020820101612460525060a060a05990590160009052600081526060518160200152608051816040015260138160600152600081608001528090502060206124605103516020026020810460005b818112156120af57806020026124605101518482015560018101905061208e565b602083066020036101000a600003816020026124605101511684820155505050506001612520526020612520f35b63be0306278114156121a35736599059016000905236600482376004356060526024356080526044356020820101612540525060a060a05990590160009052600081526060518160200152608051816040015260148160600152600081608001528090502060206125405103516020026020810460005b81811215612175578060200261254051015184820155600181019050612154565b602083066020036101000a600003816020026125405101511684820155505050506001612600526020612600f35b6383fd77f08114156122695736599059016000905236600482376004356060526024356080526044356020820101612620525060a060a05990590160009052600081526060518160200152608051816040015260158160600152600081608001528090502060206126205103516020026020810460005b8181121561223b57806020026126205101518482015560018101905061221a565b602083066020036101000a6000038160200261262051015116848201555050505060016126e05260206126e0f35b63594622058114156122d5576004356060526024356080526044356103c052606435612700526127005160a060a059905901600090526000815260605181602001526080518160400152600481606001526103c051816080015280905020556001612740526020612740f35b63bb8e419681141561244857600435606052602435612760526044356127805260006127a0525b6080608059905901600090526000815260605181602001526001612760510381604001526000816060015280905020546127a051121561243b5760a060a05990590160009052600081526060518160200152600161276051038160400152600181606001526127a0518160800152809050205460a060a05990590160009052600081526060518160200152612780518160400152600181606001526080608059905901600090526000815260605181602001526127805181604001526000816060015280905020548160800152809050205560016080608059905901600090526000815260605181602001526127805181604001526000816060015280905020540160806080599059016000905260008152606051816020015261278051816040015260008160600152809050205560016127a051016127a0526122fc565b6001612880526020612880f35b50 # noqa: E501 - contract_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x289F, value=0x0) + # 0x600061067f537c010000000000000000000000000000000000000000000000000000000060003504632f300bee8114156100ac576004356040526024356060526044356080526002608051018080602002602001599059016000905281815260208101905090506801000000000000000081526060516080516020028201526001604051036001608051016020028201528060206040820352602060208203510260400160408203f35050505b63a647a5b98114156102c85736599059016000905236600482376004356020820101610100526024356020820101610160526044356020820101610180526064356101a05260843560805250602061010051035180806020026020015990590160009052818152602081019050905060005b6101a0518112156101d557600060005b608051811215610162578060200261010051015181608051850201602002610160510151028201915060018101905061012e565b50680100000000000000008105905060005b6080518112156101c857700100000000000000000000000000000000836020026101805101518260805186020160200261016051015184020205816020028501510381602002850152600181019050610174565b505060018101905061011e565b50600060005b60805181121561020357806020028301518160200284015102820191506001810190506101db565b5068010000000000000000810590506002810560005b600b81121561024257600282680100000000000000008502058301059150600181019050610219565b5060005b60805181121561027657816801000000000000000082602002860151020581602002850152600181019050610246565b5050506001608051602002610100510151036080516020028201526001608051016020026101005101516001608051016020028201528060206040820352602060208203510260400160408203f35050505b635b18022981141561037957365990590160009052366004823760043560208201016103005260243560208201016103205260443560805250600060005b60805181121561033f57680100000000000000008160200261032051015182602002610300510151020582019150600181019050610306565b6000610320515114151561036657610320515168010000000000000000830205915061036b565b600091505b81610380526020610380f350505b63f4ca7dc481141561057157365990590160009052366004823760043560208201016103a05260243560208201016103c0526044356101a0526064356080525060206103c051035160026080510a806020026020015990590160009052818152602081019050905060005b60805181121561044d5760005b6080518112156104415768010000000000000000816020026103a0510151836020026103a051015102058160805184020160200284015101816080518402016020028401526001810190506103f1565b506001810190506103e4565b81905090508180602002602001599059016000905281815260208101905090506080516101a05102806020026020015990590160009052818152602081019050905060005b6101a05181121561051e5760005b6080518112156105125760005b608051811215610506576801000000000000000082608051830201602002870151826080518602016020026103c051015102058260805185020160200285015101826080518502016020028501526001810190506104ad565b506001810190506104a0565b50600181019050610492565b819050905060005b848112156105525780602002820151816020026103c05101510381602002840152600181019050610526565b508160206040820352602060208203510260400160408203f350505050505b63232b273481141561069d57365990590160009052366004823760043560208201016106205260243560208201016102805260443560208201016103c052606435610640526084356101a05260a435608052506000610280515112156106025760005b6080518112156106005780602002610280510151600003816020026102805101526001810190506105d4565b505b60005b6101a05181121561067f5760005b60805181121561067357680100000000000000006801000000000000000082602002610280510151610640510205826080518502016020026103c05101510205826020026106205101510182602002610620510152600181019050610613565b50600181019050610605565b6106205160206040820352602060208203510260400160408203f350505b50 # noqa: E501 + contract_11 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x67F, value=0x0) + Op.DIV( Op.CALLDATALOAD(offset=0x0), 0x100000000000000000000000000000000000000000000000000000000, ) - + Op.MSTORE( - offset=0x20, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E + + Op.JUMPI( + pc=Op.PUSH2[0xAC], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2F300BEE)) ) - + Op.JUMPI(pc=0x127, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC4982A85))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x44)) + + Op.ADD(Op.MLOAD(offset=0x80), 0x2) + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0xA0, value=Op.SLOAD(key=Op.SHA3)) - + Op.MLOAD(offset=0xA0) + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 @@ -144,42 +138,18 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0xE0] - + Op.MSTORE - + Op.MSTORE(offset=0x140, value=0x0) - + Op.JUMPDEST - + Op.JUMPI( - pc=0x10B, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x140), Op.MLOAD(offset=0xA0)) - ), + + Op.MSTORE(offset=Op.DUP2, value=0x10000000000000000) + + Op.MSTORE( + offset=Op.ADD(Op.DUP3, Op.MUL(0x20, Op.MLOAD(offset=0x80))), + value=Op.MLOAD(offset=0x60), ) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x140)) - + Op.DUP1 - + Op.SWAP1 - + Op.POP + Op.MSTORE( offset=Op.ADD( - Op.MLOAD(offset=0xE0), Op.MUL(0x20, Op.MLOAD(offset=0x140)) + Op.DUP3, Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x80), 0x1)) ), - value=Op.SLOAD(key=Op.SHA3), + value=Op.SUB(Op.MLOAD(offset=0x40), 0x1), ) - + Op.MSTORE(offset=0x140, value=Op.ADD(Op.MLOAD(offset=0x140), 0x1)) - + Op.JUMP(pc=Op.PUSH2[0xAD]) - + Op.JUMPDEST - + Op.MLOAD(offset=0xE0) + + Op.DUP1 + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + Op.RETURN( offset=Op.SUB(Op.DUP3, 0x40), @@ -187,96 +157,10 @@ def test_block504980( 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) ), ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x176, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xCC1C944E))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x1A0, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x1A0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1D5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x95A405B9))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x1E0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x1E0)) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x200, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x200, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x224, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x71EBB662))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x240, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x240, size=0x20) + + Op.POP * 3 + Op.JUMPDEST - + Op.JUMPI(pc=0x325, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7A57A3DB))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x280, value=Op.CALLDATALOAD(offset=0x44)) - + Op.PUSH1[0xC0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x3) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x280)) - + Op.MSTORE(offset=Op.ADD(0xA0, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.JUMPI(pc=0x2C8, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA647A5B9))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -284,16 +168,27 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE( + offset=0x100, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), + ) + + Op.MSTORE( + offset=0x160, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), + ) + + Op.MSTORE( + offset=0x180, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x84)) + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x100), 0x20)) + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -310,198 +205,186 @@ def test_block504980( + Op.PUSH1[0x0] + Op.JUMPDEST + Op.JUMPI( - pc=0x2E9, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + pc=0x1D5, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x1A0))), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x2C8) + + Op.PUSH1[0x0] * 2 + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + + Op.JUMPI( + pc=0x162, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + + Op.ADD( + Op.DUP3, + Op.MUL( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x160), + Op.MUL( + 0x20, + Op.ADD( + Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), Op.DUP2 + ), + ), + ) + ), + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x100), Op.MUL(0x20, Op.DUP1) + ) ), ), ) - + Op.DUP2 - + Op.SWAP1 + + Op.SWAP2 + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.SWAP1 + + Op.JUMP(pc=0x12E) + + Op.JUMPDEST + Op.POP + + Op.SDIV(Op.DUP2, 0x10000000000000000) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x394, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xF73DC690))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x3C0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x3E0, value=Op.CALLDATALOAD(offset=0x64)) - + Op.PUSH1[0xC0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x3) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x3C0)) - + Op.MSTORE(offset=Op.ADD(0xA0, Op.DUP2), value=Op.MLOAD(offset=0x3E0)) - + Op.DUP1 + + Op.JUMPDEST + + Op.JUMPI( + pc=0x1C8, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + + Op.MSTORE( + offset=Op.ADD(Op.DUP6, Op.MUL(0x20, Op.DUP2)), + value=Op.SUB( + Op.MLOAD(offset=Op.ADD(Op.DUP6, Op.MUL(0x20, Op.DUP2))), + Op.SDIV( + Op.MUL( + Op.MUL( + Op.DUP5, + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x160), + Op.MUL( + 0x20, + Op.ADD( + Op.MUL( + Op.DUP7, Op.MLOAD(offset=0x80) + ), + Op.DUP3, + ), + ), + ) + ), + ), + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x180), Op.MUL(0x20, Op.DUP4) + ) + ), + ), + 0x100000000000000000000000000000000, + ), + ), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x400, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x400, size=0x20) + + Op.JUMP(pc=0x174) + Op.JUMPDEST - + Op.JUMPI(pc=0x3F3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x54CC6109))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x3C0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x4) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x3C0)) - + Op.DUP1 + + Op.POP * 2 + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x440, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x440, size=0x20) + + Op.JUMP(pc=0x11E) + Op.JUMPDEST - + Op.JUMPI(pc=0x442, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC63EF546))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 - + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x480, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x480, size=0x20) + + Op.PUSH1[0x0] * 2 + Op.JUMPDEST - + Op.JUMPI(pc=0x533, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x9381779B))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x6) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 + + Op.JUMPI( + pc=0x203, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + + Op.ADD( + Op.DUP3, + Op.MUL( + Op.MLOAD(offset=Op.ADD(Op.DUP5, Op.MUL(0x20, Op.DUP2))), + Op.MLOAD(offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP1))), + ), + ) + + Op.SWAP2 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) - + Op.MSIZE + + Op.JUMP(pc=0x1DB) + + Op.JUMPDEST + + Op.POP + + Op.SDIV(Op.DUP2, 0x10000000000000000) + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.POP + + Op.SDIV(Op.DUP2, 0x2) + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 + + Op.JUMPDEST + + Op.JUMPI(pc=0x242, condition=Op.ISZERO(Op.SLT(Op.DUP2, 0xB))) + + Op.SDIV( + Op.ADD( + Op.DUP4, Op.SDIV(Op.MUL(Op.DUP6, 0x10000000000000000), Op.DUP3) + ), + 0x2, + ) + + Op.SWAP2 + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP + + Op.JUMP(pc=0x219) + + Op.JUMPDEST + + Op.POP + Op.PUSH1[0x0] + Op.JUMPDEST + Op.JUMPI( - pc=0x4F7, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + pc=0x276, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), ) + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + offset=Op.ADD(Op.DUP6, Op.MUL(0x20, Op.DUP2)), + value=Op.SDIV( + Op.MUL( + Op.MLOAD(offset=Op.ADD(Op.DUP7, Op.MUL(0x20, Op.DUP3))), + 0x10000000000000000, + ), + Op.DUP2, + ), ) + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x4D6) + + Op.JUMP(pc=0x246) + Op.JUMPDEST + + Op.POP * 3 + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + offset=Op.ADD(Op.DUP3, Op.MUL(0x20, Op.MLOAD(offset=0x80))), + value=Op.SUB( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x100), + Op.MUL(0x20, Op.MLOAD(offset=0x80)), + ) ), + 0x1, ), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.MSTORE( + offset=Op.ADD( + Op.DUP3, Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + ), + value=Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x100), + Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x80), 0x1)), + ) + ), + ) + + Op.DUP1 + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + Op.RETURN( offset=Op.SUB(Op.DUP3, 0x40), @@ -509,29 +392,10 @@ def test_block504980( 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) ), ) - + Op.POP + + Op.POP * 3 + Op.JUMPDEST - + Op.JUMPI(pc=0x624, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x4F9C6EEB))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x7) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.JUMPI(pc=0x379, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5B180229))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -539,92 +403,74 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x5E8, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + offset=0x300, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 + + Op.MSTORE( + offset=0x320, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), + ) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x44)) + Op.POP - + Op.JUMP(pc=0x5C7) + + Op.PUSH1[0x0] * 2 + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + + Op.JUMPI( + pc=0x33F, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + + Op.ADD( + Op.DUP3, + Op.SDIV( + Op.MUL( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x300), Op.MUL(0x20, Op.DUP3) + ) + ), + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x320), Op.MUL(0x20, Op.DUP2) + ) + ), ), + 0x10000000000000000, ), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 + + Op.SWAP2 + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + + Op.JUMP(pc=0x306) + + Op.JUMPDEST + + Op.JUMPI( + pc=0x366, + condition=Op.ISZERO( + Op.ISZERO(Op.EQ(Op.MLOAD(offset=Op.MLOAD(offset=0x320)), 0x0)) ), ) + + Op.SDIV( + Op.MUL(Op.DUP4, 0x10000000000000000), + Op.MLOAD(offset=Op.MLOAD(offset=0x320)), + ) + + Op.SWAP2 + Op.POP + + Op.JUMP(pc=0x36B) + Op.JUMPDEST - + Op.JUMPI(pc=0x715, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7DC12195))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x8) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 + + Op.SWAP2 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.JUMPDEST + + Op.MSTORE(offset=0x380, value=Op.DUP2) + + Op.RETURN(offset=0x380, size=0x20) + + Op.POP * 2 + + Op.JUMPDEST + + Op.JUMPI(pc=0x571, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xF4CA7DC4))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -632,16 +478,23 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 - + Op.SWAP1 + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE( + offset=0x3A0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), + ) + + Op.MSTORE( + offset=0x3C0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), + ) + + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x64)) + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x3C0), 0x20)) + + Op.EXP(Op.MLOAD(offset=0x80), 0x2) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -658,49 +511,70 @@ def test_block504980( + Op.PUSH1[0x0] + Op.JUMPDEST + Op.JUMPI( - pc=0x6D9, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + pc=0x44D, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x6B8) + + Op.PUSH1[0x0] + Op.JUMPDEST + + Op.JUMPI( + pc=0x441, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + offset=Op.ADD( + Op.DUP5, + Op.MUL( + 0x20, + Op.ADD(Op.MUL(Op.DUP5, Op.MLOAD(offset=0x80)), Op.DUP2), + ), + ), + value=Op.ADD( + Op.MLOAD( + offset=Op.ADD( + Op.DUP5, + Op.MUL( + 0x20, + Op.ADD( + Op.MUL(Op.DUP5, Op.MLOAD(offset=0x80)), Op.DUP2 + ), + ), + ) + ), + Op.SDIV( + Op.MUL( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x3A0), Op.MUL(0x20, Op.DUP4) + ) + ), + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x3A0), Op.MUL(0x20, Op.DUP2) + ) + ), + ), + 0x10000000000000000, ), ), ) - + Op.DUP2 + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.SWAP1 + + Op.JUMP(pc=0x3F1) + + Op.JUMPDEST + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP + + Op.JUMP(pc=0x3E4) + + Op.JUMPDEST + + Op.DUP2 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) + + Op.SWAP1 + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x806, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xFA9832D1))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.DUP2 + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -708,33 +582,14 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x9) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) - + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.MUL(Op.MLOAD(offset=0x1A0), Op.MLOAD(offset=0x80)) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -751,129 +606,115 @@ def test_block504980( + Op.PUSH1[0x0] + Op.JUMPDEST + Op.JUMPI( - pc=0x7CA, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + pc=0x51E, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x1A0))), ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x512, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x7A9) + + Op.PUSH1[0x0] + Op.JUMPDEST + + Op.JUMPI( + pc=0x506, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + offset=Op.ADD( + Op.DUP6, + Op.MUL( + 0x20, + Op.ADD(Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), Op.DUP3), + ), + ), + value=Op.ADD( + Op.MLOAD( + offset=Op.ADD( + Op.DUP6, + Op.MUL( + 0x20, + Op.ADD( + Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), Op.DUP3 + ), + ), + ) + ), + Op.SDIV( + Op.MUL( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), + Op.MUL( + 0x20, + Op.ADD( + Op.MUL(Op.DUP7, Op.MLOAD(offset=0x80)), + Op.DUP3, + ), + ), + ) + ), + Op.MLOAD( + offset=Op.ADD( + Op.DUP8, + Op.MUL( + 0x20, + Op.ADD( + Op.MUL(Op.DUP4, Op.MLOAD(offset=0x80)), + Op.DUP3, + ), + ), + ) + ), + ), + 0x10000000000000000, ), ), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.SWAP1 + + Op.JUMP(pc=0x4AD) + + Op.JUMPDEST + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP + + Op.JUMP(pc=0x4A0) + Op.JUMPDEST - + Op.JUMPI(pc=0x8F7, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2C5A40D5))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xA) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.JUMP(pc=0x492) + + Op.JUMPDEST + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP + Op.PUSH1[0x0] + Op.JUMPDEST - + Op.JUMPI( - pc=0x8BB, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x89A) - + Op.JUMPDEST + + Op.JUMPI(pc=0x552, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP5))) + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + offset=Op.ADD(Op.DUP5, Op.MUL(0x20, Op.DUP2)), + value=Op.SUB( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), Op.MUL(0x20, Op.DUP2) + ) ), + Op.MLOAD(offset=Op.ADD(Op.DUP3, Op.MUL(0x20, Op.DUP1))), ), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.SWAP1 + + Op.JUMP(pc=0x526) + + Op.JUMPDEST + Op.POP + + Op.DUP2 + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + Op.RETURN( offset=Op.SUB(Op.DUP3, 0x40), @@ -881,48 +722,10 @@ def test_block504980( 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) ), ) - + Op.POP + + Op.POP * 5 + Op.JUMPDEST - + Op.JUMPI(pc=0x9EB, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xE05DCB56))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xB) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.PUSH1[0x2] - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.ADD - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.JUMPI(pc=0x69D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x232B2734))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -930,45 +733,118 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x9AF, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + offset=0x620, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x98E) - + Op.JUMPDEST + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), + offset=0x280, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 + + Op.MSTORE( + offset=0x3C0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.MSTORE(offset=0x640, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x84)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0xA4)) + Op.POP - + Op.SWAP1 + + Op.JUMPI( + pc=0x602, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=Op.MLOAD(offset=0x280)), 0x0) + ), + ) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x600, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + + Op.MSTORE( + offset=Op.ADD(Op.MLOAD(offset=0x280), Op.MUL(0x20, Op.DUP2)), + value=Op.SUB( + 0x0, + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x280), Op.MUL(0x20, Op.DUP1) + ) + ), + ), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x5D4) + + Op.JUMPDEST + + Op.POP + + Op.JUMPDEST + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x67F, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x1A0))), + ) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x673, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + ) + + Op.MSTORE( + offset=Op.ADD(Op.MLOAD(offset=0x620), Op.MUL(0x20, Op.DUP3)), + value=Op.ADD( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x620), Op.MUL(0x20, Op.DUP3) + ) + ), + Op.SDIV( + Op.MUL( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), + Op.MUL( + 0x20, + Op.ADD( + Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), + Op.DUP3, + ), + ), + ) + ), + Op.SDIV( + Op.MUL( + Op.MLOAD(offset=0x640), + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x280), + Op.MUL(0x20, Op.DUP3), + ) + ), + ), + 0x10000000000000000, + ), + ), + 0x10000000000000000, + ), + ), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x613) + + Op.JUMPDEST + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP + + Op.JUMP(pc=0x605) + + Op.JUMPDEST + + Op.MLOAD(offset=0x620) + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + Op.RETURN( offset=Op.SUB(Op.DUP3, 0x40), @@ -976,12 +852,25 @@ def test_block504980( 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) ), ) - + Op.POP + + Op.POP * 2 + Op.JUMPDEST - + Op.JUMPI(pc=0xA3A, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x586B5BE0))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 + + Op.POP, + nonce=0, + address=Address(0xF1562E1C0D0BAA3EA746442BB7F11153FCF5CFDA), # noqa: E501 + ) + # Source: raw + # 0x600061083f537c010000000000000000000000000000000000000000000000000000000060003504637a66d7ca8114156100665760043560405260606060599059016000905260008152604051816020015260008160400152809050205460605260206060f35b63c60409c68114156100a55760043560405260606060599059016000905260008152604051816020015260018160400152809050205460a052602060a0f35b63186335768114156100e45760043560405260606060599059016000905260008152604051816020015260028160400152809050205460e052602060e0f35b63b3903c8a8114156101bc57600435604052606060605990590160009052600081526040518160200152600581604001528090502054610120526101205180602002602001599059016000905281815260208101905090506101605260006101c0525b610120516101c051121561019f57608060805990590160009052600081526040518160200152600481604001526101c051816060015280905020546101c05160200261016051015260016101c051016101c052610147565b6101605160206040820352602060208203510260400160408203f3505b636824e0fb8114156101fd57600435604052606060605990590160009052600081526040518160200152600581604001528090502054610220526020610220f35b633db16be381141561023e57600435604052606060605990590160009052600081526040518160200152600681604001528090502054610260526020610260f35b63c33878588114156102e05760006102a0526000546102c0526102c05180602002602001599059016000905281815260208101905090506102e0525b6102c0516102a05112156102c357604060405990590160009052600181526102a051816020015280905020546102a0516020026102e051015260016102a051016102a05261027a565b6102e05160206040820352602060208203510260400160408203f3505b63175c63228114156102fa57600054610380526020610380f35b63d861f2b4811415610336576004356103a052604060405990590160009052600181526103a051816020015280905020546103c05260206103c0f35b63b0dab01f81141561044f57600435610400526024356104205260443561044052606435610460526000606060605990590160009052600081526104005181602001526001816040015280905020541415610441576104205160606060599059016000905260008152610400518160200152600081604001528090502055610440516060606059905901600090526000815261040051816020015260018160400152809050205561046051606060605990590160009052600081526104005181602001526006816040015280905020556104005160406040599059016000905260018152600054816020015280905020556001600054016000556001610520526020610520f361044e565b6000610540526020610540f35b5b63aac2ffb58114156104b95760043560405260016060606059905901600090526000815260405181602001526002816040015280905020540160606060599059016000905260008152604051816020015260028160400152809050205560016105a05260206105a0f35b637265802d811415610507576004356040526024356105c0526105c0516060606059905901600090526000815260405181602001526002816040015280905020556001610600526020610600f35b63c5476efe811415610571576004356040526001606060605990590160009052600081526040518160200152600081604001528090502054016060606059905901600090526000815260405181602001526000816040015280905020556001610660526020610660f35b63c551e31e81141561063b576004356040526024356106805260606060599059016000905260008152604051816020015260058160400152809050205461012052610680516080608059905901600090526000815260405181602001526004816040015261012051816060015280905020556001606060605990590160009052600081526040518160200152600581604001528090502054016060606059905901600090526000815260405181602001526005816040015280905020556001610720526020610720f35b633d90504581141561067c57600435604052606060605990590160009052600081526040518160200152600381604001528090502054610740526020610740f35b631cda01ef8114156106e65760043560405260016060606059905901600090526000815260405181602001526003816040015280905020540160606060599059016000905260008152604051816020015260038160400152809050205560016107c05260206107c0f35b63c286273a811415610734576004356040526024356107e0526107e0516060606059905901600090526000815260405181602001526003816040015280905020556001610820526020610820f35b50 # noqa: E501 + contract_9 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x83F, value=0x0) + + Op.DIV( + Op.CALLDATALOAD(offset=0x0), + 0x100000000000000000000000000000000000000000000000000000000, + ) + + Op.JUMPI( + pc=Op.PUSH2[0x66], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7A66D7CA)) + ) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -990,19 +879,19 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xC) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0xB80, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0xB80, size=0x20) + + Op.MSTORE(offset=0x60, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x60, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0xB58, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xEB8AF5AA))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.JUMPI( + pc=Op.PUSH2[0xA5], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC60409C6)) + ) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1011,15 +900,19 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xD) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0xA0, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0xA0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI( + pc=Op.PUSH2[0xE4], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x18633576)) + ) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1028,14 +921,17 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0xE0, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0xE0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1BC, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB3903C8A))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1044,16 +940,14 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.MUL(0x20, Op.SDIV) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.MSTORE(offset=0x120, value=Op.SLOAD(key=Op.SHA3)) + + Op.MLOAD(offset=0x120) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1067,39 +961,41 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0x0] + + Op.PUSH2[0x160] + + Op.MSTORE + + Op.MSTORE(offset=0x1C0, value=0x0) + Op.JUMPDEST + Op.JUMPI( - pc=0xB1C, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0xAFB) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + pc=0x19F, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=0x1C0), Op.MLOAD(offset=0x120)) ), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + Op.SWAP1 - + Op.POP + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x4) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x1C0)) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x160), Op.MUL(0x20, Op.MLOAD(offset=0x1C0)) + ), + value=Op.SLOAD(key=Op.SHA3), + ) + + Op.MSTORE(offset=0x1C0, value=Op.ADD(Op.MLOAD(offset=0x1C0), 0x1)) + + Op.JUMP(pc=0x147) + + Op.JUMPDEST + + Op.MLOAD(offset=0x160) + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + Op.RETURN( offset=Op.SUB(Op.DUP3, 0x40), @@ -1109,10 +1005,9 @@ def test_block504980( ) + Op.POP + Op.JUMPDEST - + Op.JUMPI(pc=0xC76, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7AB6EA8A))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.JUMPI(pc=0x1FD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x6824E0FB))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1121,15 +1016,17 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xE) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0x220, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x220, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x23E, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3DB16BE3))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1138,32 +1035,19 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x6) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.MUL(0x20, Op.SDIV) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.MSTORE(offset=0x260, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x260, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x2E0, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC3387858))) + + Op.MSTORE(offset=0x2A0, value=0x0) + + Op.MSTORE(offset=0x2C0, value=Op.SLOAD(key=0x0)) + + Op.MLOAD(offset=0x2C0) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1177,39 +1061,38 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0x0] + + Op.PUSH2[0x2E0] + + Op.MSTORE + Op.JUMPDEST + Op.JUMPI( - pc=0xC3A, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0xC19) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + pc=0x2C3, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=0x2A0), Op.MLOAD(offset=0x2C0)) ), ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP + + Op.PUSH1[0x40] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + Op.SWAP1 - + Op.POP + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x1) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x2A0)) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x2E0), Op.MUL(0x20, Op.MLOAD(offset=0x2A0)) + ), + value=Op.SLOAD(key=Op.SHA3), + ) + + Op.MSTORE(offset=0x2A0, value=Op.ADD(Op.MLOAD(offset=0x2A0), 0x1)) + + Op.JUMP(pc=0x27A) + + Op.JUMPDEST + + Op.MLOAD(offset=0x2E0) + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + Op.RETURN( offset=Op.SUB(Op.DUP3, 0x40), @@ -1219,10 +1102,13 @@ def test_block504980( ) + Op.POP + Op.JUMPDEST - + Op.JUMPI(pc=0xD94, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2B810CB9))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.JUMPI(pc=0x2FA, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x175C6322))) + + Op.MSTORE(offset=0x380, value=Op.SLOAD(key=0x0)) + + Op.RETURN(offset=0x380, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x336, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xD861F2B4))) + + Op.MSTORE(offset=0x3A0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x40] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1230,16 +1116,21 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xF) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.DUP2, value=0x1) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x3A0)) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0x3C0, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x3C0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x44F, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB0DAB01F))) + + Op.MSTORE(offset=0x400, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x420, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x440, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x460, value=Op.CALLDATALOAD(offset=0x64)) + + Op.PUSH1[0x0] + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1248,14 +1139,15 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SLOAD(key=Op.SHA3) - + Op.PUSH1[0x80] * 2 + + Op.JUMPI(pc=0x441, condition=Op.ISZERO(Op.EQ)) + + Op.MLOAD(offset=0x420) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1264,16 +1156,15 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.MUL(0x20, Op.SDIV) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.SHA3 + + Op.SSTORE + + Op.MLOAD(offset=0x440) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1281,58 +1172,59 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.MLOAD(offset=0x460) + + Op.PUSH1[0x60] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0xD58, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0xD37) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x6) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.MLOAD(offset=0x400) + + Op.PUSH1[0x40] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + Op.SWAP1 - + Op.POP + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x1) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.SLOAD(key=0x0)) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.SSTORE(key=0x0, value=Op.ADD(Op.SLOAD(key=0x0), 0x1)) + + Op.MSTORE(offset=0x520, value=0x1) + + Op.RETURN(offset=0x520, size=0x20) + + Op.JUMP(pc=0x44E) + Op.JUMPDEST - + Op.JUMPI(pc=0xE85, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7FB42E46))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.MSTORE(offset=0x540, value=0x0) + + Op.RETURN(offset=0x540, size=0x20) + + Op.JUMPDEST * 2 + + Op.JUMPI(pc=0x4B9, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xAAC2FFB5))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x1] + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1341,15 +1233,14 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x10) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1358,15 +1249,21 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x5A0, value=0x1) + + Op.RETURN(offset=0x5A0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x507, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7265802D))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x5C0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MLOAD(offset=0x5C0) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1374,75 +1271,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x600, value=0x1) + + Op.RETURN(offset=0x600, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x571, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC5476EFE))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x1] + + Op.PUSH1[0x60] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0xE49, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0xE28) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0xF76, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x734FA727))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x11) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1451,15 +1310,20 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x660, value=0x1) + + Op.RETURN(offset=0x660, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x63B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC551E31E))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x680, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1467,58 +1331,15 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0xF3A, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0xF19) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x1067, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC67FA857))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.MSTORE(offset=0x120, value=Op.SLOAD(key=Op.SHA3)) + + Op.MLOAD(offset=0x680) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1527,15 +1348,16 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x12) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x4) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x120)) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.SSTORE + + Op.PUSH1[0x1] + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1544,15 +1366,14 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1560,58 +1381,20 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x102B, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x100A) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x720, value=0x1) + + Op.RETURN(offset=0x720, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x1185, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5ED853E4))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.JUMPI(pc=0x67C, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3D905045))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1620,15 +1403,18 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x13) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0x740, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x740, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x6E6, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1CDA01EF))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x1] + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1637,14 +1423,14 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SLOAD(key=Op.SHA3) - + Op.PUSH1[0x80] * 2 + + Op.ADD + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1653,16 +1439,21 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.MUL(0x20, Op.SDIV) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x7C0, value=0x1) + + Op.RETURN(offset=0x7C0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x734, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC286273A))) + + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x7E0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MLOAD(offset=0x7E0) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1670,58 +1461,73 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0x0] + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x820, value=0x1) + + Op.RETURN(offset=0x820, size=0x20) + Op.JUMPDEST - + Op.JUMPI( - pc=0x1149, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + + Op.POP, + storage={ + 0: contract_1, + 0xA4470E9D0419DF71F6257FCDFD2C0A3BAD96A23F5AB414BC10AAF1A31A536A7: 0xB4876148229C22BD2291F1A4F5468C8C789B23639370C4D447F270BA341DBBEC, # noqa: E501 + 0x16EF4193A274568D283FF919C299729E07696D9ADA48187B81D68E12E7B962DE: 0xA103C04E7ECB9B3395F77C7B0CAD28E62C85F042DE4767CCC6C005E6F47F8D4, # noqa: E501 + 0x1F1866E966F321B84535705846689749D34D5DC02994613E2931973C605D9E93: 0xC723D0AA4A60529FE42277C8094AA19263AFF36650136EFC5EDFD0785D457634, # noqa: E501 + 0x252A4EC7133643FDDCDB22A86C415F78B2DD251F18D1EFCD6A44ACF590C4AE72: 0x9CAF94B82715869E71D3CEE986094EA612F0258570B7E5EF47B5D09E9515322B, # noqa: E501 + 0x41B451E8D86D28ADD758CBD3F48A18FD04B11A80288C1DC434A5BF2D8FB1CA64: 0xB602498F12A8B4AF3A1FCA357CEA6B19BCD163DFEC1D845364CE1395F7C21FA7, # noqa: E501 + 0x491D10658C1EC762152D8AD2D890AD59111B1EE7B4BC25736046923D3534D9A5: 25246, # noqa: E501 + 0x5B0E8552EFD72A845E47318ABBBEF9DC9FCDFE0D1A06CDA44494401301581511: 0xFBC98F4017AE5C20459DAADAA6BEE519B6DE871D3DBAA9AB3F34340FEF4CB643, # noqa: E501 + 0x5B672A107BA6FAB01CBDDF079042E9F6176A8E6F154584FC4DF4B15674C9456E: 0x1603DA41D610854D85536B37D000E5EB7CA09786C43F50E7441C0AFBFF1DE0A9, # noqa: E501 + 0x605B934BD26C9ECDF7029A7DC062D3A6B87338511CFF96E0C5F13DE9EEA3462E: 0xF0D24F3D0EDA573FC5D43E3D0680993C51293752CD6DE205040D3197F412F475, # noqa: E501 + 0x618355E25491DFE86175F9D9B3147E4D680AA561D98384E3621DC6A3088B0846: 0x6B2E6D2D5DEB27DFFEC973F23AF4CAF111E66D1397F467DBBEDF5AB2192FB6B6, # noqa: E501 + 0x65112936BEC0F1E84FDA6623FB54E12BAADC8A4A208C8C4EB3ED5E79CBD7E85F: 0xA59AC24E3E0663413D0F87516BA8FB44C6C3E14DA8EAABBDE80F8EE285F65934, # noqa: E501 + 0x687CB2122DE7BACF42B9CD380B04FF2A2CE92A0B63706A9A78263B3CE86F3313: 0x200000000000000, # noqa: E501 + 0x72A539B064C98D29A514EE55694225E05FB41FE63E5FE710E4536BD9BA3591B4: 0x338ECFE6C523ED1184918B19584D97DD1095ECAADC49C7BA9DA62B8B513026E0, # noqa: E501 + 0x7AEB0A0CE8882A12D853078382A2BC72F7A94AF6109F167DE37B36C0A7DEB828: 0x4C428400EA8A7BD7C46BA9895B508770EFA4551F0D793E1BEB1207DA01D9962F, # noqa: E501 + 0x7C8F4A98E086F64E28C75F54712B5D44BEC3C29B5C70519E8880D3046A5618DC: 0xAAFC1F2601752B114D722070F75539BFEC7FAF49F0D48A48D27862F0C3B09903, # noqa: E501 + 0x809C325F50ACF5787776E960985E72443B4330AD1E2F466557FFFEE16BA51D44: 0xB940A56E64B5B661D87919B8EF03640EC077A6D72DD0B524ADEDAA7DDC91FF7A, # noqa: E501 + 0x84E4A80D33C5D2ABD2B0A5AEC0FDC5EAEED90AB31DB556E404A81718EA286E39: 28, # noqa: E501 + 0x877305412FA2486F563C457B744E5C8B1E4D0ECA73371DE5E771F2ABC263F4DC: 0x7088A36F67276D475AA62127CFDE9790CC802FDF3A54DF49461A25EB8BF15707, # noqa: E501 + 0x922A8F2FC1CBE67C8ACC6A8A720983C366D71D3E2E78E3048949EBC913EA611A: 0x50FB9F913CA102534BB0A8EB8EBF19C68DFD16FFE5E207BCC580084CD4ECD8B4, # noqa: E501 + 0x987CB9ECFD8CE499D9D0E9E6B7DA29617AA02774A34F4A8EA54442F44A1E1936: 0x5179F98F555F1E9F1D4A335D16F41154579A53E361E9859269B6FA74EA9C7D21, # noqa: E501 + 0xADA5013122D395BA3C54772283FB069B10426056EF8CA54750CB9BB552A59E7D: 0xF69B5, # noqa: E501 + 0xB16B117660F31197087F4D6FE50D3D4579152244956F753F9653CCF85F4B35C4: 0x830272E3BB35226B047244CBDC46F1B6B864A280461E7A592F70E0863F4F1D33, # noqa: E501 + 0xB1F1AAEDFB83C7755A2BFFC9E2557F1723F9ABE5642397963E76248C9209AF57: 0xE9BE955C5FBFCD846D7425EAEA05CE897786AEFAD99665342CBF30761B352526, # noqa: E501 + 0xB7BD50FDF7B043411C9AC33F0AF2CEBC69C393EB0B91F4976946F9C7B15AD0DA: 0xFCCCA0E7832BAE9AFE799A6D6177DC3869FA6C5B5105F8DF6F365DE5723820EC, # noqa: E501 + 0xBC96058EB03504EE6F5C0A9582F8720D99A6E9738B171499507FACFF0B2C0B5B: 0x9DB6A4F2766B51013B8D2F9038131D1BB4AF725D019D111D7E26FF96C023B23F, # noqa: E501 + 0xC186C4F377B7F13892ADE9656ACD1522AA1F8AC151AC4F62457B5073241D79FC: 0x7289738FEF00F1770EEB098DB9BD486C01AC12398D79CDF935514A128C585C51, # noqa: E501 + 0xCAE57AE3017972D63EFFD8EAE44F5054402C3E890D154B905ED6B5B533327FA9: 0xD2E4BF465E61993D13089B940A7C55017A5117D8E43E4115550A139E1D4B3E3A, # noqa: E501 + 0xCF569EE7BF3ACCC0F893DFFD04F1A757F373EFE80893EFF504FB3678F688EC1D: contract_3, # noqa: E501 + 0xD69B7284545A9F5275DF64CE94848DC954FCB8A8B525E7AC801517C12A75AF84: 0x4202995350ABAE303B43E564AA79121A30B5F1AEA31F69CD25E07DD3FA64DCE7, # noqa: E501 + 0xD8F6F90F51E657690EE28D1CC80D81BC1B89290065891FDD853D09CAAAF756AA: contract_1, # noqa: E501 + 0xDE72F8EED43CC2A5A3EAA51483D14B17DC92BB26C154AE184CEE4B4895011EDC: 0x47CE2B6FDB72C3FABB9C74F82C1E3E522BCD42E614FD85C208AC3C4C840CEA72, # noqa: E501 + 0xE0E687DDF317F3D2B209AE3884148EFF0F636E16827F82EDED14ADA8FC603009: 0xFA7C8939F9B033162CF8D75EA69671BB8A27041BD4CDC76594E61E99333CB041, # noqa: E501 + 0xE8CDA339D72A1A350B62F1E3FA52E254C395CC9FDD9F60ADB21C7633FBDAB531: 0x128C4FDF4801A30EAE99DD58F0F3FF5CA65F71B66A9AC0F38DD450FB24B4AAAA, # noqa: E501 + 0xEC5E7F54FA5E516E616B04F9D5A0EE433A80E09ED47D7E5269AFD76C05FF251E: 20, # noqa: E501 + 0xF9A3BF5F2CCB903EE1A7644113B794DB0260DE404FB8F11203E75A7FFF151618: 0xBD94773C0D85C68240AE8DFD53D9D33CD137509BFC5D3433381299DF768C8377, # noqa: E501 + }, + nonce=0, + address=Address(0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E), # noqa: E501 + ) + # Source: raw + # 0x6000610b7f537c01000000000000000000000000000000000000000000000000000000006000350473c9ae5868651bf7b7db6e360217db49ce4e69c07e6020526308d3d58781141561024557600435606052606060605990590160009052600081526060518160200152600181604001528090502054608052600060806080599059016000905260008152606051816020015260028160400152328160600152809050205414151561014e57608060805990590160009052600081526060518160200152600281604001523281606001528090502054608052682f000000000000000060a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020553260a060a05990590160009052600081526060518160200152600081604001526080518160600152600181608001528090502055610238565b608051608060805990590160009052600081526060518160200152600281604001523281606001528090502055682f000000000000000060a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020553260a060a059905901600090526000815260605181602001526000816040015260805181606001526001816080015280905020556001606060605990590160009052600081526060518160200152600181604001528090502054016060606059905901600090526000815260605181602001526001816040015280905020555b60016101e05260206101e0f35b6328c8b31581141561029d576004356060526024356102005260a060a0599059016000905260008152606051816020015260008160400152610200518160600152600081608001528090502054610220526020610220f35b6374af23ec8114156103865760043560605260243561026052608060805990590160009052600081526060518160200152600281604001526102605181606001528090502054610200526000610200511415610332576102605160a060a05990590160009052600081526060518160200152600081604001526102005181606001526001816080015280905020541415610335565b60005b156103475760006102c05260206102c0f35b60a060a05990590160009052600081526060518160200152600081604001526102005181606001526000816080015280905020546102e05260206102e0f35b6384d646ee8114156103dc5760043560605260243560805260a060a05990590160009052600081526060518160200152600081604001526080518160600152600181608001528090502054610320526020610320f35b63f42294278114156106f45760043561026052601c602459905901600090520163175c6322601c82035260206103a06004836000602051602d5a03f1506103a0519050610360526102605115610581576103605160020280602002602001599059016000905281815260208101905090506103c05261036051806020026020015990590160009052818152602081019050905061042052601c602459905901600090520163c3387858601c8203526103605160408160200201599059016000905281602002604001816004856000602051602d5a03f150604081019050905090506104205260006104c05260006104e0525b610360516104c051121561057c576104c051602002610420510151606052601c60645990590160009052016374af23ec601c82035260605160048201526102605160248201526020610520604483600030602d5a03f1506105205190506105005260006105005114151561056c576060516104e0516020026103c05101526105005160016104e051016020026103c051015260026104e051016104e0525b60016104c051016104c0526104ce565b6106d7565b32610260526103605160020280602002602001599059016000905281815260208101905090506103c05261036051806020026020015990590160009052818152602081019050905061042052601c602459905901600090520163c3387858601c8203526103605160408160200201599059016000905281602002604001816004856000602051602d5a03f150604081019050905090506104205260006104c05260006104e0525b610360516104c05112156106d6576104c051602002610420510151606052601c60645990590160009052016374af23ec601c820352606051600482015261026051602482015260206105c0604483600030602d5a03f1506105c0519050610500526000610500511415156106c6576060516104e0516020026103c05101526105005160016104e051016020026103c051015260026104e051016104e0525b60016104c051016104c052610628565b5b6103c05160206040820352602060208203510260400160408203f3505b6380b5e7bd81141561073557600435606052606060605990590160009052600081526060518160200152600181604001528090502054610600526020610600f35b63156f1c328114156107865760043560605260243561064052608060805990590160009052600081526060518160200152600281604001526106405181606001528090502054610660526020610660f35b63b3a24fc081141561087857365990590160009052366004823760043560208201016106c0526024356106e05250600260206106c0510351018060200260200159905901600090528181526020810190509050610700523261070051526106e051602061070051015260026104c0525b600260206106c0510351016104c05112156108385760026104c051036020026106c05101516104c05160200261070051015260016104c051016104c0526107f6565b60206107005103516020026020599059016000905260208183610700516000600287604801f15080519050905061076052610760516107c05260206107c0f35b63e346f5fc811415610a1c576004356107e0526024356108005260006104c0525b606060605990590160009052600081526107e05181602001526001816040015280905020546104c05112156109e65760a060a05990590160009052600081526107e0518160200152600081604001526104c0518160600152600181608001528090502054610840526108405160a060a0599059016000905260008152610800518160200152600081604001526104c051816060015260018160800152809050205560a060a05990590160009052600081526107e0518160200152600081604001526104c051816060015260008160800152809050205460a060a0599059016000905260008152610800518160200152600081604001526104c05181606001526000816080015280905020556104c0516080608059905901600090526000815261080051816020015260028160400152610840518160600152809050205560016104c051016104c052610899565b6104c051606060605990590160009052600081526108005181602001526001816040015280905020556001610920526020610920f35b633fb57036811415610b5457600435606052602435610940526060606059905901600090526000815260605181602001526001816040015280905020546109605261096051608060805990590160009052600081526060518160200152600281604001526109405181606001528090502055600060a060a05990590160009052600081526060518160200152600081604001526109605181606001526000816080015280905020556109405160a060a05990590160009052600081526060518160200152600081604001526109605181606001526001816080015280905020556001606060605990590160009052600081526060518160200152600181604001528090502054016060606059905901600090526000815260605181602001526001816040015280905020556001610a40526020610a40f35b6312709a33811415610beb57600435606052602435608052604435610a6052610a605160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020540160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020556001610ac0526020610ac0f35b633229cf6e811415610c8257600435606052602435608052604435610a6052610a605160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020540360a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020556001610b20526020610b20f35b63a75f5c6a811415610ce557600435606052602435608052604435610a6052610a605160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020556001610b60526020610b60f35b50 # noqa: E501 + contract_10 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0xB7F, value=0x0) + + Op.DIV( + Op.CALLDATALOAD(offset=0x0), + 0x100000000000000000000000000000000000000000000000000000000, ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1128) - + Op.JUMPDEST + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), + offset=0x20, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x12A3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB86F5125))) + + Op.JUMPI(pc=0x245, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x8D3D587))) + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1731,13 +1537,12 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x14) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 + + Op.MSTORE(offset=0x80, value=Op.SLOAD(key=Op.SHA3)) + + Op.PUSH1[0x0] + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -1748,12 +1553,13 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.ORIGIN) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SLOAD(key=Op.SHA3) + + Op.JUMPI(pc=0x14E, condition=Op.ISZERO(Op.ISZERO(Op.EQ))) + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -1764,15 +1570,14 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.ORIGIN) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.MUL(0x20, Op.SDIV) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.MSTORE(offset=0x80, value=Op.SLOAD(key=Op.SHA3)) + + Op.PUSH9[0x2F0000000000000000] + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1780,57 +1585,56 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.ORIGIN + + Op.PUSH1[0xA0] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x1267, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1246) - + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.JUMP(pc=0x238) + + Op.JUMPDEST + + Op.MLOAD(offset=0x80) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + Op.SWAP1 - + Op.POP + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.ORIGIN) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x1394, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBC3D7D85))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.SHA3 + + Op.SSTORE + + Op.PUSH9[0x2F0000000000000000] + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -1841,14 +1645,16 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x15) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.PUSH1[0x80] * 2 + + Op.SSTORE + + Op.ORIGIN + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1858,14 +1664,16 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.ADD(0x20, Op.DUP1) + + Op.SHA3 + + Op.SSTORE + + Op.PUSH1[0x1] + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1873,59 +1681,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + + Op.PUSH1[0x60] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x1358, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), - ) - + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x1337) + + Op.SHA3 + + Op.SSTORE + Op.JUMPDEST - + Op.MSTORE( - offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), - value=Op.AND( - Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.DUP2 - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP + + Op.MSTORE(offset=0x1E0, value=0x1) + + Op.RETURN(offset=0x1E0, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x1481, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA2302F2F))) + + Op.JUMPI(pc=0x29D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x28C8B315))) + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x1680, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x16A0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0x16A0) + + Op.MSTORE(offset=0x200, value=Op.CALLDATALOAD(offset=0x24)) + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -1936,10 +1722,18 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x200)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=0x220, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x220, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x386, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x74AF23EC))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x260, value=Op.CALLDATALOAD(offset=0x24)) + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -1950,21 +1744,17 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.SLOAD(key=Op.SHA3)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x260)) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0x1] - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0x200, value=Op.SLOAD(key=Op.SHA3)) + + Op.JUMPI( + pc=0x332, condition=Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x200), 0x0)) + ) + + Op.MLOAD(offset=0x260) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1974,16 +1764,23 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x200)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x80] * 2 + + Op.ISZERO(Op.EQ) + + Op.JUMP(pc=0x335) + + Op.JUMPDEST + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x347, condition=Op.ISZERO) + + Op.MSTORE(offset=0x2C0, value=0x0) + + Op.RETURN(offset=0x2C0, size=0x20) + + Op.JUMPDEST + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -1993,24 +1790,19 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x200)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x1740, value=0x1) - + Op.RETURN(offset=0x1740, size=0x20) + + Op.MSTORE(offset=0x2E0, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x2E0, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x14DD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x58CA2BC))) + + Op.JUMPI(pc=0x3DC, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x84D646EE))) + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x1760, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0x1760) - + Op.PUSH1[0x80] * 2 + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2020,18 +1812,19 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x17A0, value=0x1) - + Op.RETURN(offset=0x17A0, size=0x20) + + Op.MSTORE(offset=0x320, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x320, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x1617, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5D3B965B))) - + Op.CALLDATASIZE + + Op.JUMPI(pc=0x6F4, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xF4229427))) + + Op.MSTORE(offset=0x260, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x24] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2039,19 +1832,27 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x280, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE( - offset=0x17E0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x64)), + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x175C6322) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x4, + ret_offset=0x3A0, + ret_size=0x20, + ) ) - + Op.MSTORE(offset=0x1800, value=Op.CALLDATALOAD(offset=0x84)) + + Op.MLOAD(offset=0x3A0) + + Op.SWAP1 + Op.POP - + Op.PUSH1[0xC0] * 2 + + Op.PUSH2[0x360] + + Op.MSTORE + + Op.JUMPI(pc=0x581, condition=Op.ISZERO(Op.MLOAD(offset=0x260))) + + Op.MUL(0x2, Op.MLOAD(offset=0x360)) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2059,48 +1860,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x3) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x280)) - + Op.MSTORE(offset=Op.ADD(0xA0, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x17E0), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x158C, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x17E0), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x156B) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x17E0), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MLOAD(offset=0x1800) - + Op.PUSH1[0x80] * 2 + + Op.PUSH2[0x3C0] + + Op.MSTORE + + Op.MLOAD(offset=0x360) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2108,41 +1877,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) - + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x1900, value=0x1) - + Op.RETURN(offset=0x1900, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1673, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB0E14F0F))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x1920, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0x1920) - + Op.PUSH1[0x80] * 2 + + Op.PUSH2[0x420] + + Op.MSTORE + + Op.PUSH1[0x1C] + + Op.PUSH1[0x24] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2150,20 +1894,10 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x1960, value=0x1) - + Op.RETURN(offset=0x1960, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1739, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x6ACCCDBC))) - + Op.CALLDATASIZE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC3387858) + + Op.MLOAD(offset=0x360) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2171,86 +1905,46 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x1980, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x4, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) ) - + Op.POP - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x6) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1980), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x170B, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1980), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x16EA) + + Op.PUSH2[0x420] + + Op.MSTORE + + Op.MSTORE(offset=0x4C0, value=0x0) + + Op.MSTORE(offset=0x4E0, value=0x0) + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1980), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + + Op.JUMPI( + pc=0x57C, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=0x4C0), Op.MLOAD(offset=0x360)) ), ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1A40, value=0x1) - + Op.RETURN(offset=0x1A40, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x17FF, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA1FA51F9))) - + Op.CALLDATASIZE - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.MSTORE( - offset=0x1A60, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + offset=0x60, + value=Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x420), + Op.MUL(0x20, Op.MLOAD(offset=0x4C0)), + ) + ), ) - + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2258,50 +1952,53 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x7) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x74AF23EC) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0x260)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.ADDRESS, + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x520, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x520) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1A60), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x17D1, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1A60), Op.MUL(0x20, Op.DUP1)) + + Op.PUSH2[0x500] + + Op.MSTORE + + Op.JUMPI( + pc=0x56C, + condition=Op.ISZERO(Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x500), 0x0))), + ) + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), Op.MUL(0x20, Op.MLOAD(offset=0x4E0)) ), + value=Op.MLOAD(offset=0x60), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x17B0) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1A60), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), + Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x4E0), 0x1)), ), + value=Op.MLOAD(offset=0x500), ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1B20, value=0x1) - + Op.RETURN(offset=0x1B20, size=0x20) + + Op.MSTORE(offset=0x4E0, value=Op.ADD(Op.MLOAD(offset=0x4E0), 0x2)) + Op.JUMPDEST - + Op.JUMPI(pc=0x18C5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xCD87F43A))) - + Op.CALLDATASIZE + + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) + + Op.JUMP(pc=0x4CE) + + Op.JUMPDEST + + Op.JUMP(pc=0x6D7) + + Op.JUMPDEST + + Op.MSTORE(offset=0x260, value=Op.ORIGIN) + + Op.MUL(0x2, Op.MLOAD(offset=0x360)) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2309,17 +2006,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x1B40, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.SWAP1 + + Op.POP + + Op.PUSH2[0x3C0] + + Op.MSTORE + + Op.MLOAD(offset=0x360) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2327,50 +2023,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x8) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1B40), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1897, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1B40), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x1876) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1B40), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1C00, value=0x1) - + Op.RETURN(offset=0x1C00, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x198B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x222A8663))) - + Op.CALLDATASIZE + + Op.PUSH2[0x420] + + Op.MSTORE + + Op.PUSH1[0x1C] + + Op.PUSH1[0x24] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2378,17 +2040,10 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x1C20, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) - + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC3387858) + + Op.MLOAD(offset=0x360) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2396,68 +2051,46 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x9) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1C20), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x195D, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1C20), Op.MUL(0x20, Op.DUP1)) - ), + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x4, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) ) - + Op.ADD(Op.DUP2, 0x1) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x193C) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1C20), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1CE0, value=0x1) - + Op.RETURN(offset=0x1CE0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1A51, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB39E1FAA))) - + Op.CALLDATASIZE - + Op.MSIZE + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + + Op.POP + Op.SWAP1 + + Op.POP + + Op.PUSH2[0x420] + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + + Op.MSTORE(offset=0x4C0, value=0x0) + + Op.MSTORE(offset=0x4E0, value=0x0) + + Op.JUMPDEST + + Op.JUMPI( + pc=0x6D6, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=0x4C0), Op.MLOAD(offset=0x360)) + ), ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.MSTORE( - offset=0x1D00, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + offset=0x60, + value=Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x420), + Op.MUL(0x20, Op.MLOAD(offset=0x4C0)), + ) + ), ) - + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2465,68 +2098,61 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xA) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x74AF23EC) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0x260)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.ADDRESS, + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x5C0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x5C0) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1D00), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1A23, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1D00), Op.MUL(0x20, Op.DUP1)) + + Op.PUSH2[0x500] + + Op.MSTORE + + Op.JUMPI( + pc=0x6C6, + condition=Op.ISZERO(Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x500), 0x0))), + ) + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), Op.MUL(0x20, Op.MLOAD(offset=0x4E0)) ), + value=Op.MLOAD(offset=0x60), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1A02) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1D00), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x3C0), + Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x4E0), 0x1)), ), + value=Op.MLOAD(offset=0x500), ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1DC0, value=0x1) - + Op.RETURN(offset=0x1DC0, size=0x20) + + Op.MSTORE(offset=0x4E0, value=Op.ADD(Op.MLOAD(offset=0x4E0), 0x2)) + Op.JUMPDEST - + Op.JUMPI(pc=0x1B17, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xE365736B))) - + Op.CALLDATASIZE - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x1DE0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) + + Op.JUMP(pc=0x628) + + Op.JUMPDEST * 2 + + Op.MLOAD(offset=0x3C0) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), ) + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.JUMPDEST + + Op.JUMPI(pc=0x735, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x80B5E7BD))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2536,51 +2162,16 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xB) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1DE0), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1AE9, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1DE0), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1AC8) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1DE0), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1EA0, value=0x1) - + Op.RETURN(offset=0x1EA0, size=0x20) + + Op.MSTORE(offset=0x600, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x600, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x1B73, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xAAD7D6E3))) + + Op.JUMPI(pc=0x786, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x156F1C32))) + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x1EC0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0x1EC0) + + Op.MSTORE(offset=0x640, value=Op.CALLDATALOAD(offset=0x24)) + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -2591,17 +2182,15 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xC) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x640)) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x1F00, value=0x1) - + Op.RETURN(offset=0x1F00, size=0x20) + + Op.MSTORE(offset=0x660, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x660, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x1C39, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1112B27))) + + Op.JUMPI(pc=0x878, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB3A24FC0))) + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 @@ -2613,14 +2202,14 @@ def test_block504980( + Op.CALLDATACOPY( dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.MSTORE( - offset=0x1F20, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + offset=0x6C0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), ) + + Op.MSTORE(offset=0x6E0, value=Op.CALLDATALOAD(offset=0x24)) + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.ADD(Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x6C0), 0x20)), 0x2) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2628,50 +2217,49 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xD) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1F20), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1C0B, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x1F20), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x1BEA) + + Op.PUSH2[0x700] + + Op.MSTORE + + Op.MSTORE(offset=Op.MLOAD(offset=0x700), value=Op.ORIGIN) + + Op.MSTORE( + offset=Op.ADD(Op.MLOAD(offset=0x700), 0x20), + value=Op.MLOAD(offset=0x6E0), + ) + + Op.MSTORE(offset=0x4C0, value=0x2) + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x1F20), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + + Op.JUMPI( + pc=0x838, + condition=Op.ISZERO( + Op.SLT( + Op.MLOAD(offset=0x4C0), + Op.ADD( + Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x6C0), 0x20)), + 0x2, + ), + ) ), ) - + Op.POP * 4 - + Op.MSTORE(offset=0x1FE0, value=0x1) - + Op.RETURN(offset=0x1FE0, size=0x20) + + Op.MSTORE( + offset=Op.ADD( + Op.MLOAD(offset=0x700), Op.MUL(0x20, Op.MLOAD(offset=0x4C0)) + ), + value=Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x6C0), + Op.MUL(0x20, Op.SUB(Op.MLOAD(offset=0x4C0), 0x2)), + ) + ), + ) + + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) + + Op.JUMP(pc=0x7F6) + Op.JUMPDEST - + Op.JUMPI(pc=0x1CFF, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBDBB239B))) - + Op.CALLDATASIZE + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x700), 0x20))) + + Op.PUSH1[0x20] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2679,17 +2267,33 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x2000, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + + Op.POP( + Op.CALL( + gas=Op.ADD(0x48, Op.DUP8), + address=0x2, + value=0x0, + args_offset=Op.MLOAD(offset=0x700), + args_size=Op.DUP4, + ret_offset=Op.DUP2, + ret_size=0x20, + ) ) + + Op.MLOAD(offset=Op.DUP1) + + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.SWAP1 + + Op.POP + + Op.PUSH2[0x760] + + Op.MSTORE + + Op.MSTORE(offset=0x7C0, value=Op.MLOAD(offset=0x760)) + + Op.RETURN(offset=0x7C0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0xA1C, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xE346F5FC))) + + Op.MSTORE(offset=0x7E0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x800, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x4C0, value=0x0) + + Op.JUMPDEST + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2698,49 +2302,18 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xE) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x7E0)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2000), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1CD1, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x2000), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1CB0) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x2000), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), + + Op.JUMPI( + pc=0x9E6, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=0x4C0), Op.SLOAD(key=Op.SHA3)) ), ) - + Op.POP * 4 - + Op.MSTORE(offset=0x20C0, value=0x1) - + Op.RETURN(offset=0x20C0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1DC5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5A0CD48))) - + Op.CALLDATASIZE + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2748,16 +2321,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x20E0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x7E0)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + + Op.DUP1 + + Op.SWAP1 + Op.POP + + Op.MSTORE(offset=0x840, value=Op.SLOAD(key=Op.SHA3)) + + Op.MLOAD(offset=0x840) + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -2767,49 +2340,16 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xF) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x20E0), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1D97, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x20E0), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1D76) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x20E0), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x21A0, value=0x1) - + Op.RETURN(offset=0x21A0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1E8B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xAAA1FE35))) - + Op.CALLDATASIZE + + Op.SSTORE + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2817,16 +2357,15 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x21C0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x7E0)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -2836,49 +2375,38 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x10) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x21C0), 0x20))) - + Op.DIV(Op.DUP2, 0x20) + + Op.SSTORE + + Op.MLOAD(offset=0x4C0) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1E5D, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x21C0), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x840)) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x1E3C) + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) + + Op.JUMP(pc=0x899) + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x21C0), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x2280, value=0x1) - + Op.RETURN(offset=0x2280, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1F51, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2BE4935D))) - + Op.CALLDATASIZE + + Op.MLOAD(offset=0x4C0) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2886,17 +2414,21 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x22A0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.DUP1 + + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x920, value=0x1) + + Op.RETURN(offset=0x920, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0xB54, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3FB57036))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x940, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2906,48 +2438,13 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x11) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x22A0), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1F23, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x22A0), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1F02) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x22A0), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x2360, value=0x1) - + Op.RETURN(offset=0x2360, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x2017, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x13A8350D))) - + Op.CALLDATASIZE + + Op.MSTORE(offset=0x960, value=Op.SLOAD(key=Op.SHA3)) + + Op.MLOAD(offset=0x960) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -2955,16 +2452,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x2380, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x940)) + + Op.DUP1 + + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.PUSH1[0x0] + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -2975,48 +2472,35 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x12) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x960)) + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2380), 0x20))) - + Op.DIV(Op.DUP2, 0x20) + + Op.SSTORE + + Op.MLOAD(offset=0x940) + + Op.PUSH1[0xA0] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x1FE9, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x2380), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x960)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x1FC8) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x2380), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x2440, value=0x1) - + Op.RETURN(offset=0x2440, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x20DD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xCB540B45))) - + Op.CALLDATASIZE + + Op.SHA3 + + Op.SSTORE + + Op.PUSH1[0x1] + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3024,17 +2508,15 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x2460, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.DUP1 + + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] * 2 + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + + Op.PUSH1[0x60] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3044,48 +2526,21 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x13) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2460), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x20AF, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x2460), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x208E) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x2460), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x2520, value=0x1) - + Op.RETURN(offset=0x2520, size=0x20) + + Op.SSTORE + + Op.MSTORE(offset=0xA40, value=0x1) + + Op.RETURN(offset=0xA40, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x21A3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBE030627))) - + Op.CALLDATASIZE + + Op.JUMPI(pc=0xBEB, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x12709A33))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0xA60, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0xA60) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3093,16 +2548,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x2540, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -3113,48 +2568,23 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x14) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2540), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] + + Op.SSTORE + + Op.MSTORE(offset=0xAC0, value=0x1) + + Op.RETURN(offset=0xAC0, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x2175, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x2540), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x2154) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x2540), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x2600, value=0x1) - + Op.RETURN(offset=0x2600, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x2269, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x83FD77F0))) - + Op.CALLDATASIZE + + Op.JUMPI(pc=0xC82, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3229CF6E))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0xA60, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0xA60) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3162,16 +2592,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE( - offset=0x2620, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.SUB + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -3182,52 +2612,22 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x15) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2620), 0x20))) - + Op.DIV(Op.DUP2, 0x20) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x223B, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.MLOAD( - offset=Op.ADD(Op.MLOAD(offset=0x2620), Op.MUL(0x20, Op.DUP1)) - ), - ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x221A) - + Op.JUMPDEST - + Op.SSTORE( - key=Op.ADD(Op.DUP3, Op.DUP5), - value=Op.AND( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x2620), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.SUB( - 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) - ), - ), - ) - + Op.POP * 4 - + Op.MSTORE(offset=0x26E0, value=0x1) - + Op.RETURN(offset=0x26E0, size=0x20) + + Op.SSTORE + + Op.MSTORE(offset=0xB20, value=0x1) + + Op.RETURN(offset=0xB20, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x22D5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x59462205))) + + Op.JUMPI(pc=0xCE5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA75F5C6A))) + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x3C0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x2700, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MLOAD(offset=0x2700) + + Op.MSTORE(offset=0xA60, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0xA60) + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -3238,23 +2638,43 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x4) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x3C0)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 + Op.SSTORE - + Op.MSTORE(offset=0x2740, value=0x1) - + Op.RETURN(offset=0x2740, size=0x20) + + Op.MSTORE(offset=0xB60, value=0x1) + + Op.RETURN(offset=0xB60, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x2448, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBB8E4196))) + + Op.POP, + storage={ + 0xF299DBBE3A7A5D949FE794E9A47B3106699C8110FF986EB84921C183E69E7F0: 0x2F0000000000000000, # noqa: E501 + 0x1EDCD36F61CAE5DC6414157DFBADF9F11CA013AC763E27F8AF55FEAA8A239C89: contract_1, # noqa: E501 + 0x689082D076EC3C02CBE4B99F6D9833E3C4A161072FD42FB7649EEE5189A67CCC: 0x63524E3FE4791AEFCE1E932BBFB3FDF375BFAD89, # noqa: E501 + 0xAF1D6676BE3AB502A59D91F6F5C49BAFFC15B2CFC65A41C4D96857C0F535ADBA: 0x1D60000000000000000, # noqa: E501 + 0xDF1A770F69D93D1719292F384FDB4DA22C0E88AEF2BA462BFF16674BC7848730: 0x1C11AA45C792E202E9FFDC2F12F99D0D209BEF70, # noqa: E501 + 0xEC5E7F54FA5E516E616B04F9D5A0EE433A80E09ED47D7E5269AFD76C05FF251E: contract_2, # noqa: E501 + }, + nonce=0, + address=Address(0xE509E3A93BEB1EBA72F8CB8D25F93A85E2D54AFB), # noqa: E501 + ) + # Source: raw + # 0x600061289f537c01000000000000000000000000000000000000000000000000000000006000350473c9ae5868651bf7b7db6e360217db49ce4e69c07e60205263c4982a8581141561012757600435606052602435608052608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460a05260a051806020026020015990590160009052818152602081019050905060e0526000610140525b60a05161014051121561010b5760a060a0599059016000905260008152606051816020015260805181604001526001816060015261014051816080015280905020546101405160200260e051015260016101405101610140526100ad565b60e05160206040820352602060208203510260400160408203f3505b63cc1c944e8114156101765760043560605260243560805260806080599059016000905260008152606051816020015260805181604001526000816060015280905020546101a05260206101a0f35b6395a405b98114156101d5576004356060526024356080526044356101e05260a060a059905901600090526000815260605181602001526080518160400152600181606001526101e05181608001528090502054610200526020610200f35b6371ebb662811415610224576004356060526024356080526080608059905901600090526000815260605181602001526080518160400152600281606001528090502054610240526020610240f35b637a57a3db811415610325576004356060526024356080526044356102805260c060c0599059016000905260008152606051816020015260805181604001526003816060015261028051816080015260008160a0015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156102e95780840154816020028301526001810190506102c8565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63f73dc690811415610394576004356060526024356080526044356103c0526064356103e05260c060c059905901600090526000815260605181602001526080518160400152600381606001526103c05181608001526103e0518160a001528090502054610400526020610400f35b6354cc61098114156103f3576004356060526024356080526044356103c05260a060a059905901600090526000815260605181602001526080518160400152600481606001526103c05181608001528090502054610440526020610440f35b63c63ef546811415610442576004356060526024356080526080608059905901600090526000815260605181602001526080518160400152600581606001528090502054610480526020610480f35b639381779b8114156105335760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600681606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156104f75780840154816020028301526001810190506104d6565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b634f9c6eeb8114156106245760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600781606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156105e85780840154816020028301526001810190506105c7565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b637dc121958114156107155760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600881606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156106d95780840154816020028301526001810190506106b8565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63fa9832d18114156108065760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600981606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156107ca5780840154816020028301526001810190506107a9565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b632c5a40d58114156108f75760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600a81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260058160600152809050205460200280806020015990590160009052818152602081019050905060005b602083048112156108bb57808401548160200283015260018101905061089a565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63e05dcb568114156109eb5760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600b81606001526000816080015280905020600260806080599059016000905260008152606051816020015260805181604001526000816060015280905020546020020180806020015990590160009052818152602081019050905060005b602083048112156109af57808401548160200283015260018101905061098e565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63586b5be0811415610a3a576004356060526024356080526080608059905901600090526000815260605181602001526080518160400152600c81606001528090502054610b80526020610b80f35b63eb8af5aa811415610b585760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600d81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215610b1c578084015481602002830152600181019050610afb565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b637ab6ea8a811415610c765760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600e81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215610c3a578084015481602002830152600181019050610c19565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b632b810cb9811415610d945760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152600f81606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215610d58578084015481602002830152600181019050610d37565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b637fb42e46811415610e855760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601081606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b60208304811215610e49578084015481602002830152600181019050610e28565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63734fa727811415610f765760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601181606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b60208304811215610f3a578084015481602002830152600181019050610f19565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63c67fa8578114156110675760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601281606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b6020830481121561102b57808401548160200283015260018101905061100a565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b635ed853e48114156111855760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601381606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215611149578084015481602002830152600181019050611128565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63b86f51258114156112a35760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601481606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460806080599059016000905260008152606051816020015260805181604001526005816060015280905020540560200280806020015990590160009052818152602081019050905060005b60208304811215611267578084015481602002830152600181019050611246565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63bc3d7d858114156113945760043560605260243560805260a060a059905901600090526000815260605181602001526080518160400152601581606001526000816080015280905020608060805990590160009052600081526060518160200152608051816040015260008160600152809050205460200280806020015990590160009052818152602081019050905060005b60208304811215611358578084015481602002830152600181019050611337565b602083066020036101000a60000381850154168160200283015281905090509050905060206040820352602060208203510260400160408203f3505b63a2302f2f81141561148157600435606052602435611680526044356116a0526116a05160a060a0599059016000905260008152606051816020015261168051816040015260018160600152608060805990590160009052600081526060518160200152611680518160400152600081606001528090502054816080015280905020556001608060805990590160009052600081526060518160200152611680518160400152600081606001528090502054016080608059905901600090526000815260605181602001526116805181604001526000816060015280905020556001611740526020611740f35b63058ca2bc8114156114dd576004356060526024356080526044356117605261176051608060805990590160009052600081526060518160200152608051816040015260028160600152809050205560016117a05260206117a0f35b635d3b965b8114156116175736599059016000905236600482376004356060526024356080526044356102805260643560208201016117e052608435611800525060c060c0599059016000905260008152606051816020015260805181604001526003816060015261028051816080015260008160a001528090502060206117e05103516020026020810460005b8181121561158c57806020026117e05101518482015560018101905061156b565b602083066020036101000a600003816020026117e05101511684820155505050506118005160806080599059016000905260008152606051816020015260805181604001526002816060015280905020540160806080599059016000905260008152606051816020015260805181604001526002816060015280905020556001611900526020611900f35b63b0e14f0f81141561167357600435606052602435608052604435611920526119205160806080599059016000905260008152606051816020015260805181604001526005816060015280905020556001611960526020611960f35b636acccdbc8114156117395736599059016000905236600482376004356060526024356080526044356020820101611980525060a060a05990590160009052600081526060518160200152608051816040015260068160600152600081608001528090502060206119805103516020026020810460005b8181121561170b5780602002611980510151848201556001810190506116ea565b602083066020036101000a600003816020026119805101511684820155505050506001611a40526020611a40f35b63a1fa51f98114156117ff5736599059016000905236600482376004356060526024356080526044356020820101611a60525060a060a0599059016000905260008152606051816020015260805181604001526007816060015260008160800152809050206020611a605103516020026020810460005b818112156117d15780602002611a60510151848201556001810190506117b0565b602083066020036101000a60000381602002611a605101511684820155505050506001611b20526020611b20f35b63cd87f43a8114156118c55736599059016000905236600482376004356060526024356080526044356020820101611b40525060a060a0599059016000905260008152606051816020015260805181604001526008816060015260008160800152809050206020611b405103516020026020810460005b818112156118975780602002611b4051015184820155600181019050611876565b602083066020036101000a60000381602002611b405101511684820155505050506001611c00526020611c00f35b63222a866381141561198b5736599059016000905236600482376004356060526024356080526044356020820101611c20525060a060a0599059016000905260008152606051816020015260805181604001526009816060015260008160800152809050206020611c205103516020026020810460005b8181121561195d5780602002611c205101518482015560018101905061193c565b602083066020036101000a60000381602002611c205101511684820155505050506001611ce0526020611ce0f35b63b39e1faa811415611a515736599059016000905236600482376004356060526024356080526044356020820101611d00525060a060a059905901600090526000815260605181602001526080518160400152600a816060015260008160800152809050206020611d005103516020026020810460005b81811215611a235780602002611d0051015184820155600181019050611a02565b602083066020036101000a60000381602002611d005101511684820155505050506001611dc0526020611dc0f35b63e365736b811415611b175736599059016000905236600482376004356060526024356080526044356020820101611de0525060a060a059905901600090526000815260605181602001526080518160400152600b816060015260008160800152809050206020611de05103516020026020810460005b81811215611ae95780602002611de051015184820155600181019050611ac8565b602083066020036101000a60000381602002611de05101511684820155505050506001611ea0526020611ea0f35b63aad7d6e3811415611b7357600435606052602435608052604435611ec052611ec0516080608059905901600090526000815260605181602001526080518160400152600c816060015280905020556001611f00526020611f00f35b6301112b27811415611c395736599059016000905236600482376004356060526024356080526044356020820101611f20525060a060a059905901600090526000815260605181602001526080518160400152600d816060015260008160800152809050206020611f205103516020026020810460005b81811215611c0b5780602002611f2051015184820155600181019050611bea565b602083066020036101000a60000381602002611f205101511684820155505050506001611fe0526020611fe0f35b63bdbb239b811415611cff5736599059016000905236600482376004356060526024356080526044356020820101612000525060a060a059905901600090526000815260605181602001526080518160400152600e8160600152600081608001528090502060206120005103516020026020810460005b81811215611cd1578060200261200051015184820155600181019050611cb0565b602083066020036101000a6000038160200261200051015116848201555050505060016120c05260206120c0f35b6305a0cd48811415611dc557365990590160009052366004823760043560605260243560805260443560208201016120e0525060a060a059905901600090526000815260605181602001526080518160400152600f8160600152600081608001528090502060206120e05103516020026020810460005b81811215611d9757806020026120e051015184820155600181019050611d76565b602083066020036101000a600003816020026120e051015116848201555050505060016121a05260206121a0f35b63aaa1fe35811415611e8b57365990590160009052366004823760043560605260243560805260443560208201016121c0525060a060a05990590160009052600081526060518160200152608051816040015260108160600152600081608001528090502060206121c05103516020026020810460005b81811215611e5d57806020026121c051015184820155600181019050611e3c565b602083066020036101000a600003816020026121c05101511684820155505050506001612280526020612280f35b632be4935d811415611f5157365990590160009052366004823760043560605260243560805260443560208201016122a0525060a060a05990590160009052600081526060518160200152608051816040015260118160600152600081608001528090502060206122a05103516020026020810460005b81811215611f2357806020026122a051015184820155600181019050611f02565b602083066020036101000a600003816020026122a05101511684820155505050506001612360526020612360f35b6313a8350d8114156120175736599059016000905236600482376004356060526024356080526044356020820101612380525060a060a05990590160009052600081526060518160200152608051816040015260128160600152600081608001528090502060206123805103516020026020810460005b81811215611fe9578060200261238051015184820155600181019050611fc8565b602083066020036101000a600003816020026123805101511684820155505050506001612440526020612440f35b63cb540b458114156120dd5736599059016000905236600482376004356060526024356080526044356020820101612460525060a060a05990590160009052600081526060518160200152608051816040015260138160600152600081608001528090502060206124605103516020026020810460005b818112156120af57806020026124605101518482015560018101905061208e565b602083066020036101000a600003816020026124605101511684820155505050506001612520526020612520f35b63be0306278114156121a35736599059016000905236600482376004356060526024356080526044356020820101612540525060a060a05990590160009052600081526060518160200152608051816040015260148160600152600081608001528090502060206125405103516020026020810460005b81811215612175578060200261254051015184820155600181019050612154565b602083066020036101000a600003816020026125405101511684820155505050506001612600526020612600f35b6383fd77f08114156122695736599059016000905236600482376004356060526024356080526044356020820101612620525060a060a05990590160009052600081526060518160200152608051816040015260158160600152600081608001528090502060206126205103516020026020810460005b8181121561223b57806020026126205101518482015560018101905061221a565b602083066020036101000a6000038160200261262051015116848201555050505060016126e05260206126e0f35b63594622058114156122d5576004356060526024356080526044356103c052606435612700526127005160a060a059905901600090526000815260605181602001526080518160400152600481606001526103c051816080015280905020556001612740526020612740f35b63bb8e419681141561244857600435606052602435612760526044356127805260006127a0525b6080608059905901600090526000815260605181602001526001612760510381604001526000816060015280905020546127a051121561243b5760a060a05990590160009052600081526060518160200152600161276051038160400152600181606001526127a0518160800152809050205460a060a05990590160009052600081526060518160200152612780518160400152600181606001526080608059905901600090526000815260605181602001526127805181604001526000816060015280905020548160800152809050205560016080608059905901600090526000815260605181602001526127805181604001526000816060015280905020540160806080599059016000905260008152606051816020015261278051816040015260008160600152809050205560016127a051016127a0526122fc565b6001612880526020612880f35b50 # noqa: E501 + contract_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x289F, value=0x0) + + Op.DIV( + Op.CALLDATALOAD(offset=0x0), + 0x100000000000000000000000000000000000000000000000000000000, + ) + + Op.MSTORE( + offset=0x20, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E + ) + + Op.JUMPI(pc=0x127, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC4982A85))) + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x2760, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x2780, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x27A0, value=0x0) - + Op.JUMPDEST + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -3265,21 +2685,14 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), - value=Op.SUB(Op.MLOAD(offset=0x2760), 0x1), - ) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.JUMPI( - pc=0x243B, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x27A0), Op.SLOAD(key=Op.SHA3)) - ), - ) - + Op.PUSH1[0xA0] * 2 + + Op.MSTORE(offset=0xA0, value=Op.SLOAD(key=Op.SHA3)) + + Op.MLOAD(offset=0xA0) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3287,20 +2700,22 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), - value=Op.SUB(Op.MLOAD(offset=0x2760), 0x1), - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) - + Op.MSTORE( - offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x27A0) - ) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0xE0] + + Op.MSTORE + + Op.MSTORE(offset=0x140, value=0x0) + + Op.JUMPDEST + + Op.JUMPI( + pc=0x10B, + condition=Op.ISZERO( + Op.SLT(Op.MLOAD(offset=0x140), Op.MLOAD(offset=0xA0)) + ), + ) + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 @@ -3311,10 +2726,34 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x140)) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) + offset=Op.ADD( + Op.MLOAD(offset=0xE0), Op.MUL(0x20, Op.MLOAD(offset=0x140)) + ), + value=Op.SLOAD(key=Op.SHA3), ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.MSTORE(offset=0x140, value=Op.ADD(Op.MLOAD(offset=0x140), 0x1)) + + Op.JUMP(pc=Op.PUSH2[0xAD]) + + Op.JUMPDEST + + Op.MLOAD(offset=0xE0) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x176, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xCC1C944E))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -3325,21 +2764,19 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) - ) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.SLOAD(key=Op.SHA3)) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0x1] - + Op.PUSH1[0x80] * 2 + + Op.MSTORE(offset=0x1A0, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x1A0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1D5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x95A405B9))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x1E0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3349,15 +2786,18 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x1E0)) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD + + Op.MSTORE(offset=0x200, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x200, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x224, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x71EBB662))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 @@ -3368,107 +2808,19 @@ def test_block504980( + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE( - offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) - ) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x27A0, value=Op.ADD(Op.MLOAD(offset=0x27A0), 0x1)) - + Op.JUMP(pc=0x22FC) - + Op.JUMPDEST - + Op.MSTORE(offset=0x2880, value=0x1) - + Op.RETURN(offset=0x2880, size=0x20) + + Op.MSTORE(offset=0x240, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x240, size=0x20) + Op.JUMPDEST - + Op.POP, - storage={ - 0x65D5EFDFCC0FBA693DC9E467F633097FFDC97401901463AD0E28855486D1EDF: 0xB9D69098A6ACFE0C6411BCAAF430F78D363A9ADC32B78BC2E15CCD6E883E9784, # noqa: E501 - 0x12643FF300762717D27EFB567B82C65560D7B43249D908504E5510863AB82AAC: 0x154CF60E137C594516A065149610B6A3989396A42581D5FD8919E711C55DA225, # noqa: E501 - 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D7: 5, # noqa: E501 - 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D8: 1, # noqa: E501 - 0x19EFB13D6576359514ACE5211988A8D51379FA88CCD2B886B409F842B13D7932: 0xC849CC595B452D11C206D2EB8CDFA06DE211E3FF19EE0E0276DC857C05D4FE, # noqa: E501 - 0x1B37E91BF8580C7C6BCF8CDFF25C7ED78180124A94AF6F30C40D476A3D079AD6: 0xABA4CD295118A482A0A62579E35E4BA5BDD76146CC9E4D96172FCE8BE8977AB4, # noqa: E501 - 0x2BF9FD8FACDD6FD9C84657F5AD7381A5AECF670CDA68CB3C5829B6532C865506: 0x53098A1D111586DBCC0D051846284F5803C63C313E7F7E6D84430435D11D4C50, # noqa: E501 - 0x3111BFD25728C0ADFAD0F8C1AD79CB1B91167267DECA98DE88F156ED25CAEEDC: 0xAD393086F30B49511B08FDD27AC78810B084C7CD7DE6AC354F614C18EA9E7DF4, # noqa: E501 - 0x3379E7AE125C5C5D623D1D993C1459B61D6723B1C30D1AA026C48F6A6155B8EA: 0x8C4183732567A99A8A718E363391E102532F9A640E42968CF2354D9ACC908BB0, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE2: 1, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE3: 1, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE4: 1, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE5: 1, # noqa: E501 - 0x39050607FE892059A6344AB0F594F382FB0B345CAB373497246DBE86FE7E14E7: 0x2B3BCA833E482737E7E47B1568E6F890F8E1666490D38FE130ABD6F0CCB109CF, # noqa: E501 - 0x417BE8BC6791807372E0222A350BB8A5D67BBC8D7595C301D8A5A8372CFDCEF1: 0xABD4971B4605A7155802F70E08298B1CEB0E4E4EACCCCD348F77A77227F73A7F, # noqa: E501 - 0x41E9A54B3EE0C276AA076BABB161DE12B0F8916B47F8F6FB85CC387CF34696DD: 0x22F2F444EBDA9D2913FFEF5059B039EC9B5876AA71821991C2515BF79F64935E, # noqa: E501 - 0x45CEB8DA6FB8936592D3BCE4883F1A6A34D636F559E0A1070A5802A65AC39BD5: 0x57A5122FF3BF737B0DE0F9F08011A8648C19E43FF071FB7086234723C9383F1F, # noqa: E501 - 0x4AA6B934608A45C8F53A945C05DDEE1814A3B9F63A048FC7AD3D47E67156F024: 0xD03862BECEDADA67B4825A0238F3E67495CCB595CD7D08F1BD5D3160644B9299, # noqa: E501 - 0x4B8B58F0B0E326A5907D1A810E5FF31E05B4CAB45125B776DB8577E7DBC46BCE: 0x2F0000000000000000, # noqa: E501 - 0x4C33460347337BFC7DF08BF182988301B7B426A27A67F1C6C634F637C60E87AC: 0xBAB4AB2AD4EAFE7C84EF6A8CD69157D9CE6B843793A2CD0877B8E91F63CB2D4D, # noqa: E501 - 0x58DA0C0C256BBA101CE36FAD8BF838717A57E6AB850A191DC9C09DA9CE56BF1B: 5, # noqa: E501 - 0x5CB38B16DB1D632086D4AF695DE7F5F242A6E40947067F96EDD566FE2AC438EF: 0x6D0BE832B2007EA28CDA705B73922CBF9794C5A25B89BD2F28B7347ED2B96C86, # noqa: E501 - 0x64A9621CC4BA92BF738C55010C609DFAA3972A1138C30B5ADCEF1BA2363B360E: 0xD7953BFE8CB591F129FD0862A9E9C421151E2B5831560FF5215D23F751364B35, # noqa: E501 - 0x696664A5F0AB5ACD9304A377FB684F2D3FE6BB60B8A95CB2BDBB57DB767E7A84: 0x154CF60E137C594516A065149610B6A3989396A42581D5FD8919E711C55DA225, # noqa: E501 - 0x69AD1D19E617936ABDF05133BF268DC8CED6B518F22B249B5860967D07006487: 0x8C803B48B383DDABD1B3AFE858EFB48C203229B7317DD76149DDDAB4253B858A, # noqa: E501 - 0x70B3BF53996FAC325EB67608A4EEB0CD0B55DEF6255D7ED42AD28EC07238B5D6: 0x45E9723E9232B37207ECAC1C97B8647D053625A578D450F7456280B2FF8EFC27, # noqa: E501 - 0x7A9DCEE62E3E02CC8E020F372DF2EFDEB835F091C1EF1DBE221072D1095AABD2: 0x2F0000000000000000, # noqa: E501 - 0x7E4D8C0F6D8ABB4CE1AE45B254046ACEEDABFA9548851B8B5D3E2C0637C985FD: 11, # noqa: E501 - 0x7E95F3CC3315D289C52253BAABA29B1B00C86816E6B788D50795279A8BAA00DB: 0x45E9723E9232B37207ECAC1C97B8647D053625A578D450F7456280B2FF8EFC27, # noqa: E501 - 0x8DA187157087529EE4E9C381F8E3149C56ACF3BDFDA29B8B9B4532F24B83F5FE: 0x8C4183732567A99A8A718E363391E102532F9A640E42968CF2354D9ACC908BB0, # noqa: E501 - 0x9001F91DDAEF87BC067886E874C0749998C9B58B2EC8472CA014CA8B55F88578: 0xFB76974EEFCA01F33FB38646C2D3C1536F1A763D7AFF53AB7F877D4C5EA7FD0, # noqa: E501 - 0x9ED0CEDD2A9A78D949F40019F53D10031AEF6ED342C97E01FC03B481EE56B3CB: 4, # noqa: E501 - 0x9FDDF1DB29CAA5C1239EDD86E9E0835CDFE41F7253EC78F62D3DA8558D6F3CD7: 0x104EEF8FA35BF39F677D81855BC0B9F42317F32792E98E95E4DF441DEB634211, # noqa: E501 - 0xA0953566119395C11186B334805FC1A16175ECAC0ECC93AE0322264F0DC2E40D: 0x10C5A00466AB7C0ADAE1E93537CC275EA8CF23FF509D5466A1FD6F56B0A61D1B, # noqa: E501 - 0xAA0DBF8241EF3AE07C254E6869E84895BA2BE0779A7F261C8308A3114BE1C54A: 4, # noqa: E501 - 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2D: 1, # noqa: E501 - 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2E: 1, # noqa: E501 - 0xB4A2B68C48EF78AEB641EE538FAD51781022FD23ED9D93D211017DB6A02376CE: 0xFBC06642245CF2FED7ED46EA0A18A7185830B6F2C4E0A4CA55246041E8BFA72, # noqa: E501 - 0xBA8D79990898383919E437F2458B93B340072C89D963808D9E04F51858E3C5EC: 0x41D2CAC534D90A0DBD199117481A63E32CC11411DAB2EAA36C91C0EEC62823CF, # noqa: E501 - 0xBB3BC1A2015123750DF57D4CEFF7E28CB847910B79B34841DE905B59A8BB177C: 0x734417EB19E1873427257F1EA1594748C16CFA866A7B7CF896E281F2EC774A40, # noqa: E501 - 0xBF30CDCB83AB2BD5F5EEE691FFA4107B58B75BA6A5C2E6754D4C5C0437F2876C: 5, # noqa: E501 - 0xC2A26B80067FC36B8268B0D5B31AFFF953FA91CEBEA39F191E2763D6E71259B9: 0x2A43C547FE8DE2400D2A141016550E8BAE058D41164247C099E787DDD40E789, # noqa: E501 - 0xC98339D275EEF16E0562CA8521212CEF61AA0F39B12E2A27502AAA97A9E5E70F: 0x5A3DE2A5C268CDB75F4B01507AA80C4E4A1BC67BCB0DF265BBB00060774E5978, # noqa: E501 - 0xCBD6AE6BD61BC9270EC836F1919B3268113ABE076C7FEBFDB8CF573B199CE9A9: 0xF402B17773C1F7534034EE58DC0D2A3421470A7A67DAF4FA790DC3B420EEF790, # noqa: E501 - 0xD2C8CBB562FCCD0C9A3D0D491B7F65CC6A89856498F933427D9D21B745B9D50E: 0x3625A26FDB7B747501F1EE2500F98C49D9CD290383A21254587C3C49D2805321, # noqa: E501 - 0xD66F52A4E24585238CCC03443B2FDB8B2B100259BC7260F39097C7C339211FFE: 0x1641851904381915C86B60DF7E288896FB5F8EBAD65D594829FB9F2B59CD1DA6, # noqa: E501 - 0xD8F720C05A5526DD621D1831AE122ABDDD3DFECD8B63B0BA4C92FA7B2ADE44FF: 0xAD393086F30B49511B08FDD27AC78810B084C7CD7DE6AC354F614C18EA9E7DF4, # noqa: E501 - 0xDC22D3171B82817C910BBEAC1F8B50C8DE99F8C524F172AEF3491981BD5ED4FB: 0x94B8CBA4EA090D1C392FBC94B82FB9EF9F468A15BBC537F4D051776F4D422B1D, # noqa: E501 - 0xDCE8ADBDEFA929DBE60245F359446DB4174C62824B42E5D4D9E7B834B4D61DEB: 0x2C9069845B2E74C577FF1CD18DF6BC452805F527A9EE91FD4A059E0408B5DEA6, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D196: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D197: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D198: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D199: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D19A: 1, # noqa: E501 - 0xE54F074C81BFA60B5BF413934C108086298B77291560EDFEEAD8AA1232E95236: 0xF40AAA24323C9E6983CCFFAFEEBE4B426509B901E8C98B8A40D881804804E6B, # noqa: E501 - 0xE66C0F55F66C752EDF73027D45B7B1AE729AE15E1C67C362DBC6F25EDF8D76FF: 1, # noqa: E501 - 0xE983D899F807BBCB5881F2DDF875B2EBB5CB8A7A4E77A8C98A40AAAE6A468735: 0x6D0BE832B2007EA28CDA705B73922CBF9794C5A25B89BD2F28B7347ED2B96C86, # noqa: E501 - 0xED7D6E2D40FBD5046412FFAD1C45B63D87C6197182D6DBC66BB1E5C6E4DED5C7: 0xABA4CD295118A482A0A62579E35E4BA5BDD76146CC9E4D96172FCE8BE8977AB4, # noqa: E501 - 0xF043B5A1952847579F233706A8F130889A484D2DA3E574FDD5859F05AAF52111: 2, # noqa: E501 - 0xF40F4CFDACB62DD799F36B580349FAC1F4A4CAF8DD3383CC387C35ADB6574E21: 0x2F0000000000000000, # noqa: E501 - 0xF60FA6E25E9028A6DC6B26BBC1EADAE3DA157DF0D1D6F6628BC33CAD68A7E455: 0x2D7D00618C059EBE40593B9497C633E1AC6E161DADBD5BB734C2663CD3E8A8E1, # noqa: E501 - 0xFD280AC5182D5B2366122F38ACFA6DC471240FFDE9D5FEB985CE7A2325C960E7: 3, # noqa: E501 - }, - nonce=0, - address=Address(0x0EA65418D7BF32680F55572C943A94B590804998), # noqa: E501 - ) - # Source: raw - # 0x600061031f537c01000000000000000000000000000000000000000000000000000000006000350473c9ae5868651bf7b7db6e360217db49ce4e69c07e602052730ea65418d7bf32680f55572c943a94b5908049986040526327138bfb81141561038d57600435608052601c6044599059016000905201637a66d7ca601c8203526080516004820152602060e06024836000602051602d5a03f15060e051905060a052601c604459905901600090520163c60409c6601c820352608051600482015260206101206024836000602051602d5a03f150610120519050430561010052600061014052600061016052600061018052600260a051016101005112151561010a576001610140525b60006101a052610100516101c0525b606461010051016101c051121561018457601c606459905901600090520163cc1c944e601c82035260805160048201526101c051602482015260206101e06044836000604051602d5a03f1506101e05190506101a051016101a05260016101c051016101c052610119565b6005601c606459905901600090520163cc1c944e601c820352608051600482015260a051602482015260206102006044836000604051602d5a03f1506102005190501280156101d357806101db565b600a6101a051125b9050156101eb57610140516101ee565b60005b1561033657601c604459905901600090520163c5476efe601c820352608051600482015260206102406024836000602051602d5a03f15061024051905050601c6064599059016000905201637265802d601c82035260805160048201526000602482015260206102606044836000602051602d5a03f15061026051905050601c606459905901600090520163c286273a601c82035260805160048201526000602482015260206102806044836000602051602d5a03f15061028051905050601c6044599059016000905201637a66d7ca601c820352608051600482015260206102a06024836000602051602d5a03f1506102a051905060a052601c608459905901600090520163bb8e4196601c820352608051600482015260a051602482015261010051604482015260206102c06064836000604051602d5a03f1506102c051905050610343565b6001610160526001610180525b61014051156103555761016051610358565b60005b156103665761018051610369565b60005b1561037f5760016102e05260206102e0f361038c565b6000610300526020610300f35b5b50 # noqa: E501 - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x31F, value=0x0) - + Op.DIV( - Op.CALLDATALOAD(offset=0x0), - 0x100000000000000000000000000000000000000000000000000000000, - ) - + Op.MSTORE( - offset=0x20, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E - ) - + Op.MSTORE( - offset=0x40, value=0xEA65418D7BF32680F55572C943A94B590804998 - ) - + Op.JUMPI(pc=0x38D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x27138BFB))) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.JUMPI(pc=0x325, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7A57A3DB))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x280, value=Op.CALLDATALOAD(offset=0x44)) + + Op.PUSH1[0xC0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3476,27 +2828,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7A66D7CA) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0xE0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0xE0) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x3) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x280)) + + Op.MSTORE(offset=Op.ADD(0xA0, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] - + Op.MSTORE - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3504,55 +2846,77 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC60409C6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x120, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x120) + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.NUMBER - + Op.MSTORE(offset=0x100, value=Op.SDIV) - + Op.MSTORE(offset=0x140, value=0x0) - + Op.MSTORE(offset=0x160, value=0x0) - + Op.MSTORE(offset=0x180, value=0x0) + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + Op.JUMPI( - pc=0x10A, - condition=Op.ISZERO( - Op.ISZERO( - Op.SLT( - Op.MLOAD(offset=0x100), - Op.ADD(Op.MLOAD(offset=0xA0), 0x2), - ) - ) - ), + pc=0x2E9, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.MSTORE(offset=0x140, value=0x1) - + Op.JUMPDEST - + Op.MSTORE(offset=0x1A0, value=0x0) - + Op.MSTORE(offset=0x1C0, value=Op.MLOAD(offset=0x100)) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x2C8) + Op.JUMPDEST - + Op.JUMPI( - pc=0x184, - condition=Op.ISZERO( - Op.SLT( - Op.MLOAD(offset=0x1C0), - Op.ADD(Op.MLOAD(offset=0x100), 0x64), - ) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), ), ) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.DUP2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x394, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xF73DC690))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x3C0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x3E0, value=Op.CALLDATALOAD(offset=0x64)) + + Op.PUSH1[0xC0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3560,32 +2924,23 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xCC1C944E) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0x1C0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x40), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x1E0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x1E0) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x3) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x3C0)) + + Op.MSTORE(offset=Op.ADD(0xA0, Op.DUP2), value=Op.MLOAD(offset=0x3E0)) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MLOAD(offset=0x1A0) - + Op.MSTORE(offset=0x1A0, value=Op.ADD) - + Op.MSTORE(offset=0x1C0, value=Op.ADD(Op.MLOAD(offset=0x1C0), 0x1)) - + Op.JUMP(pc=0x119) + + Op.MSTORE(offset=0x400, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x400, size=0x20) + Op.JUMPDEST - + Op.PUSH1[0x5] - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMPI(pc=0x3F3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x54CC6109))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x3C0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3593,42 +2948,42 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xCC1C944E) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xA0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x40), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x200, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x200) - + Op.SWAP1 - + Op.POP - + Op.SLT - + Op.JUMPI(pc=0x1D3, condition=Op.ISZERO(Op.DUP1)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x4) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x3C0)) + Op.DUP1 - + Op.JUMP(pc=0x1DB) - + Op.JUMPDEST - + Op.SLT(Op.MLOAD(offset=0x1A0), 0xA) - + Op.JUMPDEST + Op.SWAP1 + Op.POP - + Op.JUMPI(pc=0x1EB, condition=Op.ISZERO) - + Op.MLOAD(offset=0x140) - + Op.JUMP(pc=0x1EE) + + Op.MSTORE(offset=0x440, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x440, size=0x20) + Op.JUMPDEST + + Op.JUMPI(pc=0x442, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC63EF546))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=0x480, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0x480, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x336, condition=Op.ISZERO) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.JUMPI(pc=0x533, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x9381779B))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3636,25 +2991,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC5476EFE) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x240, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x240) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x6) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 - + Op.POP * 2 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3662,26 +3008,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7265802D) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x260, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x260) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 - + Op.POP * 2 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3689,26 +3025,58 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC286273A) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x280, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x4F7, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.MLOAD(offset=0x280) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.POP + + Op.JUMP(pc=0x4D6) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x624, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x4F9C6EEB))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3716,27 +3084,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7A66D7CA) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x2A0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x2A0) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x7) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] - + Op.MSTORE - + Op.PUSH1[0x1C] - + Op.PUSH1[0x84] + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3744,91 +3101,75 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xBB8E4196) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xA0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x40), - value=0x0, - args_offset=Op.DUP4, - args_size=0x64, - ret_offset=0x2C0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x2C0) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0x343) - + Op.JUMPDEST - + Op.MSTORE(offset=0x160, value=0x1) - + Op.MSTORE(offset=0x180, value=0x1) - + Op.JUMPDEST - + Op.JUMPI(pc=0x355, condition=Op.ISZERO(Op.MLOAD(offset=0x140))) - + Op.MLOAD(offset=0x160) - + Op.JUMP(pc=0x358) - + Op.JUMPDEST + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x366, condition=Op.ISZERO) - + Op.MLOAD(offset=0x180) - + Op.JUMP(pc=0x369) - + Op.JUMPDEST + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + Op.PUSH1[0x0] + Op.JUMPDEST - + Op.JUMPI(pc=0x37F, condition=Op.ISZERO) - + Op.MSTORE(offset=0x2E0, value=0x1) - + Op.RETURN(offset=0x2E0, size=0x20) - + Op.JUMP(pc=0x38C) - + Op.JUMPDEST - + Op.MSTORE(offset=0x300, value=0x0) - + Op.RETURN(offset=0x300, size=0x20) - + Op.JUMPDEST * 2 - + Op.POP, - nonce=0, - address=Address(0x142A6927CF0060133187BA8A8E74D641438F0C1C), # noqa: E501 - ) - # Source: hex - # 0x - coinbase = pre.deploy_contract( # noqa: F841 - code="", - balance=1, - nonce=0, - address=Address(0x1CDC8315BDB1362DE8B7B2FA9EE75DC873037179), # noqa: E501 - ) - # Source: raw - # 0x60006105df537c010000000000000000000000000000000000000000000000000000000060003504730ea65418d7bf32680f55572c943a94b59080499860205273e509e3a93beb1eba72f8cb8d25f93a85e2d54afb60405273c9ae5868651bf7b7db6e360217db49ce4e69c07e60605273f1562e1c0d0baa3ea746442bb7f11153fcf5cfda60805263546fdeb381141561038d5760043560c05260243560e05260443561010052606435610120526084356101405260026101005101601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f150604081019050905090506000600161010051016020028201511415610250576060601c61014c59905901600090520163e365736b601c82035260c051600482015260e0516024820152601c6084599059016000905201632f300bee601c82035260026004820152600560248201526101005160448201528460408160200201599059016000905281602002604001816064856000608051602d5a03f1506040810190509050905060208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf16101fc57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f161022357fe5b50808401935050808303602061028082846000602051602d5a03f15061028051905090509050905061037d565b6060601c61014c59905901600090520163e365736b601c82035260c051600482015260e0516024820152601c6084599059016000905201632f300bee601c820352600160016101005101602002850151036004820152600560248201526101005160448201528460408160200201599059016000905281602002604001816064856000608051602d5a03f1506040810190509050905060208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf161032d57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f161035457fe5b5080840193505080830360206102c082846000602051602d5a03f1506102c05190509050905090505b5060016102e05260206102e0f350505b63de9080c88114156107645760043560c05260243560e05260443561010052606435610120526084356101405260026101005101601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201528160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c6064599059016000905201632c5a40d5601c82035260c051600482015260e05160248201526101405160408160200201599059016000905281602002604001816044856000602051602d5a03f1506040810190509050905061012051806020026020015990590160009052818152602081019050905060005b610120518112156104ee57601c60645990590160009052016328c8b315601c82035260c051600482015281602482015260206103606044836000604051602d5a03f15061036051905081602002830152600181019050610493565b5060a0601c61020c59905901600090520163a647a5b9601c8203528460208103516020026020018360048401526020820360a484015280610148840152808401935050508360208103516020026020018360248401526020820360c484015280610168840152808401935050508260208103516020026020018360448401526020820360e4840152806101888401528084019350505061012051606482015261010051608482015281600401599059016000905260a48160a484600060046022f16105b557fe5b60a4810192506101488201518080858260a487015160006004600a8705601201f16105dc57fe5b508084019350506101688201518080858260c487015160006004600a8705601201f161060457fe5b508084019350506101888201518080858260e487015160006004600a8705601201f161062c57fe5b5080840193505080830387604081602002015990590160009052816020026040018184866000608051602d5a03f1506040810190509050905090509050905092506060601c61014c59905901600090520163e365736b601c82035260c051600482015260e05160248201528460208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf16106df57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f161070657fe5b5080840193505080830360206103c082846000602051602d5a03f1506103c05190509050905090505060006101005160200284015114156107525760006103e05260206103e0f361075f565b6001610400526020610400f35b505050505b63384ca8dd811415610a665760043560c05260243560e052604435610100526064356101205260843561014052601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c606459905901600090520163fa9832d1601c82035260c051600482015260e05160248201526101005160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c608459905901600090520163aad7d6e3601c82035260c051600482015260e05160248201526060601c61014c599059016000905201635b180229601c8203528360208103516020026020018360048401526020820360648401528060c8840152808401935050508460208103516020026020018360248401526020820360848401528060e88401528084019350505061010051604482015281600401599059016000905260648160648460006004601cf161090157fe5b60648101925060c882015180808582606487015160006004600a8705601201f161092757fe5b5080840193505060e882015180808582608487015160006004600a8705601201f161094e57fe5b50808401935050808303602061044082846000608051602d5a03f150610440519050905090509050604482015260206104606064836000602051602d5a03f150610460519050506060601c61014c59905901600090520163222a8663601c82035260c051600482015260e05160248201528260208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1610a0757fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1610a2e57fe5b50808401935050808303602061048082846000602051602d5a03f1506104805190509050905090505060016104a05260206104a0f350505b63d5dc5af1811415610d4b5760043560c05260243560e052604435610100526064356101205260843561014052601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c6064599059016000905201632c5a40d5601c82035260c051600482015260e05160248201526101405160408160200201599059016000905281602002604001816044856000602051602d5a03f150604081019050905090506080601c6101ac59905901600090520163f4ca7dc4601c82035283602081035160200260200183600484015260208203608484015280610108840152808401935050508260208103516020026020018360248401526020820360a4840152806101288401528084019350505061012051604482015261010051606482015281600401599059016000905260848160848460006004601ff1610be757fe5b60848101925061010882015180808582608487015160006004600a8705601201f1610c0e57fe5b508084019350506101288201518080858260a487015160006004600a8705601201f1610c3657fe5b5080840193505080830361014051604081602002015990590160009052816020026040018184866000608051602d5a03f1506040810190509050905090509050905090506060601c61014c59905901600090520163b39e1faa601c82035260c051600482015260e05160248201528260208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1610cec57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1610d1357fe5b5080840193505080830360206104c082846000602051602d5a03f1506104c05190509050905090505060016104e05260206104e0f350505b630939aa8c81141561114c5760043560c05260243560e052604435610100526064356101205260843561014052601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c6064599059016000905201637dc12195601c82035260c051600482015260e05160248201526101405160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c606459905901600090520163586b5be0601c82035260c051600482015260e051602482015260206105006044836000602051602d5a03f150610500519050601c606459905901600090520163eb8af5aa601c82035260c051600482015260e05160248201526101205160408160200201599059016000905281602002604001816044856000602051602d5a03f1506040810190509050905060c0601c61026c59905901600090520163232b2734601c8203528260208103516020026020018360048401526020820360c484015280610188840152808401935050508560208103516020026020018360248401526020820360e4840152806101a88401528084019350505084602081035160200260200183604484015260208203610104840152806101c8840152808401935050508360648201526101205160848201526101005160a482015281600401599059016000905260c48160c484600060046025f1610f9657fe5b60c4810192506101888201518080858260c487015160006004600a8705601201f1610fbd57fe5b508084019350506101a88201518080858260e487015160006004600a8705601201f1610fe557fe5b508084019350506101c88201518080858261010487015160006004600a8705601201f161100e57fe5b5080840193505080830361012051604081602002015990590160009052816020026040018184866000608051602d5a03f1506040810190509050905090509050905090506060601c61014c5990590160009052016301112b27601c82035260c051600482015260e05160248201528260208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf16110c457fe5b6064810192506101088201518080858260a487015160006004600a8705601201f16110eb57fe5b50808401935050808303602061058082846000602051602d5a03f15061058051905090509050905050600060016101005101602002850151141561113a5760006105a05260206105a0f3611147565b60016105c05260206105c0f35b505050505b50 # noqa: E501 - contract_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x5DF, value=0x0) - + Op.DIV( - Op.CALLDATALOAD(offset=0x0), - 0x100000000000000000000000000000000000000000000000000000000, - ) - + Op.MSTORE( - offset=0x20, value=0xEA65418D7BF32680F55572C943A94B590804998 + + Op.JUMPI( + pc=0x5E8, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) + Op.MSTORE( - offset=0x40, value=0xE509E3A93BEB1EBA72F8CB8D25F93A85E2D54AFB + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x5C7) + + Op.JUMPDEST + Op.MSTORE( - offset=0x60, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MSTORE( - offset=0x80, value=0xF1562E1C0D0BAA3EA746442BB7F11153FCF5CFDA + + Op.DUP2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), ) - + Op.JUMPI(pc=0x38D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x546FDEB3))) - + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) - + Op.ADD(Op.MLOAD(offset=0x100), 0x2) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x715, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7DC12195))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3836,12 +3177,33 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x8) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.ADD(Op.MLOAD(offset=0x100), 0x2) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3849,41 +3211,58 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x6D9, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x6B8) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.JUMPI( - pc=0x250, - condition=Op.ISZERO( - Op.EQ( - Op.MLOAD( - offset=Op.ADD( - Op.DUP3, - Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x100), 0x1)), - ) - ), - 0x0, - ) + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) ), ) - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x806, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xFA9832D1))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3891,12 +3270,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE365736B) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x84] + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x9) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3904,13 +3287,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2F300BEE) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=0x2) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) - + Op.DUP5 - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -3918,102 +3304,58 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP6, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x7CA, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP + + Op.JUMP(pc=0x7A9) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.ADD(0x4, Op.DUP2) - + Op.MSIZE + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + + Op.POP + Op.SWAP1 - + Op.MSTORE - + Op.JUMPI( - pc=0x1FC, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) - + Op.DUP1 - + Op.JUMPI( - pc=0x223, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) ), ) - + Op.INVALID - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x280, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x280) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x37D) + Op.JUMPDEST - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.JUMPI(pc=0x8F7, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2C5A40D5))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4021,12 +3363,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE365736B) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x84] + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xA) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4034,24 +3380,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2F300BEE) - + Op.MSTORE( - offset=Op.ADD(Op.DUP3, 0x4), - value=Op.SUB( - Op.MLOAD( - offset=Op.ADD( - Op.DUP6, - Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x100), 0x1)), - ) - ), - 0x1, - ), - ) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) - + Op.DUP5 - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4059,89 +3397,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP6, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.ADD(0x4, Op.DUP2) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.JUMPI( - pc=0x32D, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 - + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) - + Op.DUP1 + Op.JUMPI( - pc=0x354, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), + pc=0x8BB, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.INVALID - + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x2C0, - ret_size=0x20, - ) + + Op.JUMP(pc=0x89A) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x2C0) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 @@ -4150,21 +3436,19 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.JUMPDEST + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + Op.POP - + Op.MSTORE(offset=0x2E0, value=0x1) - + Op.RETURN(offset=0x2E0, size=0x20) - + Op.POP * 2 + Op.JUMPDEST - + Op.JUMPI(pc=0x764, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xDE9080C8))) - + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) - + Op.ADD(Op.MLOAD(offset=0x100), 0x2) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMPI(pc=0x9EB, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xE05DCB56))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4172,12 +3456,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.DUP2 - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xB) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x2] + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4185,26 +3474,76 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.ADD + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x9AF, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x98E) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0xA3A, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x586B5BE0))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4212,12 +3551,20 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2C5A40D5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.MLOAD(offset=0x140) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xC) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=0xB80, value=Op.SLOAD(key=Op.SHA3)) + + Op.RETURN(offset=0xB80, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0xB58, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xEB8AF5AA))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4225,26 +3572,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xD) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MLOAD(offset=0x120) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.SLOAD(key=Op.SHA3) + + Op.MUL(0x20, Op.SDIV) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4261,47 +3632,49 @@ def test_block504980( + Op.PUSH1[0x0] + Op.JUMPDEST + Op.JUMPI( - pc=0x4EE, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x120))), + pc=0xB1C, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x28C8B315) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP2) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x40), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x360, - ret_size=0x20, - ) + + Op.POP + + Op.JUMP(pc=0xAFB) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x360) + + Op.DUP2 + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)) - + Op.MSTORE - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x493) - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.PUSH1[0xA0] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x20C] + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0xC76, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7AB6EA8A))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4309,35 +3682,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xA647A5B9) - + Op.DUP5 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x148), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.DUP4 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xC4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x168), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.DUP3 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xE4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x188), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.MLOAD(offset=0x120)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.MLOAD(offset=0x100)) - + Op.ADD(0x4, Op.DUP2) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xE) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4345,86 +3699,33 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0x5B5, - condition=Op.CALL( - gas=0x22, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0xA4, - ret_offset=Op.DUP2, - ret_size=0xA4, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0xA4) - + Op.SWAP3 - + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x148)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 - + Op.JUMPI( - pc=0x5DC, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x168)) + + Op.SLOAD(key=Op.SHA3) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + Op.DUP1 - + Op.JUMPI( - pc=0x604, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xC4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x188)) + + Op.SLOAD(key=Op.SHA3) + + Op.MUL(0x20, Op.SDIV) + Op.DUP1 - + Op.JUMPI( - pc=0x62C, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xE4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.DUP8 - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4432,22 +3733,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP7, - args_size=Op.DUP5, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + Op.SWAP1 + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0xC3A, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + ) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP + + Op.JUMP(pc=0xC19) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 @@ -4456,11 +3772,19 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.SWAP3 + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + Op.POP - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.JUMPDEST + + Op.JUMPI(pc=0xD94, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2B810CB9))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4468,19 +3792,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE365736B) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.DUP5 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.ADD(0x4, Op.DUP2) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xF) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4488,94 +3809,92 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0x6DF, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 - + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 - + Op.JUMPI( - pc=0x706, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x3C0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x3C0) + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.MUL(0x20, Op.SDIV) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP + Op.SWAP1 - + Op.POP * 2 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + Op.JUMPI( - pc=0x752, - condition=Op.ISZERO( - Op.EQ( - Op.MLOAD( - offset=Op.ADD( - Op.DUP5, Op.MUL(0x20, Op.MLOAD(offset=0x100)) - ) - ), - 0x0, - ) - ), + pc=0xD58, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.MSTORE(offset=0x3E0, value=0x0) - + Op.RETURN(offset=0x3E0, size=0x20) - + Op.JUMP(pc=0x75F) - + Op.JUMPDEST - + Op.MSTORE(offset=0x400, value=0x1) - + Op.RETURN(offset=0x400, size=0x20) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0xD37) + Op.JUMPDEST - + Op.POP * 4 + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + Op.JUMPDEST - + Op.JUMPI(pc=0xA66, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x384CA8DD))) - + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMPI(pc=0xE85, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7FB42E46))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4583,12 +3902,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.ADD(Op.MLOAD(offset=0x100), 0x2) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x10) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4596,26 +3919,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4623,39 +3936,58 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xFA9832D1) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.MLOAD(offset=0x100) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) - + Op.MSIZE + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.POP + + Op.SWAP1 + + Op.POP + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0xE49, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + ) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.POP + + Op.JUMP(pc=0xE28) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.ADD(Op.DUP2, 0x40) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x84] + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0xF76, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x734FA727))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4663,13 +3995,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAAD7D6E3) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x11) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4677,26 +4012,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x5B180229) - + Op.DUP4 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x64), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xC8), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.DUP5 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x84), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xE8), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) - + Op.ADD(0x4, Op.DUP2) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4704,76 +4029,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0x901, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0xC8)) - + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + Op.JUMPI( - pc=0x927, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x64)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), + pc=0xF3A, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.INVALID - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0xE8)) - + Op.DUP1 - + Op.JUMPI( - pc=0x94E, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x84)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), ) - + Op.INVALID - + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x440, - ret_size=0x20, - ) + + Op.JUMP(pc=0xF19) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x440) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 @@ -4782,25 +4068,19 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP3, 0x44) - + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x64, - ret_offset=0x460, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), ) - + Op.MLOAD(offset=0x460) - + Op.SWAP1 - + Op.POP * 2 - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x1067, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC67FA857))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4808,19 +4088,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x222A8663) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.DUP3 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.ADD(0x4, Op.DUP2) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x12) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4828,56 +4105,54 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0xA07, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + Op.JUMPI( - pc=0xA2E, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), + pc=0x102B, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.INVALID - + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x480, - ret_size=0x20, - ) + + Op.JUMP(pc=0x100A) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x480) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 @@ -4885,19 +4160,20 @@ def test_block504980( + Op.SWAP1 + Op.POP + Op.SWAP1 - + Op.POP * 2 - + Op.MSTORE(offset=0x4A0, value=0x1) - + Op.RETURN(offset=0x4A0, size=0x20) - + Op.POP * 2 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + Op.JUMPDEST - + Op.JUMPI(pc=0xD4B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xD5DC5AF1))) - + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMPI(pc=0x1185, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5ED853E4))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4905,12 +4181,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.ADD(Op.MLOAD(offset=0x100), 0x2) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x13) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4918,26 +4198,15 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.SLOAD(key=Op.SHA3) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4945,12 +4214,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2C5A40D5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.MLOAD(offset=0x140) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SLOAD(key=Op.SHA3) + + Op.MUL(0x20, Op.SDIV) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4958,27 +4232,58 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x1149, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + + Op.POP + + Op.JUMP(pc=0x1128) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0x80] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x1AC] + + Op.SWAP1 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x12A3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB86F5125))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -4986,27 +4291,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xF4CA7DC4) - + Op.DUP4 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x84), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.DUP3 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x128), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x120)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.MLOAD(offset=0x100)) - + Op.ADD(0x4, Op.DUP2) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x14) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5014,66 +4308,33 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0xBE7, - condition=Op.CALL( - gas=0x1F, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x84, - ret_offset=Op.DUP2, - ret_size=0x84, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x84) - + Op.SWAP3 - + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 - + Op.JUMPI( - pc=0xC0E, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x84)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x128)) + + Op.SLOAD(key=Op.SHA3) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + Op.DUP1 - + Op.JUMPI( - pc=0xC36, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.MLOAD(offset=0x140) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.SLOAD(key=Op.SHA3) + + Op.MUL(0x20, Op.SDIV) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5081,24 +4342,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP7, - args_size=Op.DUP5, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI( + pc=0x1267, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), + ) + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP + + Op.JUMP(pc=0x1246) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 @@ -5107,9 +4381,19 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + + Op.JUMPDEST + + Op.JUMPI(pc=0x1394, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBC3D7D85))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5117,19 +4401,33 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x15) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xB39E1FAA) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.DUP3 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.ADD(0x4, Op.DUP2) + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.MUL(0x20, Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + + Op.ADD(0x20, Op.DUP1) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5137,56 +4435,37 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0xCEC, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + + Op.SWAP1 + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) - + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + + Op.JUMPDEST + Op.JUMPI( - pc=0xD13, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), + pc=0x1358, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DIV(Op.DUP4, 0x20))), ) - + Op.INVALID - + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.SLOAD(key=Op.ADD(Op.DUP5, Op.DUP1)), + ) + + Op.ADD(Op.DUP2, 0x1) + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x4C0, - ret_size=0x20, - ) + + Op.JUMP(pc=0x1337) + + Op.JUMPDEST + + Op.MSTORE( + offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)), + value=Op.AND( + Op.SLOAD(key=Op.ADD(Op.DUP6, Op.DUP2)), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x4C0) + + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 @@ -5194,19 +4473,22 @@ def test_block504980( + Op.SWAP1 + Op.POP + Op.SWAP1 - + Op.POP * 2 - + Op.MSTORE(offset=0x4E0, value=0x1) - + Op.RETURN(offset=0x4E0, size=0x20) - + Op.POP * 2 + + Op.POP + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) + + Op.RETURN( + offset=Op.SUB(Op.DUP3, 0x40), + size=Op.ADD( + 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + ), + ) + + Op.POP + Op.JUMPDEST - + Op.JUMPI(pc=0x114C, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x939AA8C))) - + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMPI(pc=0x1481, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA2302F2F))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x1680, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x16A0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0x16A0) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5214,12 +4496,13 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.ADD(Op.MLOAD(offset=0x100), 0x2) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5227,26 +4510,23 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.SLOAD(key=Op.SHA3)) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.SHA3 + + Op.SSTORE + + Op.PUSH1[0x1] + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5254,12 +4534,18 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SLOAD(key=Op.SHA3) + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7DC12195) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.MLOAD(offset=0x140) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5267,26 +4553,47 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x1680) ) - + Op.ADD(Op.DUP2, 0x40) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x1740, value=0x1) + + Op.RETURN(offset=0x1740, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x14DD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x58CA2BC))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x1760, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0x1760) + + Op.PUSH1[0x80] * 2 + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x17A0, value=0x1) + + Op.RETURN(offset=0x17A0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1617, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5D3B965B))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5294,26 +4601,19 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x586B5BE0) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x500, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MLOAD(offset=0x500) - + Op.SWAP1 + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x280, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE( + offset=0x17E0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x64)), + ) + + Op.MSTORE(offset=0x1800, value=Op.CALLDATALOAD(offset=0x84)) + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.PUSH1[0xC0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5321,40 +4621,48 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xEB8AF5AA) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.MLOAD(offset=0x120) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) - + Op.MSIZE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x3) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x280)) + + Op.MSTORE(offset=Op.ADD(0xA0, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x17E0), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) + + Op.JUMPDEST + + Op.JUMPI(pc=0x158C, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x17E0), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.PUSH1[0xC0] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x26C] + + Op.JUMP(pc=0x156B) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x17E0), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MLOAD(offset=0x1800) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5362,36 +4670,16 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SLOAD(key=Op.SHA3) + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x232B2734) - + Op.DUP3 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xC4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x188), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.DUP6 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xE4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x1A8), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.DUP5 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x104), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x1C8), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.MLOAD(offset=0x120)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0xA4), value=Op.MLOAD(offset=0x100)) - + Op.ADD(0x4, Op.DUP2) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5399,86 +4687,24 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0xF96, - condition=Op.CALL( - gas=0x25, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0xC4, - ret_offset=Op.DUP2, - ret_size=0xC4, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0xC4) - + Op.SWAP3 - + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x188)) - + Op.DUP1 - + Op.JUMPI( - pc=0xFBD, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xC4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x1A8)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x2) + Op.DUP1 - + Op.JUMPI( - pc=0xFE5, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xE4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x1C8)) - + Op.DUP1 - + Op.JUMPI( - pc=0x100E, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x104)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x1900, value=0x1) + + Op.RETURN(offset=0x1900, size=0x20) + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.MLOAD(offset=0x120) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.JUMPI(pc=0x1673, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB0E14F0F))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x1920, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0x1920) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5486,35 +4712,20 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP7, - args_size=Op.DUP5, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x5) + + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.PUSH1[0x60] - + Op.PUSH1[0x1C] - + Op.PUSH2[0x14C] + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x1960, value=0x1) + + Op.RETURN(offset=0x1960, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1739, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x6ACCCDBC))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5522,19 +4733,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x1112B27) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) - + Op.DUP3 - + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) - + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 3 - + Op.ADD(0x4, Op.DUP2) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x1980, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5542,137 +4751,68 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.JUMPI( - pc=0x10C4, - condition=Op.CALL( - gas=0x1C, - address=0x4, - value=0x0, - args_offset=Op.DUP5, - args_size=0x64, - ret_offset=Op.DUP2, - ret_size=0x64, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.ADD(Op.DUP2, 0x64) - + Op.SWAP3 - + Op.POP - + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x6) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 - + Op.JUMPI( - pc=0x10EB, - condition=Op.CALL( - gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), - address=0x4, - value=0x0, - args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), - args_size=Op.DUP3, - ret_offset=Op.DUP6, - ret_size=Op.DUP1, - ), - ) - + Op.INVALID - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP5, Op.DUP1) - + Op.SWAP4 - + Op.POP * 2 - + Op.SUB(Op.DUP4, Op.DUP1) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), - value=0x0, - args_offset=Op.DUP5, - args_size=Op.DUP3, - ret_offset=0x580, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x580) - + Op.SWAP1 - + Op.POP + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1980), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x170B, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1980), Op.MUL(0x20, Op.DUP1)) + ), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMPI( - pc=0x113A, - condition=Op.ISZERO( - Op.EQ( - Op.MLOAD( - offset=Op.ADD( - Op.DUP6, - Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x100), 0x1)), - ) - ), - 0x0, - ) + + Op.JUMP(pc=0x16EA) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1980), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), ), ) - + Op.MSTORE(offset=0x5A0, value=0x0) - + Op.RETURN(offset=0x5A0, size=0x20) - + Op.JUMP(pc=0x1147) - + Op.JUMPDEST - + Op.MSTORE(offset=0x5C0, value=0x1) - + Op.RETURN(offset=0x5C0, size=0x20) - + Op.JUMPDEST + Op.POP * 4 + + Op.MSTORE(offset=0x1A40, value=0x1) + + Op.RETURN(offset=0x1A40, size=0x20) + Op.JUMPDEST - + Op.POP, - nonce=0, - address=Address(0x9761FECF88590592CF05CE545504D376D1693AB3), # noqa: E501 - ) - pre[sender] = Account(balance=0xD8D726B7177A800000) - # Source: raw - # 0x600061075f537c010000000000000000000000000000000000000000000000000000000060003504731e147037f0a63df228fe6e7aef730f1ea31c8ce3602052730ea65418d7bf32680f55572c943a94b59080499860405273e509e3a93beb1eba72f8cb8d25f93a85e2d54afb60605273c9ae5868651bf7b7db6e360217db49ce4e69c07e60805273142a6927cf0060133187ba8a8e74d641438f0c1c60a05273b163e767e4c1ba5ae88b2ee7594f3a3fec2bb09660c05273ba7b277319128ef4c22635534d0f61dffdaa13ab60e052739761fecf88590592cf05ce545504d376d1693ab36101005273f70bbc50f1468cecae0761ef09386a87c1c696ea6101205273a89d22f049aaa5bbfb5f1a1939fff3ae7a26ae746101405273174827f7e53e8ce13b047adcac0eb3f2cb0c3285610160526336a560bd811415610a88576004356101a052601c60445990590160009052016327138bfb601c8203526101a051600482015260206101e0602483600060a051602d5a03f1506101e05190501515610195576001600003610200526020610200f35b601c6044599059016000905201637a66d7ca601c8203526101a051600482015260206102206024836000608051602d5a03f150610220519050601c606459905901600090520163cc1c944e601c8203526101a05160048201528160248201526020610260604483600061028051602d5a03f150610260519050601c60445990590160009052016380b5e7bd601c8203526101a051600482015260206102a06024836000606051602d5a03f1506102a0519050808202601c60445990590160009052016318633576601c8203526101a051600482015260206103006024836000608051602d5a03f150610300519050600981141561036d57601c60c459905901600090520163ac44d71e601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061036060a483600061016051602d5a03f15061036051905050601c6064599059016000905201637265802d601c8203526101a05160048201526000602482015260206103806044836000608051602d5a03f15061038051905050601c604459905901600090520163c5476efe601c8203526101a051600482015260206103a06024836000608051602d5a03f1506103a051905050600185016103c05260206103c0f3610a3a565b60008114156103cd57601c60c459905901600090520163ef72638a601c8203526101a051600482015285602482015284604482015283606482015282608482015260206103e060a483600060c051602d5a03f1506103e051905050610a39565b600181141561042d57601c60c459905901600090520163a63e976c601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061040060a483600060e051602d5a03f15061040051905050610a38565b600281141561048d57601c60c459905901600090520163533ea0ed601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061042060a483600060e051602d5a03f15061042051905050610a37565b600381141561085057601c606459905901600090520163e05dcb56601c8203526101a0516004820152856024820152600285016040816020020159905901600090528160200260400181604485600061028051602d5a03f15060408101905090509050601c6044599059016000905201633d905045601c8203526101a051600482015260206104806024836000608051602d5a03f150610480519050600481141561063357601c60c4599059016000905201630939aa8c601c8203526101a051600482015287602482015286604482015285606482015284608482015260206104e060a483600061010051602d5a03f1506104e05190506104c052601c606459905901600090520163c286273a601c8203526101a05160048201526000602482015260206105006044836000608051602d5a03f1506105005190505060016104c05114156105e55782610520526020610520f361062e565b601c604459905901600090520163aac2ffb5601c8203526101a051600482015260206105406024836000608051602d5a03f1506105405190505060018301610560526020610560f35b610804565b600081141561069457601c60c459905901600090520163546fdeb3601c8203526101a0516004820152876024820152866044820152856064820152846084820152602061058060a483600061010051602d5a03f15061058051905050610803565b6001811415610742576000601c60c459905901600090520163de9080c8601c8203526101a051600482015288602482015287604482015286606482015285608482015260206105a060a483600061010051602d5a03f1506105a0519050141561073257601c6044599059016000905201631cda01ef601c8203526101a051600482015260206105c06024836000608051602d5a03f1506105c0519050505b826105e05260206105e0f3610802565b60028114156107a357601c60c459905901600090520163384ca8dd601c8203526101a0516004820152876024820152866044820152856064820152846084820152602061060060a483600061010051602d5a03f15061060051905050610801565b600381141561080057601c60c459905901600090520163d5dc5af1601c8203526101a0516004820152876024820152866044820152856064820152846084820152602061062060a483600061010051602d5a03f150610620519050505b5b5b5b5b601c6044599059016000905201631cda01ef601c8203526101a051600482015260206106406024836000608051602d5a03f1506106405190505082610660526020610660f35050610a36565b60048114156108b157601c60c459905901600090520163f6559853601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061068060a483600061012051602d5a03f15061068051905050610a35565b600581141561091257601c60c459905901600090520163d8e5473d601c8203526101a051600482015285602482015284604482015283606482015282608482015260206106a060a483600061012051602d5a03f1506106a051905050610a34565b600681141561097357601c60c459905901600090520163090507ea601c8203526101a051600482015285602482015284604482015283606482015282608482015260206106c060a483600061012051602d5a03f1506106c051905050610a33565b60078114156109d457601c60c4599059016000905201635b911842601c8203526101a051600482015285602482015284604482015283606482015282608482015260206106e060a483600061014051602d5a03f1506106e051905050610a32565b6008811415610a3157601c60c459905901600090520163abe22b84601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061070060a483600061014051602d5a03f150610700519050505b5b5b5b5b5b5b5b5b5b601c604459905901600090520163aac2ffb5601c8203526101a051600482015260206107206024836000608051602d5a03f1506107205190505060018101610740526020610740f350505050505b50 # noqa: E501 - contract_8 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x75F, value=0x0) - + Op.DIV( - Op.CALLDATALOAD(offset=0x0), - 0x100000000000000000000000000000000000000000000000000000000, - ) - + Op.MSTORE( - offset=0x20, value=0x1E147037F0A63DF228FE6E7AEF730F1EA31C8CE3 - ) - + Op.MSTORE( - offset=0x40, value=0xEA65418D7BF32680F55572C943A94B590804998 - ) - + Op.MSTORE( - offset=0x60, value=0xE509E3A93BEB1EBA72F8CB8D25F93A85E2D54AFB - ) - + Op.MSTORE( - offset=0x80, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E - ) - + Op.MSTORE( - offset=0xA0, value=0x142A6927CF0060133187BA8A8E74D641438F0C1C - ) - + Op.MSTORE( - offset=0xC0, value=0xB163E767E4C1BA5AE88B2EE7594F3A3FEC2BB096 - ) - + Op.MSTORE( - offset=0xE0, value=0xBA7B277319128EF4C22635534D0F61DFFDAA13AB - ) - + Op.MSTORE( - offset=0x100, value=0x9761FECF88590592CF05CE545504D376D1693AB3 - ) - + Op.MSTORE( - offset=0x120, value=0xF70BBC50F1468CECAE0761EF09386A87C1C696EA - ) - + Op.MSTORE( - offset=0x140, value=0xA89D22F049AAA5BBFB5F1A1939FFF3AE7A26AE74 + + Op.JUMPI(pc=0x17FF, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA1FA51F9))) + + Op.CALLDATASIZE + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + Op.MSTORE( - offset=0x160, value=0x174827F7E53E8CE13B047ADCAC0EB3F2CB0C3285 + offset=0x1A60, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.JUMPI(pc=0xA88, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x36A560BD))) - + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5680,29 +4820,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x27138BFB) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0xA0), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x1E0, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x7) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1A60), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x17D1, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1A60), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x1E0) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMPI(pc=0x195, condition=Op.ISZERO(Op.ISZERO)) - + Op.MSTORE(offset=0x200, value=Op.SUB(0x0, 0x1)) - + Op.RETURN(offset=0x200, size=0x20) + + Op.JUMP(pc=0x17B0) + Op.JUMPDEST - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1A60), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x1B20, value=0x1) + + Op.RETURN(offset=0x1B20, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x18C5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xCD87F43A))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5710,25 +4871,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7A66D7CA) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x220, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x1B40, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.MLOAD(offset=0x220) - + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5736,26 +4889,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xCC1C944E) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP2) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x280), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x260, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x8) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1B40), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1897, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1B40), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x260) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.JUMP(pc=0x1876) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1B40), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x1C00, value=0x1) + + Op.RETURN(offset=0x1C00, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x198B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x222A8663))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5763,26 +4940,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x80B5E7BD) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x60), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x2A0, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x1C20, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.MLOAD(offset=0x2A0) - + Op.SWAP1 + Op.POP - + Op.MUL(Op.DUP3, Op.DUP1) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5790,26 +4958,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x18633576) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x300, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x9) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1C20), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x195D, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1C20), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x300) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMPI(pc=0x36D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x9))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.JUMP(pc=0x193C) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1C20), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x1CE0, value=0x1) + + Op.RETURN(offset=0x1CE0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1A51, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB39E1FAA))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5817,29 +5009,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAC44D71E) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x160), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x360, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MLOAD(offset=0x360) - + Op.SWAP1 - + Op.POP * 2 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x1D00, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5847,26 +5027,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7265802D) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x380, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xA) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1D00), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1A23, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1D00), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x380) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.POP + + Op.JUMP(pc=0x1A02) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1D00), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x1DC0, value=0x1) + + Op.RETURN(offset=0x1DC0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1B17, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xE365736B))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5874,30 +5078,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC5476EFE) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x3A0, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MLOAD(offset=0x3A0) - + Op.SWAP1 - + Op.POP * 2 - + Op.MSTORE(offset=0x3C0, value=Op.ADD(Op.DUP6, 0x1)) - + Op.RETURN(offset=0x3C0, size=0x20) - + Op.JUMP(pc=0xA3A) - + Op.JUMPDEST - + Op.JUMPI(pc=0x3CD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x0))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x1DE0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5905,65 +5096,54 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xEF72638A) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0xC0), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x3E0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x3E0) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA39) - + Op.JUMPDEST - + Op.JUMPI(pc=0x42D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] - + Op.MSIZE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xB) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1DE0), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xA63E976C) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0xE0), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x400, - ret_size=0x20, - ) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1AE9, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1DE0), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x400) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA38) + + Op.POP + + Op.JUMP(pc=0x1AC8) + Op.JUMPDEST - + Op.JUMPI(pc=0x48D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1DE0), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x1EA0, value=0x1) + + Op.RETURN(offset=0x1EA0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1B73, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xAAD7D6E3))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x1EC0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MLOAD(offset=0x1EC0) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -5971,32 +5151,20 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x533EA0ED) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0xE0), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x420, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x420) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xC) + + Op.DUP1 + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA37) + + Op.POP + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x1F00, value=0x1) + + Op.RETURN(offset=0x1F00, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x850, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMPI(pc=0x1C39, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1112B27))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6004,12 +5172,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.ADD(Op.DUP6, 0x2) - + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x1F20, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6017,26 +5190,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x280), - value=0x0, - args_offset=Op.DUP6, - args_size=0x44, - ret_offset=Op.DUP2, - ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), - ) - ) - + Op.ADD(Op.DUP2, 0x40) - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xD) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x1F20), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1C0B, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x1F20), Op.MUL(0x20, Op.DUP1)) + ), + ) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.JUMP(pc=0x1BEA) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x1F20), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x1FE0, value=0x1) + + Op.RETURN(offset=0x1FE0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1CFF, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBDBB239B))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6044,26 +5241,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x3D905045) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x480, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x2000, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.MLOAD(offset=0x480) - + Op.SWAP1 + Op.POP - + Op.JUMPI(pc=0x633, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x4))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6071,31 +5259,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x939AA8C) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x100), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x4E0, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xE) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2000), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1CD1, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x2000), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x4E0) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.PUSH2[0x4C0] - + Op.MSTORE - + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.JUMP(pc=0x1CB0) + + Op.JUMPDEST + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x2000), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x20C0, value=0x1) + + Op.RETURN(offset=0x20C0, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1DC5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5A0CD48))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6103,33 +5310,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC286273A) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x500, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MLOAD(offset=0x500) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMPI( - pc=0x5E5, condition=Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x4C0), 0x1)) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x20E0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.MSTORE(offset=0x520, value=Op.DUP3) - + Op.RETURN(offset=0x520, size=0x20) - + Op.JUMP(pc=0x62E) - + Op.JUMPDEST - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6137,31 +5328,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAAC2FFB5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x540, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0xF) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x20E0), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1D97, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x20E0), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x540) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.MSTORE(offset=0x560, value=Op.ADD(Op.DUP4, 0x1)) - + Op.RETURN(offset=0x560, size=0x20) + + Op.POP + + Op.JUMP(pc=0x1D76) + Op.JUMPDEST - + Op.JUMP(pc=0x804) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x20E0), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x21A0, value=0x1) + + Op.RETURN(offset=0x21A0, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x694, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x0))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.JUMPI(pc=0x1E8B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xAAA1FE35))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6169,33 +5379,68 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x21C0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x546FDEB3) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x100), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x580, - ret_size=0x20, - ) + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x10) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x21C0), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1E5D, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x21C0), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x580) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0x803) + + Op.POP + + Op.JUMP(pc=0x1E3C) + Op.JUMPDEST - + Op.JUMPI(pc=0x742, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1))) - + Op.PUSH1[0x0] - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x21C0), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x2280, value=0x1) + + Op.RETURN(offset=0x2280, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1F51, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2BE4935D))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6203,30 +5448,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xDE9080C8) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP9) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP8) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP7) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP6) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x100), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x5A0, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x22A0, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.MLOAD(offset=0x5A0) - + Op.SWAP1 + Op.POP - + Op.JUMPI(pc=0x732, condition=Op.ISZERO(Op.EQ)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6234,31 +5466,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x1CDA01EF) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x5C0, - ret_size=0x20, - ) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x11) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + + Op.SWAP1 + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x22A0), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x1F23, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x22A0), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x5C0) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 + + Op.POP + + Op.JUMP(pc=0x1F02) + Op.JUMPDEST - + Op.MSTORE(offset=0x5E0, value=Op.DUP3) - + Op.RETURN(offset=0x5E0, size=0x20) - + Op.JUMP(pc=0x802) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x22A0), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), + ) + + Op.POP * 4 + + Op.MSTORE(offset=0x2360, value=0x1) + + Op.RETURN(offset=0x2360, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x7A3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.JUMPI(pc=0x2017, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x13A8350D))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6266,32 +5517,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x384CA8DD) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x100), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x600, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MLOAD(offset=0x600) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0x801) - + Op.JUMPDEST - + Op.JUMPI(pc=0x800, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x2380, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6299,95 +5535,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xD5DC5AF1) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x100), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x620, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x620) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMPDEST * 5 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] - + Op.MSIZE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x12) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2380), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x1CDA01EF) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x640, - ret_size=0x20, - ) + + Op.JUMPDEST + + Op.JUMPI(pc=0x1FE9, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x2380), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x640) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.MSTORE(offset=0x660, value=Op.DUP3) - + Op.RETURN(offset=0x660, size=0x20) - + Op.POP * 2 - + Op.JUMP(pc=0xA36) + + Op.POP + + Op.JUMP(pc=0x1FC8) + Op.JUMPDEST - + Op.JUMPI(pc=0x8B1, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x4))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xF6559853) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x120), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x680, - ret_size=0x20, - ) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x2380), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x680) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA35) + + Op.POP * 4 + + Op.MSTORE(offset=0x2440, value=0x1) + + Op.RETURN(offset=0x2440, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x912, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.JUMPI(pc=0x20DD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xCB540B45))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6395,32 +5586,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xD8E5473D) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x120), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x6A0, - ret_size=0x20, - ) + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.MLOAD(offset=0x6A0) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA34) - + Op.JUMPDEST - + Op.JUMPI(pc=0x973, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x6))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x2460, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6428,96 +5604,50 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x90507EA) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x120), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x6C0, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x6C0) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA33) - + Op.JUMPDEST - + Op.JUMPI(pc=0x9D4, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] - + Op.MSIZE + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x13) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.DUP1 + Op.SWAP1 - + Op.MSIZE - + Op.ADD + + Op.POP + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2460), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x5B911842) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x140), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x6E0, - ret_size=0x20, - ) + + Op.JUMPDEST + + Op.JUMPI(pc=0x20AF, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x2460), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MLOAD(offset=0x6E0) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP * 2 - + Op.JUMP(pc=0xA32) + + Op.POP + + Op.JUMP(pc=0x208E) + Op.JUMPDEST - + Op.JUMPI(pc=0xA31, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x8))) - + Op.PUSH1[0x1C] - + Op.PUSH1[0xC4] - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xABE22B84) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x140), - value=0x0, - args_offset=Op.DUP4, - args_size=0xA4, - ret_offset=0x700, - ret_size=0x20, - ) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x2460), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MLOAD(offset=0x700) - + Op.SWAP1 - + Op.POP * 2 - + Op.JUMPDEST * 10 - + Op.PUSH1[0x1C] - + Op.PUSH1[0x44] + + Op.POP * 4 + + Op.MSTORE(offset=0x2520, value=0x1) + + Op.RETURN(offset=0x2520, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x21A3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBE030627))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6525,44 +5655,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAAC2FFB5) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x80), - value=0x0, - args_offset=Op.DUP4, - args_size=0x24, - ret_offset=0x720, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x720) - + Op.SWAP1 - + Op.POP * 2 - + Op.MSTORE(offset=0x740, value=Op.ADD(Op.DUP2, 0x1)) - + Op.RETURN(offset=0x740, size=0x20) - + Op.POP * 5 - + Op.JUMPDEST - + Op.POP, - nonce=0, - address=Address(0xB03F030056DB7D467D778326658BAC0D1B35D8F7), # noqa: E501 - ) - # Source: raw - # 0x600061083f537c010000000000000000000000000000000000000000000000000000000060003504637a66d7ca8114156100665760043560405260606060599059016000905260008152604051816020015260008160400152809050205460605260206060f35b63c60409c68114156100a55760043560405260606060599059016000905260008152604051816020015260018160400152809050205460a052602060a0f35b63186335768114156100e45760043560405260606060599059016000905260008152604051816020015260028160400152809050205460e052602060e0f35b63b3903c8a8114156101bc57600435604052606060605990590160009052600081526040518160200152600581604001528090502054610120526101205180602002602001599059016000905281815260208101905090506101605260006101c0525b610120516101c051121561019f57608060805990590160009052600081526040518160200152600481604001526101c051816060015280905020546101c05160200261016051015260016101c051016101c052610147565b6101605160206040820352602060208203510260400160408203f3505b636824e0fb8114156101fd57600435604052606060605990590160009052600081526040518160200152600581604001528090502054610220526020610220f35b633db16be381141561023e57600435604052606060605990590160009052600081526040518160200152600681604001528090502054610260526020610260f35b63c33878588114156102e05760006102a0526000546102c0526102c05180602002602001599059016000905281815260208101905090506102e0525b6102c0516102a05112156102c357604060405990590160009052600181526102a051816020015280905020546102a0516020026102e051015260016102a051016102a05261027a565b6102e05160206040820352602060208203510260400160408203f3505b63175c63228114156102fa57600054610380526020610380f35b63d861f2b4811415610336576004356103a052604060405990590160009052600181526103a051816020015280905020546103c05260206103c0f35b63b0dab01f81141561044f57600435610400526024356104205260443561044052606435610460526000606060605990590160009052600081526104005181602001526001816040015280905020541415610441576104205160606060599059016000905260008152610400518160200152600081604001528090502055610440516060606059905901600090526000815261040051816020015260018160400152809050205561046051606060605990590160009052600081526104005181602001526006816040015280905020556104005160406040599059016000905260018152600054816020015280905020556001600054016000556001610520526020610520f361044e565b6000610540526020610540f35b5b63aac2ffb58114156104b95760043560405260016060606059905901600090526000815260405181602001526002816040015280905020540160606060599059016000905260008152604051816020015260028160400152809050205560016105a05260206105a0f35b637265802d811415610507576004356040526024356105c0526105c0516060606059905901600090526000815260405181602001526002816040015280905020556001610600526020610600f35b63c5476efe811415610571576004356040526001606060605990590160009052600081526040518160200152600081604001528090502054016060606059905901600090526000815260405181602001526000816040015280905020556001610660526020610660f35b63c551e31e81141561063b576004356040526024356106805260606060599059016000905260008152604051816020015260058160400152809050205461012052610680516080608059905901600090526000815260405181602001526004816040015261012051816060015280905020556001606060605990590160009052600081526040518160200152600581604001528090502054016060606059905901600090526000815260405181602001526005816040015280905020556001610720526020610720f35b633d90504581141561067c57600435604052606060605990590160009052600081526040518160200152600381604001528090502054610740526020610740f35b631cda01ef8114156106e65760043560405260016060606059905901600090526000815260405181602001526003816040015280905020540160606060599059016000905260008152604051816020015260038160400152809050205560016107c05260206107c0f35b63c286273a811415610734576004356040526024356107e0526107e0516060606059905901600090526000815260405181602001526003816040015280905020556001610820526020610820f35b50 # noqa: E501 - contract_9 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x83F, value=0x0) - + Op.DIV( - Op.CALLDATALOAD(offset=0x0), - 0x100000000000000000000000000000000000000000000000000000000, + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE ) - + Op.JUMPI( - pc=Op.PUSH2[0x66], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7A66D7CA)) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x2540, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), ) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.POP + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6571,40 +5674,49 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x14) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x60, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x60, size=0x20) + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2540), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + Op.JUMPDEST - + Op.JUMPI( - pc=Op.PUSH2[0xA5], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC60409C6)) + + Op.JUMPI(pc=0x2175, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x2540), Op.MUL(0x20, Op.DUP1)) + ), ) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0xA0, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0xA0, size=0x20) + + Op.JUMP(pc=0x2154) + Op.JUMPDEST - + Op.JUMPI( - pc=Op.PUSH2[0xE4], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x18633576)) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x2540), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), + ), ) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.POP * 4 + + Op.MSTORE(offset=0x2600, value=0x1) + + Op.RETURN(offset=0x2600, size=0x20) + + Op.JUMPDEST + + Op.JUMPI(pc=0x2269, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x83FD77F0))) + + Op.CALLDATASIZE + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6612,18 +5724,17 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.DUP1 - + Op.SWAP1 + + Op.CALLDATACOPY( + dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE + ) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE( + offset=0x2620, + value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + ) + Op.POP - + Op.MSTORE(offset=0xE0, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0xE0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x1BC, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB3903C8A))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6632,74 +5743,54 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x15) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x120, value=Op.SLOAD(key=Op.SHA3)) - + Op.MLOAD(offset=0x120) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH2[0x160] - + Op.MSTORE - + Op.MSTORE(offset=0x1C0, value=0x0) + + Op.SHA3 + + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x2620), 0x20))) + + Op.DIV(Op.DUP2, 0x20) + + Op.PUSH1[0x0] + Op.JUMPDEST - + Op.JUMPI( - pc=0x19F, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x1C0), Op.MLOAD(offset=0x120)) + + Op.JUMPI(pc=0x223B, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP2))) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.MLOAD( + offset=Op.ADD(Op.MLOAD(offset=0x2620), Op.MUL(0x20, Op.DUP1)) ), ) - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x4) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x1C0)) - + Op.DUP1 + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x160), Op.MUL(0x20, Op.MLOAD(offset=0x1C0)) - ), - value=Op.SLOAD(key=Op.SHA3), - ) - + Op.MSTORE(offset=0x1C0, value=Op.ADD(Op.MLOAD(offset=0x1C0), 0x1)) - + Op.JUMP(pc=0x147) + + Op.JUMP(pc=0x221A) + Op.JUMPDEST - + Op.MLOAD(offset=0x160) - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + + Op.SSTORE( + key=Op.ADD(Op.DUP3, Op.DUP5), + value=Op.AND( + Op.MLOAD( + offset=Op.ADD( + Op.MLOAD(offset=0x2620), Op.MUL(0x20, Op.DUP2) + ) + ), + Op.SUB( + 0x0, Op.EXP(0x100, Op.SUB(0x20, Op.MOD(Op.DUP4, 0x20))) + ), ), ) - + Op.POP + + Op.POP * 4 + + Op.MSTORE(offset=0x26E0, value=0x1) + + Op.RETURN(offset=0x26E0, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x1FD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x6824E0FB))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.JUMPI(pc=0x22D5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x59462205))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x3C0, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x2700, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MLOAD(offset=0x2700) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6708,17 +5799,25 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x4) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x3C0)) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x220, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x220, size=0x20) + + Op.SHA3 + + Op.SSTORE + + Op.MSTORE(offset=0x2740, value=0x1) + + Op.RETURN(offset=0x2740, size=0x20) + Op.JUMPDEST - + Op.JUMPI(pc=0x23E, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3DB16BE3))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.JUMPI(pc=0x2448, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xBB8E4196))) + + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0x2760, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x2780, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x27A0, value=0x0) + + Op.JUMPDEST + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6727,42 +5826,22 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x6) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), + value=Op.SUB(Op.MLOAD(offset=0x2760), 0x1), + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x260, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x260, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x2E0, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC3387858))) - + Op.MSTORE(offset=0x2A0, value=0x0) - + Op.MSTORE(offset=0x2C0, value=Op.SLOAD(key=0x0)) - + Op.MLOAD(offset=0x2C0) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH2[0x2E0] - + Op.MSTORE - + Op.JUMPDEST + Op.JUMPI( - pc=0x2C3, + pc=0x243B, condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x2A0), Op.MLOAD(offset=0x2C0)) + Op.SLT(Op.MLOAD(offset=0x27A0), Op.SLOAD(key=Op.SHA3)) ), ) - + Op.PUSH1[0x40] * 2 + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6770,59 +5849,21 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x1) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x2A0)) - + Op.DUP1 - + Op.SWAP1 - + Op.POP + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x2E0), Op.MUL(0x20, Op.MLOAD(offset=0x2A0)) - ), - value=Op.SLOAD(key=Op.SHA3), + offset=Op.ADD(0x40, Op.DUP2), + value=Op.SUB(Op.MLOAD(offset=0x2760), 0x1), ) - + Op.MSTORE(offset=0x2A0, value=Op.ADD(Op.MLOAD(offset=0x2A0), 0x1)) - + Op.JUMP(pc=0x27A) - + Op.JUMPDEST - + Op.MLOAD(offset=0x2E0) - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.MSTORE( + offset=Op.ADD(0x80, Op.DUP2), value=Op.MLOAD(offset=0x27A0) ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x2FA, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x175C6322))) - + Op.MSTORE(offset=0x380, value=Op.SLOAD(key=0x0)) - + Op.RETURN(offset=0x380, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x336, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xD861F2B4))) - + Op.MSTORE(offset=0x3A0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x40] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x1) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x3A0)) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x3C0, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x3C0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x44F, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB0DAB01F))) - + Op.MSTORE(offset=0x400, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x420, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x440, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x460, value=Op.CALLDATALOAD(offset=0x64)) - + Op.PUSH1[0x0] - + Op.PUSH1[0x60] * 2 + + Op.SLOAD(key=Op.SHA3) + + Op.PUSH1[0xA0] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6831,15 +5872,12 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.JUMPI(pc=0x441, condition=Op.ISZERO(Op.EQ)) - + Op.MLOAD(offset=0x420) - + Op.PUSH1[0x60] * 2 + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x1) + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6848,32 +5886,22 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MLOAD(offset=0x440) - + Op.PUSH1[0x60] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=Op.SLOAD(key=Op.SHA3)) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 + Op.SSTORE - + Op.MLOAD(offset=0x460) - + Op.PUSH1[0x60] * 2 + + Op.PUSH1[0x1] + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6882,15 +5910,17 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x400)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x6) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MLOAD(offset=0x400) - + Op.PUSH1[0x40] * 2 + + Op.SLOAD(key=Op.SHA3) + + Op.ADD + + Op.PUSH1[0x80] * 2 + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6898,25 +5928,109 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x1) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.SLOAD(key=0x0)) + + Op.MSTORE(offset=Op.DUP2, value=0x0) + + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) + + Op.MSTORE( + offset=Op.ADD(0x40, Op.DUP2), value=Op.MLOAD(offset=0x2780) + ) + + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=0x0) + Op.DUP1 + Op.SWAP1 + Op.POP + Op.SHA3 + Op.SSTORE - + Op.SSTORE(key=0x0, value=Op.ADD(Op.SLOAD(key=0x0), 0x1)) - + Op.MSTORE(offset=0x520, value=0x1) - + Op.RETURN(offset=0x520, size=0x20) - + Op.JUMP(pc=0x44E) + + Op.MSTORE(offset=0x27A0, value=Op.ADD(Op.MLOAD(offset=0x27A0), 0x1)) + + Op.JUMP(pc=0x22FC) + Op.JUMPDEST - + Op.MSTORE(offset=0x540, value=0x0) - + Op.RETURN(offset=0x540, size=0x20) - + Op.JUMPDEST * 2 - + Op.JUMPI(pc=0x4B9, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xAAC2FFB5))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x1] - + Op.PUSH1[0x60] * 2 + + Op.MSTORE(offset=0x2880, value=0x1) + + Op.RETURN(offset=0x2880, size=0x20) + + Op.JUMPDEST + + Op.POP, + storage={ + 0x65D5EFDFCC0FBA693DC9E467F633097FFDC97401901463AD0E28855486D1EDF: 0xB9D69098A6ACFE0C6411BCAAF430F78D363A9ADC32B78BC2E15CCD6E883E9784, # noqa: E501 + 0x12643FF300762717D27EFB567B82C65560D7B43249D908504E5510863AB82AAC: 0x154CF60E137C594516A065149610B6A3989396A42581D5FD8919E711C55DA225, # noqa: E501 + 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D7: 5, # noqa: E501 + 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D8: contract_1, # noqa: E501 + 0x19EFB13D6576359514ACE5211988A8D51379FA88CCD2B886B409F842B13D7932: 0xC849CC595B452D11C206D2EB8CDFA06DE211E3FF19EE0E0276DC857C05D4FE, # noqa: E501 + 0x1B37E91BF8580C7C6BCF8CDFF25C7ED78180124A94AF6F30C40D476A3D079AD6: 0xABA4CD295118A482A0A62579E35E4BA5BDD76146CC9E4D96172FCE8BE8977AB4, # noqa: E501 + 0x2BF9FD8FACDD6FD9C84657F5AD7381A5AECF670CDA68CB3C5829B6532C865506: 0x53098A1D111586DBCC0D051846284F5803C63C313E7F7E6D84430435D11D4C50, # noqa: E501 + 0x3111BFD25728C0ADFAD0F8C1AD79CB1B91167267DECA98DE88F156ED25CAEEDC: 0xAD393086F30B49511B08FDD27AC78810B084C7CD7DE6AC354F614C18EA9E7DF4, # noqa: E501 + 0x3379E7AE125C5C5D623D1D993C1459B61D6723B1C30D1AA026C48F6A6155B8EA: 0x8C4183732567A99A8A718E363391E102532F9A640E42968CF2354D9ACC908BB0, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE2: contract_1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE3: contract_1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE4: contract_1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE5: contract_1, # noqa: E501 + 0x39050607FE892059A6344AB0F594F382FB0B345CAB373497246DBE86FE7E14E7: 0x2B3BCA833E482737E7E47B1568E6F890F8E1666490D38FE130ABD6F0CCB109CF, # noqa: E501 + 0x417BE8BC6791807372E0222A350BB8A5D67BBC8D7595C301D8A5A8372CFDCEF1: 0xABD4971B4605A7155802F70E08298B1CEB0E4E4EACCCCD348F77A77227F73A7F, # noqa: E501 + 0x41E9A54B3EE0C276AA076BABB161DE12B0F8916B47F8F6FB85CC387CF34696DD: 0x22F2F444EBDA9D2913FFEF5059B039EC9B5876AA71821991C2515BF79F64935E, # noqa: E501 + 0x45CEB8DA6FB8936592D3BCE4883F1A6A34D636F559E0A1070A5802A65AC39BD5: 0x57A5122FF3BF737B0DE0F9F08011A8648C19E43FF071FB7086234723C9383F1F, # noqa: E501 + 0x4AA6B934608A45C8F53A945C05DDEE1814A3B9F63A048FC7AD3D47E67156F024: 0xD03862BECEDADA67B4825A0238F3E67495CCB595CD7D08F1BD5D3160644B9299, # noqa: E501 + 0x4B8B58F0B0E326A5907D1A810E5FF31E05B4CAB45125B776DB8577E7DBC46BCE: 0x2F0000000000000000, # noqa: E501 + 0x4C33460347337BFC7DF08BF182988301B7B426A27A67F1C6C634F637C60E87AC: 0xBAB4AB2AD4EAFE7C84EF6A8CD69157D9CE6B843793A2CD0877B8E91F63CB2D4D, # noqa: E501 + 0x58DA0C0C256BBA101CE36FAD8BF838717A57E6AB850A191DC9C09DA9CE56BF1B: 5, # noqa: E501 + 0x5CB38B16DB1D632086D4AF695DE7F5F242A6E40947067F96EDD566FE2AC438EF: 0x6D0BE832B2007EA28CDA705B73922CBF9794C5A25B89BD2F28B7347ED2B96C86, # noqa: E501 + 0x64A9621CC4BA92BF738C55010C609DFAA3972A1138C30B5ADCEF1BA2363B360E: 0xD7953BFE8CB591F129FD0862A9E9C421151E2B5831560FF5215D23F751364B35, # noqa: E501 + 0x696664A5F0AB5ACD9304A377FB684F2D3FE6BB60B8A95CB2BDBB57DB767E7A84: 0x154CF60E137C594516A065149610B6A3989396A42581D5FD8919E711C55DA225, # noqa: E501 + 0x69AD1D19E617936ABDF05133BF268DC8CED6B518F22B249B5860967D07006487: 0x8C803B48B383DDABD1B3AFE858EFB48C203229B7317DD76149DDDAB4253B858A, # noqa: E501 + 0x70B3BF53996FAC325EB67608A4EEB0CD0B55DEF6255D7ED42AD28EC07238B5D6: 0x45E9723E9232B37207ECAC1C97B8647D053625A578D450F7456280B2FF8EFC27, # noqa: E501 + 0x7A9DCEE62E3E02CC8E020F372DF2EFDEB835F091C1EF1DBE221072D1095AABD2: 0x2F0000000000000000, # noqa: E501 + 0x7E4D8C0F6D8ABB4CE1AE45B254046ACEEDABFA9548851B8B5D3E2C0637C985FD: 11, # noqa: E501 + 0x7E95F3CC3315D289C52253BAABA29B1B00C86816E6B788D50795279A8BAA00DB: 0x45E9723E9232B37207ECAC1C97B8647D053625A578D450F7456280B2FF8EFC27, # noqa: E501 + 0x8DA187157087529EE4E9C381F8E3149C56ACF3BDFDA29B8B9B4532F24B83F5FE: 0x8C4183732567A99A8A718E363391E102532F9A640E42968CF2354D9ACC908BB0, # noqa: E501 + 0x9001F91DDAEF87BC067886E874C0749998C9B58B2EC8472CA014CA8B55F88578: 0xFB76974EEFCA01F33FB38646C2D3C1536F1A763D7AFF53AB7F877D4C5EA7FD0, # noqa: E501 + 0x9ED0CEDD2A9A78D949F40019F53D10031AEF6ED342C97E01FC03B481EE56B3CB: contract_4, # noqa: E501 + 0x9FDDF1DB29CAA5C1239EDD86E9E0835CDFE41F7253EC78F62D3DA8558D6F3CD7: 0x104EEF8FA35BF39F677D81855BC0B9F42317F32792E98E95E4DF441DEB634211, # noqa: E501 + 0xA0953566119395C11186B334805FC1A16175ECAC0ECC93AE0322264F0DC2E40D: 0x10C5A00466AB7C0ADAE1E93537CC275EA8CF23FF509D5466A1FD6F56B0A61D1B, # noqa: E501 + 0xAA0DBF8241EF3AE07C254E6869E84895BA2BE0779A7F261C8308A3114BE1C54A: contract_4, # noqa: E501 + 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2D: contract_1, # noqa: E501 + 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2E: contract_1, # noqa: E501 + 0xB4A2B68C48EF78AEB641EE538FAD51781022FD23ED9D93D211017DB6A02376CE: 0xFBC06642245CF2FED7ED46EA0A18A7185830B6F2C4E0A4CA55246041E8BFA72, # noqa: E501 + 0xBA8D79990898383919E437F2458B93B340072C89D963808D9E04F51858E3C5EC: 0x41D2CAC534D90A0DBD199117481A63E32CC11411DAB2EAA36C91C0EEC62823CF, # noqa: E501 + 0xBB3BC1A2015123750DF57D4CEFF7E28CB847910B79B34841DE905B59A8BB177C: 0x734417EB19E1873427257F1EA1594748C16CFA866A7B7CF896E281F2EC774A40, # noqa: E501 + 0xBF30CDCB83AB2BD5F5EEE691FFA4107B58B75BA6A5C2E6754D4C5C0437F2876C: 5, # noqa: E501 + 0xC2A26B80067FC36B8268B0D5B31AFFF953FA91CEBEA39F191E2763D6E71259B9: 0x2A43C547FE8DE2400D2A141016550E8BAE058D41164247C099E787DDD40E789, # noqa: E501 + 0xC98339D275EEF16E0562CA8521212CEF61AA0F39B12E2A27502AAA97A9E5E70F: 0x5A3DE2A5C268CDB75F4B01507AA80C4E4A1BC67BCB0DF265BBB00060774E5978, # noqa: E501 + 0xCBD6AE6BD61BC9270EC836F1919B3268113ABE076C7FEBFDB8CF573B199CE9A9: 0xF402B17773C1F7534034EE58DC0D2A3421470A7A67DAF4FA790DC3B420EEF790, # noqa: E501 + 0xD2C8CBB562FCCD0C9A3D0D491B7F65CC6A89856498F933427D9D21B745B9D50E: 0x3625A26FDB7B747501F1EE2500F98C49D9CD290383A21254587C3C49D2805321, # noqa: E501 + 0xD66F52A4E24585238CCC03443B2FDB8B2B100259BC7260F39097C7C339211FFE: 0x1641851904381915C86B60DF7E288896FB5F8EBAD65D594829FB9F2B59CD1DA6, # noqa: E501 + 0xD8F720C05A5526DD621D1831AE122ABDDD3DFECD8B63B0BA4C92FA7B2ADE44FF: 0xAD393086F30B49511B08FDD27AC78810B084C7CD7DE6AC354F614C18EA9E7DF4, # noqa: E501 + 0xDC22D3171B82817C910BBEAC1F8B50C8DE99F8C524F172AEF3491981BD5ED4FB: 0x94B8CBA4EA090D1C392FBC94B82FB9EF9F468A15BBC537F4D051776F4D422B1D, # noqa: E501 + 0xDCE8ADBDEFA929DBE60245F359446DB4174C62824B42E5D4D9E7B834B4D61DEB: 0x2C9069845B2E74C577FF1CD18DF6BC452805F527A9EE91FD4A059E0408B5DEA6, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D196: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D197: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D198: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D199: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D19A: contract_1, # noqa: E501 + 0xE54F074C81BFA60B5BF413934C108086298B77291560EDFEEAD8AA1232E95236: 0xF40AAA24323C9E6983CCFFAFEEBE4B426509B901E8C98B8A40D881804804E6B, # noqa: E501 + 0xE66C0F55F66C752EDF73027D45B7B1AE729AE15E1C67C362DBC6F25EDF8D76FF: contract_1, # noqa: E501 + 0xE983D899F807BBCB5881F2DDF875B2EBB5CB8A7A4E77A8C98A40AAAE6A468735: 0x6D0BE832B2007EA28CDA705B73922CBF9794C5A25B89BD2F28B7347ED2B96C86, # noqa: E501 + 0xED7D6E2D40FBD5046412FFAD1C45B63D87C6197182D6DBC66BB1E5C6E4DED5C7: 0xABA4CD295118A482A0A62579E35E4BA5BDD76146CC9E4D96172FCE8BE8977AB4, # noqa: E501 + 0xF043B5A1952847579F233706A8F130889A484D2DA3E574FDD5859F05AAF52111: contract_2, # noqa: E501 + 0xF40F4CFDACB62DD799F36B580349FAC1F4A4CAF8DD3383CC387C35ADB6574E21: 0x2F0000000000000000, # noqa: E501 + 0xF60FA6E25E9028A6DC6B26BBC1EADAE3DA157DF0D1D6F6628BC33CAD68A7E455: 0x2D7D00618C059EBE40593B9497C633E1AC6E161DADBD5BB734C2663CD3E8A8E1, # noqa: E501 + 0xFD280AC5182D5B2366122F38ACFA6DC471240FFDE9D5FEB985CE7A2325C960E7: contract_3, # noqa: E501 + }, + nonce=0, + address=Address(0x0EA65418D7BF32680F55572C943A94B590804998), # noqa: E501 + ) + # Source: raw + # 0x600061031f537c01000000000000000000000000000000000000000000000000000000006000350473c9ae5868651bf7b7db6e360217db49ce4e69c07e602052730ea65418d7bf32680f55572c943a94b5908049986040526327138bfb81141561038d57600435608052601c6044599059016000905201637a66d7ca601c8203526080516004820152602060e06024836000602051602d5a03f15060e051905060a052601c604459905901600090520163c60409c6601c820352608051600482015260206101206024836000602051602d5a03f150610120519050430561010052600061014052600061016052600061018052600260a051016101005112151561010a576001610140525b60006101a052610100516101c0525b606461010051016101c051121561018457601c606459905901600090520163cc1c944e601c82035260805160048201526101c051602482015260206101e06044836000604051602d5a03f1506101e05190506101a051016101a05260016101c051016101c052610119565b6005601c606459905901600090520163cc1c944e601c820352608051600482015260a051602482015260206102006044836000604051602d5a03f1506102005190501280156101d357806101db565b600a6101a051125b9050156101eb57610140516101ee565b60005b1561033657601c604459905901600090520163c5476efe601c820352608051600482015260206102406024836000602051602d5a03f15061024051905050601c6064599059016000905201637265802d601c82035260805160048201526000602482015260206102606044836000602051602d5a03f15061026051905050601c606459905901600090520163c286273a601c82035260805160048201526000602482015260206102806044836000602051602d5a03f15061028051905050601c6044599059016000905201637a66d7ca601c820352608051600482015260206102a06024836000602051602d5a03f1506102a051905060a052601c608459905901600090520163bb8e4196601c820352608051600482015260a051602482015261010051604482015260206102c06064836000604051602d5a03f1506102c051905050610343565b6001610160526001610180525b61014051156103555761016051610358565b60005b156103665761018051610369565b60005b1561037f5760016102e05260206102e0f361038c565b6000610300526020610300f35b5b50 # noqa: E501 + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x31F, value=0x0) + + Op.DIV( + Op.CALLDATALOAD(offset=0x0), + 0x100000000000000000000000000000000000000000000000000000000, + ) + + Op.MSTORE( + offset=0x20, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E + ) + + Op.MSTORE( + offset=0x40, value=0xEA65418D7BF32680F55572C943A94B590804998 + ) + + Op.JUMPI(pc=0x38D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x27138BFB))) + + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6924,15 +6038,27 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7A66D7CA) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0xE0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0xE0) + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x60] * 2 + + Op.PUSH1[0xA0] + + Op.MSTORE + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6940,22 +6066,55 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC60409C6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x120, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x120) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x5A0, value=0x1) - + Op.RETURN(offset=0x5A0, size=0x20) + + Op.NUMBER + + Op.MSTORE(offset=0x100, value=Op.SDIV) + + Op.MSTORE(offset=0x140, value=0x0) + + Op.MSTORE(offset=0x160, value=0x0) + + Op.MSTORE(offset=0x180, value=0x0) + + Op.JUMPI( + pc=0x10A, + condition=Op.ISZERO( + Op.ISZERO( + Op.SLT( + Op.MLOAD(offset=0x100), + Op.ADD(Op.MLOAD(offset=0xA0), 0x2), + ) + ) + ), + ) + + Op.MSTORE(offset=0x140, value=0x1) + Op.JUMPDEST - + Op.JUMPI(pc=0x507, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7265802D))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x5C0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MLOAD(offset=0x5C0) - + Op.PUSH1[0x60] * 2 + + Op.MSTORE(offset=0x1A0, value=0x0) + + Op.MSTORE(offset=0x1C0, value=Op.MLOAD(offset=0x100)) + + Op.JUMPDEST + + Op.JUMPI( + pc=0x184, + condition=Op.ISZERO( + Op.SLT( + Op.MLOAD(offset=0x1C0), + Op.ADD(Op.MLOAD(offset=0x100), 0x64), + ) + ), + ) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6963,21 +6122,32 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xCC1C944E) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0x1C0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x40), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x1E0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x1E0) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x600, value=0x1) - + Op.RETURN(offset=0x600, size=0x20) + + Op.MLOAD(offset=0x1A0) + + Op.MSTORE(offset=0x1A0, value=Op.ADD) + + Op.MSTORE(offset=0x1C0, value=Op.ADD(Op.MLOAD(offset=0x1C0), 0x1)) + + Op.JUMP(pc=0x119) + Op.JUMPDEST - + Op.JUMPI(pc=0x571, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC5476EFE))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x1] - + Op.PUSH1[0x60] * 2 + + Op.PUSH1[0x5] + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -6985,15 +6155,42 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xCC1C944E) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xA0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x40), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x200, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x200) + + Op.SWAP1 + + Op.POP + + Op.SLT + + Op.JUMPI(pc=0x1D3, condition=Op.ISZERO(Op.DUP1)) + Op.DUP1 + + Op.JUMP(pc=0x1DB) + + Op.JUMPDEST + + Op.SLT(Op.MLOAD(offset=0x1A0), 0xA) + + Op.JUMPDEST + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x60] * 2 + + Op.JUMPI(pc=0x1EB, condition=Op.ISZERO) + + Op.MLOAD(offset=0x140) + + Op.JUMP(pc=0x1EE) + + Op.JUMPDEST + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x336, condition=Op.ISZERO) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7001,21 +6198,25 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x660, value=0x1) - + Op.RETURN(offset=0x660, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x63B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC551E31E))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x680, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x60] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC5476EFE) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x240, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x240) + + Op.SWAP1 + + Op.POP * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7023,15 +6224,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7265802D) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x260, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x260) + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x120, value=Op.SLOAD(key=Op.SHA3)) - + Op.MLOAD(offset=0x680) - + Op.PUSH1[0x80] * 2 + + Op.POP * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7039,17 +6251,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x4) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x120)) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC286273A) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x280, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x280) + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0x1] - + Op.PUSH1[0x60] * 2 + + Op.POP * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7057,15 +6278,27 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7A66D7CA) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x2A0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x2A0) + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x60] * 2 + + Op.PUSH1[0xA0] + + Op.MSTORE + + Op.PUSH1[0x1C] + + Op.PUSH1[0x84] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7073,20 +6306,83 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x5) - + Op.DUP1 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xBB8E4196) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x80)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xA0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x40), + value=0x0, + args_offset=Op.DUP4, + args_size=0x64, + ret_offset=0x2C0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x2C0) + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x720, value=0x1) - + Op.RETURN(offset=0x720, size=0x20) + + Op.POP * 2 + + Op.JUMP(pc=0x343) + Op.JUMPDEST - + Op.JUMPI(pc=0x67C, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3D905045))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.MSTORE(offset=0x160, value=0x1) + + Op.MSTORE(offset=0x180, value=0x1) + + Op.JUMPDEST + + Op.JUMPI(pc=0x355, condition=Op.ISZERO(Op.MLOAD(offset=0x140))) + + Op.MLOAD(offset=0x160) + + Op.JUMP(pc=0x358) + + Op.JUMPDEST + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x366, condition=Op.ISZERO) + + Op.MLOAD(offset=0x180) + + Op.JUMP(pc=0x369) + + Op.JUMPDEST + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.JUMPI(pc=0x37F, condition=Op.ISZERO) + + Op.MSTORE(offset=0x2E0, value=0x1) + + Op.RETURN(offset=0x2E0, size=0x20) + + Op.JUMP(pc=0x38C) + + Op.JUMPDEST + + Op.MSTORE(offset=0x300, value=0x0) + + Op.RETURN(offset=0x300, size=0x20) + + Op.JUMPDEST * 2 + + Op.POP, + nonce=0, + address=Address(0x142A6927CF0060133187BA8A8E74D641438F0C1C), # noqa: E501 + ) + # Source: raw + # 0x60006105df537c010000000000000000000000000000000000000000000000000000000060003504730ea65418d7bf32680f55572c943a94b59080499860205273e509e3a93beb1eba72f8cb8d25f93a85e2d54afb60405273c9ae5868651bf7b7db6e360217db49ce4e69c07e60605273f1562e1c0d0baa3ea746442bb7f11153fcf5cfda60805263546fdeb381141561038d5760043560c05260243560e05260443561010052606435610120526084356101405260026101005101601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f150604081019050905090506000600161010051016020028201511415610250576060601c61014c59905901600090520163e365736b601c82035260c051600482015260e0516024820152601c6084599059016000905201632f300bee601c82035260026004820152600560248201526101005160448201528460408160200201599059016000905281602002604001816064856000608051602d5a03f1506040810190509050905060208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf16101fc57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f161022357fe5b50808401935050808303602061028082846000602051602d5a03f15061028051905090509050905061037d565b6060601c61014c59905901600090520163e365736b601c82035260c051600482015260e0516024820152601c6084599059016000905201632f300bee601c820352600160016101005101602002850151036004820152600560248201526101005160448201528460408160200201599059016000905281602002604001816064856000608051602d5a03f1506040810190509050905060208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf161032d57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f161035457fe5b5080840193505080830360206102c082846000602051602d5a03f1506102c05190509050905090505b5060016102e05260206102e0f350505b63de9080c88114156107645760043560c05260243560e05260443561010052606435610120526084356101405260026101005101601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201528160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c6064599059016000905201632c5a40d5601c82035260c051600482015260e05160248201526101405160408160200201599059016000905281602002604001816044856000602051602d5a03f1506040810190509050905061012051806020026020015990590160009052818152602081019050905060005b610120518112156104ee57601c60645990590160009052016328c8b315601c82035260c051600482015281602482015260206103606044836000604051602d5a03f15061036051905081602002830152600181019050610493565b5060a0601c61020c59905901600090520163a647a5b9601c8203528460208103516020026020018360048401526020820360a484015280610148840152808401935050508360208103516020026020018360248401526020820360c484015280610168840152808401935050508260208103516020026020018360448401526020820360e4840152806101888401528084019350505061012051606482015261010051608482015281600401599059016000905260a48160a484600060046022f16105b557fe5b60a4810192506101488201518080858260a487015160006004600a8705601201f16105dc57fe5b508084019350506101688201518080858260c487015160006004600a8705601201f161060457fe5b508084019350506101888201518080858260e487015160006004600a8705601201f161062c57fe5b5080840193505080830387604081602002015990590160009052816020026040018184866000608051602d5a03f1506040810190509050905090509050905092506060601c61014c59905901600090520163e365736b601c82035260c051600482015260e05160248201528460208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf16106df57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f161070657fe5b5080840193505080830360206103c082846000602051602d5a03f1506103c05190509050905090505060006101005160200284015114156107525760006103e05260206103e0f361075f565b6001610400526020610400f35b505050505b63384ca8dd811415610a665760043560c05260243560e052604435610100526064356101205260843561014052601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c606459905901600090520163fa9832d1601c82035260c051600482015260e05160248201526101005160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c608459905901600090520163aad7d6e3601c82035260c051600482015260e05160248201526060601c61014c599059016000905201635b180229601c8203528360208103516020026020018360048401526020820360648401528060c8840152808401935050508460208103516020026020018360248401526020820360848401528060e88401528084019350505061010051604482015281600401599059016000905260648160648460006004601cf161090157fe5b60648101925060c882015180808582606487015160006004600a8705601201f161092757fe5b5080840193505060e882015180808582608487015160006004600a8705601201f161094e57fe5b50808401935050808303602061044082846000608051602d5a03f150610440519050905090509050604482015260206104606064836000602051602d5a03f150610460519050506060601c61014c59905901600090520163222a8663601c82035260c051600482015260e05160248201528260208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1610a0757fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1610a2e57fe5b50808401935050808303602061048082846000602051602d5a03f1506104805190509050905090505060016104a05260206104a0f350505b63d5dc5af1811415610d4b5760043560c05260243560e052604435610100526064356101205260843561014052601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c6064599059016000905201632c5a40d5601c82035260c051600482015260e05160248201526101405160408160200201599059016000905281602002604001816044856000602051602d5a03f150604081019050905090506080601c6101ac59905901600090520163f4ca7dc4601c82035283602081035160200260200183600484015260208203608484015280610108840152808401935050508260208103516020026020018360248401526020820360a4840152806101288401528084019350505061012051604482015261010051606482015281600401599059016000905260848160848460006004601ff1610be757fe5b60848101925061010882015180808582608487015160006004600a8705601201f1610c0e57fe5b508084019350506101288201518080858260a487015160006004600a8705601201f1610c3657fe5b5080840193505080830361014051604081602002015990590160009052816020026040018184866000608051602d5a03f1506040810190509050905090509050905090506060601c61014c59905901600090520163b39e1faa601c82035260c051600482015260e05160248201528260208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1610cec57fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1610d1357fe5b5080840193505080830360206104c082846000602051602d5a03f1506104c05190509050905090505060016104e05260206104e0f350505b630939aa8c81141561114c5760043560c05260243560e052604435610100526064356101205260843561014052601c606459905901600090520163e05dcb56601c82035260c051600482015260e05160248201526002610100510160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c6064599059016000905201637dc12195601c82035260c051600482015260e05160248201526101405160408160200201599059016000905281602002604001816044856000602051602d5a03f15060408101905090509050601c606459905901600090520163586b5be0601c82035260c051600482015260e051602482015260206105006044836000602051602d5a03f150610500519050601c606459905901600090520163eb8af5aa601c82035260c051600482015260e05160248201526101205160408160200201599059016000905281602002604001816044856000602051602d5a03f1506040810190509050905060c0601c61026c59905901600090520163232b2734601c8203528260208103516020026020018360048401526020820360c484015280610188840152808401935050508560208103516020026020018360248401526020820360e4840152806101a88401528084019350505084602081035160200260200183604484015260208203610104840152806101c8840152808401935050508360648201526101205160848201526101005160a482015281600401599059016000905260c48160c484600060046025f1610f9657fe5b60c4810192506101888201518080858260c487015160006004600a8705601201f1610fbd57fe5b508084019350506101a88201518080858260e487015160006004600a8705601201f1610fe557fe5b508084019350506101c88201518080858261010487015160006004600a8705601201f161100e57fe5b5080840193505080830361012051604081602002015990590160009052816020026040018184866000608051602d5a03f1506040810190509050905090509050905090506060601c61014c5990590160009052016301112b27601c82035260c051600482015260e05160248201528260208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf16110c457fe5b6064810192506101088201518080858260a487015160006004600a8705601201f16110eb57fe5b50808401935050808303602061058082846000602051602d5a03f15061058051905090509050905050600060016101005101602002850151141561113a5760006105a05260206105a0f3611147565b60016105c05260206105c0f35b505050505b50 # noqa: E501 + contract_7 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x5DF, value=0x0) + + Op.DIV( + Op.CALLDATALOAD(offset=0x0), + 0x100000000000000000000000000000000000000000000000000000000, + ) + + Op.MSTORE( + offset=0x20, value=0xEA65418D7BF32680F55572C943A94B590804998 + ) + + Op.MSTORE( + offset=0x40, value=0xE509E3A93BEB1EBA72F8CB8D25F93A85E2D54AFB + ) + + Op.MSTORE( + offset=0x60, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E + ) + + Op.MSTORE( + offset=0x80, value=0xF1562E1C0D0BAA3EA746442BB7F11153FCF5CFDA + ) + + Op.JUMPI(pc=0x38D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x546FDEB3))) + + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) + + Op.ADD(Op.MLOAD(offset=0x100), 0x2) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7094,19 +6390,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x740, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x740, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x6E6, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1CDA01EF))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x1] - + Op.PUSH1[0x60] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.ADD(Op.MLOAD(offset=0x100), 0x2) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7114,15 +6403,41 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x60] * 2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.JUMPI( + pc=0x250, + condition=Op.ISZERO( + Op.EQ( + Op.MLOAD( + offset=Op.ADD( + Op.DUP3, + Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x100), 0x1)), + ) + ), + 0x0, + ) + ), + ) + + Op.PUSH1[0x60] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7130,22 +6445,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x7C0, value=0x1) - + Op.RETURN(offset=0x7C0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x734, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xC286273A))) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x7E0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MLOAD(offset=0x7E0) - + Op.PUSH1[0x60] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE365736B) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x84] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7153,73 +6458,13 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x40)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x3) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x820, value=0x1) - + Op.RETURN(offset=0x820, size=0x20) - + Op.JUMPDEST - + Op.POP, - storage={ - 0: 1, - 0xA4470E9D0419DF71F6257FCDFD2C0A3BAD96A23F5AB414BC10AAF1A31A536A7: 0xB4876148229C22BD2291F1A4F5468C8C789B23639370C4D447F270BA341DBBEC, # noqa: E501 - 0x16EF4193A274568D283FF919C299729E07696D9ADA48187B81D68E12E7B962DE: 0xA103C04E7ECB9B3395F77C7B0CAD28E62C85F042DE4767CCC6C005E6F47F8D4, # noqa: E501 - 0x1F1866E966F321B84535705846689749D34D5DC02994613E2931973C605D9E93: 0xC723D0AA4A60529FE42277C8094AA19263AFF36650136EFC5EDFD0785D457634, # noqa: E501 - 0x252A4EC7133643FDDCDB22A86C415F78B2DD251F18D1EFCD6A44ACF590C4AE72: 0x9CAF94B82715869E71D3CEE986094EA612F0258570B7E5EF47B5D09E9515322B, # noqa: E501 - 0x41B451E8D86D28ADD758CBD3F48A18FD04B11A80288C1DC434A5BF2D8FB1CA64: 0xB602498F12A8B4AF3A1FCA357CEA6B19BCD163DFEC1D845364CE1395F7C21FA7, # noqa: E501 - 0x491D10658C1EC762152D8AD2D890AD59111B1EE7B4BC25736046923D3534D9A5: 25246, # noqa: E501 - 0x5B0E8552EFD72A845E47318ABBBEF9DC9FCDFE0D1A06CDA44494401301581511: 0xFBC98F4017AE5C20459DAADAA6BEE519B6DE871D3DBAA9AB3F34340FEF4CB643, # noqa: E501 - 0x5B672A107BA6FAB01CBDDF079042E9F6176A8E6F154584FC4DF4B15674C9456E: 0x1603DA41D610854D85536B37D000E5EB7CA09786C43F50E7441C0AFBFF1DE0A9, # noqa: E501 - 0x605B934BD26C9ECDF7029A7DC062D3A6B87338511CFF96E0C5F13DE9EEA3462E: 0xF0D24F3D0EDA573FC5D43E3D0680993C51293752CD6DE205040D3197F412F475, # noqa: E501 - 0x618355E25491DFE86175F9D9B3147E4D680AA561D98384E3621DC6A3088B0846: 0x6B2E6D2D5DEB27DFFEC973F23AF4CAF111E66D1397F467DBBEDF5AB2192FB6B6, # noqa: E501 - 0x65112936BEC0F1E84FDA6623FB54E12BAADC8A4A208C8C4EB3ED5E79CBD7E85F: 0xA59AC24E3E0663413D0F87516BA8FB44C6C3E14DA8EAABBDE80F8EE285F65934, # noqa: E501 - 0x687CB2122DE7BACF42B9CD380B04FF2A2CE92A0B63706A9A78263B3CE86F3313: 0x200000000000000, # noqa: E501 - 0x72A539B064C98D29A514EE55694225E05FB41FE63E5FE710E4536BD9BA3591B4: 0x338ECFE6C523ED1184918B19584D97DD1095ECAADC49C7BA9DA62B8B513026E0, # noqa: E501 - 0x7AEB0A0CE8882A12D853078382A2BC72F7A94AF6109F167DE37B36C0A7DEB828: 0x4C428400EA8A7BD7C46BA9895B508770EFA4551F0D793E1BEB1207DA01D9962F, # noqa: E501 - 0x7C8F4A98E086F64E28C75F54712B5D44BEC3C29B5C70519E8880D3046A5618DC: 0xAAFC1F2601752B114D722070F75539BFEC7FAF49F0D48A48D27862F0C3B09903, # noqa: E501 - 0x809C325F50ACF5787776E960985E72443B4330AD1E2F466557FFFEE16BA51D44: 0xB940A56E64B5B661D87919B8EF03640EC077A6D72DD0B524ADEDAA7DDC91FF7A, # noqa: E501 - 0x84E4A80D33C5D2ABD2B0A5AEC0FDC5EAEED90AB31DB556E404A81718EA286E39: 28, # noqa: E501 - 0x877305412FA2486F563C457B744E5C8B1E4D0ECA73371DE5E771F2ABC263F4DC: 0x7088A36F67276D475AA62127CFDE9790CC802FDF3A54DF49461A25EB8BF15707, # noqa: E501 - 0x922A8F2FC1CBE67C8ACC6A8A720983C366D71D3E2E78E3048949EBC913EA611A: 0x50FB9F913CA102534BB0A8EB8EBF19C68DFD16FFE5E207BCC580084CD4ECD8B4, # noqa: E501 - 0x987CB9ECFD8CE499D9D0E9E6B7DA29617AA02774A34F4A8EA54442F44A1E1936: 0x5179F98F555F1E9F1D4A335D16F41154579A53E361E9859269B6FA74EA9C7D21, # noqa: E501 - 0xADA5013122D395BA3C54772283FB069B10426056EF8CA54750CB9BB552A59E7D: 0xF69B5, # noqa: E501 - 0xB16B117660F31197087F4D6FE50D3D4579152244956F753F9653CCF85F4B35C4: 0x830272E3BB35226B047244CBDC46F1B6B864A280461E7A592F70E0863F4F1D33, # noqa: E501 - 0xB1F1AAEDFB83C7755A2BFFC9E2557F1723F9ABE5642397963E76248C9209AF57: 0xE9BE955C5FBFCD846D7425EAEA05CE897786AEFAD99665342CBF30761B352526, # noqa: E501 - 0xB7BD50FDF7B043411C9AC33F0AF2CEBC69C393EB0B91F4976946F9C7B15AD0DA: 0xFCCCA0E7832BAE9AFE799A6D6177DC3869FA6C5B5105F8DF6F365DE5723820EC, # noqa: E501 - 0xBC96058EB03504EE6F5C0A9582F8720D99A6E9738B171499507FACFF0B2C0B5B: 0x9DB6A4F2766B51013B8D2F9038131D1BB4AF725D019D111D7E26FF96C023B23F, # noqa: E501 - 0xC186C4F377B7F13892ADE9656ACD1522AA1F8AC151AC4F62457B5073241D79FC: 0x7289738FEF00F1770EEB098DB9BD486C01AC12398D79CDF935514A128C585C51, # noqa: E501 - 0xCAE57AE3017972D63EFFD8EAE44F5054402C3E890D154B905ED6B5B533327FA9: 0xD2E4BF465E61993D13089B940A7C55017A5117D8E43E4115550A139E1D4B3E3A, # noqa: E501 - 0xCF569EE7BF3ACCC0F893DFFD04F1A757F373EFE80893EFF504FB3678F688EC1D: 3, # noqa: E501 - 0xD69B7284545A9F5275DF64CE94848DC954FCB8A8B525E7AC801517C12A75AF84: 0x4202995350ABAE303B43E564AA79121A30B5F1AEA31F69CD25E07DD3FA64DCE7, # noqa: E501 - 0xD8F6F90F51E657690EE28D1CC80D81BC1B89290065891FDD853D09CAAAF756AA: 1, # noqa: E501 - 0xDE72F8EED43CC2A5A3EAA51483D14B17DC92BB26C154AE184CEE4B4895011EDC: 0x47CE2B6FDB72C3FABB9C74F82C1E3E522BCD42E614FD85C208AC3C4C840CEA72, # noqa: E501 - 0xE0E687DDF317F3D2B209AE3884148EFF0F636E16827F82EDED14ADA8FC603009: 0xFA7C8939F9B033162CF8D75EA69671BB8A27041BD4CDC76594E61E99333CB041, # noqa: E501 - 0xE8CDA339D72A1A350B62F1E3FA52E254C395CC9FDD9F60ADB21C7633FBDAB531: 0x128C4FDF4801A30EAE99DD58F0F3FF5CA65F71B66A9AC0F38DD450FB24B4AAAA, # noqa: E501 - 0xEC5E7F54FA5E516E616B04F9D5A0EE433A80E09ED47D7E5269AFD76C05FF251E: 20, # noqa: E501 - 0xF9A3BF5F2CCB903EE1A7644113B794DB0260DE404FB8F11203E75A7FFF151618: 0xBD94773C0D85C68240AE8DFD53D9D33CD137509BFC5D3433381299DF768C8377, # noqa: E501 - }, - nonce=0, - address=Address(0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E), # noqa: E501 - ) - # Source: raw - # 0x6000610b7f537c01000000000000000000000000000000000000000000000000000000006000350473c9ae5868651bf7b7db6e360217db49ce4e69c07e6020526308d3d58781141561024557600435606052606060605990590160009052600081526060518160200152600181604001528090502054608052600060806080599059016000905260008152606051816020015260028160400152328160600152809050205414151561014e57608060805990590160009052600081526060518160200152600281604001523281606001528090502054608052682f000000000000000060a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020553260a060a05990590160009052600081526060518160200152600081604001526080518160600152600181608001528090502055610238565b608051608060805990590160009052600081526060518160200152600281604001523281606001528090502055682f000000000000000060a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020553260a060a059905901600090526000815260605181602001526000816040015260805181606001526001816080015280905020556001606060605990590160009052600081526060518160200152600181604001528090502054016060606059905901600090526000815260605181602001526001816040015280905020555b60016101e05260206101e0f35b6328c8b31581141561029d576004356060526024356102005260a060a0599059016000905260008152606051816020015260008160400152610200518160600152600081608001528090502054610220526020610220f35b6374af23ec8114156103865760043560605260243561026052608060805990590160009052600081526060518160200152600281604001526102605181606001528090502054610200526000610200511415610332576102605160a060a05990590160009052600081526060518160200152600081604001526102005181606001526001816080015280905020541415610335565b60005b156103475760006102c05260206102c0f35b60a060a05990590160009052600081526060518160200152600081604001526102005181606001526000816080015280905020546102e05260206102e0f35b6384d646ee8114156103dc5760043560605260243560805260a060a05990590160009052600081526060518160200152600081604001526080518160600152600181608001528090502054610320526020610320f35b63f42294278114156106f45760043561026052601c602459905901600090520163175c6322601c82035260206103a06004836000602051602d5a03f1506103a0519050610360526102605115610581576103605160020280602002602001599059016000905281815260208101905090506103c05261036051806020026020015990590160009052818152602081019050905061042052601c602459905901600090520163c3387858601c8203526103605160408160200201599059016000905281602002604001816004856000602051602d5a03f150604081019050905090506104205260006104c05260006104e0525b610360516104c051121561057c576104c051602002610420510151606052601c60645990590160009052016374af23ec601c82035260605160048201526102605160248201526020610520604483600030602d5a03f1506105205190506105005260006105005114151561056c576060516104e0516020026103c05101526105005160016104e051016020026103c051015260026104e051016104e0525b60016104c051016104c0526104ce565b6106d7565b32610260526103605160020280602002602001599059016000905281815260208101905090506103c05261036051806020026020015990590160009052818152602081019050905061042052601c602459905901600090520163c3387858601c8203526103605160408160200201599059016000905281602002604001816004856000602051602d5a03f150604081019050905090506104205260006104c05260006104e0525b610360516104c05112156106d6576104c051602002610420510151606052601c60645990590160009052016374af23ec601c820352606051600482015261026051602482015260206105c0604483600030602d5a03f1506105c0519050610500526000610500511415156106c6576060516104e0516020026103c05101526105005160016104e051016020026103c051015260026104e051016104e0525b60016104c051016104c052610628565b5b6103c05160206040820352602060208203510260400160408203f3505b6380b5e7bd81141561073557600435606052606060605990590160009052600081526060518160200152600181604001528090502054610600526020610600f35b63156f1c328114156107865760043560605260243561064052608060805990590160009052600081526060518160200152600281604001526106405181606001528090502054610660526020610660f35b63b3a24fc081141561087857365990590160009052366004823760043560208201016106c0526024356106e05250600260206106c0510351018060200260200159905901600090528181526020810190509050610700523261070051526106e051602061070051015260026104c0525b600260206106c0510351016104c05112156108385760026104c051036020026106c05101516104c05160200261070051015260016104c051016104c0526107f6565b60206107005103516020026020599059016000905260208183610700516000600287604801f15080519050905061076052610760516107c05260206107c0f35b63e346f5fc811415610a1c576004356107e0526024356108005260006104c0525b606060605990590160009052600081526107e05181602001526001816040015280905020546104c05112156109e65760a060a05990590160009052600081526107e0518160200152600081604001526104c0518160600152600181608001528090502054610840526108405160a060a0599059016000905260008152610800518160200152600081604001526104c051816060015260018160800152809050205560a060a05990590160009052600081526107e0518160200152600081604001526104c051816060015260008160800152809050205460a060a0599059016000905260008152610800518160200152600081604001526104c05181606001526000816080015280905020556104c0516080608059905901600090526000815261080051816020015260028160400152610840518160600152809050205560016104c051016104c052610899565b6104c051606060605990590160009052600081526108005181602001526001816040015280905020556001610920526020610920f35b633fb57036811415610b5457600435606052602435610940526060606059905901600090526000815260605181602001526001816040015280905020546109605261096051608060805990590160009052600081526060518160200152600281604001526109405181606001528090502055600060a060a05990590160009052600081526060518160200152600081604001526109605181606001526000816080015280905020556109405160a060a05990590160009052600081526060518160200152600081604001526109605181606001526001816080015280905020556001606060605990590160009052600081526060518160200152600181604001528090502054016060606059905901600090526000815260605181602001526001816040015280905020556001610a40526020610a40f35b6312709a33811415610beb57600435606052602435608052604435610a6052610a605160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020540160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020556001610ac0526020610ac0f35b633229cf6e811415610c8257600435606052602435608052604435610a6052610a605160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020540360a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020556001610b20526020610b20f35b63a75f5c6a811415610ce557600435606052602435608052604435610a6052610a605160a060a059905901600090526000815260605181602001526000816040015260805181606001526000816080015280905020556001610b60526020610b60f35b50 # noqa: E501 - contract_10 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0xB7F, value=0x0) - + Op.DIV( - Op.CALLDATALOAD(offset=0x0), - 0x100000000000000000000000000000000000000000000000000000000, - ) - + Op.MSTORE( - offset=0x20, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E - ) - + Op.JUMPI(pc=0x245, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x8D3D587))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2F300BEE) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=0x2) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) + + Op.DUP5 + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7227,32 +6472,32 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP6, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x80, value=Op.SLOAD(key=Op.SHA3)) - + Op.PUSH1[0x0] - + Op.PUSH1[0x80] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.ORIGIN) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.JUMPI(pc=0x14E, condition=Op.ISZERO(Op.ISZERO(Op.EQ))) - + Op.PUSH1[0x80] * 2 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7260,35 +6505,69 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.ORIGIN) + + Op.JUMPI( + pc=0x1FC, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + Op.DUP1 + + Op.JUMPI( + pc=0x223, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x280, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x280) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x80, value=Op.SLOAD(key=Op.SHA3)) - + Op.PUSH9[0x2F0000000000000000] - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + + Op.POP + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.ORIGIN - + Op.PUSH1[0xA0] * 2 + + Op.JUMP(pc=0x37D) + + Op.JUMPDEST + + Op.PUSH1[0x60] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7296,20 +6575,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.JUMP(pc=0x238) - + Op.JUMPDEST - + Op.MLOAD(offset=0x80) - + Op.PUSH1[0x80] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE365736B) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x84] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7317,17 +6588,24 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.ORIGIN) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH9[0x2F0000000000000000] - + Op.PUSH1[0xA0] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2F300BEE) + + Op.MSTORE( + offset=Op.ADD(Op.DUP3, 0x4), + value=Op.SUB( + Op.MLOAD( + offset=Op.ADD( + Op.DUP6, + Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x100), 0x1)), + ) + ), + 0x1, + ), + ) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) + + Op.DUP5 + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7335,18 +6613,32 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP6, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.ORIGIN - + Op.PUSH1[0xA0] * 2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7354,34 +6646,79 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + + Op.JUMPI( + pc=0x32D, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + Op.DUP1 + + Op.JUMPI( + pc=0x354, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x2C0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x2C0) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0x1] - + Op.PUSH1[0x60] * 2 - + Op.MSIZE + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + + Op.POP + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x60] * 2 + + Op.JUMPDEST + + Op.POP + + Op.MSTORE(offset=0x2E0, value=0x1) + + Op.RETURN(offset=0x2E0, size=0x20) + + Op.POP * 2 + + Op.JUMPDEST + + Op.JUMPI(pc=0x764, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xDE9080C8))) + + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) + + Op.ADD(Op.MLOAD(offset=0x100), 0x2) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7389,22 +6726,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.JUMPDEST - + Op.MSTORE(offset=0x1E0, value=0x1) - + Op.RETURN(offset=0x1E0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x29D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x28C8B315))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x200, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.DUP2 + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7412,21 +6739,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x200)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x220, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x220, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x386, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x74AF23EC))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x260, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7434,19 +6766,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x260)) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x200, value=Op.SLOAD(key=Op.SHA3)) - + Op.JUMPI( - pc=0x332, condition=Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x200), 0x0)) - ) - + Op.MLOAD(offset=0x260) - + Op.PUSH1[0xA0] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2C5A40D5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.MLOAD(offset=0x140) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7454,25 +6779,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x200)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ISZERO(Op.EQ) - + Op.JUMP(pc=0x335) - + Op.JUMPDEST - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x347, condition=Op.ISZERO) - + Op.MSTORE(offset=0x2C0, value=0x0) - + Op.RETURN(offset=0x2C0, size=0x20) - + Op.JUMPDEST - + Op.PUSH1[0xA0] * 2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.MLOAD(offset=0x120) + + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7480,43 +6806,20 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x200)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) + + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x2E0, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x2E0, size=0x20) + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x0] + Op.JUMPDEST - + Op.JUMPI(pc=0x3DC, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x84D646EE))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x320, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x320, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x6F4, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xF4229427))) - + Op.MSTORE(offset=0x260, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x1C] - + Op.PUSH1[0x24] + + Op.JUMPI( + pc=0x4EE, + condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x120))), + ) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7525,43 +6828,34 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x175C6322) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x28C8B315) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP2) + Op.POP( Op.CALL( gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), + address=Op.MLOAD(offset=0x40), value=0x0, args_offset=Op.DUP4, - args_size=0x4, - ret_offset=0x3A0, + args_size=0x44, + ret_offset=0x360, ret_size=0x20, ) ) - + Op.MLOAD(offset=0x3A0) + + Op.MLOAD(offset=0x360) + Op.SWAP1 + Op.POP - + Op.PUSH2[0x360] - + Op.MSTORE - + Op.JUMPI(pc=0x581, condition=Op.ISZERO(Op.MLOAD(offset=0x260))) - + Op.MUL(0x2, Op.MLOAD(offset=0x360)) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 + + Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP2)) + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.SWAP1 + + Op.JUMP(pc=0x493) + + Op.JUMPDEST + Op.POP - + Op.PUSH2[0x3C0] - + Op.MSTORE - + Op.MLOAD(offset=0x360) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.PUSH1[0xA0] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x20C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7569,16 +6863,35 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH2[0x420] - + Op.MSTORE - + Op.PUSH1[0x1C] - + Op.PUSH1[0x24] + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xA647A5B9) + + Op.DUP5 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x148), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.DUP4 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xC4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x168), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.DUP3 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xE4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x188), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.MLOAD(offset=0x120)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.MLOAD(offset=0x100)) + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7586,9 +6899,85 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC3387858) - + Op.MLOAD(offset=0x360) + + Op.JUMPI( + pc=0x5B5, + condition=Op.CALL( + gas=0x22, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0xA4, + ret_offset=Op.DUP2, + ret_size=0xA4, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0xA4) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x148)) + + Op.DUP1 + + Op.JUMPI( + pc=0x5DC, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x168)) + + Op.DUP1 + + Op.JUMPI( + pc=0x604, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xC4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x188)) + + Op.DUP1 + + Op.JUMPI( + pc=0x62C, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xE4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.DUP8 + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 @@ -7600,10 +6989,10 @@ def test_block504980( + Op.POP( Op.CALL( gas=Op.SUB(Op.GAS, 0x2D), - address=Op.MLOAD(offset=0x20), + address=Op.MLOAD(offset=0x80), value=0x0, - args_offset=Op.DUP6, - args_size=0x4, + args_offset=Op.DUP7, + args_size=Op.DUP5, ret_offset=Op.DUP2, ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), ) @@ -7615,28 +7004,17 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH2[0x420] - + Op.MSTORE - + Op.MSTORE(offset=0x4C0, value=0x0) - + Op.MSTORE(offset=0x4E0, value=0x0) - + Op.JUMPDEST - + Op.JUMPI( - pc=0x57C, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x4C0), Op.MLOAD(offset=0x360)) - ), - ) - + Op.MSTORE( - offset=0x60, - value=Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x420), - Op.MUL(0x20, Op.MLOAD(offset=0x4C0)), - ) - ), - ) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP3 + + Op.POP + + Op.PUSH1[0x60] + Op.PUSH1[0x1C] - + Op.PUSH1[0x64] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7645,86 +7023,113 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x74AF23EC) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0x260)) - + Op.POP( - Op.CALL( - gas=Op.SUB(Op.GAS, 0x2D), - address=Op.ADDRESS, - value=0x0, - args_offset=Op.DUP4, - args_size=0x44, - ret_offset=0x520, - ret_size=0x20, - ) - ) - + Op.MLOAD(offset=0x520) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE365736B) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.DUP5 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.ADD(0x4, Op.DUP2) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + Op.SWAP1 - + Op.POP - + Op.PUSH2[0x500] + Op.MSTORE + Op.JUMPI( - pc=0x56C, - condition=Op.ISZERO(Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x500), 0x0))), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), Op.MUL(0x20, Op.MLOAD(offset=0x4E0)) - ), - value=Op.MLOAD(offset=0x60), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), - Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x4E0), 0x1)), + pc=0x6DF, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, ), - value=Op.MLOAD(offset=0x500), ) - + Op.MSTORE(offset=0x4E0, value=Op.ADD(Op.MLOAD(offset=0x4E0), 0x2)) - + Op.JUMPDEST - + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) - + Op.JUMP(pc=0x4CE) + + Op.INVALID + Op.JUMPDEST - + Op.JUMP(pc=0x6D7) + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + + Op.DUP1 + + Op.JUMPI( + pc=0x706, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + Op.JUMPDEST - + Op.MSTORE(offset=0x260, value=Op.ORIGIN) - + Op.MUL(0x2, Op.MLOAD(offset=0x360)) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x3C0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x3C0) + Op.SWAP1 + Op.POP - + Op.PUSH2[0x3C0] - + Op.MSTORE - + Op.MLOAD(offset=0x360) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH2[0x420] - + Op.MSTORE + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMPI( + pc=0x752, + condition=Op.ISZERO( + Op.EQ( + Op.MLOAD( + offset=Op.ADD( + Op.DUP5, Op.MUL(0x20, Op.MLOAD(offset=0x100)) + ) + ), + 0x0, + ) + ), + ) + + Op.MSTORE(offset=0x3E0, value=0x0) + + Op.RETURN(offset=0x3E0, size=0x20) + + Op.JUMP(pc=0x75F) + + Op.JUMPDEST + + Op.MSTORE(offset=0x400, value=0x1) + + Op.RETURN(offset=0x400, size=0x20) + + Op.JUMPDEST + + Op.POP * 4 + + Op.JUMPDEST + + Op.JUMPI(pc=0xA66, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x384CA8DD))) + + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) + Op.PUSH1[0x1C] - + Op.PUSH1[0x24] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7733,8 +7138,10 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC3387858) - + Op.MLOAD(offset=0x360) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.ADD(Op.MLOAD(offset=0x100), 0x2) + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 @@ -7749,7 +7156,7 @@ def test_block504980( address=Op.MLOAD(offset=0x20), value=0x0, args_offset=Op.DUP6, - args_size=0x4, + args_size=0x44, ret_offset=Op.DUP2, ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), ) @@ -7761,26 +7168,6 @@ def test_block504980( + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH2[0x420] - + Op.MSTORE - + Op.MSTORE(offset=0x4C0, value=0x0) - + Op.MSTORE(offset=0x4E0, value=0x0) - + Op.JUMPDEST - + Op.JUMPI( - pc=0x6D6, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x4C0), Op.MLOAD(offset=0x360)) - ), - ) - + Op.MSTORE( - offset=0x60, - value=Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x420), - Op.MUL(0x20, Op.MLOAD(offset=0x4C0)), - ) - ), - ) + Op.PUSH1[0x1C] + Op.PUSH1[0x64] + Op.MSIZE @@ -7791,80 +7178,38 @@ def test_block504980( + Op.SWAP1 + Op.MSTORE + Op.ADD - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x74AF23EC) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0x260)) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xFA9832D1) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.MLOAD(offset=0x100) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + Op.POP( Op.CALL( gas=Op.SUB(Op.GAS, 0x2D), - address=Op.ADDRESS, + address=Op.MLOAD(offset=0x20), value=0x0, - args_offset=Op.DUP4, + args_offset=Op.DUP6, args_size=0x44, - ret_offset=0x5C0, - ret_size=0x20, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), ) ) - + Op.MLOAD(offset=0x5C0) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.PUSH2[0x500] - + Op.MSTORE - + Op.JUMPI( - pc=0x6C6, - condition=Op.ISZERO(Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x500), 0x0))), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), Op.MUL(0x20, Op.MLOAD(offset=0x4E0)) - ), - value=Op.MLOAD(offset=0x60), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), - Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x4E0), 0x1)), - ), - value=Op.MLOAD(offset=0x500), - ) - + Op.MSTORE(offset=0x4E0, value=Op.ADD(Op.MLOAD(offset=0x4E0), 0x2)) - + Op.JUMPDEST - + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) - + Op.JUMP(pc=0x628) - + Op.JUMPDEST * 2 - + Op.MLOAD(offset=0x3C0) - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP - + Op.JUMPDEST - + Op.JUMPI(pc=0x735, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x80B5E7BD))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.PUSH1[0x60] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=0x600, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x600, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x786, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x156F1C32))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x640, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x80] * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x84] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7872,18 +7217,13 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x640)) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x660, value=Op.SLOAD(key=Op.SHA3)) - + Op.RETURN(offset=0x660, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0x878, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xB3A24FC0))) - + Op.CALLDATASIZE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAAD7D6E3) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.PUSH1[0x60] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -7891,121 +7231,130 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE( - offset=0x6C0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), - ) - + Op.MSTORE(offset=0x6E0, value=Op.CALLDATALOAD(offset=0x24)) - + Op.POP - + Op.ADD(Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x6C0), 0x20)), 0x2) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x5B180229) + + Op.DUP4 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x64), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xC8), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.DUP5 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x84), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xE8), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x100)) + + Op.ADD(0x4, Op.DUP2) + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + Op.SWAP1 - + Op.POP - + Op.PUSH2[0x700] + Op.MSTORE - + Op.MSTORE(offset=Op.MLOAD(offset=0x700), value=Op.ORIGIN) - + Op.MSTORE( - offset=Op.ADD(Op.MLOAD(offset=0x700), 0x20), - value=Op.MLOAD(offset=0x6E0), + + Op.JUMPI( + pc=0x901, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, + ), ) - + Op.MSTORE(offset=0x4C0, value=0x2) + + Op.INVALID + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0xC8)) + + Op.DUP1 + Op.JUMPI( - pc=0x838, - condition=Op.ISZERO( - Op.SLT( - Op.MLOAD(offset=0x4C0), - Op.ADD( - Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x6C0), 0x20)), - 0x2, - ), - ) + pc=0x927, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x64)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, ), ) - + Op.MSTORE( - offset=Op.ADD( - Op.MLOAD(offset=0x700), Op.MUL(0x20, Op.MLOAD(offset=0x4C0)) - ), - value=Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x6C0), - Op.MUL(0x20, Op.SUB(Op.MLOAD(offset=0x4C0), 0x2)), - ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0xE8)) + + Op.DUP1 + + Op.JUMPI( + pc=0x94E, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x84)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, ), ) - + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) - + Op.JUMP(pc=0x7F6) + + Op.INVALID + Op.JUMPDEST - + Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x700), 0x20))) - + Op.PUSH1[0x20] - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + Op.POP( Op.CALL( - gas=Op.ADD(0x48, Op.DUP8), - address=0x2, + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), value=0x0, - args_offset=Op.MLOAD(offset=0x700), - args_size=Op.DUP4, - ret_offset=Op.DUP2, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x440, ret_size=0x20, ) ) - + Op.MLOAD(offset=Op.DUP1) + + Op.MLOAD(offset=0x440) + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.PUSH2[0x760] - + Op.MSTORE - + Op.MSTORE(offset=0x7C0, value=Op.MLOAD(offset=0x760)) - + Op.RETURN(offset=0x7C0, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0xA1C, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xE346F5FC))) - + Op.MSTORE(offset=0x7E0, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x800, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x4C0, value=0x0) - + Op.JUMPDEST - + Op.PUSH1[0x60] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x7E0)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.JUMPI( - pc=0x9E6, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=0x4C0), Op.SLOAD(key=Op.SHA3)) - ), + + Op.ADD(Op.DUP3, 0x44) + + Op.MSTORE + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x64, + ret_offset=0x460, + ret_size=0x20, + ) ) - + Op.PUSH1[0xA0] * 2 + + Op.MLOAD(offset=0x460) + + Op.SWAP1 + + Op.POP * 2 + + Op.PUSH1[0x60] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8013,17 +7362,19 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x7E0)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x840, value=Op.SLOAD(key=Op.SHA3)) - + Op.MLOAD(offset=0x840) - + Op.PUSH1[0xA0] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x222A8663) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.DUP3 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8031,34 +7382,76 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) + + Op.JUMPI( + pc=0xA07, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + Op.DUP1 + + Op.JUMPI( + pc=0xA2E, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x480, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x480) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x7E0)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.PUSH1[0xA0] * 2 + + Op.SWAP1 + + Op.POP * 2 + + Op.MSTORE(offset=0x4A0, value=0x1) + + Op.RETURN(offset=0x4A0, size=0x20) + + Op.POP * 2 + + Op.JUMPDEST + + Op.JUMPI(pc=0xD4B, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xD5DC5AF1))) + + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8066,18 +7459,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x4C0)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MLOAD(offset=0x4C0) - + Op.PUSH1[0x80] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.ADD(Op.MLOAD(offset=0x100), 0x2) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8085,42 +7472,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x840)) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x4C0, value=Op.ADD(Op.MLOAD(offset=0x4C0), 0x1)) - + Op.JUMP(pc=0x899) - + Op.JUMPDEST - + Op.MLOAD(offset=0x4C0) - + Op.PUSH1[0x60] * 2 - + Op.MSIZE - + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x800)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0x920, value=0x1) - + Op.RETURN(offset=0x920, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0xB54, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3FB57036))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x940, value=Op.CALLDATALOAD(offset=0x24)) - + Op.PUSH1[0x60] * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8128,15 +7499,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.MSTORE(offset=0x960, value=Op.SLOAD(key=Op.SHA3)) - + Op.MLOAD(offset=0x960) - + Op.PUSH1[0x80] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x2C5A40D5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.MLOAD(offset=0x140) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8144,36 +7512,27 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x2) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x940)) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0x0] - + Op.PUSH1[0xA0] * 2 - + Op.MSIZE + Op.SWAP1 - + Op.MSIZE - + Op.ADD - + Op.PUSH1[0x0] - + Op.SWAP1 - + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x960)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MLOAD(offset=0x940) - + Op.PUSH1[0xA0] * 2 + + Op.PUSH1[0x80] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x1AC] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8181,18 +7540,27 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x960)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.PUSH1[0x1] - + Op.PUSH1[0x60] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xF4CA7DC4) + + Op.DUP4 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x84), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.DUP3 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x128), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.MLOAD(offset=0x120)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.MLOAD(offset=0x100)) + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8200,15 +7568,66 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) + + Op.JUMPI( + pc=0xBE7, + condition=Op.CALL( + gas=0x1F, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x84, + ret_offset=Op.DUP2, + ret_size=0x84, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x84) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + Op.DUP1 - + Op.SWAP1 + + Op.JUMPI( + pc=0xC0E, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x84)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.ADD - + Op.PUSH1[0x60] * 2 + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x128)) + + Op.DUP1 + + Op.JUMPI( + pc=0xC36, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.MLOAD(offset=0x140) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8216,23 +7635,35 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x1) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0xA40, value=0x1) - + Op.RETURN(offset=0xA40, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0xBEB, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x12709A33))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0xA60, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0xA60) - + Op.PUSH1[0xA0] * 2 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP7, + args_size=Op.DUP5, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x60] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8240,17 +7671,19 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SLOAD(key=Op.SHA3) + Op.ADD - + Op.PUSH1[0xA0] * 2 + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xB39E1FAA) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.DUP3 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8258,25 +7691,76 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) + + Op.JUMPI( + pc=0xCEC, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + Op.DUP1 + + Op.JUMPI( + pc=0xD13, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, + ), + ) + + Op.INVALID + + Op.JUMPDEST + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x4C0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x4C0) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0xAC0, value=0x1) - + Op.RETURN(offset=0xAC0, size=0x20) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP * 2 + + Op.MSTORE(offset=0x4E0, value=0x1) + + Op.RETURN(offset=0x4E0, size=0x20) + + Op.POP * 2 + Op.JUMPDEST - + Op.JUMPI(pc=0xC82, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3229CF6E))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0xA60, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0xA60) - + Op.PUSH1[0xA0] * 2 + + Op.JUMPI(pc=0x114C, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x939AA8C))) + + Op.MSTORE(offset=0xC0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.MSTORE(offset=0xE0, value=Op.CALLDATALOAD(offset=0x24)) + + Op.MSTORE(offset=0x100, value=Op.CALLDATALOAD(offset=0x44)) + + Op.MSTORE(offset=0x120, value=Op.CALLDATALOAD(offset=0x64)) + + Op.MSTORE(offset=0x140, value=Op.CALLDATALOAD(offset=0x84)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8284,17 +7768,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SLOAD(key=Op.SHA3) - + Op.SUB - + Op.PUSH1[0xA0] * 2 + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.ADD(Op.MLOAD(offset=0x100), 0x2) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8302,25 +7781,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0xB20, value=0x1) - + Op.RETURN(offset=0xB20, size=0x20) - + Op.JUMPDEST - + Op.JUMPI(pc=0xCE5, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA75F5C6A))) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0xA60, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MLOAD(offset=0xA60) - + Op.PUSH1[0xA0] * 2 + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8328,48 +7808,12 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=0x0) - + Op.MSTORE(offset=Op.ADD(0x20, Op.DUP2), value=Op.MLOAD(offset=0x60)) - + Op.MSTORE(offset=Op.ADD(0x40, Op.DUP2), value=0x0) - + Op.MSTORE(offset=Op.ADD(0x60, Op.DUP2), value=Op.MLOAD(offset=0x80)) - + Op.MSTORE(offset=Op.ADD(0x80, Op.DUP2), value=0x0) - + Op.DUP1 - + Op.SWAP1 - + Op.POP - + Op.SHA3 - + Op.SSTORE - + Op.MSTORE(offset=0xB60, value=0x1) - + Op.RETURN(offset=0xB60, size=0x20) - + Op.JUMPDEST - + Op.POP, - storage={ - 0xF299DBBE3A7A5D949FE794E9A47B3106699C8110FF986EB84921C183E69E7F0: 0x2F0000000000000000, # noqa: E501 - 0x1EDCD36F61CAE5DC6414157DFBADF9F11CA013AC763E27F8AF55FEAA8A239C89: 1, # noqa: E501 - 0x689082D076EC3C02CBE4B99F6D9833E3C4A161072FD42FB7649EEE5189A67CCC: 0x63524E3FE4791AEFCE1E932BBFB3FDF375BFAD89, # noqa: E501 - 0xAF1D6676BE3AB502A59D91F6F5C49BAFFC15B2CFC65A41C4D96857C0F535ADBA: 0x1D60000000000000000, # noqa: E501 - 0xDF1A770F69D93D1719292F384FDB4DA22C0E88AEF2BA462BFF16674BC7848730: 0x1C11AA45C792E202E9FFDC2F12F99D0D209BEF70, # noqa: E501 - 0xEC5E7F54FA5E516E616B04F9D5A0EE433A80E09ED47D7E5269AFD76C05FF251E: 2, # noqa: E501 - }, - nonce=0, - address=Address(0xE509E3A93BEB1EBA72F8CB8D25F93A85E2D54AFB), # noqa: E501 - ) - # Source: raw - # 0x600061067f537c010000000000000000000000000000000000000000000000000000000060003504632f300bee8114156100ac576004356040526024356060526044356080526002608051018080602002602001599059016000905281815260208101905090506801000000000000000081526060516080516020028201526001604051036001608051016020028201528060206040820352602060208203510260400160408203f35050505b63a647a5b98114156102c85736599059016000905236600482376004356020820101610100526024356020820101610160526044356020820101610180526064356101a05260843560805250602061010051035180806020026020015990590160009052818152602081019050905060005b6101a0518112156101d557600060005b608051811215610162578060200261010051015181608051850201602002610160510151028201915060018101905061012e565b50680100000000000000008105905060005b6080518112156101c857700100000000000000000000000000000000836020026101805101518260805186020160200261016051015184020205816020028501510381602002850152600181019050610174565b505060018101905061011e565b50600060005b60805181121561020357806020028301518160200284015102820191506001810190506101db565b5068010000000000000000810590506002810560005b600b81121561024257600282680100000000000000008502058301059150600181019050610219565b5060005b60805181121561027657816801000000000000000082602002860151020581602002850152600181019050610246565b5050506001608051602002610100510151036080516020028201526001608051016020026101005101516001608051016020028201528060206040820352602060208203510260400160408203f35050505b635b18022981141561037957365990590160009052366004823760043560208201016103005260243560208201016103205260443560805250600060005b60805181121561033f57680100000000000000008160200261032051015182602002610300510151020582019150600181019050610306565b6000610320515114151561036657610320515168010000000000000000830205915061036b565b600091505b81610380526020610380f350505b63f4ca7dc481141561057157365990590160009052366004823760043560208201016103a05260243560208201016103c0526044356101a0526064356080525060206103c051035160026080510a806020026020015990590160009052818152602081019050905060005b60805181121561044d5760005b6080518112156104415768010000000000000000816020026103a0510151836020026103a051015102058160805184020160200284015101816080518402016020028401526001810190506103f1565b506001810190506103e4565b81905090508180602002602001599059016000905281815260208101905090506080516101a05102806020026020015990590160009052818152602081019050905060005b6101a05181121561051e5760005b6080518112156105125760005b608051811215610506576801000000000000000082608051830201602002870151826080518602016020026103c051015102058260805185020160200285015101826080518502016020028501526001810190506104ad565b506001810190506104a0565b50600181019050610492565b819050905060005b848112156105525780602002820151816020026103c05101510381602002840152600181019050610526565b508160206040820352602060208203510260400160408203f350505050505b63232b273481141561069d57365990590160009052366004823760043560208201016106205260243560208201016102805260443560208201016103c052606435610640526084356101a05260a435608052506000610280515112156106025760005b6080518112156106005780602002610280510151600003816020026102805101526001810190506105d4565b505b60005b6101a05181121561067f5760005b60805181121561067357680100000000000000006801000000000000000082602002610280510151610640510205826080518502016020026103c05101510205826020026106205101510182602002610620510152600181019050610613565b50600181019050610605565b6106205160206040820352602060208203510260400160408203f350505b50 # noqa: E501 - contract_11 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x67F, value=0x0) - + Op.DIV( - Op.CALLDATALOAD(offset=0x0), - 0x100000000000000000000000000000000000000000000000000000000, - ) - + Op.JUMPI( - pc=Op.PUSH2[0xAC], condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2F300BEE)) - ) - + Op.MSTORE(offset=0x40, value=Op.CALLDATALOAD(offset=0x4)) - + Op.MSTORE(offset=0x60, value=Op.CALLDATALOAD(offset=0x24)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x44)) - + Op.ADD(Op.MLOAD(offset=0x80), 0x2) - + Op.DUP1 - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7DC12195) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.MLOAD(offset=0x140) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8377,35 +7821,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.MSTORE(offset=Op.DUP2, value=0x10000000000000000) - + Op.MSTORE( - offset=Op.ADD(Op.DUP3, Op.MUL(0x20, Op.MLOAD(offset=0x80))), - value=Op.MLOAD(offset=0x60), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.DUP3, Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - ), - value=Op.SUB(Op.MLOAD(offset=0x40), 0x1), - ) - + Op.DUP1 - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), - ) - + Op.POP * 3 - + Op.JUMPDEST - + Op.JUMPI(pc=0x2C8, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xA647A5B9))) - + Op.CALLDATASIZE + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8413,27 +7848,26 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE( - offset=0x100, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), - ) - + Op.MSTORE( - offset=0x160, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), - ) - + Op.MSTORE( - offset=0x180, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x586B5BE0) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x500, + ret_size=0x20, + ) ) - + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x84)) + + Op.MLOAD(offset=0x500) + + Op.SWAP1 + Op.POP - + Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x100), 0x20)) - + Op.DUP1 - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8441,206 +7875,164 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xEB8AF5AA) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.MLOAD(offset=0x120) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x1D5, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x1A0))), - ) - + Op.PUSH1[0x0] * 2 - + Op.JUMPDEST - + Op.JUMPI( - pc=0x162, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.ADD( - Op.DUP3, - Op.MUL( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x160), - Op.MUL( - 0x20, - Op.ADD( - Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), Op.DUP2 - ), - ), - ) - ), - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x100), Op.MUL(0x20, Op.DUP1) - ) - ), - ), + + Op.SWAP1 + + Op.MSTORE + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) ) - + Op.SWAP2 - + Op.POP - + Op.ADD(Op.DUP2, 0x1) + + Op.ADD(Op.DUP2, 0x40) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x12E) - + Op.JUMPDEST + + Op.SWAP1 + Op.POP - + Op.SDIV(Op.DUP2, 0x10000000000000000) + Op.SWAP1 + Op.POP + + Op.PUSH1[0xC0] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x26C] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x232B2734) + + Op.DUP3 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x4), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xC4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x188), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.DUP6 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x24), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xE4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x1A8), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.DUP5 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x104), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x1C8), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.MLOAD(offset=0x120)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0xA4), value=Op.MLOAD(offset=0x100)) + + Op.ADD(0x4, Op.DUP2) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + Op.JUMPI( - pc=0x1C8, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP6, Op.MUL(0x20, Op.DUP2)), - value=Op.SUB( - Op.MLOAD(offset=Op.ADD(Op.DUP6, Op.MUL(0x20, Op.DUP2))), - Op.SDIV( - Op.MUL( - Op.MUL( - Op.DUP5, - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x160), - Op.MUL( - 0x20, - Op.ADD( - Op.MUL( - Op.DUP7, Op.MLOAD(offset=0x80) - ), - Op.DUP3, - ), - ), - ) - ), - ), - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x180), Op.MUL(0x20, Op.DUP4) - ) - ), - ), - 0x100000000000000000000000000000000, - ), + pc=0xF96, + condition=Op.CALL( + gas=0x25, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0xC4, + ret_offset=Op.DUP2, + ret_size=0xC4, ), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x174) - + Op.JUMPDEST - + Op.POP * 2 - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x11E) + + Op.INVALID + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0xC4) + + Op.SWAP3 + Op.POP - + Op.PUSH1[0x0] * 2 - + Op.JUMPDEST + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x188)) + + Op.DUP1 + Op.JUMPI( - pc=0x203, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.ADD( - Op.DUP3, - Op.MUL( - Op.MLOAD(offset=Op.ADD(Op.DUP5, Op.MUL(0x20, Op.DUP2))), - Op.MLOAD(offset=Op.ADD(Op.DUP4, Op.MUL(0x20, Op.DUP1))), + pc=0xFBD, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xC4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, ), ) - + Op.SWAP2 - + Op.POP - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x1DB) + + Op.INVALID + Op.JUMPDEST + Op.POP - + Op.SDIV(Op.DUP2, 0x10000000000000000) - + Op.SWAP1 - + Op.POP - + Op.SDIV(Op.DUP2, 0x2) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x242, condition=Op.ISZERO(Op.SLT(Op.DUP2, 0xB))) - + Op.SDIV( - Op.ADD( - Op.DUP4, Op.SDIV(Op.MUL(Op.DUP6, 0x10000000000000000), Op.DUP3) - ), - 0x2, - ) - + Op.SWAP2 - + Op.POP - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x219) - + Op.JUMPDEST - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x1A8)) + + Op.DUP1 + Op.JUMPI( - pc=0x276, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.DUP6, Op.MUL(0x20, Op.DUP2)), - value=Op.SDIV( - Op.MUL( - Op.MLOAD(offset=Op.ADD(Op.DUP7, Op.MUL(0x20, Op.DUP3))), - 0x10000000000000000, - ), - Op.DUP2, + pc=0xFE5, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xE4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, ), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x246) + + Op.INVALID + Op.JUMPDEST - + Op.POP * 3 - + Op.MSTORE( - offset=Op.ADD(Op.DUP3, Op.MUL(0x20, Op.MLOAD(offset=0x80))), - value=Op.SUB( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x100), - Op.MUL(0x20, Op.MLOAD(offset=0x80)), - ) - ), - 0x1, - ), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.DUP3, Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - ), - value=Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x100), - Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x80), 0x1)), - ) - ), - ) + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x1C8)) + Op.DUP1 - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) + + Op.JUMPI( + pc=0x100E, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0x104)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, ), ) - + Op.POP * 3 + + Op.INVALID + Op.JUMPDEST - + Op.JUMPI(pc=0x379, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5B180229))) - + Op.CALLDATASIZE + + Op.POP + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.MLOAD(offset=0x120) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8648,74 +8040,35 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE( - offset=0x300, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), - ) - + Op.MSTORE( - offset=0x320, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP7, + args_size=Op.DUP5, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) ) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x44)) + + Op.ADD(Op.DUP2, 0x40) + + Op.SWAP1 + Op.POP - + Op.PUSH1[0x0] * 2 - + Op.JUMPDEST - + Op.JUMPI( - pc=0x33F, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.ADD( - Op.DUP3, - Op.SDIV( - Op.MUL( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x300), Op.MUL(0x20, Op.DUP3) - ) - ), - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x320), Op.MUL(0x20, Op.DUP2) - ) - ), - ), - 0x10000000000000000, - ), - ) - + Op.SWAP2 + + Op.SWAP1 + Op.POP - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x306) - + Op.JUMPDEST - + Op.JUMPI( - pc=0x366, - condition=Op.ISZERO( - Op.ISZERO(Op.EQ(Op.MLOAD(offset=Op.MLOAD(offset=0x320)), 0x0)) - ), - ) - + Op.SDIV( - Op.MUL(Op.DUP4, 0x10000000000000000), - Op.MLOAD(offset=Op.MLOAD(offset=0x320)), - ) - + Op.SWAP2 + + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x36B) - + Op.JUMPDEST - + Op.PUSH1[0x0] - + Op.SWAP2 + + Op.SWAP1 + Op.POP - + Op.JUMPDEST - + Op.MSTORE(offset=0x380, value=Op.DUP2) - + Op.RETURN(offset=0x380, size=0x20) - + Op.POP * 2 - + Op.JUMPDEST - + Op.JUMPI(pc=0x571, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0xF4CA7DC4))) - + Op.CALLDATASIZE + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x60] + + Op.PUSH1[0x1C] + + Op.PUSH2[0x14C] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8723,23 +8076,19 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE( - offset=0x3A0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), - ) - + Op.MSTORE( - offset=0x3C0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), - ) - + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x44)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0x64)) - + Op.POP - + Op.MLOAD(offset=Op.SUB(Op.MLOAD(offset=0x3C0), 0x20)) - + Op.EXP(Op.MLOAD(offset=0x80), 0x2) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x1112B27) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0xC0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.MLOAD(offset=0xE0)) + + Op.DUP3 + + Op.ADD(0x20, Op.MUL(0x20, Op.MLOAD(offset=Op.SUB(Op.DUP2, 0x20)))) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x44), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0xA4), value=Op.SUB(Op.DUP3, 0x20)) + + Op.MSTORE(offset=Op.ADD(Op.DUP5, 0x108), value=Op.DUP1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 3 + + Op.ADD(0x4, Op.DUP2) + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8747,79 +8096,136 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP - + Op.SWAP1 - + Op.POP - + Op.PUSH1[0x0] - + Op.JUMPDEST + Op.JUMPI( - pc=0x44D, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + pc=0x10C4, + condition=Op.CALL( + gas=0x1C, + address=0x4, + value=0x0, + args_offset=Op.DUP5, + args_size=0x64, + ret_offset=Op.DUP2, + ret_size=0x64, + ), ) - + Op.PUSH1[0x0] + + Op.INVALID + Op.JUMPDEST + + Op.ADD(Op.DUP2, 0x64) + + Op.SWAP3 + + Op.POP + + Op.MLOAD(offset=Op.ADD(Op.DUP3, 0x108)) + + Op.DUP1 + Op.JUMPI( - pc=0x441, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.DUP5, - Op.MUL( - 0x20, - Op.ADD(Op.MUL(Op.DUP5, Op.MLOAD(offset=0x80)), Op.DUP2), - ), - ), - value=Op.ADD( - Op.MLOAD( - offset=Op.ADD( - Op.DUP5, - Op.MUL( - 0x20, - Op.ADD( - Op.MUL(Op.DUP5, Op.MLOAD(offset=0x80)), Op.DUP2 - ), - ), - ) - ), - Op.SDIV( - Op.MUL( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x3A0), Op.MUL(0x20, Op.DUP4) - ) - ), - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x3A0), Op.MUL(0x20, Op.DUP2) - ) - ), - ), - 0x10000000000000000, - ), + pc=0x10EB, + condition=Op.CALL( + gas=Op.ADD(0x12, Op.SDIV(Op.DUP8, 0xA)), + address=0x4, + value=0x0, + args_offset=Op.MLOAD(offset=Op.ADD(Op.DUP8, 0xA4)), + args_size=Op.DUP3, + ret_offset=Op.DUP6, + ret_size=Op.DUP1, ), ) - + Op.ADD(Op.DUP2, 0x1) - + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x3F1) + + Op.INVALID + Op.JUMPDEST + Op.POP - + Op.ADD(Op.DUP2, 0x1) + + Op.ADD(Op.DUP5, Op.DUP1) + + Op.SWAP4 + + Op.POP * 2 + + Op.SUB(Op.DUP4, Op.DUP1) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x20), + value=0x0, + args_offset=Op.DUP5, + args_size=Op.DUP3, + ret_offset=0x580, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x580) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x3E4) - + Op.JUMPDEST - + Op.DUP2 + Op.SWAP1 + Op.POP + Op.SWAP1 + Op.POP - + Op.DUP2 - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMPI( + pc=0x113A, + condition=Op.ISZERO( + Op.EQ( + Op.MLOAD( + offset=Op.ADD( + Op.DUP6, + Op.MUL(0x20, Op.ADD(Op.MLOAD(offset=0x100), 0x1)), + ) + ), + 0x0, + ) + ), + ) + + Op.MSTORE(offset=0x5A0, value=0x0) + + Op.RETURN(offset=0x5A0, size=0x20) + + Op.JUMP(pc=0x1147) + + Op.JUMPDEST + + Op.MSTORE(offset=0x5C0, value=0x1) + + Op.RETURN(offset=0x5C0, size=0x20) + + Op.JUMPDEST + + Op.POP * 4 + + Op.JUMPDEST + + Op.POP, + nonce=0, + address=Address(0x9761FECF88590592CF05CE545504D376D1693AB3), # noqa: E501 + ) + # Source: raw + # 0x600061075f537c010000000000000000000000000000000000000000000000000000000060003504731e147037f0a63df228fe6e7aef730f1ea31c8ce3602052730ea65418d7bf32680f55572c943a94b59080499860405273e509e3a93beb1eba72f8cb8d25f93a85e2d54afb60605273c9ae5868651bf7b7db6e360217db49ce4e69c07e60805273142a6927cf0060133187ba8a8e74d641438f0c1c60a05273b163e767e4c1ba5ae88b2ee7594f3a3fec2bb09660c05273ba7b277319128ef4c22635534d0f61dffdaa13ab60e052739761fecf88590592cf05ce545504d376d1693ab36101005273f70bbc50f1468cecae0761ef09386a87c1c696ea6101205273a89d22f049aaa5bbfb5f1a1939fff3ae7a26ae746101405273174827f7e53e8ce13b047adcac0eb3f2cb0c3285610160526336a560bd811415610a88576004356101a052601c60445990590160009052016327138bfb601c8203526101a051600482015260206101e0602483600060a051602d5a03f1506101e05190501515610195576001600003610200526020610200f35b601c6044599059016000905201637a66d7ca601c8203526101a051600482015260206102206024836000608051602d5a03f150610220519050601c606459905901600090520163cc1c944e601c8203526101a05160048201528160248201526020610260604483600061028051602d5a03f150610260519050601c60445990590160009052016380b5e7bd601c8203526101a051600482015260206102a06024836000606051602d5a03f1506102a0519050808202601c60445990590160009052016318633576601c8203526101a051600482015260206103006024836000608051602d5a03f150610300519050600981141561036d57601c60c459905901600090520163ac44d71e601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061036060a483600061016051602d5a03f15061036051905050601c6064599059016000905201637265802d601c8203526101a05160048201526000602482015260206103806044836000608051602d5a03f15061038051905050601c604459905901600090520163c5476efe601c8203526101a051600482015260206103a06024836000608051602d5a03f1506103a051905050600185016103c05260206103c0f3610a3a565b60008114156103cd57601c60c459905901600090520163ef72638a601c8203526101a051600482015285602482015284604482015283606482015282608482015260206103e060a483600060c051602d5a03f1506103e051905050610a39565b600181141561042d57601c60c459905901600090520163a63e976c601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061040060a483600060e051602d5a03f15061040051905050610a38565b600281141561048d57601c60c459905901600090520163533ea0ed601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061042060a483600060e051602d5a03f15061042051905050610a37565b600381141561085057601c606459905901600090520163e05dcb56601c8203526101a0516004820152856024820152600285016040816020020159905901600090528160200260400181604485600061028051602d5a03f15060408101905090509050601c6044599059016000905201633d905045601c8203526101a051600482015260206104806024836000608051602d5a03f150610480519050600481141561063357601c60c4599059016000905201630939aa8c601c8203526101a051600482015287602482015286604482015285606482015284608482015260206104e060a483600061010051602d5a03f1506104e05190506104c052601c606459905901600090520163c286273a601c8203526101a05160048201526000602482015260206105006044836000608051602d5a03f1506105005190505060016104c05114156105e55782610520526020610520f361062e565b601c604459905901600090520163aac2ffb5601c8203526101a051600482015260206105406024836000608051602d5a03f1506105405190505060018301610560526020610560f35b610804565b600081141561069457601c60c459905901600090520163546fdeb3601c8203526101a0516004820152876024820152866044820152856064820152846084820152602061058060a483600061010051602d5a03f15061058051905050610803565b6001811415610742576000601c60c459905901600090520163de9080c8601c8203526101a051600482015288602482015287604482015286606482015285608482015260206105a060a483600061010051602d5a03f1506105a0519050141561073257601c6044599059016000905201631cda01ef601c8203526101a051600482015260206105c06024836000608051602d5a03f1506105c0519050505b826105e05260206105e0f3610802565b60028114156107a357601c60c459905901600090520163384ca8dd601c8203526101a0516004820152876024820152866044820152856064820152846084820152602061060060a483600061010051602d5a03f15061060051905050610801565b600381141561080057601c60c459905901600090520163d5dc5af1601c8203526101a0516004820152876024820152866044820152856064820152846084820152602061062060a483600061010051602d5a03f150610620519050505b5b5b5b5b601c6044599059016000905201631cda01ef601c8203526101a051600482015260206106406024836000608051602d5a03f1506106405190505082610660526020610660f35050610a36565b60048114156108b157601c60c459905901600090520163f6559853601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061068060a483600061012051602d5a03f15061068051905050610a35565b600581141561091257601c60c459905901600090520163d8e5473d601c8203526101a051600482015285602482015284604482015283606482015282608482015260206106a060a483600061012051602d5a03f1506106a051905050610a34565b600681141561097357601c60c459905901600090520163090507ea601c8203526101a051600482015285602482015284604482015283606482015282608482015260206106c060a483600061012051602d5a03f1506106c051905050610a33565b60078114156109d457601c60c4599059016000905201635b911842601c8203526101a051600482015285602482015284604482015283606482015282608482015260206106e060a483600061014051602d5a03f1506106e051905050610a32565b6008811415610a3157601c60c459905901600090520163abe22b84601c8203526101a0516004820152856024820152846044820152836064820152826084820152602061070060a483600061014051602d5a03f150610700519050505b5b5b5b5b5b5b5b5b5b601c604459905901600090520163aac2ffb5601c8203526101a051600482015260206107206024836000608051602d5a03f1506107205190505060018101610740526020610740f350505050505b50 # noqa: E501 + contract_8 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x75F, value=0x0) + + Op.DIV( + Op.CALLDATALOAD(offset=0x0), + 0x100000000000000000000000000000000000000000000000000000000, + ) + + Op.MSTORE( + offset=0x20, value=0x1E147037F0A63DF228FE6E7AEF730F1EA31C8CE3 + ) + + Op.MSTORE( + offset=0x40, value=0xEA65418D7BF32680F55572C943A94B590804998 + ) + + Op.MSTORE( + offset=0x60, value=0xE509E3A93BEB1EBA72F8CB8D25F93A85E2D54AFB + ) + + Op.MSTORE( + offset=0x80, value=0xC9AE5868651BF7B7DB6E360217DB49CE4E69C07E + ) + + Op.MSTORE( + offset=0xA0, value=0x142A6927CF0060133187BA8A8E74D641438F0C1C + ) + + Op.MSTORE( + offset=0xC0, value=0xB163E767E4C1BA5AE88B2EE7594F3A3FEC2BB096 + ) + + Op.MSTORE( + offset=0xE0, value=0xBA7B277319128EF4C22635534D0F61DFFDAA13AB + ) + + Op.MSTORE( + offset=0x100, value=0x9761FECF88590592CF05CE545504D376D1693AB3 + ) + + Op.MSTORE( + offset=0x120, value=0xF70BBC50F1468CECAE0761EF09386A87C1C696EA + ) + + Op.MSTORE( + offset=0x140, value=0xA89D22F049AAA5BBFB5F1A1939FFF3AE7A26AE74 + ) + + Op.MSTORE( + offset=0x160, value=0x174827F7E53E8CE13B047ADCAC0EB3F2CB0C3285 + ) + + Op.JUMPI(pc=0xA88, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x36A560BD))) + + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x4)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8827,14 +8233,29 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) - + Op.SWAP1 - + Op.POP + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x27138BFB) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0xA0), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x1E0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x1E0) + Op.SWAP1 + Op.POP - + Op.MUL(Op.MLOAD(offset=0x1A0), Op.MLOAD(offset=0x80)) - + Op.ADD(0x20, Op.MUL(0x20, Op.DUP1)) + + Op.JUMPI(pc=0x195, condition=Op.ISZERO(Op.ISZERO)) + + Op.MSTORE(offset=0x200, value=Op.SUB(0x0, 0x1)) + + Op.RETURN(offset=0x200, size=0x20) + + Op.JUMPDEST + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8842,135 +8263,750 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.MSTORE(offset=Op.DUP2, value=Op.DUP2) - + Op.ADD(Op.DUP2, 0x20) + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7A66D7CA) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x220, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x220) + Op.SWAP1 + Op.POP + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x51E, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x1A0))), + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xCC1C944E) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP2) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x280), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x260, + ret_size=0x20, + ) ) + + Op.MLOAD(offset=0x260) + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x512, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x80B5E7BD) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x60), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x2A0, + ret_size=0x20, + ) ) + + Op.MLOAD(offset=0x2A0) + + Op.SWAP1 + + Op.POP + + Op.MUL(Op.DUP3, Op.DUP1) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x506, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.MSTORE( - offset=Op.ADD( - Op.DUP6, - Op.MUL( - 0x20, - Op.ADD(Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), Op.DUP3), - ), - ), - value=Op.ADD( - Op.MLOAD( - offset=Op.ADD( - Op.DUP6, - Op.MUL( - 0x20, - Op.ADD( - Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), Op.DUP3 - ), - ), - ) - ), - Op.SDIV( - Op.MUL( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), - Op.MUL( - 0x20, - Op.ADD( - Op.MUL(Op.DUP7, Op.MLOAD(offset=0x80)), - Op.DUP3, - ), - ), - ) - ), - Op.MLOAD( - offset=Op.ADD( - Op.DUP8, - Op.MUL( - 0x20, - Op.ADD( - Op.MUL(Op.DUP4, Op.MLOAD(offset=0x80)), - Op.DUP3, - ), - ), - ) - ), - ), - 0x10000000000000000, - ), - ), + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x18633576) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x300, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x300) + + Op.SWAP1 + + Op.POP + + Op.JUMPI(pc=0x36D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x9))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAC44D71E) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x160), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x360, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x360) + + Op.SWAP1 + + Op.POP * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x7265802D) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x380, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x380) + + Op.SWAP1 + + Op.POP * 2 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC5476EFE) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x3A0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x3A0) + + Op.SWAP1 + + Op.POP * 2 + + Op.MSTORE(offset=0x3C0, value=Op.ADD(Op.DUP6, 0x1)) + + Op.RETURN(offset=0x3C0, size=0x20) + + Op.JUMP(pc=0xA3A) + + Op.JUMPDEST + + Op.JUMPI(pc=0x3CD, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x0))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xEF72638A) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0xC0), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x3E0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x3E0) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMP(pc=0xA39) + + Op.JUMPDEST + + Op.JUMPI(pc=0x42D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xA63E976C) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0xE0), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x400, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x400) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMP(pc=0xA38) + + Op.JUMPDEST + + Op.JUMPI(pc=0x48D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x533EA0ED) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0xE0), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x420, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x420) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMP(pc=0xA37) + + Op.JUMPDEST + + Op.JUMPI(pc=0x850, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xE05DCB56) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.ADD(Op.DUP6, 0x2) + + Op.ADD(Op.MUL(0x20, Op.DUP2), 0x40) + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x280), + value=0x0, + args_offset=Op.DUP6, + args_size=0x44, + ret_offset=Op.DUP2, + ret_size=Op.ADD(0x40, Op.MUL(0x20, Op.DUP2)), + ) + ) + + Op.ADD(Op.DUP2, 0x40) + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.SWAP1 + + Op.POP + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x3D905045) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x480, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x480) + + Op.SWAP1 + + Op.POP + + Op.JUMPI(pc=0x633, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x4))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x939AA8C) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x100), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x4E0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x4E0) + + Op.SWAP1 + + Op.POP + + Op.PUSH2[0x4C0] + + Op.MSTORE + + Op.PUSH1[0x1C] + + Op.PUSH1[0x64] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xC286273A) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=0x0) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x44, + ret_offset=0x500, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x500) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMPI( + pc=0x5E5, condition=Op.ISZERO(Op.EQ(Op.MLOAD(offset=0x4C0), 0x1)) + ) + + Op.MSTORE(offset=0x520, value=Op.DUP3) + + Op.RETURN(offset=0x520, size=0x20) + + Op.JUMP(pc=0x62E) + + Op.JUMPDEST + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAAC2FFB5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x540, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x540) + + Op.SWAP1 + + Op.POP * 2 + + Op.MSTORE(offset=0x560, value=Op.ADD(Op.DUP4, 0x1)) + + Op.RETURN(offset=0x560, size=0x20) + + Op.JUMPDEST + + Op.JUMP(pc=0x804) + + Op.JUMPDEST + + Op.JUMPI(pc=0x694, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x0))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x546FDEB3) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x100), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x580, + ret_size=0x20, + ) ) - + Op.ADD(Op.DUP2, 0x1) + + Op.MLOAD(offset=0x580) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x4AD) + + Op.POP * 2 + + Op.JUMP(pc=0x803) + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP2, 0x1) + + Op.JUMPI(pc=0x742, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x1))) + + Op.PUSH1[0x0] + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xDE9080C8) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP9) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP8) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP7) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP6) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x100), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x5A0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x5A0) + Op.SWAP1 + Op.POP - + Op.JUMP(pc=0x4A0) + + Op.JUMPI(pc=0x732, condition=Op.ISZERO(Op.EQ)) + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x1CDA01EF) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x5C0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x5C0) + + Op.SWAP1 + + Op.POP * 2 + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP2, 0x1) + + Op.MSTORE(offset=0x5E0, value=Op.DUP3) + + Op.RETURN(offset=0x5E0, size=0x20) + + Op.JUMP(pc=0x802) + + Op.JUMPDEST + + Op.JUMPI(pc=0x7A3, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x2))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x384CA8DD) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x100), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x600, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x600) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMP(pc=0x801) + + Op.JUMPDEST + + Op.JUMPI(pc=0x800, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x3))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xD5DC5AF1) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP8) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP7) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP5) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x100), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x620, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x620) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMPDEST * 5 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x1CDA01EF) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x640, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x640) + + Op.SWAP1 + + Op.POP * 2 + + Op.MSTORE(offset=0x660, value=Op.DUP3) + + Op.RETURN(offset=0x660, size=0x20) + + Op.POP * 2 + + Op.JUMP(pc=0xA36) + + Op.JUMPDEST + + Op.JUMPI(pc=0x8B1, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x4))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xF6559853) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x120), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x680, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x680) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMP(pc=0xA35) + + Op.JUMPDEST + + Op.JUMPI(pc=0x912, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x5))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xD8E5473D) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x120), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x6A0, + ret_size=0x20, + ) + ) + + Op.MLOAD(offset=0x6A0) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x492) + + Op.POP * 2 + + Op.JUMP(pc=0xA34) + Op.JUMPDEST - + Op.DUP2 - + Op.SWAP1 - + Op.POP + + Op.JUMPI(pc=0x973, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x6))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + Op.SWAP1 - + Op.POP + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI(pc=0x552, condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.DUP5))) - + Op.MSTORE( - offset=Op.ADD(Op.DUP5, Op.MUL(0x20, Op.DUP2)), - value=Op.SUB( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), Op.MUL(0x20, Op.DUP2) - ) - ), - Op.MLOAD(offset=Op.ADD(Op.DUP3, Op.MUL(0x20, Op.DUP1))), - ), - ) - + Op.ADD(Op.DUP2, 0x1) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x526) - + Op.JUMPDEST - + Op.POP - + Op.DUP2 - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x90507EA) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x120), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x6C0, + ret_size=0x20, + ) ) - + Op.POP * 5 + + Op.MLOAD(offset=0x6C0) + + Op.SWAP1 + + Op.POP * 2 + + Op.JUMP(pc=0xA33) + Op.JUMPDEST - + Op.JUMPI(pc=0x69D, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x232B2734))) - + Op.CALLDATASIZE + + Op.JUMPI(pc=0x9D4, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x7))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + Op.MSIZE + Op.SWAP1 + Op.MSIZE @@ -8978,130 +9014,94 @@ def test_block504980( + Op.PUSH1[0x0] + Op.SWAP1 + Op.MSTORE - + Op.CALLDATACOPY( - dest_offset=Op.DUP3, offset=0x4, size=Op.CALLDATASIZE - ) - + Op.MSTORE( - offset=0x620, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x4)), - ) - + Op.MSTORE( - offset=0x280, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x24)), - ) - + Op.MSTORE( - offset=0x3C0, - value=Op.ADD(Op.ADD(Op.DUP3, 0x20), Op.CALLDATALOAD(offset=0x44)), - ) - + Op.MSTORE(offset=0x640, value=Op.CALLDATALOAD(offset=0x64)) - + Op.MSTORE(offset=0x1A0, value=Op.CALLDATALOAD(offset=0x84)) - + Op.MSTORE(offset=0x80, value=Op.CALLDATALOAD(offset=0xA4)) - + Op.POP - + Op.JUMPI( - pc=0x602, - condition=Op.ISZERO( - Op.SLT(Op.MLOAD(offset=Op.MLOAD(offset=0x280)), 0x0) - ), - ) - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x600, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.MLOAD(offset=0x280), Op.MUL(0x20, Op.DUP2)), - value=Op.SUB( - 0x0, - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x280), Op.MUL(0x20, Op.DUP1) - ) - ), - ), + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0x5B911842) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x140), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x6E0, + ret_size=0x20, + ) ) - + Op.ADD(Op.DUP2, 0x1) + + Op.MLOAD(offset=0x6E0) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x5D4) - + Op.JUMPDEST - + Op.POP - + Op.JUMPDEST - + Op.PUSH1[0x0] + + Op.POP * 2 + + Op.JUMP(pc=0xA32) + Op.JUMPDEST - + Op.JUMPI( - pc=0x67F, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x1A0))), - ) + + Op.JUMPI(pc=0xA31, condition=Op.ISZERO(Op.EQ(Op.DUP2, 0x8))) + + Op.PUSH1[0x1C] + + Op.PUSH1[0xC4] + + Op.MSIZE + + Op.SWAP1 + + Op.MSIZE + + Op.ADD + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.JUMPI( - pc=0x673, - condition=Op.ISZERO(Op.SLT(Op.DUP2, Op.MLOAD(offset=0x80))), - ) - + Op.MSTORE( - offset=Op.ADD(Op.MLOAD(offset=0x620), Op.MUL(0x20, Op.DUP3)), - value=Op.ADD( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x620), Op.MUL(0x20, Op.DUP3) - ) - ), - Op.SDIV( - Op.MUL( - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x3C0), - Op.MUL( - 0x20, - Op.ADD( - Op.MUL(Op.DUP6, Op.MLOAD(offset=0x80)), - Op.DUP3, - ), - ), - ) - ), - Op.SDIV( - Op.MUL( - Op.MLOAD(offset=0x640), - Op.MLOAD( - offset=Op.ADD( - Op.MLOAD(offset=0x280), - Op.MUL(0x20, Op.DUP3), - ) - ), - ), - 0x10000000000000000, - ), - ), - 0x10000000000000000, - ), - ), + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xABE22B84) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x24), value=Op.DUP6) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x44), value=Op.DUP5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x64), value=Op.DUP4) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x84), value=Op.DUP3) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x140), + value=0x0, + args_offset=Op.DUP4, + args_size=0xA4, + ret_offset=0x700, + ret_size=0x20, + ) ) - + Op.ADD(Op.DUP2, 0x1) + + Op.MLOAD(offset=0x700) + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x613) - + Op.JUMPDEST - + Op.POP - + Op.ADD(Op.DUP2, 0x1) + + Op.POP * 2 + + Op.JUMPDEST * 10 + + Op.PUSH1[0x1C] + + Op.PUSH1[0x44] + + Op.MSIZE + Op.SWAP1 - + Op.POP - + Op.JUMP(pc=0x605) - + Op.JUMPDEST - + Op.MLOAD(offset=0x620) - + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x40), value=0x20) - + Op.RETURN( - offset=Op.SUB(Op.DUP3, 0x40), - size=Op.ADD( - 0x40, Op.MUL(Op.MLOAD(offset=Op.SUB(Op.DUP3, 0x20)), 0x20) - ), + + Op.MSIZE + + Op.ADD + + Op.PUSH1[0x0] + + Op.SWAP1 + + Op.MSTORE + + Op.ADD + + Op.MSTORE(offset=Op.SUB(Op.DUP3, 0x1C), value=0xAAC2FFB5) + + Op.MSTORE(offset=Op.ADD(Op.DUP3, 0x4), value=Op.MLOAD(offset=0x1A0)) + + Op.POP( + Op.CALL( + gas=Op.SUB(Op.GAS, 0x2D), + address=Op.MLOAD(offset=0x80), + value=0x0, + args_offset=Op.DUP4, + args_size=0x24, + ret_offset=0x720, + ret_size=0x20, + ) ) + + Op.MLOAD(offset=0x720) + + Op.SWAP1 + Op.POP * 2 + + Op.MSTORE(offset=0x740, value=Op.ADD(Op.DUP2, 0x1)) + + Op.RETURN(offset=0x740, size=0x20) + + Op.POP * 5 + Op.JUMPDEST + Op.POP, nonce=0, - address=Address(0xF1562E1C0D0BAA3EA746442BB7F11153FCF5CFDA), # noqa: E501 + address=Address(0xB03F030056DB7D467D778326658BAC0D1B35D8F7), # noqa: E501 ) tx = Transaction( @@ -9123,16 +9123,16 @@ def test_block504980( 0x65D5EFDFCC0FBA693DC9E467F633097FFDC97401901463AD0E28855486D1EDF: 0xB9D69098A6ACFE0C6411BCAAF430F78D363A9ADC32B78BC2E15CCD6E883E9784, # noqa: E501 0x12643FF300762717D27EFB567B82C65560D7B43249D908504E5510863AB82AAC: 0x154CF60E137C594516A065149610B6A3989396A42581D5FD8919E711C55DA225, # noqa: E501 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D7: 5, # noqa: E501 - 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D8: 1, # noqa: E501 + 0x1489023D18C5D10427C4AA8DC726E840EB5AE7F604A8E9243C61634FB009E4D8: contract_1, # noqa: E501 0x19EFB13D6576359514ACE5211988A8D51379FA88CCD2B886B409F842B13D7932: 0xC849CC595B452D11C206D2EB8CDFA06DE211E3FF19EE0E0276DC857C05D4FE, # noqa: E501 0x1B37E91BF8580C7C6BCF8CDFF25C7ED78180124A94AF6F30C40D476A3D079AD6: 0xABA4CD295118A482A0A62579E35E4BA5BDD76146CC9E4D96172FCE8BE8977AB4, # noqa: E501 0x2BF9FD8FACDD6FD9C84657F5AD7381A5AECF670CDA68CB3C5829B6532C865506: 0x53098A1D111586DBCC0D051846284F5803C63C313E7F7E6D84430435D11D4C50, # noqa: E501 0x3111BFD25728C0ADFAD0F8C1AD79CB1B91167267DECA98DE88F156ED25CAEEDC: 0xAD393086F30B49511B08FDD27AC78810B084C7CD7DE6AC354F614C18EA9E7DF4, # noqa: E501 0x3379E7AE125C5C5D623D1D993C1459B61D6723B1C30D1AA026C48F6A6155B8EA: 0x8C4183732567A99A8A718E363391E102532F9A640E42968CF2354D9ACC908BB0, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE2: 1, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE3: 1, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE4: 1, # noqa: E501 - 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE5: 1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE2: contract_1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE3: contract_1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE4: contract_1, # noqa: E501 + 0x34CABE0C7E64A2CAA93FD8D6A0DEFC07ACB9D44B13430FA3AE9282FFFD40DEE5: contract_1, # noqa: E501 0x39050607FE892059A6344AB0F594F382FB0B345CAB373497246DBE86FE7E14E7: 0x2B3BCA833E482737E7E47B1568E6F890F8E1666490D38FE130ABD6F0CCB109CF, # noqa: E501 0x417BE8BC6791807372E0222A350BB8A5D67BBC8D7595C301D8A5A8372CFDCEF1: 0xABD4971B4605A7155802F70E08298B1CEB0E4E4EACCCCD348F77A77227F73A7F, # noqa: E501 0x41E9A54B3EE0C276AA076BABB161DE12B0F8916B47F8F6FB85CC387CF34696DD: 0x22F2F444EBDA9D2913FFEF5059B039EC9B5876AA71821991C2515BF79F64935E, # noqa: E501 @@ -9151,12 +9151,12 @@ def test_block504980( 0x7E95F3CC3315D289C52253BAABA29B1B00C86816E6B788D50795279A8BAA00DB: 0x45E9723E9232B37207ECAC1C97B8647D053625A578D450F7456280B2FF8EFC27, # noqa: E501 0x8DA187157087529EE4E9C381F8E3149C56ACF3BDFDA29B8B9B4532F24B83F5FE: 0x8C4183732567A99A8A718E363391E102532F9A640E42968CF2354D9ACC908BB0, # noqa: E501 0x9001F91DDAEF87BC067886E874C0749998C9B58B2EC8472CA014CA8B55F88578: 0xFB76974EEFCA01F33FB38646C2D3C1536F1A763D7AFF53AB7F877D4C5EA7FD0, # noqa: E501 - 0x9ED0CEDD2A9A78D949F40019F53D10031AEF6ED342C97E01FC03B481EE56B3CB: 4, # noqa: E501 + 0x9ED0CEDD2A9A78D949F40019F53D10031AEF6ED342C97E01FC03B481EE56B3CB: contract_4, # noqa: E501 0x9FDDF1DB29CAA5C1239EDD86E9E0835CDFE41F7253EC78F62D3DA8558D6F3CD7: 0x104EEF8FA35BF39F677D81855BC0B9F42317F32792E98E95E4DF441DEB634211, # noqa: E501 0xA0953566119395C11186B334805FC1A16175ECAC0ECC93AE0322264F0DC2E40D: 0x10C5A00466AB7C0ADAE1E93537CC275EA8CF23FF509D5466A1FD6F56B0A61D1B, # noqa: E501 - 0xAA0DBF8241EF3AE07C254E6869E84895BA2BE0779A7F261C8308A3114BE1C54A: 4, # noqa: E501 - 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2D: 1, # noqa: E501 - 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2E: 1, # noqa: E501 + 0xAA0DBF8241EF3AE07C254E6869E84895BA2BE0779A7F261C8308A3114BE1C54A: contract_4, # noqa: E501 + 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2D: contract_1, # noqa: E501 + 0xAFFE808B495D13A14391CE5F27C211C36DA12826969CD7841EE0D81E5B900E2E: contract_1, # noqa: E501 0xB4A2B68C48EF78AEB641EE538FAD51781022FD23ED9D93D211017DB6A02376CE: 0xFBC06642245CF2FED7ED46EA0A18A7185830B6F2C4E0A4CA55246041E8BFA72, # noqa: E501 0xBA8D79990898383919E437F2458B93B340072C89D963808D9E04F51858E3C5EC: 0x41D2CAC534D90A0DBD199117481A63E32CC11411DAB2EAA36C91C0EEC62823CF, # noqa: E501 0xBB3BC1A2015123750DF57D4CEFF7E28CB847910B79B34841DE905B59A8BB177C: 0x734417EB19E1873427257F1EA1594748C16CFA866A7B7CF896E281F2EC774A40, # noqa: E501 @@ -9169,19 +9169,19 @@ def test_block504980( 0xD8F720C05A5526DD621D1831AE122ABDDD3DFECD8B63B0BA4C92FA7B2ADE44FF: 0xAD393086F30B49511B08FDD27AC78810B084C7CD7DE6AC354F614C18EA9E7DF4, # noqa: E501 0xDC22D3171B82817C910BBEAC1F8B50C8DE99F8C524F172AEF3491981BD5ED4FB: 0x94B8CBA4EA090D1C392FBC94B82FB9EF9F468A15BBC537F4D051776F4D422B1D, # noqa: E501 0xDCE8ADBDEFA929DBE60245F359446DB4174C62824B42E5D4D9E7B834B4D61DEB: 0x2C9069845B2E74C577FF1CD18DF6BC452805F527A9EE91FD4A059E0408B5DEA6, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D196: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D197: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D198: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D199: 1, # noqa: E501 - 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D19A: 1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D196: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D197: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D198: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D199: contract_1, # noqa: E501 + 0xDD9493073DB9E42FD955E834C89A74089F99196186EE0B2688124989BE00D19A: contract_1, # noqa: E501 0xE54F074C81BFA60B5BF413934C108086298B77291560EDFEEAD8AA1232E95236: 0xF40AAA24323C9E6983CCFFAFEEBE4B426509B901E8C98B8A40D881804804E6B, # noqa: E501 - 0xE66C0F55F66C752EDF73027D45B7B1AE729AE15E1C67C362DBC6F25EDF8D76FF: 1, # noqa: E501 + 0xE66C0F55F66C752EDF73027D45B7B1AE729AE15E1C67C362DBC6F25EDF8D76FF: contract_1, # noqa: E501 0xE983D899F807BBCB5881F2DDF875B2EBB5CB8A7A4E77A8C98A40AAAE6A468735: 0x6D0BE832B2007EA28CDA705B73922CBF9794C5A25B89BD2F28B7347ED2B96C86, # noqa: E501 0xED7D6E2D40FBD5046412FFAD1C45B63D87C6197182D6DBC66BB1E5C6E4DED5C7: 0xABA4CD295118A482A0A62579E35E4BA5BDD76146CC9E4D96172FCE8BE8977AB4, # noqa: E501 - 0xF043B5A1952847579F233706A8F130889A484D2DA3E574FDD5859F05AAF52111: 2, # noqa: E501 + 0xF043B5A1952847579F233706A8F130889A484D2DA3E574FDD5859F05AAF52111: contract_2, # noqa: E501 0xF40F4CFDACB62DD799F36B580349FAC1F4A4CAF8DD3383CC387C35ADB6574E21: 0x2F0000000000000000, # noqa: E501 0xF60FA6E25E9028A6DC6B26BBC1EADAE3DA157DF0D1D6F6628BC33CAD68A7E455: 0x2D7D00618C059EBE40593B9497C633E1AC6E161DADBD5BB734C2663CD3E8A8E1, # noqa: E501 - 0xFD280AC5182D5B2366122F38ACFA6DC471240FFDE9D5FEB985CE7A2325C960E7: 3, # noqa: E501 + 0xFD280AC5182D5B2366122F38ACFA6DC471240FFDE9D5FEB985CE7A2325C960E7: contract_3, # noqa: E501 }, balance=0, nonce=0, @@ -9197,7 +9197,7 @@ def test_block504980( sender: Account(nonce=1), contract_9: Account( storage={ - 0: 1, + 0: contract_1, 0xA4470E9D0419DF71F6257FCDFD2C0A3BAD96A23F5AB414BC10AAF1A31A536A7: 0xB4876148229C22BD2291F1A4F5468C8C789B23639370C4D447F270BA341DBBEC, # noqa: E501 0x16EF4193A274568D283FF919C299729E07696D9ADA48187B81D68E12E7B962DE: 0xA103C04E7ECB9B3395F77C7B0CAD28E62C85F042DE4767CCC6C005E6F47F8D4, # noqa: E501 0x1F1866E966F321B84535705846689749D34D5DC02994613E2931973C605D9E93: 0xC723D0AA4A60529FE42277C8094AA19263AFF36650136EFC5EDFD0785D457634, # noqa: E501 @@ -9225,9 +9225,9 @@ def test_block504980( 0xBC96058EB03504EE6F5C0A9582F8720D99A6E9738B171499507FACFF0B2C0B5B: 0x9DB6A4F2766B51013B8D2F9038131D1BB4AF725D019D111D7E26FF96C023B23F, # noqa: E501 0xC186C4F377B7F13892ADE9656ACD1522AA1F8AC151AC4F62457B5073241D79FC: 0x7289738FEF00F1770EEB098DB9BD486C01AC12398D79CDF935514A128C585C51, # noqa: E501 0xCAE57AE3017972D63EFFD8EAE44F5054402C3E890D154B905ED6B5B533327FA9: 0xD2E4BF465E61993D13089B940A7C55017A5117D8E43E4115550A139E1D4B3E3A, # noqa: E501 - 0xCF569EE7BF3ACCC0F893DFFD04F1A757F373EFE80893EFF504FB3678F688EC1D: 3, # noqa: E501 + 0xCF569EE7BF3ACCC0F893DFFD04F1A757F373EFE80893EFF504FB3678F688EC1D: contract_3, # noqa: E501 0xD69B7284545A9F5275DF64CE94848DC954FCB8A8B525E7AC801517C12A75AF84: 0x4202995350ABAE303B43E564AA79121A30B5F1AEA31F69CD25E07DD3FA64DCE7, # noqa: E501 - 0xD8F6F90F51E657690EE28D1CC80D81BC1B89290065891FDD853D09CAAAF756AA: 1, # noqa: E501 + 0xD8F6F90F51E657690EE28D1CC80D81BC1B89290065891FDD853D09CAAAF756AA: contract_1, # noqa: E501 0xDE72F8EED43CC2A5A3EAA51483D14B17DC92BB26C154AE184CEE4B4895011EDC: 0x47CE2B6FDB72C3FABB9C74F82C1E3E522BCD42E614FD85C208AC3C4C840CEA72, # noqa: E501 0xE0E687DDF317F3D2B209AE3884148EFF0F636E16827F82EDED14ADA8FC603009: 0xFA7C8939F9B033162CF8D75EA69671BB8A27041BD4CDC76594E61E99333CB041, # noqa: E501 0xE8CDA339D72A1A350B62F1E3FA52E254C395CC9FDD9F60ADB21C7633FBDAB531: 0x128C4FDF4801A30EAE99DD58F0F3FF5CA65F71B66A9AC0F38DD450FB24B4AAAA, # noqa: E501 @@ -9243,11 +9243,11 @@ def test_block504980( contract_10: Account( storage={ 0xF299DBBE3A7A5D949FE794E9A47B3106699C8110FF986EB84921C183E69E7F0: 0x2F0000000000000000, # noqa: E501 - 0x1EDCD36F61CAE5DC6414157DFBADF9F11CA013AC763E27F8AF55FEAA8A239C89: 1, # noqa: E501 + 0x1EDCD36F61CAE5DC6414157DFBADF9F11CA013AC763E27F8AF55FEAA8A239C89: contract_1, # noqa: E501 0x689082D076EC3C02CBE4B99F6D9833E3C4A161072FD42FB7649EEE5189A67CCC: 0x63524E3FE4791AEFCE1E932BBFB3FDF375BFAD89, # noqa: E501 0xAF1D6676BE3AB502A59D91F6F5C49BAFFC15B2CFC65A41C4D96857C0F535ADBA: 0x1D60000000000000000, # noqa: E501 0xDF1A770F69D93D1719292F384FDB4DA22C0E88AEF2BA462BFF16674BC7848730: 0x1C11AA45C792E202E9FFDC2F12F99D0D209BEF70, # noqa: E501 - 0xEC5E7F54FA5E516E616B04F9D5A0EE433A80E09ED47D7E5269AFD76C05FF251E: 2, # noqa: E501 + 0xEC5E7F54FA5E516E616B04F9D5A0EE433A80E09ED47D7E5269AFD76C05FF251E: contract_2, # noqa: E501 }, nonce=0, ), diff --git a/tests/ported_static/stSpecialTest/test_deployment_error.py b/tests/ported_static/stSpecialTest/test_deployment_error.py index 15f75b9adf3..9cc8a073ac7 100644 --- a/tests/ported_static/stSpecialTest/test_deployment_error.py +++ b/tests/ported_static/stSpecialTest/test_deployment_error.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stSpecialTest/deploymentErrorFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_deployment_error( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_deployment_error.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_deployment_error( gas_limit=314159200, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stSpecialTest/test_eoa_empty_paris.py b/tests/ported_static/stSpecialTest/test_eoa_empty_paris.py index 12c51407162..5c93c366823 100644 --- a/tests/ported_static/stSpecialTest/test_eoa_empty_paris.py +++ b/tests/ported_static/stSpecialTest/test_eoa_empty_paris.py @@ -239,7 +239,7 @@ def test_eoa_empty_paris( sender: Account(nonce=1), contract_5: Account( storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 0: sender, 49: 0, 59: 0, 63: 0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, # noqa: E501 @@ -261,7 +261,7 @@ def test_eoa_empty_paris( sender: Account(nonce=1), contract_5: Account( storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 0: sender, 49: 0, 59: 0, 63: 0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, # noqa: E501 @@ -291,7 +291,7 @@ def test_eoa_empty_paris( sender: Account(nonce=1), contract_5: Account( storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 0: sender, 49: 100, 59: 0, 63: 0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, # noqa: E501 @@ -313,7 +313,7 @@ def test_eoa_empty_paris( sender: Account(nonce=1), contract_5: Account( storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 0: sender, 49: 100, 59: 0, 63: 0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, # noqa: E501 @@ -335,7 +335,7 @@ def test_eoa_empty_paris( sender: Account(nonce=1), contract_5: Account( storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 0: sender, 49: 0, 59: 0, 63: 0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, # noqa: E501 @@ -357,7 +357,7 @@ def test_eoa_empty_paris( sender: Account(nonce=1), contract_5: Account( storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 0: sender, 49: 0, 59: 0, 63: 0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, # noqa: E501 diff --git a/tests/ported_static/stSpecialTest/test_failed_tx_xcf416c53_paris.py b/tests/ported_static/stSpecialTest/test_failed_tx_xcf416c53_paris.py index 7c16045ccf5..6eef9fc2104 100644 --- a/tests/ported_static/stSpecialTest/test_failed_tx_xcf416c53_paris.py +++ b/tests/ported_static/stSpecialTest/test_failed_tx_xcf416c53_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,10 +33,8 @@ def test_failed_tx_xcf416c53_paris( ) -> None: """Test_failed_tx_xcf416c53_paris.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0xFF8D58222F34F6890DDAA468C023B77D6691ED7D3C4DCDDAE38336212FAF54B - ) + addr = Address(0x0000000000000000000000000000000000000003) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,7 @@ def test_failed_tx_xcf416c53_paris( gas_limit=200000000, ) + pre[addr] = Account(balance=10) # Source: raw # 0x7c0100000000000000000000000000000000000000000000000000000000600035046397dd3054811415610065576004356040526024356060526040516060515b808212156100625760006000600060006000866000f150600182019150610040565b50505b50 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,10 +84,7 @@ def test_failed_tx_xcf416c53_paris( + Op.JUMPDEST + Op.POP, nonce=0, - address=Address(0x7E6E9B4CA1B88937ABEAEC23BC4B6986CAF05188), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_gas_price0.py b/tests/ported_static/stSpecialTest/test_gas_price0.py index 6ca472522c2..4a0daeecfad 100644 --- a/tests/ported_static/stSpecialTest/test_gas_price0.py +++ b/tests/ported_static/stSpecialTest/test_gas_price0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_gas_price0( ) -> None: """Test_gas_price0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_gas_price0( code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_jumpdest_attack.py b/tests/ported_static/stSpecialTest/test_jumpdest_attack.py index 3007372aed1..e57e316b083 100644 --- a/tests/ported_static/stSpecialTest/test_jumpdest_attack.py +++ b/tests/ported_static/stSpecialTest/test_jumpdest_attack.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_jumpdest_attack( ) -> None: """Test_jumpdest_attack.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -63,9 +60,7 @@ def test_jumpdest_attack( + Op.JUMPDEST * 15000, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBC04EF30BA9EA0F7CE4543BAC777F6AAD09A2096), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_jumpdest_attackwith_jump.py b/tests/ported_static/stSpecialTest/test_jumpdest_attackwith_jump.py index 927bbb4b8fd..e95a5175932 100644 --- a/tests/ported_static/stSpecialTest/test_jumpdest_attackwith_jump.py +++ b/tests/ported_static/stSpecialTest/test_jumpdest_attackwith_jump.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_jumpdest_attackwith_jump( ) -> None: """Test_jumpdest_attackwith_jump.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_jumpdest_attackwith_jump( + Op.JUMPDEST * 15000, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3F9D62603C0D43765C8BC6EF623E68A4FC7D78EB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_make_money.py b/tests/ported_static/stSpecialTest/test_make_money.py index fd59a272d80..9f0678d1dc0 100644 --- a/tests/ported_static/stSpecialTest/test_make_money.py +++ b/tests/ported_static/stSpecialTest/test_make_money.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_make_money( ) -> None: """Test_make_money.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,14 @@ def test_make_money( gas_limit=1000000, ) + # Source: raw + # 0x600160015532600255 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.SSTORE(key=0x2, value=Op.ORIGIN), + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) (CALL 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +60,7 @@ def test_make_money( ) + Op.CALL( gas=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC, # noqa: E501 - address=0x802EDCCF6CDE9162A05FD89CDFCD8DC4A230B978, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -65,17 +70,6 @@ def test_make_money( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x56F6DA36928BFFD1FDB9EADE8A5B8BAFFDE0DEA4), # noqa: E501 - ) - pre[sender] = Account(balance=0x3B9ACA00) - # Source: raw - # 0x600160015532600255 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.SSTORE(key=0x2, value=Op.ORIGIN), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x802EDCCF6CDE9162A05FD89CDFCD8DC4A230B978), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stSpecialTest/test_overflow_gas_make_money.py b/tests/ported_static/stSpecialTest/test_overflow_gas_make_money.py index b124fcd7b5a..8bdbfd8f863 100644 --- a/tests/ported_static/stSpecialTest/test_overflow_gas_make_money.py +++ b/tests/ported_static/stSpecialTest/test_overflow_gas_make_money.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -25,16 +24,13 @@ ["state_tests/stSpecialTest/OverflowGasMakeMoneyFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_overflow_gas_make_money( state_test: StateTestFiller, pre: Alloc, ) -> None: """Apparently this test was testing theoretical issue occur when tr...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4C30106C229CD77A61E9EAB5FCEE11CC912BF94F785EE56F406817744BB6A074 - ) + sender = pre.fund_eoa(amount=0x4FEC000000000139C) env = Environment( fee_recipient=coinbase, @@ -45,8 +41,6 @@ def test_overflow_gas_make_money( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0x4FEC000000000139C) - tx = Transaction( sender=sender, to=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), diff --git a/tests/ported_static/stSpecialTest/test_push32without_byte.py b/tests/ported_static/stSpecialTest/test_push32without_byte.py index 734c570bb64..86a780c0d8a 100644 --- a/tests/ported_static/stSpecialTest/test_push32without_byte.py +++ b/tests/ported_static/stSpecialTest/test_push32without_byte.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -32,9 +31,7 @@ def test_push32without_byte( ) -> None: """Push expect 32 bytes.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - sender = EOA( - key=0x43F683FF58B5310699989DD19A4E1439E5333E2E3445374F7BC1446BAEDDD80 - ) + sender = pre.fund_eoa(amount=0x8AC7230489E80000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -50,9 +47,7 @@ def test_push32without_byte( target = pre.deploy_contract( # noqa: F841 code=bytes.fromhex("7f11223344556677889910"), nonce=0, - address=Address(0xC46EA1C1AD6C8EE63711D0377EF63E51C05D38A0), # noqa: E501 ) - pre[sender] = Account(balance=0x8AC7230489E80000, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_selfdestruct_eip2929.py b/tests/ported_static/stSpecialTest/test_selfdestruct_eip2929.py index ebaa2b3217d..a899276c3c7 100644 --- a/tests/ported_static/stSpecialTest/test_selfdestruct_eip2929.py +++ b/tests/ported_static/stSpecialTest/test_selfdestruct_eip2929.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,18 +25,13 @@ ["state_tests/stSpecialTest/selfdestructEIP2929Filler.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_selfdestruct_eip2929( state_test: StateTestFiller, pre: Alloc, ) -> None: """Martin: @tkstanczak requested a state-test regarding selfdestructs...""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0x9ECBDBDBD8448CDD955755CDD81D6918E436F68A) - addr_2 = Address(0x7704D8A022A1BA8F3539FC82C7D7FB065ABC0DF3) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,8 +42,8 @@ def test_selfdestruct_eip2929( gas_limit=10944489199640098, ) - pre[addr] = Account(balance=0, nonce=1) - pre[addr_2] = Account(balance=0, nonce=1) + addr = pre.fund_eoa(amount=0) # noqa: F841 + addr_2 = pre.fund_eoa(amount=0) # noqa: F841 # Source: raw # 0x6000600060006000600060cc6000f1506000600060006000600060dd6000f1506000600060006000600060036000f15060aa6000526000600060206000600061dead5af15060aa6000526000600060206000600061dead5af15060bb6000526000600060206000600061dead5af15060bb6000526000600060206000600061dead5af15060cc6000526000600060206000600061dead5af15060cc6000526000600060206000600061dead5af15060dd6000526000600060206000600061dead5af15060dd6000526000600060206000600061dead5af15060016000526000600060206000600061dead5af15060016000526000600060206000600061dead5af15060026000526000600060206000600061dead5af15060026000526000600060206000600061dead5af15060036000526000600060206000600061dead5af1506001600155 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -245,7 +239,6 @@ def test_selfdestruct_eip2929( + Op.SSTORE(key=0x1, value=0x1), balance=1, nonce=1, - address=Address(0xB686BE1A7A0F441FAE9583884043AC034FE82089), # noqa: E501 ) # Source: raw # 0x60003574ffffffffffffffffffffffffffffffffffffffffff16ff @@ -258,9 +251,7 @@ def test_selfdestruct_eip2929( ), balance=1, nonce=1, - address=Address(0xD2E5C26A2F035A63D0859E255621ED1E57148085), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_sha3_deja.py b/tests/ported_static/stSpecialTest/test_sha3_deja.py index f10c83819e1..5c7a8f4d997 100644 --- a/tests/ported_static/stSpecialTest/test_sha3_deja.py +++ b/tests/ported_static/stSpecialTest/test_sha3_deja.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_sha3_deja( ) -> None: """Test_sha3_deja.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_sha3_deja( + Op.DUP1, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCC4CDC08ED5801A6C7D1D87EFB229F9556D50CE6), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSpecialTest/test_stack_depth_limit_sec.py b/tests/ported_static/stSpecialTest/test_stack_depth_limit_sec.py index 25a8f78af6e..4bc84e2ae16 100644 --- a/tests/ported_static/stSpecialTest/test_stack_depth_limit_sec.py +++ b/tests/ported_static/stSpecialTest/test_stack_depth_limit_sec.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stSpecialTest/StackDepthLimitSECFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_stack_depth_limit_sec( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_stack_depth_limit_sec.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_stack_depth_limit_sec( gas_limit=1000000, ) - pre[sender] = Account(balance=0x2540BE400) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stSpecialTest/test_tx_e1c174e2.py b/tests/ported_static/stSpecialTest/test_tx_e1c174e2.py index c13872d98cf..a42f5c81aa1 100644 --- a/tests/ported_static/stSpecialTest/test_tx_e1c174e2.py +++ b/tests/ported_static/stSpecialTest/test_tx_e1c174e2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_tx_e1c174e2( ) -> None: """Test_tx_e1c174e2.""" coinbase = Address(0x68795C4AA09D6F4ED3E5DEDDF8C2AD3049A601DA) - sender = EOA( - key=0x98D5E7375843784F7EB2606A693BAB39EBAC533561559E372DC3017F30519535 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=24) env = Environment( fee_recipient=coinbase, @@ -3294,7 +3291,6 @@ def test_tx_e1c174e2( nonce=0, address=Address(0xF47BACB0D8F13FA44D31623C3D5AE72907D241C1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=24) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStackTests/test_shallow_stack.py b/tests/ported_static/stStackTests/test_shallow_stack.py index 87b5f7b3db2..0ba5126b719 100644 --- a/tests/ported_static/stStackTests/test_shallow_stack.py +++ b/tests/ported_static/stStackTests/test_shallow_stack.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -518,7 +517,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_shallow_stack( state_test: StateTestFiller, pre: Alloc, @@ -529,9 +527,7 @@ def test_shallow_stack( ) -> None: """Test_shallow_stack.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x271000000000) env = Environment( fee_recipient=coinbase, @@ -542,8 +538,6 @@ def test_shallow_stack( gas_limit=42949672960, ) - pre[sender] = Account(balance=0x271000000000) - tx_data = [ Op.PUSH1[0x1] + Op.SSTORE(key=0x0, value=Op.ADD), Op.PUSH1[0x1] + Op.SSTORE(key=0x0, value=Op.MUL), diff --git a/tests/ported_static/stStackTests/test_stack_overflow.py b/tests/ported_static/stStackTests/test_stack_overflow.py index cc8c212d394..d8e7f4d4596 100644 --- a/tests/ported_static/stStackTests/test_stack_overflow.py +++ b/tests/ported_static/stStackTests/test_stack_overflow.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -128,7 +127,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_stack_overflow( state_test: StateTestFiller, pre: Alloc, @@ -139,10 +137,7 @@ def test_stack_overflow( ) -> None: """Test_stack_overflow.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A5100000000000) env = Environment( fee_recipient=coinbase, @@ -153,8 +148,7 @@ def test_stack_overflow( gas_limit=42949672960, ) - pre[contract_0] = Account(balance=0xE8D4A5100000000000) - pre[sender] = Account(balance=0xE8D4A5100000000000) + contract_0 = pre.fund_eoa(amount=0xE8D4A5100000000000) # noqa: F841 tx_data = [ Op.ADDRESS * 1025, diff --git a/tests/ported_static/stStackTests/test_stack_overflow_dup.py b/tests/ported_static/stStackTests/test_stack_overflow_dup.py index 14a96232c64..2b935d280fa 100644 --- a/tests/ported_static/stStackTests/test_stack_overflow_dup.py +++ b/tests/ported_static/stStackTests/test_stack_overflow_dup.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -128,7 +127,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_stack_overflow_dup( state_test: StateTestFiller, pre: Alloc, @@ -139,10 +137,7 @@ def test_stack_overflow_dup( ) -> None: """Test_stack_overflow_dup.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A5100000000000) env = Environment( fee_recipient=coinbase, @@ -153,8 +148,7 @@ def test_stack_overflow_dup( gas_limit=42949672960, ) - pre[contract_0] = Account(balance=0xE8D4A5100000000000) - pre[sender] = Account(balance=0xE8D4A5100000000000) + contract_0 = pre.fund_eoa(amount=0xE8D4A5100000000000) # noqa: F841 tx_data = [ Op.PUSH1[0x1] + Op.DUP1 * 1024, diff --git a/tests/ported_static/stStackTests/test_stack_overflow_m1.py b/tests/ported_static/stStackTests/test_stack_overflow_m1.py index f86e0735cbf..c4d6fc9ee97 100644 --- a/tests/ported_static/stStackTests/test_stack_overflow_m1.py +++ b/tests/ported_static/stStackTests/test_stack_overflow_m1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -128,7 +127,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_stack_overflow_m1( state_test: StateTestFiller, pre: Alloc, @@ -139,10 +137,7 @@ def test_stack_overflow_m1( ) -> None: """Test_stack_overflow_m1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A5100000000000) env = Environment( fee_recipient=coinbase, @@ -153,8 +148,7 @@ def test_stack_overflow_m1( gas_limit=42949672960, ) - pre[contract_0] = Account(balance=0xE8D4A5100000000000) - pre[sender] = Account(balance=0xE8D4A5100000000000) + contract_0 = pre.fund_eoa(amount=0xE8D4A5100000000000) # noqa: F841 tx_data = [ Op.ADDRESS * 1024, diff --git a/tests/ported_static/stStackTests/test_stack_overflow_m1_dup.py b/tests/ported_static/stStackTests/test_stack_overflow_m1_dup.py index 0f0cd2c01c3..53569c363c8 100644 --- a/tests/ported_static/stStackTests/test_stack_overflow_m1_dup.py +++ b/tests/ported_static/stStackTests/test_stack_overflow_m1_dup.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -128,7 +127,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_stack_overflow_m1_dup( state_test: StateTestFiller, pre: Alloc, @@ -139,10 +137,7 @@ def test_stack_overflow_m1_dup( ) -> None: """Test_stack_overflow_m1_dup.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A5100000000000) env = Environment( fee_recipient=coinbase, @@ -153,8 +148,7 @@ def test_stack_overflow_m1_dup( gas_limit=42949672960, ) - pre[contract_0] = Account(balance=0xE8D4A5100000000000) - pre[sender] = Account(balance=0xE8D4A5100000000000) + contract_0 = pre.fund_eoa(amount=0xE8D4A5100000000000) # noqa: F841 tx_data = [ Op.PUSH1[0x1] + Op.DUP1 * 1023, diff --git a/tests/ported_static/stStackTests/test_stack_overflow_swap.py b/tests/ported_static/stStackTests/test_stack_overflow_swap.py index 9c5a2a1f34b..8cdda0a7279 100644 --- a/tests/ported_static/stStackTests/test_stack_overflow_swap.py +++ b/tests/ported_static/stStackTests/test_stack_overflow_swap.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,17 +25,13 @@ ["state_tests/stStackTests/stackOverflowSWAPFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_stack_overflow_swap( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_stack_overflow_swap.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A5100000000000) env = Environment( fee_recipient=coinbase, @@ -47,8 +42,7 @@ def test_stack_overflow_swap( gas_limit=42949672960, ) - pre[contract_0] = Account(balance=0xE8D4A5100000000000) - pre[sender] = Account(balance=0xE8D4A5100000000000) + contract_0 = pre.fund_eoa(amount=0xE8D4A5100000000000) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStackTests/test_stacksanity_swap.py b/tests/ported_static/stStackTests/test_stacksanity_swap.py index 2b399586969..d37c14c48a5 100644 --- a/tests/ported_static/stStackTests/test_stacksanity_swap.py +++ b/tests/ported_static/stStackTests/test_stacksanity_swap.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,17 +25,13 @@ ["state_tests/stStackTests/stacksanitySWAPFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_stacksanity_swap( state_test: StateTestFiller, pre: Alloc, ) -> None: """Checks stack usage for SWAP.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A5100000000000) env = Environment( fee_recipient=coinbase, @@ -47,8 +42,7 @@ def test_stacksanity_swap( gas_limit=42949672960, ) - pre[contract_0] = Account(balance=0xE8D4A5100000000000) - pre[sender] = Account(balance=0xE8D4A5100000000000) + contract_0 = pre.fund_eoa(amount=0xE8D4A5100000000000) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStackTests/test_underflow_test.py b/tests/ported_static/stStackTests/test_underflow_test.py index ce8b321e923..92b79de5edb 100644 --- a/tests/ported_static/stStackTests/test_underflow_test.py +++ b/tests/ported_static/stStackTests/test_underflow_test.py @@ -1056,6 +1056,7 @@ def test_underflow_test( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: raw # 0x600160015560800100 addr = pre.deploy_contract( # noqa: F841 @@ -2762,7 +2763,6 @@ def test_underflow_test( nonce=0, address=Address(0x4C5F839D523E76FC3837E085A3E1538CD36E288A), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_ab_acalls0.py b/tests/ported_static/stStaticCall/test_static_ab_acalls0.py index cc37220c170..ca1b6965436 100644 --- a/tests/ported_static/stStaticCall/test_static_ab_acalls0.py +++ b/tests/ported_static/stStaticCall/test_static_ab_acalls0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_ab_acalls0( ) -> None: """Test_static_ab_acalls0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -168,7 +165,6 @@ def test_static_ab_acalls0( nonce=0, address=Address(0x718A83E869D6F4DEA50A650B9825CBFE683BDF16), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_ab_acalls1.py b/tests/ported_static/stStaticCall/test_static_ab_acalls1.py index 5eaa13d198d..7f4ceb8d318 100644 --- a/tests/ported_static/stStaticCall/test_static_ab_acalls1.py +++ b/tests/ported_static/stStaticCall/test_static_ab_acalls1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_ab_acalls1( ) -> None: """Test_static_ab_acalls1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -174,7 +171,6 @@ def test_static_ab_acalls1( nonce=0, address=Address(0x5E75046384134A4554C3C7061D4637CB978D5699), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_ab_acalls2.py b/tests/ported_static/stStaticCall/test_static_ab_acalls2.py index 74aff756abe..df9f37353a3 100644 --- a/tests/ported_static/stStaticCall/test_static_ab_acalls2.py +++ b/tests/ported_static/stStaticCall/test_static_ab_acalls2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_ab_acalls2( ) -> None: """Test_static_ab_acalls2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -159,7 +156,6 @@ def test_static_ab_acalls2( nonce=0, address=Address(0x57EFC7A25D8E40B0798FB4CBC2BCC3C124141CBB), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_ab_acalls3.py b/tests/ported_static/stStaticCall/test_static_ab_acalls3.py index e2ac4c86d9a..7e32882c2b8 100644 --- a/tests/ported_static/stStaticCall/test_static_ab_acalls3.py +++ b/tests/ported_static/stStaticCall/test_static_ab_acalls3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_ab_acalls3( ) -> None: """Test_static_ab_acalls3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -158,7 +155,6 @@ def test_static_ab_acalls3( nonce=0, address=Address(0x0B1F7380DB647F1D85565B28978BA83861B99965), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide0.py b/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide0.py index 3b6c5bf3f3e..94fcf44f866 100644 --- a/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide0.py +++ b/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_ab_acalls_suicide0( ) -> None: """Test_static_ab_acalls_suicide0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -176,7 +173,6 @@ def test_static_ab_acalls_suicide0( nonce=0, address=Address(0x644AC2B24A9316ED4C55001E5EDA02D77F729C7B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide1.py b/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide1.py index 8603614a8d5..5119b012e3e 100644 --- a/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide1.py +++ b/tests/ported_static/stStaticCall/test_static_ab_acalls_suicide1.py @@ -71,6 +71,7 @@ def test_static_ab_acalls_suicide1( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) (STATICCALL (CALLDATALOAD 0) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 0 32 0 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -108,7 +109,6 @@ def test_static_ab_acalls_suicide1( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(0x186A0), diff --git a/tests/ported_static/stStaticCall/test_static_call10.py b/tests/ported_static/stStaticCall/test_static_call10.py index 703f0759083..36c2f6bf4e0 100644 --- a/tests/ported_static/stStaticCall/test_static_call10.py +++ b/tests/ported_static/stStaticCall/test_static_call10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,10 +58,7 @@ def test_static_call10( ) -> None: """Test_static_call10.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,8 +69,7 @@ def test_static_call10( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low.py b/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low.py index b23dffab7fb..c35d515be61 100644 --- a/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low.py +++ b/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_static_call1024_balance_too_low( ) -> None: """Test_static_call1024_balance_too_low.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,8 +70,7 @@ def test_static_call1024_balance_too_low( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low2.py b/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low2.py index c01e8578647..6b2a4856aee 100644 --- a/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low2.py +++ b/tests/ported_static/stStaticCall/test_static_call1024_balance_too_low2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_static_call1024_balance_too_low2( ) -> None: """Test_static_call1024_balance_too_low2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,8 +70,7 @@ def test_static_call1024_balance_too_low2( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1024_oog.py b/tests/ported_static/stStaticCall/test_static_call1024_oog.py index d44a8c1bf11..bdb6507da01 100644 --- a/tests/ported_static/stStaticCall/test_static_call1024_oog.py +++ b/tests/ported_static/stStaticCall/test_static_call1024_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,10 +58,7 @@ def test_static_call1024_oog( ) -> None: """Test_static_call1024_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,8 +69,7 @@ def test_static_call1024_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1024_pre_calls.py b/tests/ported_static/stStaticCall/test_static_call1024_pre_calls.py index 077d9c2b1d3..e0d260f263f 100644 --- a/tests/ported_static/stStaticCall/test_static_call1024_pre_calls.py +++ b/tests/ported_static/stStaticCall/test_static_call1024_pre_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_static_call1024_pre_calls( ) -> None: """Test_static_call1024_pre_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xCC381C83857B17CA629268ED418E2915A0287B84EFE9CF2204C020302E83CDA0 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,7 +70,7 @@ def test_static_call1024_pre_calls( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -95,7 +91,6 @@ def test_static_call1024_pre_calls( nonce=0, address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) - pre[addr] = Account(balance=7000) # Source: lll # { [[ 2 ]] (STATICCALL 0xffff 0 0 0 0) [[ 3 ]] (STATICCALL 0xffff 0 0 0 0) [[ 0 ]] (ADD @@0 1) [[ 1 ]] (STATICCALL 0xfffffffffff 0 0 0 0) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1024_pre_calls2.py b/tests/ported_static/stStaticCall/test_static_call1024_pre_calls2.py index 1f8653ca43b..8cf74830cb1 100644 --- a/tests/ported_static/stStaticCall/test_static_call1024_pre_calls2.py +++ b/tests/ported_static/stStaticCall/test_static_call1024_pre_calls2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call1024_pre_calls2( ) -> None: """Test_static_call1024_pre_calls2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xCC381C83857B17CA629268ED418E2915A0287B84EFE9CF2204C020302E83CDA0 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call1024_pre_calls2( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1024_pre_calls3.py b/tests/ported_static/stStaticCall/test_static_call1024_pre_calls3.py index f6f9a96d1ae..6448a69f8f0 100644 --- a/tests/ported_static/stStaticCall/test_static_call1024_pre_calls3.py +++ b/tests/ported_static/stStaticCall/test_static_call1024_pre_calls3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_static_call1024_pre_calls3( ) -> None: """Test_static_call1024_pre_calls3.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xCC381C83857B17CA629268ED418E2915A0287B84EFE9CF2204C020302E83CDA0 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,7 +70,7 @@ def test_static_call1024_pre_calls3( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -95,7 +91,6 @@ def test_static_call1024_pre_calls3( nonce=0, address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) - pre[addr] = Account(balance=7000) # Source: lll # { [[ 2 ]] (STATICCALL 0xffff 0 0 0 0) [[ 3 ]] (STATICCALL 0xffff 0 0 0 0) [[ 0 ]] (ADD @@0 1) [[ 1 ]] (STATICCALL 0xfffffffffff 0 0 0 0) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call1_mb1024_calldepth.py b/tests/ported_static/stStaticCall/test_static_call1_mb1024_calldepth.py index 5602ad54f1b..09ad53cc867 100644 --- a/tests/ported_static/stStaticCall/test_static_call1_mb1024_calldepth.py +++ b/tests/ported_static/stStaticCall/test_static_call1_mb1024_calldepth.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,10 +59,7 @@ def test_static_call1_mb1024_calldepth( ) -> None: """Test_static_call1_mb1024_calldepth.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0x2AB8257767339461506C0C67824CF17BC77B52CA) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -74,8 +70,7 @@ def test_static_call1_mb1024_calldepth( gas_limit=892500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=0xFFFFFFFFFFFFF) + addr = pre.fund_eoa(amount=0xFFFFFFFFFFFFF) # noqa: F841 # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000.py b/tests/ported_static/stStaticCall/test_static_call50000.py index 3a91cc8c5cd..00bf19407fd 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000.py +++ b/tests/ported_static/stStaticCall/test_static_call50000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000( ) -> None: """Test_static_call50000.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000( gas_limit=100000000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (MSTORE 0 (SLOAD 0)) } addr = pre.deploy_contract( # noqa: F841 @@ -113,8 +109,8 @@ def test_static_call50000( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (STATICCALL 100000 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (SSTORE 0 (STATICCALL 100000 0 50000 0 0)) ) (SSTORE 32 @i ) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 code=Op.JUMPDEST + Op.JUMPI( pc=0x3E, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) @@ -123,7 +119,7 @@ def test_static_call50000( key=0x0, value=Op.STATICCALL( gas=0x186A0, - address=0x7EFD7E4E34D1783F5D86B7862A37B3BBBD13DEB8, + address=0x6D440CD3E818056E21914C856E3712F4186B06C8, args_offset=0x0, args_size=0xC350, ret_offset=0x0, @@ -133,15 +129,15 @@ def test_static_call50000( + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + Op.JUMP(pc=0x0) + Op.JUMPDEST - + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x80)) + + Op.SSTORE(key=0x20, value=Op.MLOAD(offset=0x80)) + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x2E396FD4F6F2799D61F534B43175F5344C65ECAC), # noqa: E501 + address=Address(0xB00A8701F877B1152CD955E957FCBAF51A15F55F), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (SSTORE 0 (STATICCALL 100000 0 50000 0 0)) ) (SSTORE 32 @i ) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (STATICCALL 100000 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.JUMPDEST + Op.JUMPI( pc=0x3E, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) @@ -150,7 +146,7 @@ def test_static_call50000( key=0x0, value=Op.STATICCALL( gas=0x186A0, - address=0x6D440CD3E818056E21914C856E3712F4186B06C8, + address=0x7EFD7E4E34D1783F5D86B7862A37B3BBBD13DEB8, args_offset=0x0, args_size=0xC350, ret_offset=0x0, @@ -160,11 +156,11 @@ def test_static_call50000( + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + Op.JUMP(pc=0x0) + Op.JUMPDEST - + Op.SSTORE(key=0x20, value=Op.MLOAD(offset=0x80)) + + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x80)) + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0xB00A8701F877B1152CD955E957FCBAF51A15F55F), # noqa: E501 + address=Address(0x2E396FD4F6F2799D61F534B43175F5344C65ECAC), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stStaticCall/test_static_call50000_ecrec.py b/tests/ported_static/stStaticCall/test_static_call50000_ecrec.py index 8ebac330d83..00a665359f4 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000_ecrec.py +++ b/tests/ported_static/stStaticCall/test_static_call50000_ecrec.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000_ecrec( ) -> None: """Test_static_call50000_ecrec.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000_ecrec( gas_limit=95000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000_identity.py b/tests/ported_static/stStaticCall/test_static_call50000_identity.py index 3f355179f01..411f8506a38 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000_identity.py +++ b/tests/ported_static/stStaticCall/test_static_call50000_identity.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000_identity( ) -> None: """Test_static_call50000_identity.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000_identity( gas_limit=89250000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000_identity2.py b/tests/ported_static/stStaticCall/test_static_call50000_identity2.py index 5fcef6d8efd..cbbe552fd44 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000_identity2.py +++ b/tests/ported_static/stStaticCall/test_static_call50000_identity2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000_identity2( ) -> None: """Test_static_call50000_identity2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000_identity2( gas_limit=8925000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000_rip160.py b/tests/ported_static/stStaticCall/test_static_call50000_rip160.py index a0fa22cf401..12a1fa68939 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000_rip160.py +++ b/tests/ported_static/stStaticCall/test_static_call50000_rip160.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -57,9 +56,7 @@ def test_static_call50000_rip160( ) -> None: """Test_static_call50000_rip160.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -70,7 +67,6 @@ def test_static_call50000_rip160( gas_limit=39250000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_1.py b/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_1.py index a18045ffdc0..c1571a59264 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_1.py +++ b/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000bytes_contract50_1( ) -> None: """Test_static_call50000bytes_contract50_1.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000bytes_contract50_1( gas_limit=892500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -96,7 +92,9 @@ def test_static_call50000bytes_contract50_1( ) # Source: raw # 0x6001600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600055 # noqa: E501 - addr = Address(0x784C659B2B4D2B69AB5564D60F4E565C7A1CEB2B) + addr = Address( + 0x784C659B2B4D2B69AB5564D60F4E565C7A1CEB2B + ) # oversized contract pre[addr] = Account( code=bytes.fromhex( "6001600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600101600055" # noqa: E501 @@ -104,6 +102,18 @@ def test_static_call50000bytes_contract50_1( balance=0xFFFFFFFFFFFFF, nonce=0, ) + # Source: raw + # 0x60016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016000 # noqa: E501 + addr_3 = Address( + 0x80C3355386CD2326418157DBD8764B380B971F67 + ) # oversized contract + pre[addr_3] = Account( + code=bytes.fromhex( + "60016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016000" # noqa: E501 + ), + balance=0xFFFFFFFFFFFFF, + nonce=0, + ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (STATICCALL 88250000000 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 @@ -131,16 +141,6 @@ def test_static_call50000bytes_contract50_1( nonce=0, address=Address(0xD7B377D5D96EF739E27BC58E021C51E934A9A85B), # noqa: E501 ) - # Source: raw - # 0x60016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016000 # noqa: E501 - addr_3 = Address(0x80C3355386CD2326418157DBD8764B380B971F67) - pre[addr_3] = Account( - code=bytes.fromhex( - "60016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016001016000" # noqa: E501 - ), - balance=0xFFFFFFFFFFFFF, - nonce=0, - ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) (MSTORE 0 (STATICCALL 88250000000 0 0 0 0)) ) (MSTORE 32 @i) } # noqa: E501 addr_4 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_2.py b/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_2.py index a4f30efc60b..ad164e9725c 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_2.py +++ b/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000bytes_contract50_2( ) -> None: """Test_static_call50000bytes_contract50_2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000bytes_contract50_2( gas_limit=892500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -96,7 +92,9 @@ def test_static_call50000bytes_contract50_2( ) # Source: raw # 0x60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055 # noqa: E501 - addr = Address(0x1836FD8C1DB3E96AE2A516F50C27483CD48D2EF0) + addr = Address( + 0x1836FD8C1DB3E96AE2A516F50C27483CD48D2EF0 + ) # oversized contract pre[addr] = Account( code=bytes.fromhex( "60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055" # noqa: E501 @@ -104,6 +102,18 @@ def test_static_call50000bytes_contract50_2( balance=0xFFFFFFFFFFFFF, nonce=0, ) + # Source: raw + # 0x60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101 # noqa: E501 + addr_3 = Address( + 0xEA3174AB39F002DEF28B14B425DC9E7E67FED805 + ) # oversized contract + pre[addr_3] = Account( + code=bytes.fromhex( + "60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101" # noqa: E501 + ), + balance=0xFFFFFFFFFFFFF, + nonce=0, + ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (STATICCALL 88250000000 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 @@ -131,16 +141,6 @@ def test_static_call50000bytes_contract50_2( nonce=0, address=Address(0xD7B377D5D96EF739E27BC58E021C51E934A9A85B), # noqa: E501 ) - # Source: raw - # 0x60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101 # noqa: E501 - addr_3 = Address(0xEA3174AB39F002DEF28B14B425DC9E7E67FED805) - pre[addr_3] = Account( - code=bytes.fromhex( - "60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101" # noqa: E501 - ), - balance=0xFFFFFFFFFFFFF, - nonce=0, - ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) (MSTORE 0 (STATICCALL 88250000000 0 0 0 0)) ) (MSTORE 32 @i ) } # noqa: E501 addr_4 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_3.py b/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_3.py index 133193e6426..1041834efd5 100644 --- a/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_3.py +++ b/tests/ported_static/stStaticCall/test_static_call50000bytes_contract50_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_call50000bytes_contract50_3( ) -> None: """Test_static_call50000bytes_contract50_3.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -73,7 +70,6 @@ def test_static_call50000bytes_contract50_3( gas_limit=892500000000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -96,7 +92,9 @@ def test_static_call50000bytes_contract50_3( ) # Source: raw # 0x600161da8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055 # noqa: E501 - addr = Address(0x653CF6168B15C28D212F20D652C34BBE734A8718) + addr = Address( + 0x653CF6168B15C28D212F20D652C34BBE734A8718 + ) # oversized contract pre[addr] = Account( code=bytes.fromhex( "600161da8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055" # noqa: E501 @@ -104,6 +102,18 @@ def test_static_call50000bytes_contract50_3( balance=0xFFFFFFFFFFFFF, nonce=0, ) + # Source: raw + # 0x600161da8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101 # noqa: E501 + addr_3 = Address( + 0x0431FBE9C18DC43AF2C372A7554BB2826176BDFD + ) # oversized contract + pre[addr_3] = Account( + code=bytes.fromhex( + "600161da8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101" # noqa: E501 + ), + balance=0xFFFFFFFFFFFFF, + nonce=0, + ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (STATICCALL 88250000000 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 @@ -131,16 +141,6 @@ def test_static_call50000bytes_contract50_3( nonce=0, address=Address(0xD7B377D5D96EF739E27BC58E021C51E934A9A85B), # noqa: E501 ) - # Source: raw - # 0x600161da8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101 # noqa: E501 - addr_3 = Address(0x0431FBE9C18DC43AF2C372A7554BB2826176BDFD) - pre[addr_3] = Account( - code=bytes.fromhex( - "600161da8e565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101" # noqa: E501 - ), - balance=0xFFFFFFFFFFFFF, - nonce=0, - ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) (MSTORE 0 (STATICCALL 88250000000 0 0 0 0)) ) (MSTORE 32 @i ) } # noqa: E501 addr_4 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call_and_callcode_consume_more_gas_then_transaction_has.py b/tests/ported_static/stStaticCall/test_static_call_and_callcode_consume_more_gas_then_transaction_has.py index 31a04a8e0e4..1186ce1cc64 100644 --- a/tests/ported_static/stStaticCall/test_static_call_and_callcode_consume_more_gas_then_transaction_has.py +++ b/tests/ported_static/stStaticCall/test_static_call_and_callcode_consume_more_gas_then_transaction_has.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_static_call_and_callcode_consume_more_gas_then_transaction_has( ) -> None: """Test_static_call_and_callcode_consume_more_gas_then_transaction_has.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -74,7 +71,6 @@ def test_static_call_and_callcode_consume_more_gas_then_transaction_has( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -96,6 +92,20 @@ def test_static_call_and_callcode_consume_more_gas_then_transaction_has( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll + # { (SSTORE 0 0x12) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x12) + Op.STOP, + nonce=0, + address=Address(0xFD59ABAE521384B5731AC657616680219FBC423D), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 0x12) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x12) + Op.STOP, + nonce=0, + address=Address(0x9620801959B49D6D1BD08F0CDAFDA5D87E900403), # noqa: E501 + ) + # Source: lll # { (SSTORE 9 (STATICCALL 600000 0 0 0 0)) (SSTORE 10 (CALLCODE 600000 0 0 0 0 0)) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( @@ -126,13 +136,6 @@ def test_static_call_and_callcode_consume_more_gas_then_transaction_has( address=Address(0x438F316BA8E30F69666A3477A7F5CD26235D3CBB), # noqa: E501 ) # Source: lll - # { (SSTORE 0 0x12) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x12) + Op.STOP, - nonce=0, - address=Address(0xFD59ABAE521384B5731AC657616680219FBC423D), # noqa: E501 - ) - # Source: lll # { (SSTORE 9 (STATICCALL 600000 0 0 0 0)) (SSTORE 10 (CALLCODE 600000 0 0 0 0 0)) } # noqa: E501 addr_3 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( @@ -162,13 +165,6 @@ def test_static_call_and_callcode_consume_more_gas_then_transaction_has( nonce=0, address=Address(0x7D77EAF6DC93E2B7B83A8E06314AF1CE47CD2596), # noqa: E501 ) - # Source: lll - # { (MSTORE 0 0x12) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x12) + Op.STOP, - nonce=0, - address=Address(0x9620801959B49D6D1BD08F0CDAFDA5D87E900403), # noqa: E501 - ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_call_ask_more_gas_on_depth2_then_transaction_has.py b/tests/ported_static/stStaticCall/test_static_call_ask_more_gas_on_depth2_then_transaction_has.py index 3d69d184695..1ff95945afb 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ask_more_gas_on_depth2_then_transaction_has.py +++ b/tests/ported_static/stStaticCall/test_static_call_ask_more_gas_on_depth2_then_transaction_has.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( ) -> None: """Test_static_call_ask_more_gas_on_depth2_then_transaction_has.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -74,7 +71,6 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[ 0 ]] (CALL (GAS) (CALLDATALOAD 0) (CALLVALUE) 0 0 0 0) [[ 1 ]] 1 } target = pre.deploy_contract( # noqa: F841 @@ -96,14 +92,28 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { (SSTORE 8 1) (SSTORE 9 (STATICCALL 200000 0 0 0 0)) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=0x1) - + Op.SSTORE( - key=0x9, + # { (SSTORE 8 1)} + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x5044BFB29664A79DE12215897C630DC8A11B0B97), # noqa: E501 + ) + # Source: lll + # { (MSTORE 8 (GAS))} + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x8, value=Op.GAS) + Op.STOP, + nonce=0, + address=Address(0x91B291A3336BC1357388354DF18CA061B39E3745), # noqa: E501 + ) + # Source: lll + # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 0 0 0 0)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x8, value=Op.GAS) + + Op.MSTORE( + offset=0x9, value=Op.STATICCALL( - gas=0x30D40, - address=0xD9539C5A3DC4713D47A547BFC9A075BD97287080, + gas=0x927C0, + address=0x5044BFB29664A79DE12215897C630DC8A11B0B97, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -112,17 +122,17 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0xEF69A9B2C20255FB7BD2B0AC7D45601A03D570B0), # noqa: E501 + address=Address(0xD9539C5A3DC4713D47A547BFC9A075BD97287080), # noqa: E501 ) # Source: lll - # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 0 0 0 0)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 0 0 0 0)) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x8, value=Op.GAS) + Op.MSTORE( offset=0x9, value=Op.STATICCALL( gas=0x927C0, - address=0x5044BFB29664A79DE12215897C630DC8A11B0B97, + address=0x91B291A3336BC1357388354DF18CA061B39E3745, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -131,24 +141,17 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0xD9539C5A3DC4713D47A547BFC9A075BD97287080), # noqa: E501 - ) - # Source: lll - # { (SSTORE 8 1)} - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x8, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x5044BFB29664A79DE12215897C630DC8A11B0B97), # noqa: E501 + address=Address(0xE5A4D8074950EC8067D602848B666CA151B09C9F), # noqa: E501 ) # Source: lll - # { (SSTORE 8 1) (SSTORE 9 (STATICCALL 200000 0 0 0 0)) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { (SSTORE 8 1) (SSTORE 9 (STATICCALL 200000 0 0 0 0)) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x8, value=0x1) + Op.SSTORE( key=0x9, value=Op.STATICCALL( gas=0x30D40, - address=0xE5A4D8074950EC8067D602848B666CA151B09C9F, + address=0xD9539C5A3DC4713D47A547BFC9A075BD97287080, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -157,17 +160,17 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0x8169DC735802BB5C18A777052CF4CE326B5FD725), # noqa: E501 + address=Address(0xEF69A9B2C20255FB7BD2B0AC7D45601A03D570B0), # noqa: E501 ) # Source: lll - # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 0 0 0 0)) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x8, value=Op.GAS) - + Op.MSTORE( - offset=0x9, + # { (SSTORE 8 1) (SSTORE 9 (STATICCALL 200000 0 0 0 0)) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x8, value=0x1) + + Op.SSTORE( + key=0x9, value=Op.STATICCALL( - gas=0x927C0, - address=0x91B291A3336BC1357388354DF18CA061B39E3745, + gas=0x30D40, + address=0xE5A4D8074950EC8067D602848B666CA151B09C9F, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -176,14 +179,7 @@ def test_static_call_ask_more_gas_on_depth2_then_transaction_has( ) + Op.STOP, nonce=0, - address=Address(0xE5A4D8074950EC8067D602848B666CA151B09C9F), # noqa: E501 - ) - # Source: lll - # { (MSTORE 8 (GAS))} - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x8, value=Op.GAS) + Op.STOP, - nonce=0, - address=Address(0x91B291A3336BC1357388354DF18CA061B39E3745), # noqa: E501 + address=Address(0x8169DC735802BB5C18A777052CF4CE326B5FD725), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stStaticCall/test_static_call_basic.py b/tests/ported_static/stStaticCall/test_static_call_basic.py index 00a1b0623e4..a3cf98b6409 100644 --- a/tests/ported_static/stStaticCall/test_static_call_basic.py +++ b/tests/ported_static/stStaticCall/test_static_call_basic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -71,9 +70,7 @@ def test_static_call_basic( ) -> None: """Test_static_call_basic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -123,6 +120,24 @@ def test_static_call_basic( address=Address(0xEAD198F480FB91A5FBEDCF5EB28CD369EE4C6CF2), # noqa: E501 ) # Source: lll + # { (LOG0 1 10) (MSTORE 1 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.LOG0(offset=0x1, size=0xA) + + Op.MSTORE(offset=0x1, value=0x1) + + Op.STOP, + balance=23, + nonce=0, + address=Address(0x2E0DD8ABE4E68C5B602F3C65051F4B30C6D018DA), # noqa: E501 + ) + # Source: lll + # { (MSTORE 1 1) } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + balance=23, + nonce=0, + address=Address(0xC93C7A588B13699E562B3933E8F2B1C15E610781), # noqa: E501 + ) + # Source: lll # { (CALL 40000 0 0 0 0 0) (MSTORE 1 1) } # noqa: E501 addr_3 = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -143,16 +158,6 @@ def test_static_call_basic( address=Address(0xEB015F637A39C63F8B6DB67505F5C02C613DEFC1), # noqa: E501 ) # Source: lll - # { (LOG0 1 10) (MSTORE 1 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.LOG0(offset=0x1, size=0xA) - + Op.MSTORE(offset=0x1, value=0x1) - + Op.STOP, - balance=23, - nonce=0, - address=Address(0x2E0DD8ABE4E68C5B602F3C65051F4B30C6D018DA), # noqa: E501 - ) - # Source: lll # { (CALLCODE 40000 1 0 0 0 0) (MSTORE 1 1) } # noqa: E501 addr_5 = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -172,15 +177,6 @@ def test_static_call_basic( nonce=0, address=Address(0xD5B64FA2CA1E471B45B639A5E9C259CA24C28ACE), # noqa: E501 ) - # Source: lll - # { (MSTORE 1 1) } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - balance=23, - nonce=0, - address=Address(0xC93C7A588B13699E562B3933E8F2B1C15E610781), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_call_change_revert.py b/tests/ported_static/stStaticCall/test_static_call_change_revert.py index 1aa56589b9b..2d6b7295118 100644 --- a/tests/ported_static/stStaticCall/test_static_call_change_revert.py +++ b/tests/ported_static/stStaticCall/test_static_call_change_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -65,9 +64,7 @@ def test_static_call_change_revert( ) -> None: """Test_static_call_change_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -96,6 +93,22 @@ def test_static_call_change_revert( address=Address(0x492BB18ADCE7DA2BED3592742FB4E3DF9086FB4C), # noqa: E501 ) # Source: lll + # { (MSTORE 1 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + address=Address(0xC031FC0AA7B61A5D7D962AFEE8838DEC6948ABB7), # noqa: E501 + ) + # Source: lll + # { (MSTORE 1 1) (SSTORE 1 (SLOAD 1)) } + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + + Op.SSTORE(key=0x1, value=Op.SLOAD(key=0x1)) + + Op.STOP, + nonce=0, + address=Address(0x47C4ED3D93429CB8304737E2327B522E8928C9F3), # noqa: E501 + ) + # Source: lll # { [[ 0 ]] (CALL 100000 1 0 0 0 0) [[ 1 ]] (STATICCALL 100000 0 0 0 0) [[ 2 ]] (CALL 100000 1 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( @@ -139,13 +152,6 @@ def test_static_call_change_revert( address=Address(0xE6F1FDAA1C99007971C641E10AF3A8FAC0B641C8), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xC031FC0AA7B61A5D7D962AFEE8838DEC6948ABB7), # noqa: E501 - ) - # Source: lll # { [[ 0 ]] (CALL 100000 1 0 0 0 0) [[ 1 ]] (STATICCALL 100000 0 0 0 0) [[ 2 ]] (CALL 100000 1 0 0 0 0) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 addr_3 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( @@ -239,16 +245,6 @@ def test_static_call_change_revert( nonce=0, address=Address(0x2C004389EDAAE817E664B6D660F46735756B56D3), # noqa: E501 ) - # Source: lll - # { (MSTORE 1 1) (SSTORE 1 (SLOAD 1)) } - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) - + Op.SSTORE(key=0x1, value=Op.SLOAD(key=0x1)) - + Op.STOP, - nonce=0, - address=Address(0x47C4ED3D93429CB8304737E2327B522E8928C9F3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_and_call_it_oog.py b/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_and_call_it_oog.py index 6710604ac0c..e6b7b771be7 100644 --- a/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_and_call_it_oog.py +++ b/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_and_call_it_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -63,9 +62,7 @@ def test_static_call_contract_to_create_contract_and_call_it_oog( """Test_static_call_contract_to_create_contract_and_call_it_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -104,7 +101,6 @@ def test_static_call_contract_to_create_contract_and_call_it_oog( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) expect_entries_: list[dict] = [ { @@ -112,7 +108,9 @@ def test_static_call_contract_to_create_contract_and_call_it_oog( "network": [">=Cancun"], "result": { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), sender: Account(nonce=1), diff --git a/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog.py b/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog.py index b389aa587f1..cdf25c71569 100644 --- a/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog.py +++ b/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.forks import Fork from execution_testing.specs.static_state.expect_section import ( @@ -62,9 +62,7 @@ def test_static_call_contract_to_create_contract_oog( """Test_static_call_contract_to_create_contract_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -94,7 +92,6 @@ def test_static_call_contract_to_create_contract_oog( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) expect_entries_: list[dict] = [ { @@ -110,7 +107,9 @@ def test_static_call_contract_to_create_contract_oog( "network": [">=Cancun"], "result": { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), sender: Account(nonce=1), diff --git a/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog_bonus_gas.py b/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog_bonus_gas.py index 54d37a49a9f..33baff843c7 100644 --- a/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog_bonus_gas.py +++ b/tests/ported_static/stStaticCall/test_static_call_contract_to_create_contract_oog_bonus_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,9 +63,7 @@ def test_static_call_contract_to_create_contract_oog_bonus_gas( """Gas analysis showed this test's gas can go as low as 101174, and...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -100,7 +97,6 @@ def test_static_call_contract_to_create_contract_oog_bonus_gas( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) expect_entries_: list[dict] = [ { @@ -108,7 +104,9 @@ def test_static_call_contract_to_create_contract_oog_bonus_gas( "network": [">=Cancun None: """Test_static_call_create.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -104,6 +101,14 @@ def test_static_call_create( address=Address(0xE49F04B30026F23E9E04493C44ECE7CFEC9224CA), # noqa: E501 ) # Source: lll + # { (CREATE 0 1 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.CREATE(value=0x0, offset=0x1, size=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x29D4D72A31D1B141B2067D1D4193BDF12FCDDC41), # noqa: E501 + ) + # Source: lll # { (CALL 150000 0 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.CALL( @@ -152,15 +157,6 @@ def test_static_call_create( nonce=0, address=Address(0xF9ECFE0635FEFB5AD44418F97D7FCAF210EBD5AA), # noqa: E501 ) - # Source: lll - # { (CREATE 0 1 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.CREATE(value=0x0, offset=0x1, size=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x29D4D72A31D1B141B2067D1D4193BDF12FCDDC41), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_call_create2.py b/tests/ported_static/stStaticCall/test_static_call_create2.py index 54c33b8d0a8..98394b0847c 100644 --- a/tests/ported_static/stStaticCall/test_static_call_create2.py +++ b/tests/ported_static/stStaticCall/test_static_call_create2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -70,9 +69,7 @@ def test_static_call_create2( contract_1 = Address(0x1000000000000000000000000000000000000000) contract_2 = Address(0x1000000000000000000000000000000000000001) contract_3 = Address(0x1000000000000000000000000000000000000002) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -172,7 +169,6 @@ def test_static_call_create2( nonce=0, address=Address(0x1000000000000000000000000000000000000002), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { @@ -181,7 +177,7 @@ def test_static_call_create2( "result": { contract_1: Account( storage={ - 0: 0x13136008B64FF592819B2FA6D43F2835C452020E, + 0: compute_create_address(address=contract_1, nonce=0), 1: 1, }, ), @@ -193,7 +189,7 @@ def test_static_call_create2( "result": { contract_2: Account( storage={ - 0: 0x5DDDFCE53EE040D9EB21AFBC0AE1BB4DBB0BA643, + 0: compute_create_address(address=contract_2, nonce=0), 1: 0, }, ), diff --git a/tests/ported_static/stStaticCall/test_static_call_create3.py b/tests/ported_static/stStaticCall/test_static_call_create3.py index 44f5ac81bc3..9df3d855c26 100644 --- a/tests/ported_static/stStaticCall/test_static_call_create3.py +++ b/tests/ported_static/stStaticCall/test_static_call_create3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Hash, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -36,9 +36,7 @@ def test_static_call_create3( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA000000000000000000000000000000000000000) contract_1 = Address(0x1000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -90,7 +88,6 @@ def test_static_call_create3( nonce=0, address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -103,7 +100,7 @@ def test_static_call_create3( post = { contract_1: Account( storage={ - 0: 0x13136008B64FF592819B2FA6D43F2835C452020E, + 0: compute_create_address(address=contract_1, nonce=0), 1: 1, 2: 1, }, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0.py index 402741a5515..5ee180c5ce7 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0.py @@ -48,6 +48,7 @@ def test_static_call_ecrecover0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_static_call_ecrecover0( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,14 +94,6 @@ def test_static_call_ecrecover0( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_0input.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_0input.py index 08e2b13a797..3e8f4614d9f 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_0input.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_0input.py @@ -114,6 +114,7 @@ def test_static_call_ecrecover0_0input( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (STATICCALL 300000 (CALLDATALOAD 0) 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -136,7 +137,6 @@ def test_static_call_ecrecover0_0input( nonce=0, address=Address(0x1FD04A51AC69C94C58521D30E2DEFC4856A581B0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_complete_return_value.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_complete_return_value.py index da95498db9e..15059991aec 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_complete_return_value.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_complete_return_value.py @@ -50,6 +50,7 @@ def test_static_call_ecrecover0_complete_return_value( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 13000 1 0 128 128 32) [[ 0 ]] (MLOAD 128) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_static_call_ecrecover0_complete_return_value( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -93,13 +93,6 @@ def test_static_call_ecrecover0_complete_return_value( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas2999.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas2999.py index 512e421fd88..ce7ceef21ed 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas2999.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas2999.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_ecrecover0_gas2999( ) -> None: """Test_static_call_ecrecover0_gas2999.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_static_call_ecrecover0_gas2999( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xA2C5B42CEEF52ED9FAD58B7C78F1A9FDE7241247), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas3000.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas3000.py index bfca4018811..c95af7ecce3 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas3000.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_gas3000.py @@ -48,6 +48,7 @@ def test_static_call_ecrecover0_gas3000( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 3000 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_static_call_ecrecover0_gas3000( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,14 +94,6 @@ def test_static_call_ecrecover0_gas3000( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_no_gas.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_no_gas.py index 674c360d8f5..9857b5cc971 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_no_gas.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_no_gas.py @@ -7,8 +7,6 @@ import pytest from execution_testing import ( - EOA, - Account, Address, Alloc, Bytes, @@ -34,9 +32,7 @@ def test_static_call_ecrecover0_no_gas( ) -> None: """Test_static_call_ecrecover0_no_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +77,7 @@ def test_static_call_ecrecover0_no_gas( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x6231F5F50790A293B60749CF936C2F442D692BB4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_overlapping_input_output.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_overlapping_input_output.py index 58be186c704..b1c2bb72d51 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover0_overlapping_input_output.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover0_overlapping_input_output.py @@ -50,6 +50,7 @@ def test_static_call_ecrecover0_overlapping_input_output( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_static_call_ecrecover0_overlapping_input_output( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_static_call_ecrecover0_overlapping_input_output( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover1.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover1.py index 7651d0d4548..c6844562034 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover1.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_ecrecover1( ) -> None: """Test_static_call_ecrecover1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_static_call_ecrecover1( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x618120F7C175E20B183ADDD8859095183359B357), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover2.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover2.py index 6c8479c30b7..29c1943b26d 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover2.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_ecrecover2( ) -> None: """Test_static_call_ecrecover2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_static_call_ecrecover2( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x77C4DEDD873BB751217A744A41CCC43A37E0859E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover3.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover3.py index dd6afae45f5..eb69f789789 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover3.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover3.py @@ -47,6 +47,7 @@ def test_static_call_ecrecover3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (STATICCALL 100000 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_static_call_ecrecover3( nonce=0, address=Address(0xC2F38613F26B4B1C6DE179462718C7E67C175419), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover80.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover80.py index 88caa192658..28cd2eeb1d2 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover80.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover80.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_ecrecover80( ) -> None: """Test_static_call_ecrecover80.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_static_call_ecrecover80( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xB04D781B56FBA0546D9C9FD33C9FB623908D49D2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length.py index 57d6e56cfed..9a13e86548e 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length.py @@ -48,6 +48,7 @@ def test_static_call_ecrecover_check_length( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 128 0x1122334455667788990011223344556677889900112233445566778899001122) (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 128 32) [[ 0 ]] (MLOAD 128) [[ 1 ]] (MSIZE) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +87,6 @@ def test_static_call_ecrecover_check_length( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -96,14 +96,6 @@ def test_static_call_ecrecover_check_length( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 160, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 160, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length_wrong_v.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length_wrong_v.py index d3acf5ef081..08b06436b82 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length_wrong_v.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover_check_length_wrong_v.py @@ -49,6 +49,7 @@ def test_static_call_ecrecover_check_length_wrong_v( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 128 0x1122334455667788990011223344556677889900112233445566778899001122) (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 29) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 128 32) [[ 0 ]] (MLOAD 128) [[ 1 ]] (MSIZE) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_static_call_ecrecover_check_length_wrong_v( nonce=0, address=Address(0x41F7EE7D96703A0F8BD1BF92288996596CA85BD6), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover_h_prefixed0.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover_h_prefixed0.py index ea35f8768dc..be4fc0ca392 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover_h_prefixed0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover_h_prefixed0.py @@ -47,6 +47,7 @@ def test_static_call_ecrecover_h_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_static_call_ecrecover_h_prefixed0( nonce=0, address=Address(0xEEAA46C8D2B439BCCC8BA7B735F1F68564C75801), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover_r_prefixed0.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover_r_prefixed0.py index c543ae7ba01..7fd5e2936e9 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover_r_prefixed0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover_r_prefixed0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_ecrecover_r_prefixed0( ) -> None: """Test_static_call_ecrecover_r_prefixed0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,9 +78,7 @@ def test_static_call_ecrecover_r_prefixed0( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x2E063E550F3F9751EF9EB0DA5E2B392C3ECE8E6E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover_s_prefixed0.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover_s_prefixed0.py index 15ef873cde3..afba19f8745 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover_s_prefixed0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover_s_prefixed0.py @@ -47,6 +47,7 @@ def test_static_call_ecrecover_s_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -83,7 +84,6 @@ def test_static_call_ecrecover_s_prefixed0( nonce=0, address=Address(0x200ECC0698B28EF50EE8BF150B2D7A87ED969482), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ecrecover_v_prefixed0.py b/tests/ported_static/stStaticCall/test_static_call_ecrecover_v_prefixed0.py index 4330ce2f807..cd0496d97af 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ecrecover_v_prefixed0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ecrecover_v_prefixed0.py @@ -48,6 +48,7 @@ def test_static_call_ecrecover_v_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 0x001c) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (STATICCALL 300000 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -84,7 +85,6 @@ def test_static_call_ecrecover_v_prefixed0( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -94,14 +94,6 @@ def test_static_call_ecrecover_v_prefixed0( value=0x186A0, ) - post = { - contract_0: Account( - storage={ - 0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 1: 1, - 2: 1, - }, - ), - } + post = {contract_0: Account(storage={0: sender, 1: 1, 2: 1})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level.py b/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level.py index 67c548c3359..c9bfd6ecd1b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level.py +++ b/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_goes_oog_on_second_level( ) -> None: """Test_static_call_goes_oog_on_second_level.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,51 +44,47 @@ def test_static_call_goes_oog_on_second_level( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (SSTORE 9 (STATICCALL 600000 0 0 0 0)) [[ 10 ]] (GAS) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x9, + # { (KECCAK256 0x00 0x2fffff) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 0 0 0 0)) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x8, value=Op.GAS) + + Op.MSTORE( + offset=0x9, value=Op.STATICCALL( gas=0x927C0, - address=0xA1202B00F0CB8ACDD112E4FC87899F33572541C6, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, ret_size=0x0, ), ) - + Op.SSTORE(key=0xA, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x6A2A170A903E470C3DD8BFD7974C77020C5FD8F9), # noqa: E501 ) # Source: lll - # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 0 0 0 0)) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x8, value=Op.GAS) - + Op.MSTORE( - offset=0x9, + # { (SSTORE 9 (STATICCALL 600000 0 0 0 0)) [[ 10 ]] (GAS) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x9, value=Op.STATICCALL( gas=0x927C0, - address=0x44969261D9660FCC1A2E03DB83BA372EBF5F652D, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, ret_size=0x0, ), ) + + Op.SSTORE(key=0xA, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xA1202B00F0CB8ACDD112E4FC87899F33572541C6), # noqa: E501 - ) - # Source: lll - # { (KECCAK256 0x00 0x2fffff) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - nonce=0, - address=Address(0x44969261D9660FCC1A2E03DB83BA372EBF5F652D), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level2.py b/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level2.py index a101aad3b73..62ed98b8dc7 100644 --- a/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level2.py +++ b/tests/ported_static/stStaticCall/test_static_call_goes_oog_on_second_level2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_call_goes_oog_on_second_level2( ) -> None: """Test_static_call_goes_oog_on_second_level2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -69,27 +66,6 @@ def test_static_call_goes_oog_on_second_level2( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 600000 0 32 0 0) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x927C0, - address=0x666EBB8AFC7A9BA4BEDB7D78F85184B65639531D, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xB9C1C6C39CB3E528B2EF06493C17D63B7827077B), # noqa: E501 - ) # Source: lll # { (MSTORE 8 (GAS)) (MSTORE 9 (STATICCALL 600000 (CALLDATALOAD 0) 0 0 0 0)) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -131,6 +107,26 @@ def test_static_call_goes_oog_on_second_level2( nonce=0, address=Address(0x45E70D14D712A8898DCE133FE063F71179F04059), # noqa: E501 ) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 600000 0 32 0 0) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x927C0, + address=0x666EBB8AFC7A9BA4BEDB7D78F85184B65639531D, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0xB9C1C6C39CB3E528B2EF06493C17D63B7827077B), # noqa: E501 + ) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_call_identitiy_1.py b/tests/ported_static/stStaticCall/test_static_call_identitiy_1.py index d4cea15356c..69543edfe7d 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identitiy_1.py +++ b/tests/ported_static/stStaticCall/test_static_call_identitiy_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_identitiy_1( ) -> None: """Test_static_call_identitiy_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_static_call_identitiy_1( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x93D25CE7C8AF6CACE03DCB393962CB32BA8D4F42), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_1_nonzero_value.py b/tests/ported_static/stStaticCall/test_static_call_identity_1_nonzero_value.py index af26095d83c..3b572358cc7 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_1_nonzero_value.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_1_nonzero_value.py @@ -47,6 +47,7 @@ def test_static_call_identity_1_nonzero_value( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (STATICCALL 200000 4 0 0 0 32) (CALL 50000 4 0x13 0 0 0 0) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -78,7 +79,6 @@ def test_static_call_identity_1_nonzero_value( nonce=0, address=Address(0x07F023A2418EB0DC955C465D7E5EF48189F005BE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_2.py b/tests/ported_static/stStaticCall/test_static_call_identity_2.py index 96ea610d598..31dce0ef656 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_2.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_2.py @@ -47,6 +47,7 @@ def test_static_call_identity_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (STATICCALL 500 4 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_identity_2( nonce=0, address=Address(0xC23A3B84D36D8D9D3D045162C4C153465DE4816C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_3.py b/tests/ported_static/stStaticCall/test_static_call_identity_3.py index b186a4b22f9..57753b43a4b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_3.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_3.py @@ -47,6 +47,7 @@ def test_static_call_identity_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (STATICCALL 500 4 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_identity_3( nonce=0, address=Address(0xC23A3B84D36D8D9D3D045162C4C153465DE4816C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_4.py b/tests/ported_static/stStaticCall/test_static_call_identity_4.py index 75b52c55ce9..dd549863976 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_4.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_4.py @@ -47,6 +47,7 @@ def test_static_call_identity_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 100 4 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_identity_4( nonce=0, address=Address(0x1E23B8487DE5C16B372F0ABE69D7C9D57118DEFD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_4_gas17.py b/tests/ported_static/stStaticCall/test_static_call_identity_4_gas17.py index d7828e843e3..1cee3493e76 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_4_gas17.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_4_gas17.py @@ -47,6 +47,7 @@ def test_static_call_identity_4_gas17( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 17 4 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_identity_4_gas17( nonce=0, address=Address(0x23EF65623397A46F452ADA1DC7E9F974B028AD46), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_4_gas18.py b/tests/ported_static/stStaticCall/test_static_call_identity_4_gas18.py index b9708a272c1..cc67adad4e3 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_4_gas18.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_4_gas18.py @@ -47,6 +47,7 @@ def test_static_call_identity_4_gas18( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 18 4 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_identity_4_gas18( nonce=0, address=Address(0x3B631E26EB9003C05E06782820DB8893B7C864DF), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_identity_5.py b/tests/ported_static/stStaticCall/test_static_call_identity_5.py index 12369f7713e..70b71f555ee 100644 --- a/tests/ported_static/stStaticCall/test_static_call_identity_5.py +++ b/tests/ported_static/stStaticCall/test_static_call_identity_5.py @@ -47,6 +47,7 @@ def test_static_call_identity_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 600 4 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_identity_5( nonce=0, address=Address(0xE916A006634545DCD9A7DF166A5DA16ED90148B0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_lose_gas_oog.py b/tests/ported_static/stStaticCall/test_static_call_lose_gas_oog.py index b0af0e1ee31..da74a333e31 100644 --- a/tests/ported_static/stStaticCall/test_static_call_lose_gas_oog.py +++ b/tests/ported_static/stStaticCall/test_static_call_lose_gas_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,10 +33,7 @@ def test_static_call_lose_gas_oog( ) -> None: """Test_static_call_lose_gas_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,7 @@ def test_static_call_lose_gas_oog( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { [[ 0 ]] (ADD @@0 1) [[ 1 ]] (STATICCALL (ADD 1(MUL @@0 100000)) 0 0 0 0) [[ 2 ]] (ADD 1(MUL @@0 1000)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call_one_v_call_suicide.py b/tests/ported_static/stStaticCall/test_static_call_one_v_call_suicide.py index 33065232403..dbf7225d7e6 100644 --- a/tests/ported_static/stStaticCall/test_static_call_one_v_call_suicide.py +++ b/tests/ported_static/stStaticCall/test_static_call_one_v_call_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_one_v_call_suicide( ) -> None: """Test_static_call_one_v_call_suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_static_call_one_v_call_suicide( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[1]](STATICCALL 60000 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs1.py b/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs1.py index beaf18a288e..2d1f355c82b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs1.py +++ b/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_call_oog_additional_gas_costs1( ) -> None: """Test_static_call_oog_additional_gas_costs1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -67,9 +64,7 @@ def test_static_call_oog_additional_gas_costs1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE5625454DFC66A8DCC86F028C5F5AB384F2E8CC3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs2_paris.py b/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs2_paris.py index c801c9e79b2..82f93e20b98 100644 --- a/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs2_paris.py +++ b/tests/ported_static/stStaticCall/test_static_call_oog_additional_gas_costs2_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,10 +35,7 @@ def test_static_call_oog_additional_gas_costs2_paris( ) -> None: """Test_static_call_oog_additional_gas_costs2_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,6 +46,7 @@ def test_static_call_oog_additional_gas_costs2_paris( gas_limit=3000000000, ) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[ 0 ]] (STATICCALL 6000 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +54,7 @@ def test_static_call_oog_additional_gas_costs2_paris( key=0x0, value=Op.STATICCALL( gas=0x1770, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -68,10 +65,7 @@ def test_static_call_oog_additional_gas_costs2_paris( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB836BAD7C1AE4C13AC3CBEC9A4445EA8B80E3A31), # noqa: E501 ) - pre[addr] = Account(balance=10) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_output1.py b/tests/ported_static/stStaticCall/test_static_call_output1.py index df38cded9a3..eb4e4be0b7c 100644 --- a/tests/ported_static/stStaticCall/test_static_call_output1.py +++ b/tests/ported_static/stStaticCall/test_static_call_output1.py @@ -47,6 +47,15 @@ def test_static_call_output1( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (STATICCALL 50000 0 0 0 0) [[ 0 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +66,7 @@ def test_static_call_output1( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,15 +79,6 @@ def test_static_call_output1( nonce=0, address=Address(0x9C450200C431343E91665596BD7F249469F3823A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_output2.py b/tests/ported_static/stStaticCall/test_static_call_output2.py index ab3aa1a330c..040fd1e0cc5 100644 --- a/tests/ported_static/stStaticCall/test_static_call_output2.py +++ b/tests/ported_static/stStaticCall/test_static_call_output2.py @@ -47,6 +47,15 @@ def test_static_call_output2( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (STATICCALL 50000 0 32 0 0) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +66,7 @@ def test_static_call_output2( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x20, ret_offset=0x0, @@ -70,15 +79,6 @@ def test_static_call_output2( nonce=0, address=Address(0x0CC5226EEA92A2AF2F4F36413737F04F984C43A7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_output3.py b/tests/ported_static/stStaticCall/test_static_call_output3.py index ebeb6891dab..42e1f2232bd 100644 --- a/tests/ported_static/stStaticCall/test_static_call_output3.py +++ b/tests/ported_static/stStaticCall/test_static_call_output3.py @@ -47,6 +47,15 @@ def test_static_call_output3( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (STATICCALL 50000 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +66,7 @@ def test_static_call_output3( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,15 +79,6 @@ def test_static_call_output3( nonce=0, address=Address(0x70663C1333ECBAEA42F33AB4EC9BB647C794BFCD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_output3_fail.py b/tests/ported_static/stStaticCall/test_static_call_output3_fail.py index 4ded5413f69..a5dfaea9b35 100644 --- a/tests/ported_static/stStaticCall/test_static_call_output3_fail.py +++ b/tests/ported_static/stStaticCall/test_static_call_output3_fail.py @@ -47,6 +47,15 @@ def test_static_call_output3_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (STATICCALL 50000 0 0 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +66,7 @@ def test_static_call_output3_fail( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,15 +79,6 @@ def test_static_call_output3_fail( nonce=0, address=Address(0x70663C1333ECBAEA42F33AB4EC9BB647C794BFCD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_output3partial.py b/tests/ported_static/stStaticCall/test_static_call_output3partial.py index 3fd4cd42c25..e480e7984f5 100644 --- a/tests/ported_static/stStaticCall/test_static_call_output3partial.py +++ b/tests/ported_static/stStaticCall/test_static_call_output3partial.py @@ -47,6 +47,15 @@ def test_static_call_output3partial( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x6001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (STATICCALL 50000 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +66,7 @@ def test_static_call_output3partial( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0xBCC1197CCD23A97607F2F96D031F3432E0D16A02, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,15 +79,6 @@ def test_static_call_output3partial( nonce=0, address=Address(0xA4216CFBA09E812CE041C734F1A2F266CB02B02D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x6001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBCC1197CCD23A97607F2F96D031F3432E0D16A02), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_output3partial_fail.py b/tests/ported_static/stStaticCall/test_static_call_output3partial_fail.py index 6a701a9a979..780dc6dbf1c 100644 --- a/tests/ported_static/stStaticCall/test_static_call_output3partial_fail.py +++ b/tests/ported_static/stStaticCall/test_static_call_output3partial_fail.py @@ -47,6 +47,15 @@ def test_static_call_output3partial_fail( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x016001600101600055 + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6) (STATICCALL 50000 0 0 0 10) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +66,7 @@ def test_static_call_output3partial_fail( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -70,15 +79,6 @@ def test_static_call_output3partial_fail( nonce=0, address=Address(0xA4216CFBA09E812CE041C734F1A2F266CB02B02D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - # Source: raw - # 0x016001600101600055 - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD + Op.SSTORE(key=0x0, value=Op.ADD(0x1, 0x1)), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x834ABC2C68C5F44EA9AE82B67AAF92044901CDC6), # noqa: E501 - ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0.py index 363c767a98f..657e3514442 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb0( ) -> None: """Test_static_call_recursive_bomb0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,22 @@ def test_static_call_recursive_bomb0( gas_limit=100000000000, ) + # Source: lll + # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 11000) (ADDRESS) 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) + + Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0x2AF8), + address=Op.ADDRESS, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 100000000 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +68,7 @@ def test_static_call_recursive_bomb0( key=0x0, value=Op.STATICCALL( gas=0x5F5E100, - address=0xC2641F62F868340A29AFB342ECBE22936A4336AE, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -66,26 +79,7 @@ def test_static_call_recursive_bomb0( + Op.STOP, balance=0x77359400, nonce=0, - address=Address(0xA8F75B202DBA133E3184B84520CF27623E8C993F), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 11000) (ADDRESS) 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) - + Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0x2AF8), - address=Op.ADDRESS, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC2641F62F868340A29AFB342ECBE22936A4336AE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0_oog_at_max_call_depth.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0_oog_at_max_call_depth.py index a4c926743a6..0d65d75e520 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0_oog_at_max_call_depth.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb0_oog_at_max_call_depth.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_static_call_recursive_bomb0_oog_at_max_call_depth( ) -> None: """Test_static_call_recursive_bomb0_oog_at_max_call_depth.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,26 +47,6 @@ def test_static_call_recursive_bomb0_oog_at_max_call_depth( gas_limit=110000000000, ) - # Source: lll - # { (CALLCODE (GAS) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.CALLCODE( - gas=Op.GAS, - address=0xBB09BB747BB11897420C59CACB65853142C67BB7, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0x4A20A569D7008020C8CD630CFF560F3E627522D3), # noqa: E501 - ) # Source: lll # { (MSTORE 0 (+ (SLOAD 0) 1)) (MSTORE 2 (MUL (DIV (MLOAD 0) 0x0402) 0xfffffffffffffffffff)) (STATICCALL (- (GAS) 1024) (ADDRESS) 0 (MUL (DIV (MLOAD 0) 0x0402) 0xfffffffffffffffffff) 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -93,9 +70,26 @@ def test_static_call_recursive_bomb0_oog_at_max_call_depth( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xBB09BB747BB11897420C59CACB65853142C67BB7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (CALLCODE (GAS) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.CALLCODE( + gas=Op.GAS, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb1.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb1.py index e1779f0b26d..cf3f30a8c2a 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb1.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb1( ) -> None: """Test_static_call_recursive_bomb1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,29 @@ def test_static_call_recursive_bomb1( gas_limit=100000000, ) + # Source: lll + # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 15000) (ADDRESS) 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) + + Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0x3A98), + address=Op.ADDRESS, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) # Source: lll # { (CALLCODE (GAS) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=Op.GAS, - address=0xCF55FF2B7D15859F0CEA76885B2D9E850D7DCACD, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,26 +79,7 @@ def test_static_call_recursive_bomb1( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x3134AAC90D2474F00108572CB10AD2DE05BFA7EE), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 15000) (ADDRESS) 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) - + Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0x3A98), - address=Op.ADDRESS, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0xCF55FF2B7D15859F0CEA76885B2D9E850D7DCACD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb2.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb2.py index f8af9c790ab..751b3586db1 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb2.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb2( ) -> None: """Test_static_call_recursive_bomb2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,22 @@ def test_static_call_recursive_bomb2( gas_limit=100000000, ) + # Source: lll + # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 15000) (ADDRESS) 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) + + Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0x3A98), + address=Op.ADDRESS, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALLCODE (GAS) 0 0 0 0 0) [[ 1 ]] 1} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +68,7 @@ def test_static_call_recursive_bomb2( key=0x0, value=Op.CALLCODE( gas=Op.GAS, - address=0xCF55FF2B7D15859F0CEA76885B2D9E850D7DCACD, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -67,26 +80,7 @@ def test_static_call_recursive_bomb2( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xFB952C049826590F07BEE2F88274ADF6C4724A6C), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 15000) (ADDRESS) 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) - + Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0x3A98), - address=Op.ADDRESS, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0xCF55FF2B7D15859F0CEA76885B2D9E850D7DCACD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb3.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb3.py index e9b23c04fac..352dacad6d4 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb3.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_recursive_bomb3( ) -> None: """Test_static_call_recursive_bomb3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_static_call_recursive_bomb3( gas_limit=10000000, ) + # Source: lll + # { (MSTORE 0 (+ (SLOAD 0) 1)) (STATICCALL (- (GAS) 224) (ADDRESS) 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.SLOAD(key=0x0), 0x1)) + + Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0xE0), + address=Op.ADDRESS, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALLCODE ( - (GAS) 100000) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +67,7 @@ def test_static_call_recursive_bomb3( key=0x0, value=Op.CALLCODE( gas=Op.SUB(Op.GAS, 0x186A0), - address=0xDA47DB5B3761AED22B9F70AEDAA7D54C5E340CC5, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -66,26 +79,7 @@ def test_static_call_recursive_bomb3( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xB5347F5CFB7BF5DA15162FB6D93A36B5CB3F4FA9), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (+ (SLOAD 0) 1)) (STATICCALL (- (GAS) 224) (ADDRESS) 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.SLOAD(key=0x0), 0x1)) - + Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0xE0), - address=Op.ADDRESS, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0xDA47DB5B3761AED22B9F70AEDAA7D54C5E340CC5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log.py index 962c9ed3eda..dc7f03d6b11 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb_log( ) -> None: """Test_static_call_recursive_bomb_log.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,26 +45,6 @@ def test_static_call_recursive_bomb_log( gas_limit=100000000000, ) - # Source: lll - # { [[ 0 ]] (STATICCALL (- (GAS) 100000) 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0x186A0), - address=0xC60FAB741BDA8373B3905ED824826A8F6EA8FD0A, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0x2EFFE40C3FDB4ABB2979BFCFB8D814F1A786576D), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) (STATICCALL (- (GAS) 25000) (ADDRESS) 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -87,9 +64,26 @@ def test_static_call_recursive_bomb_log( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC60FAB741BDA8373B3905ED824826A8F6EA8FD0A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { [[ 0 ]] (STATICCALL (- (GAS) 100000) 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0x186A0), + address=addr, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log2.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log2.py index 1253691d71f..c4ff86cdbfe 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log2.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_log2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb_log2( ) -> None: """Test_static_call_recursive_bomb_log2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,23 @@ def test_static_call_recursive_bomb_log2( gas_limit=20000000000, ) + # Source: lll + # { (MSTORE 0 (GAS)) (LOG0 0 32) (STATICCALL (- (GAS) 25000) (ADDRESS) 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.GAS) + + Op.LOG0(offset=0x0, size=0x20) + + Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0x61A8), + address=Op.ADDRESS, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL ( - (GAS) 100000) 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +69,7 @@ def test_static_call_recursive_bomb_log2( key=0x0, value=Op.STATICCALL( gas=Op.SUB(Op.GAS, 0x186A0), - address=0xB6D3EDE67FDCDD6C67468B0EE88BD06FA680F8B3, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -66,27 +80,7 @@ def test_static_call_recursive_bomb_log2( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x846AC33C2465429E6D236EEB8A440983AC2349ED), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (GAS)) (LOG0 0 32) (STATICCALL (- (GAS) 25000) (ADDRESS) 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.GAS) - + Op.LOG0(offset=0x0, size=0x20) - + Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0x61A8), - address=Op.ADDRESS, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xB6D3EDE67FDCDD6C67468B0EE88BD06FA680F8B3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call.py index f44790d4296..4738e9904e3 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb_pre_call( ) -> None: """Test_static_call_recursive_bomb_pre_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x77F65B71F1F16A75476F469F7106D1B60BFEC266AE25B8DA16A9091D223AA24A - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -95,7 +92,6 @@ def test_static_call_recursive_bomb_pre_call( nonce=0, address=Address(0x72E480206054168CFA7D5C6A1BD8C3FFE26A4D82), # noqa: E501 ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call2.py b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call2.py index 4eed5ee7da2..cd1ce27254d 100644 --- a/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call2.py +++ b/tests/ported_static/stStaticCall/test_static_call_recursive_bomb_pre_call2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_static_call_recursive_bomb_pre_call2( ) -> None: """Test_static_call_recursive_bomb_pre_call2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x77F65B71F1F16A75476F469F7106D1B60BFEC266AE25B8DA16A9091D223AA24A - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,22 @@ def test_static_call_recursive_bomb_pre_call2( gas_limit=9223372036854775807, ) + # Source: lll + # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 224000) (ADDRESS) 0 0 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) + + Op.STATICCALL( + gas=Op.SUB(Op.GAS, 0x36B00), + address=Op.ADDRESS, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { (STATICCALL 100000 0xbad304eb96065b2a98b57a48a06ae28d285a71b5 0 0 0 0) [[ 0 ]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -65,7 +78,7 @@ def test_static_call_recursive_bomb_pre_call2( key=0x0, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xED136EDCE8F08EF121C25430E7DEC4ED3FEB511D, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -76,26 +89,7 @@ def test_static_call_recursive_bomb_pre_call2( + Op.STOP, balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, nonce=0, - address=Address(0x5E01FE5D73A471C61018A02F7CF7D8F977343093), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (+ (MLOAD 0) 1)) (STATICCALL (- (GAS) 224000) (ADDRESS) 0 0 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(Op.MLOAD(offset=0x0), 0x1)) - + Op.STATICCALL( - gas=Op.SUB(Op.GAS, 0x36B00), - address=Op.ADDRESS, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xED136EDCE8F08EF121C25430E7DEC4ED3FEB511D), # noqa: E501 ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_1.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_1.py index 8c2c71d3895..b08cd8a5b78 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_1.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_1.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (STATICCALL 600 3 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_static_call_ripemd160_1( nonce=0, address=Address(0xE9854E2C2FFBD0C6F24140954AD56F59EBC56434), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_2.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_2.py index b3016d6372d..cd4c0242cf9 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_2.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_2.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 5 0xf34578907f) [[ 2 ]] (STATICCALL 6000 3 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_ripemd160_2( nonce=0, address=Address(0x0D371480E081540255FBCEF75D8C5C09535CEC3A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_3.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_3.py index 28e6f3818a2..1321863a278 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_3.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_3.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (STATICCALL 6000 3 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_ripemd160_3( nonce=0, address=Address(0xEBBC88FF981239628C72A1B30BC50038E636471F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_postfixed0.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_postfixed0.py index 834286c14e3..29786ca5a33 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_postfixed0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_postfixed0.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_3_postfixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f00) [[ 2 ]] (STATICCALL 6000 3 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_ripemd160_3_postfixed0( nonce=0, address=Address(0x8152F3B3414AC9676CD28740BD7900E041CB726C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_prefixed0.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_prefixed0.py index e4edefdd9da..d031dda8803 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_prefixed0.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_3_prefixed0.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_3_prefixed0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00f34578907f) [[ 2 ]] (STATICCALL 6000 3 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_ripemd160_3_prefixed0( nonce=0, address=Address(0xA70CC468F5DF9F13D75A41B072FC82378BE1B31D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_4.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_4.py index 28ed6281b48..f47e5d763ce 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_4.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_4.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 720 3 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_ripemd160_4( nonce=0, address=Address(0xD2243CBF1DE778D48E5FAE09F95D4707623A9FB6), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_4_gas719.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_4_gas719.py index 11277fd777b..8ad51a14383 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_4_gas719.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_4_gas719.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_4_gas719( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 719 3 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_ripemd160_4_gas719( nonce=0, address=Address(0x17CF516DEA393215768EE3BE0A92DBE1DB6A82CC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_ripemd160_5.py b/tests/ported_static/stStaticCall/test_static_call_ripemd160_5.py index ed93f53c218..e0cbcfe7ee9 100644 --- a/tests/ported_static/stStaticCall/test_static_call_ripemd160_5.py +++ b/tests/ported_static/stStaticCall/test_static_call_ripemd160_5.py @@ -47,6 +47,7 @@ def test_static_call_ripemd160_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 6000 3 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_ripemd160_5( nonce=0, address=Address(0x1D3E8582B56142AC3A4D5E93971AB0B6DC2F1636), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_1.py b/tests/ported_static/stStaticCall/test_static_call_sha256_1.py index 2de0c6ae909..6402837e4e1 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_1.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_1.py @@ -47,6 +47,7 @@ def test_static_call_sha256_1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (STATICCALL 500 2 0 0 0 32) [[ 0 ]] (MLOAD 0)} target = pre.deploy_contract( # noqa: F841 @@ -67,7 +68,6 @@ def test_static_call_sha256_1( nonce=0, address=Address(0x9385A5D182321342581977632B67B71FFCE94C7C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_1_nonzero_value.py b/tests/ported_static/stStaticCall/test_static_call_sha256_1_nonzero_value.py index fcb372febe3..6bd0f39acaa 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_1_nonzero_value.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_1_nonzero_value.py @@ -47,6 +47,7 @@ def test_static_call_sha256_1_nonzero_value( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 2 ]] (STATICCALL 200000 2 0 0 0 32) [[ 0 ]] (MLOAD 0) (CALL (GAS) 2 19 0 0 0 0) (CALLCODE (GAS) 2 19 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +88,6 @@ def test_static_call_sha256_1_nonzero_value( nonce=0, address=Address(0x6EFBD97A458C5B978BEA2D03F8808BF02FE8C42D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_2.py b/tests/ported_static/stStaticCall/test_static_call_sha256_2.py index b86128f4223..78c0f14b84b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_2.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_2.py @@ -47,6 +47,7 @@ def test_static_call_sha256_2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 5 0xf34578907f) [[ 2 ]] (STATICCALL 500 2 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_sha256_2( nonce=0, address=Address(0xC3764EF9B916CF39BBC2F0092B1C2E792F160CB1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_3.py b/tests/ported_static/stStaticCall/test_static_call_sha256_3.py index 78784076a20..83f95b4b063 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_3.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_3.py @@ -47,6 +47,7 @@ def test_static_call_sha256_3( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f) [[ 2 ]] (STATICCALL 500 2 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_sha256_3( nonce=0, address=Address(0x9B35A511EDE9CDECC6DFC827744E0CA1D0E5F236), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_3_postfix0.py b/tests/ported_static/stStaticCall/test_static_call_sha256_3_postfix0.py index 5aba000d1f4..538d0123355 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_3_postfix0.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_3_postfix0.py @@ -47,6 +47,7 @@ def test_static_call_sha256_3_postfix0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xf34578907f00) [[ 2 ]] (STATICCALL 500 2 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_sha256_3_postfix0( nonce=0, address=Address(0xD147FCE2C6650060E058B25CCFD3C7B24D744503), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_3_prefix0.py b/tests/ported_static/stStaticCall/test_static_call_sha256_3_prefix0.py index c3b120e768b..467ddd4c5ec 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_3_prefix0.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_3_prefix0.py @@ -47,6 +47,7 @@ def test_static_call_sha256_3_prefix0( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x00f34578907f) [[ 2 ]] (STATICCALL 500 2 0 37 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_static_call_sha256_3_prefix0( nonce=0, address=Address(0x0219107BB8477432AFD6777A32E63E0E7C4B999A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_4.py b/tests/ported_static/stStaticCall/test_static_call_sha256_4.py index 37ddc46be13..e7887f46179 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_4.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_4.py @@ -47,6 +47,7 @@ def test_static_call_sha256_4( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 100 2 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_sha256_4( nonce=0, address=Address(0x91666CD4C3EC5456566D5107F1A3CEE6DC078818), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_4_gas99.py b/tests/ported_static/stStaticCall/test_static_call_sha256_4_gas99.py index 3b2a51c8720..a5d437b3bca 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_4_gas99.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_4_gas99.py @@ -47,6 +47,7 @@ def test_static_call_sha256_4_gas99( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 99 2 0 32 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_sha256_4_gas99( nonce=0, address=Address(0xEDA46FA30192C0AB5A8E9C2567FAF9A110CE6720), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_sha256_5.py b/tests/ported_static/stStaticCall/test_static_call_sha256_5.py index 6cf423cbf01..ad2a974cefb 100644 --- a/tests/ported_static/stStaticCall/test_static_call_sha256_5.py +++ b/tests/ported_static/stStaticCall/test_static_call_sha256_5.py @@ -47,6 +47,7 @@ def test_static_call_sha256_5( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (STATICCALL 600 2 0 1000000 0 32) [[ 0 ]] (MLOAD 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_static_call_sha256_5( nonce=0, address=Address(0x76A2F21C718430C6918BA8C11E175C2636B35671), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_to_call_code_op_code_check.py b/tests/ported_static/stStaticCall/test_static_call_to_call_code_op_code_check.py index 8e13d44b592..1c992da0d5b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_to_call_code_op_code_check.py +++ b/tests/ported_static/stStaticCall/test_static_call_to_call_code_op_code_check.py @@ -47,6 +47,7 @@ def test_static_call_to_call_code_op_code_check( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]] (STATICCALL 100000 (CALLDATALOAD 0) 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -139,7 +140,6 @@ def test_static_call_to_call_code_op_code_check( nonce=0, address=Address(0xF0D7D1B32BBC0012F183FB3E3F4F9434ABED93BD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_to_call_op_code_check.py b/tests/ported_static/stStaticCall/test_static_call_to_call_op_code_check.py index b595a4bdac5..2a383f0cf1b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_to_call_op_code_check.py +++ b/tests/ported_static/stStaticCall/test_static_call_to_call_op_code_check.py @@ -47,6 +47,7 @@ def test_static_call_to_call_op_code_check( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]] (STATICCALL 100000 (CALLDATALOAD 0) 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -139,7 +140,6 @@ def test_static_call_to_call_op_code_check( nonce=0, address=Address(0x0D366057A988CB6562F7FA2A601F06A503D30A90), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_to_del_call_op_code_check.py b/tests/ported_static/stStaticCall/test_static_call_to_del_call_op_code_check.py index a37cc64680d..c46023f3c26 100644 --- a/tests/ported_static/stStaticCall/test_static_call_to_del_call_op_code_check.py +++ b/tests/ported_static/stStaticCall/test_static_call_to_del_call_op_code_check.py @@ -47,6 +47,7 @@ def test_static_call_to_del_call_op_code_check( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]] (STATICCALL 100000 (CALLDATALOAD 0) 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -138,7 +139,6 @@ def test_static_call_to_del_call_op_code_check( nonce=0, address=Address(0x114CA039127835CA3472EF43E00D15E2D8623286), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_to_name_registrator0.py b/tests/ported_static/stStaticCall/test_static_call_to_name_registrator0.py index 1a7da61d349..14fe9f2ed21 100644 --- a/tests/ported_static/stStaticCall/test_static_call_to_name_registrator0.py +++ b/tests/ported_static/stStaticCall/test_static_call_to_name_registrator0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_to_name_registrator0( ) -> None: """Test_static_call_to_name_registrator0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,21 @@ def test_static_call_to_name_registrator0( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (STATICCALL 100000 0 64 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,7 +74,7 @@ def test_static_call_to_name_registrator0( key=0x0, value=Op.STATICCALL( gas=0x186A0, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x40, @@ -72,25 +84,7 @@ def test_static_call_to_name_registrator0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBF5DCED1C89E98F99D5702C65FC3A881E0BDA929), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_to_return1.py b/tests/ported_static/stStaticCall/test_static_call_to_return1.py index 35f82164f46..840e627c8a6 100644 --- a/tests/ported_static/stStaticCall/test_static_call_to_return1.py +++ b/tests/ported_static/stStaticCall/test_static_call_to_return1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_to_return1( ) -> None: """Test_static_call_to_return1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_call_to_return1( gas_limit=10000000, ) + # Source: raw + # 0x602a601f536001601ff3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x1F, value=0x2A) + + Op.RETURN(offset=0x1F, size=0x1), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 31 1) [[ 1 ]] @0 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +59,7 @@ def test_static_call_to_return1( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0xD0A322C1EA1978A5D1EDB863E5A6C9027039BF6C, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x1F, @@ -65,18 +70,7 @@ def test_static_call_to_return1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x60F1C8AF50C827C6787A7BC5249E9BDDE475A4BA), # noqa: E501 - ) - # Source: raw - # 0x602a601f536001601ff3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x1F, value=0x2A) - + Op.RETURN(offset=0x1F, size=0x1), - balance=23, - nonce=0, - address=Address(0xD0A322C1EA1978A5D1EDB863E5A6C9027039BF6C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_to_static_op_code_check.py b/tests/ported_static/stStaticCall/test_static_call_to_static_op_code_check.py index c80ccfdfd56..97a1361828f 100644 --- a/tests/ported_static/stStaticCall/test_static_call_to_static_op_code_check.py +++ b/tests/ported_static/stStaticCall/test_static_call_to_static_op_code_check.py @@ -47,6 +47,7 @@ def test_static_call_to_static_op_code_check( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[ 0 ]] (STATICCALL 100000 (CALLDATALOAD 0) 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -138,7 +139,6 @@ def test_static_call_to_static_op_code_check( nonce=0, address=Address(0x0D366057A988CB6562F7FA2A601F06A503D30A90), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_value_inherit.py b/tests/ported_static/stStaticCall/test_static_call_value_inherit.py index 82aa94d2839..4770328fd86 100644 --- a/tests/ported_static/stStaticCall/test_static_call_value_inherit.py +++ b/tests/ported_static/stStaticCall/test_static_call_value_inherit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_value_inherit( ) -> None: """Test_static_call_value_inherit.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,15 @@ def test_static_call_value_inherit( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (MSTORE 0 (CALLVALUE)) (RETURN 0 32) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLVALUE) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=1, + nonce=0, + ) # Source: lll # { [[0]] (STATICCALL 50000 0 0 0 32) [[1]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +60,7 @@ def test_static_call_value_inherit( key=0x0, value=Op.STATICCALL( gas=0xC350, - address=0xCB9A81371BC2600A843F60738091E390318CDA9C, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -67,17 +72,6 @@ def test_static_call_value_inherit( storage={1: 1}, balance=1, nonce=0, - address=Address(0x453C54CFC5AF8E6FD9110C386DA8FBC47105D611), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (CALLVALUE)) (RETURN 0 32) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLVALUE) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=1, - nonce=0, - address=Address(0xCB9A81371BC2600A843F60738091E390318CDA9C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_call_value_inherit_from_call.py b/tests/ported_static/stStaticCall/test_static_call_value_inherit_from_call.py index 2a7ebfd5448..930f7670065 100644 --- a/tests/ported_static/stStaticCall/test_static_call_value_inherit_from_call.py +++ b/tests/ported_static/stStaticCall/test_static_call_value_inherit_from_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_call_value_inherit_from_call( ) -> None: """Test_static_call_value_inherit_from_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +46,15 @@ def test_static_call_value_inherit_from_call( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (MSTORE 0 (CALLVALUE)) (RETURN 0 32) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLVALUE) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=1, + nonce=0, + ) # Source: lll # { [[0]] (STATICCALL 50000 0 0 0 32) [[1]] (MLOAD 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -57,7 +62,7 @@ def test_static_call_value_inherit_from_call( key=0x0, value=Op.STATICCALL( gas=0xC350, - address=0xCB9A81371BC2600A843F60738091E390318CDA9C, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -69,14 +74,13 @@ def test_static_call_value_inherit_from_call( storage={1: 1}, balance=1, nonce=0, - address=Address(0x453C54CFC5AF8E6FD9110C386DA8FBC47105D611), # noqa: E501 ) # Source: lll # { (CALL 100000 10 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x186A0, - address=0x453C54CFC5AF8E6FD9110C386DA8FBC47105D611, + address=addr, value=0xA, args_offset=0x0, args_size=0x0, @@ -85,17 +89,6 @@ def test_static_call_value_inherit_from_call( ) + Op.STOP, nonce=0, - address=Address(0x0AF4AE2156E6347E93D875A9D46085E31E57BBE9), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (CALLVALUE)) (RETURN 0 32) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLVALUE) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=1, - nonce=0, - address=Address(0xCB9A81371BC2600A843F60738091E390318CDA9C), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_call_with_high_value.py b/tests/ported_static/stStaticCall/test_static_call_with_high_value.py index 6956ed78807..6ebed354848 100644 --- a/tests/ported_static/stStaticCall/test_static_call_with_high_value.py +++ b/tests/ported_static/stStaticCall/test_static_call_with_high_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_with_high_value( ) -> None: """Test_static_call_with_high_value.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_call_with_high_value( gas_limit=30000000, ) + # Source: raw + # 0x603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 50000 0 64 0 2 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +59,7 @@ def test_static_call_with_high_value( key=0x0, value=Op.STATICCALL( gas=0xC350, - address=0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -65,18 +70,7 @@ def test_static_call_with_high_value( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC81DA1AC86642F6600ECF1369D53787A64412CFC), # noqa: E501 - ) - # Source: raw - # 0x603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_gas_oog.py b/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_gas_oog.py index 7f925647e29..ddf1233324b 100644 --- a/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_gas_oog.py +++ b/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_gas_oog.py @@ -72,6 +72,7 @@ def test_static_call_with_high_value_and_gas_oog( gas_limit=30000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (CALL 500000 (CALLDATALOAD 0) 0 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 @@ -89,6 +90,23 @@ def test_static_call_with_high_value_and_gas_oog( nonce=0, address=Address(0x46FCFDFD17A5789B6AB6D7E23F33F4EADECFB5AD), # noqa: E501 ) + # Source: raw + # 0x603760005360026000f3 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 + ) + # Source: lll + # { (KECCAK256 0x00 0x2fffff) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, + balance=23, + nonce=0, + address=Address(0xD2B07D10E28B46411527B841F0E0382A8E3BCB80), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (STATICCALL 0xffffffffffffffffffffffff 0 64 0 2 ) [[ 1 ]] (MLOAD 0)} # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -146,24 +164,6 @@ def test_static_call_with_high_value_and_gas_oog( nonce=0, address=Address(0xBE9C847927D7E832FF5655392C160933D99CB4E8), # noqa: E501 ) - # Source: raw - # 0x603760005360026000f3 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 - ) - # Source: lll - # { (KECCAK256 0x00 0x2fffff) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, - balance=23, - nonce=0, - address=Address(0xD2B07D10E28B46411527B841F0E0382A8E3BCB80), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_oo_gat_tx_level.py b/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_oo_gat_tx_level.py index 33f528e4b98..09265353f6d 100644 --- a/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_oo_gat_tx_level.py +++ b/tests/ported_static/stStaticCall/test_static_call_with_high_value_and_oo_gat_tx_level.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_call_with_high_value_and_oo_gat_tx_level( ) -> None: """Test_static_call_with_high_value_and_oo_gat_tx_level.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_call_with_high_value_and_oo_gat_tx_level( gas_limit=30000000, ) + # Source: raw + # 0x603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 3000001 0 0 0 0 ) [[ 1 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +61,7 @@ def test_static_call_with_high_value_and_oo_gat_tx_level( key=0x0, value=Op.STATICCALL( gas=0x2DC6C1, - address=0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -67,18 +72,7 @@ def test_static_call_with_high_value_and_oo_gat_tx_level( + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x5B4A9566E26075AA8FFBEE639B15CBF0292368F6), # noqa: E501 - ) - # Source: raw - # 0x603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_with_high_value_oo_gin_call.py b/tests/ported_static/stStaticCall/test_static_call_with_high_value_oo_gin_call.py index 64c5ba35f5b..0663469cbc5 100644 --- a/tests/ported_static/stStaticCall/test_static_call_with_high_value_oo_gin_call.py +++ b/tests/ported_static/stStaticCall/test_static_call_with_high_value_oo_gin_call.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_with_high_value_oo_gin_call( ) -> None: """Test_static_call_with_high_value_oo_gin_call.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_call_with_high_value_oo_gin_call( gas_limit=30000000, ) + # Source: raw + # 0x603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (ADD (STATICCALL 10 0 0 0 0 ) 1) [[ 1 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +60,7 @@ def test_static_call_with_high_value_oo_gin_call( value=Op.ADD( Op.STATICCALL( gas=0xA, - address=0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,18 +73,7 @@ def test_static_call_with_high_value_oo_gin_call( + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x211D767449420E452C129490CA6AD58ADAD11530), # noqa: E501 - ) - # Source: raw - # 0x603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_call_zero_v_call_suicide.py b/tests/ported_static/stStaticCall/test_static_call_zero_v_call_suicide.py index 8ef6e121a52..b0bfdc77740 100644 --- a/tests/ported_static/stStaticCall/test_static_call_zero_v_call_suicide.py +++ b/tests/ported_static/stStaticCall/test_static_call_zero_v_call_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_call_zero_v_call_suicide( ) -> None: """Test_static_call_zero_v_call_suicide.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_static_call_zero_v_call_suicide( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (STATICCALL 60000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_callcall_00.py b/tests/ported_static/stStaticCall/test_static_callcall_00.py index 0026a734ccf..1dc2606afd2 100644 --- a/tests/ported_static/stStaticCall/test_static_callcall_00.py +++ b/tests/ported_static/stStaticCall/test_static_callcall_00.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcall_00( ) -> None: """Test_static_callcall_00.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,23 +90,34 @@ def test_static_callcall_00( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x620B442C84D5068E6B57D390A1AC99130205406E, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE))} # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0xE6, value=Op.ADDRESS) + + Op.SSTORE(key=0xE8, value=Op.ORIGIN) + + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0xEE, value=Op.CODESIZE) + + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2F9EC0AFCB4EDCD7D38C6A48F5E36038263CA3CD), # noqa: E501 + address=Address(0x33F368F0B54063613CF5944941E8E0E4EEB64697), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 1) (MSTORE 32 (CALLER)) (MSTORE 64 (CALLVALUE)) (MSTORE 96 (ADDRESS)) (MSTORE 128 (ORIGIN)) (MSTORE 160 (CALLDATASIZE)) (MSTORE 192 (CODESIZE)) (MSTORE 224 (GASPRICE))} # noqa: E501 + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x1) + + Op.MSTORE(offset=0x20, value=Op.CALLER) + + Op.MSTORE(offset=0x40, value=Op.CALLVALUE) + + Op.MSTORE(offset=0x60, value=Op.ADDRESS) + + Op.MSTORE(offset=0x80, value=Op.ORIGIN) + + Op.MSTORE(offset=0xA0, value=Op.CALLDATASIZE) + + Op.MSTORE(offset=0xC0, value=Op.CODESIZE) + + Op.MSTORE(offset=0xE0, value=Op.GASPRICE) + + Op.STOP, + nonce=0, + address=Address(0x29736372C0FAB51DB4556614EF27D74A89ACFE21), # noqa: E501 ) # Source: lll # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 @@ -128,28 +136,29 @@ def test_static_callcall_00( address=Address(0x620B442C84D5068E6B57D390A1AC99130205406E), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 230 (ADDRESS)) (SSTORE 232 (ORIGIN)) (SSTORE 236 (CALLDATASIZE)) (SSTORE 238 (CODESIZE)) (SSTORE 240 (GASPRICE))} # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0xE6, value=Op.ADDRESS) - + Op.SSTORE(key=0xE8, value=Op.ORIGIN) - + Op.SSTORE(key=0xEC, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0xEE, value=Op.CODESIZE) - + Op.SSTORE(key=0xF0, value=Op.GASPRICE) + # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x3D090, + address=0x29736372C0FAB51DB4556614EF27D74A89ACFE21, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x33F368F0B54063613CF5944941E8E0E4EEB64697), # noqa: E501 + address=Address(0xDCC76191E9F918ECFE9FBA5414884D5EE621AE00), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.STATICCALL( gas=0x55730, - address=0xDCC76191E9F918ECFE9FBA5414884D5EE621AE00, + address=0x620B442C84D5068E6B57D390A1AC99130205406E, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -159,40 +168,27 @@ def test_static_callcall_00( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 + address=Address(0x2F9EC0AFCB4EDCD7D38C6A48F5E36038263CA3CD), # noqa: E501 ) # Source: lll - # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x3D090, - address=0x29736372C0FAB51DB4556614EF27D74A89ACFE21, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0xDCC76191E9F918ECFE9FBA5414884D5EE621AE00, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDCC76191E9F918ECFE9FBA5414884D5EE621AE00), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 1) (MSTORE 32 (CALLER)) (MSTORE 64 (CALLVALUE)) (MSTORE 96 (ADDRESS)) (MSTORE 128 (ORIGIN)) (MSTORE 160 (CALLDATASIZE)) (MSTORE 192 (CODESIZE)) (MSTORE 224 (GASPRICE))} # noqa: E501 - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x1) - + Op.MSTORE(offset=0x20, value=Op.CALLER) - + Op.MSTORE(offset=0x40, value=Op.CALLVALUE) - + Op.MSTORE(offset=0x60, value=Op.ADDRESS) - + Op.MSTORE(offset=0x80, value=Op.ORIGIN) - + Op.MSTORE(offset=0xA0, value=Op.CALLDATASIZE) - + Op.MSTORE(offset=0xC0, value=Op.CODESIZE) - + Op.MSTORE(offset=0xE0, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x29736372C0FAB51DB4556614EF27D74A89ACFE21), # noqa: E501 + address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcall_00_ooge.py b/tests/ported_static/stStaticCall/test_static_callcall_00_ooge.py index 3cfcc58cdde..8ba69156208 100644 --- a/tests/ported_static/stStaticCall/test_static_callcall_00_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcall_00_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcall_00_ooge( ) -> None: """Test_static_callcall_00_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,23 +90,28 @@ def test_static_callcall_00_ooge( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x2814F1BE80FCE656766C827BC6E55BFB7A3BC4B9, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (SSTORE 2 1) (MSTORE 2 1)} + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.MSTORE(offset=0x2, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0xCE21F15217A7B94DB9C505A66C9549E803BF141C), # noqa: E501 + ) + # Source: lll + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) )} + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2F9EC0AFCB4EDCD7D38C6A48F5E36038263CA3CD), # noqa: E501 + address=Address(0xE574F7EC5305BE91332B5B8B12DEB8966E05F42D), # noqa: E501 ) # Source: lll # { (MSTORE 2 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 @@ -131,22 +133,32 @@ def test_static_callcall_00_ooge( address=Address(0x2814F1BE80FCE656766C827BC6E55BFB7A3BC4B9), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (MSTORE 2 1)} - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.MSTORE(offset=0x2, value=0x1) + # { (MSTORE 2 1) (STATICCALL 20020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x4E34, + address=0xE574F7EC5305BE91332B5B8B12DEB8966E05F42D, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, nonce=0, - address=Address(0xCE21F15217A7B94DB9C505A66C9549E803BF141C), # noqa: E501 + address=Address(0xA18394A87A4C414718BBBEE0F695D74CD7A4F9DE), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.STATICCALL( - gas=0x249F0, - address=0xA18394A87A4C414718BBBEE0F695D74CD7A4F9DE, + gas=0x55730, + address=0x2814F1BE80FCE656766C827BC6E55BFB7A3BC4B9, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -156,43 +168,27 @@ def test_static_callcall_00_ooge( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x998A75F1A4457FB7B5872C51F34AA7256F732B1E), # noqa: E501 + address=Address(0x2F9EC0AFCB4EDCD7D38C6A48F5E36038263CA3CD), # noqa: E501 ) # Source: lll - # { (MSTORE 2 1) (STATICCALL 20020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x4E34, - address=0xE574F7EC5305BE91332B5B8B12DEB8966E05F42D, + # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x249F0, + address=0xA18394A87A4C414718BBBEE0F695D74CD7A4F9DE, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x20, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xA18394A87A4C414718BBBEE0F695D74CD7A4F9DE), # noqa: E501 - ) - # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) )} - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE574F7EC5305BE91332B5B8B12DEB8966E05F42D), # noqa: E501 + address=Address(0x998A75F1A4457FB7B5872C51F34AA7256F732B1E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_1.py b/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_1.py index 6225f08f068..b1f3f3deb06 100644 --- a/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_1.py +++ b/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcall_00_ooge_1( ) -> None: """Test_static_callcall_00_ooge_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,23 +90,28 @@ def test_static_callcall_00_ooge_1( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x249F0, - address=0xA122FC55193A6573FA47C988F537AE631E411058, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (SSTORE 2 1) (SSTORE 5 (CALLVALUE)) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + + Op.STOP, + nonce=0, + address=Address(0xA65F4B36F21EF107A26AB282B736F93D47BF83DE), # noqa: E501 + ) + # Source: lll + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA2CA69F1CF9FFA7A761899E8DD2F941D40326FD6), # noqa: E501 + address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 ) # Source: lll # { (MSTORE 2 1) (STATICCALL 100000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 @@ -132,22 +134,33 @@ def test_static_callcall_00_ooge_1( address=Address(0xA122FC55193A6573FA47C988F537AE631E411058), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 5 (CALLVALUE)) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + # { (MSTORE 2 1) (STATICCALL 100000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x186A0, + address=0x609E4DFE6190235B9A0362084C741D9EC330FB1E, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA65F4B36F21EF107A26AB282B736F93D47BF83DE), # noqa: E501 + address=Address(0x1D401212BA6C32405B4FDC993079ACAB6C7AAB6F), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.STATICCALL( gas=0x249F0, - address=0x1D401212BA6C32405B4FDC993079ACAB6C7AAB6F, + address=0xA122FC55193A6573FA47C988F537AE631E411058, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -157,44 +170,27 @@ def test_static_callcall_00_ooge_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x998A75F1A4457FB7B5872C51F34AA7256F732B1E), # noqa: E501 + address=Address(0xA2CA69F1CF9FFA7A761899E8DD2F941D40326FD6), # noqa: E501 ) # Source: lll - # { (MSTORE 2 1) (STATICCALL 100000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x186A0, - address=0x609E4DFE6190235B9A0362084C741D9EC330FB1E, + # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x249F0, + address=0x1D401212BA6C32405B4FDC993079ACAB6C7AAB6F, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1D401212BA6C32405B4FDC993079ACAB6C7AAB6F), # noqa: E501 - ) - # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) - ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST - + Op.STOP, - nonce=0, - address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 + address=Address(0x998A75F1A4457FB7B5872C51F34AA7256F732B1E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_2.py index f3f3058d0f0..cd3bcbb96cb 100644 --- a/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcall_00_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcall_00_ooge_2( ) -> None: """Test_static_callcall_00_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -90,23 +87,28 @@ def test_static_callcall_00_ooge_2( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x249F0, - address=0x2DEFC3FB57B42969B271935D982740948B92E86B, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (SSTORE 2 1) (SSTORE 5 (CALLVALUE)) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + + Op.STOP, + nonce=0, + address=Address(0xA65F4B36F21EF107A26AB282B736F93D47BF83DE), # noqa: E501 + ) + # Source: lll + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA2CA69F1CF9FFA7A761899E8DD2F941D40326FD6), # noqa: E501 + address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 ) # Source: lll # { (MSTORE 2 1) (STATICCALL 100000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 @@ -129,22 +131,33 @@ def test_static_callcall_00_ooge_2( address=Address(0x2DEFC3FB57B42969B271935D982740948B92E86B), # noqa: E501 ) # Source: lll - # { (SSTORE 2 1) (SSTORE 5 (CALLVALUE)) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) - + Op.SSTORE(key=0x5, value=Op.CALLVALUE) + # { (MSTORE 2 1) (STATICCALL 100000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x186A0, + address=0x609E4DFE6190235B9A0362084C741D9EC330FB1E, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA65F4B36F21EF107A26AB282B736F93D47BF83DE), # noqa: E501 + address=Address(0xDDC2B4BC1FB31ED3CD95025FB7C668BA01B2DB6C), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.SSTORE( key=0x0, value=Op.STATICCALL( gas=0x249F0, - address=0xDDC2B4BC1FB31ED3CD95025FB7C668BA01B2DB6C, + address=0x2DEFC3FB57B42969B271935D982740948B92E86B, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -154,44 +167,27 @@ def test_static_callcall_00_ooge_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x998A75F1A4457FB7B5872C51F34AA7256F732B1E), # noqa: E501 + address=Address(0xA2CA69F1CF9FFA7A761899E8DD2F941D40326FD6), # noqa: E501 ) # Source: lll - # { (MSTORE 2 1) (STATICCALL 100000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x186A0, - address=0x609E4DFE6190235B9A0362084C741D9EC330FB1E, + # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x249F0, + address=0xDDC2B4BC1FB31ED3CD95025FB7C668BA01B2DB6C, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDDC2B4BC1FB31ED3CD95025FB7C668BA01B2DB6C), # noqa: E501 - ) - # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) - ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST - + Op.STOP, - nonce=0, - address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 + address=Address(0x998A75F1A4457FB7B5872C51F34AA7256F732B1E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcall_00_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcall_00_suicide_end.py index 058da94535f..773ad47ca84 100644 --- a/tests/ported_static/stStaticCall/test_static_callcall_00_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcall_00_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcall_00_suicide_end( ) -> None: """Test_static_callcall_00_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_callcall_00_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,15 +91,6 @@ def test_static_callcall_00_suicide_end( nonce=0, address=Address(0x662727C5FEC3E62DB4F386D95388CAEDD4067BB8), # noqa: E501 ) - # Source: lll - # { (MSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000.py index 10b37a976e2..2388568f0db 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcall_000( ) -> None: """Test_static_callcallcall_000.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,32 +90,35 @@ def test_static_callcallcall_000( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 650000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x9EB10, - address=0x36ACE903A154317B8FA379AAD88A425B7EF025DC, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFB157BFD4470AB46DFFEC6F8390B747C67F62B38), # noqa: E501 + address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 400000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.STATICCALL( - gas=0x61A80, - address=0x3F6D147A714319EF90C47921715DC5F0CCFE3B09, + gas=0x3D090, + address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -129,16 +129,16 @@ def test_static_callcallcall_000( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x36ACE903A154317B8FA379AAD88A425B7EF025DC), # noqa: E501 + address=Address(0x3F6D147A714319EF90C47921715DC5F0CCFE3B09), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.STATICCALL( gas=0x3D090, - address=0x181B4ED322E192361633CC3C0A418F259AB0CF4B, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -149,41 +149,27 @@ def test_static_callcallcall_000( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3F6D147A714319EF90C47921715DC5F0CCFE3B09), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE))} # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x181B4ED322E192361633CC3C0A418F259AB0CF4B), # noqa: E501 + address=Address(0x85EE033B8FF327153F5C82D191B4942102DEBFFC), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0xD518EBB39FB88BEB34AD1598FE3CCD3F8E4C4708, + # { (MSTORE 3 1) (STATICCALL 400000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x61A80, + address=0x3F6D147A714319EF90C47921715DC5F0CCFE3B09, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 + address=Address(0x36ACE903A154317B8FA379AAD88A425B7EF025DC), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 @@ -206,33 +192,43 @@ def test_static_callcallcall_000( address=Address(0xD518EBB39FB88BEB34AD1598FE3CCD3F8E4C4708), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x3D090, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (STATICCALL 650000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x9EB10, + address=0x36ACE903A154317B8FA379AAD88A425B7EF025DC, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x85EE033B8FF327153F5C82D191B4942102DEBFFC), # noqa: E501 + address=Address(0xFB157BFD4470AB46DFFEC6F8390B747C67F62B38), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0xD518EBB39FB88BEB34AD1598FE3CCD3F8E4C4708, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000_ooge.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000_ooge.py index a7cd6aba1dc..83d2fc21188 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcall_000_ooge( ) -> None: """Test_static_callcallcall_000_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,32 +90,37 @@ def test_static_callcallcall_000_ooge( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x7A120, - address=0xA69F4D8056BB192982BF07D59AD0FF96A15B41D9, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (SSTORE 3 1) (MSTORE 3 1)} + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x9D41CA9233D19D3202BEFCEF33F16AF7201F0EAA), # noqa: E501 + ) + # Source: lll + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x071587C3E5F2EBF88B2A5B048733778605ADDB28), # noqa: E501 + address=Address(0xF31E5B020AFCCF373BFA588C4D3A199C4F7A46A4), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.STATICCALL( - gas=0x493E0, - address=0xCD0BD482BAEEB001E6F3FFD36BCEB34D32169C93, + gas=0x1D4D4, + address=0x9D41CA9233D19D3202BEFCEF33F16AF7201F0EAA, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -128,16 +130,16 @@ def test_static_callcallcall_000_ooge( + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, nonce=0, - address=Address(0xA69F4D8056BB192982BF07D59AD0FF96A15B41D9), # noqa: E501 + address=Address(0xCD0BD482BAEEB001E6F3FFD36BCEB34D32169C93), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 )(MSTORE 32 1) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.STATICCALL( gas=0x1D4D4, - address=0x9D41CA9233D19D3202BEFCEF33F16AF7201F0EAA, + address=0xF31E5B020AFCCF373BFA588C4D3A199C4F7A46A4, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -147,35 +149,26 @@ def test_static_callcallcall_000_ooge( + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, nonce=0, - address=Address(0xCD0BD482BAEEB001E6F3FFD36BCEB34D32169C93), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (MSTORE 3 1)} - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x9D41CA9233D19D3202BEFCEF33F16AF7201F0EAA), # noqa: E501 + address=Address(0xAC6BF72C47193C6FEFC55EFCC14674F8023F39F9), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 600000 0 64 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x927C0, - address=0xA69F4D8056BB192982BF07D59AD0FF96A15B41D9, + # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x493E0, + address=0xCD0BD482BAEEB001E6F3FFD36BCEB34D32169C93, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9B0CB3CB3655D3173FF7C2CD51319AAF2CCA3CAD), # noqa: E501 + address=Address(0xA69F4D8056BB192982BF07D59AD0FF96A15B41D9), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 )(MSTORE 32 1) } # noqa: E501 @@ -197,40 +190,43 @@ def test_static_callcallcall_000_ooge( address=Address(0xA76CE2DE971EA2B78BC19BA706CB135F4FFF2CC2), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 )(MSTORE 32 1) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x1D4D4, - address=0xF31E5B020AFCCF373BFA588C4D3A199C4F7A46A4, + # { [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x7A120, + address=0xA69F4D8056BB192982BF07D59AD0FF96A15B41D9, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAC6BF72C47193C6FEFC55EFCC14674F8023F39F9), # noqa: E501 + address=Address(0x071587C3E5F2EBF88B2A5B048733778605ADDB28), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + # { [[ 0 ]] (STATICCALL 600000 0 64 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x927C0, + address=0xA69F4D8056BB192982BF07D59AD0FF96A15B41D9, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF31E5B020AFCCF373BFA588C4D3A199C4F7A46A4), # noqa: E501 + address=Address(0x9B0CB3CB3655D3173FF7C2CD51319AAF2CCA3CAD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after.py index e5f0cd0132b..07d09664469 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcall_000_oogm_after( ) -> None: """Test_static_callcallcall_000_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,28 @@ def test_static_callcallcall_000_oogm_after( ) # Source: lll - # { [[ 0 ]] (STATICCALL 600150 0 64 0 64 ) [[ 111 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x92856, - address=0x8FF16542095DE9F85F7C395D6D543D19B30D97D7, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x1D4D4, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x6F, value=0x1) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x03681C634A188409B5F9B8CA2382C1A1499D8A0D), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 400080 0 64 0 64 ) (SSTORE 3 1)} # noqa: E501 @@ -74,7 +75,7 @@ def test_static_callcallcall_000_oogm_after( + Op.POP( Op.STATICCALL( gas=0x61AD0, - address=0xC2234F6B4A777DB8DF1447C9C2D0C8CEE376DE76, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,35 +85,26 @@ def test_static_callcallcall_000_oogm_after( + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8FF16542095DE9F85F7C395D6D543D19B30D97D7), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (STATICCALL 600150 0 64 0 64 ) [[ 111 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x92856, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.SSTORE(key=0x6F, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC2234F6B4A777DB8DF1447C9C2D0C8CEE376DE76), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after2.py index 7ee3733bc9b..e1d996d11d3 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcall_000_oogm_after2( ) -> None: """Test_static_callcallcall_000_oogm_after2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,28 @@ def test_static_callcallcall_000_oogm_after2( ) # Source: lll - # { [[ 0 ]] (STATICCALL 700000 0 64 0 64 ) [[ 111 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0xAAE60, - address=0x10345562E309B2045C737FFDD46E941710495FC4, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1)} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x1D4D4, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x6F, value=0x1) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6DE4E4FA82A7139E6804B5B47B42E366A9595946), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 450000 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } # noqa: E501 @@ -74,7 +75,7 @@ def test_static_callcallcall_000_oogm_after2( + Op.POP( Op.STATICCALL( gas=0x6DDD0, - address=0xA34EEE061F267A63C872265BED51C483F777A7B0, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -91,35 +92,26 @@ def test_static_callcallcall_000_oogm_after2( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x10345562E309B2045C737FFDD46E941710495FC4), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 32 1)} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (STATICCALL 700000 0 64 0 64 ) [[ 111 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0xAAE60, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.SSTORE(key=0x6F, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA34EEE061F267A63C872265BED51C483F777A7B0), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_before.py index e7d8adf51d1..d7cef670092 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcall_000_oogm_before( ) -> None: """Test_static_callcallcall_000_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,39 +45,10 @@ def test_static_callcallcall_000_oogm_before( ) # Source: lll - # { [[ 0 ]] (STATICCALL 600000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x927C0, - address=0xEDBFA645E2C5462398C0BD3A12E41EF8EC1F9F5, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x081FA564A44BD568ECF6D6B044899F7EE4057F5F), # noqa: E501 - ) - # Source: lll - # { (STATICCALL 400080 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x61AD0, - address=0x97498B4CE896BE02417BCFE036BEAC3332185563, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x0EDBFA645E2C5462398C0BD3A12E41EF8EC1F9F5), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 @@ -95,7 +63,7 @@ def test_static_callcallcall_000_oogm_before( + Op.JUMPDEST + Op.STATICCALL( gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -103,16 +71,40 @@ def test_static_callcallcall_000_oogm_before( ) + Op.STOP, nonce=0, - address=Address(0x97498B4CE896BE02417BCFE036BEAC3332185563), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (STATICCALL 400080 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x61AD0, + address=addr_2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 0 ]] (STATICCALL 600000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x927C0, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_end.py index a328a71f912..78d2acd9b59 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcall_000_suicide_end( ) -> None: """Test_static_callcallcall_000_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_callcallcall_000_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x3423652BB0C864AC51C919168F106E55D6F7D138), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -107,15 +112,6 @@ def test_static_callcallcall_000_suicide_end( nonce=0, address=Address(0xCB401DA610F6DE2240321640E8BF2803CE6BFD0A), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x3423652BB0C864AC51C919168F106E55D6F7D138), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_middle.py index 322f1bb57d0..56cf3224bd1 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_000_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcall_000_suicide_middle( ) -> None: """Test_static_callcallcall_000_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcall_000_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_static_callcallcall_000_suicide_middle( nonce=0, address=Address(0x72CC05B5A698AA0AE6848A4814180A756561F046), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcall_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcallcall_abcb_recursive.py index 5f07e240f11..0a0b4b64deb 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcall_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcall_abcb_recursive( ) -> None: """Test_static_callcallcall_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -107,7 +104,6 @@ def test_static_callcallcall_abcb_recursive( nonce=0, address=Address(0xE6F4B463900F4C325A940DCA2C0C6B1C075631C9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001.py index 9834b2ed84b..10695d92061 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcallcode_001( ) -> None: """Test_static_callcallcallcode_001.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,33 +90,35 @@ def test_static_callcallcallcode_001( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x5CCB387AB81F41F0B490664795E7004D5D14BF91, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.MSTORE(offset=0x3, value=0x1) + # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.SSTORE(key=0x4, value=Op.CALLER) + + Op.SSTORE(key=0x7, value=Op.CALLVALUE) + + Op.SSTORE(key=0x14A, value=Op.ADDRESS) + + Op.SSTORE(key=0x14C, value=Op.ORIGIN) + + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) + + Op.SSTORE(key=0x152, value=Op.CODESIZE) + + Op.SSTORE(key=0x154, value=Op.GASPRICE) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9121E482ADD3986513A14639DB36D5EC5AE41FB8), # noqa: E501 + address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( - Op.STATICCALL( - gas=0x493E0, - address=0x82D1FD8C6ED53A58BD8B065074A6B572A7CA89FA, + Op.DELEGATECALL( + gas=0x3D090, + address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -130,16 +129,16 @@ def test_static_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5CCB387AB81F41F0B490664795E7004D5D14BF91), # noqa: E501 + address=Address(0x82D1FD8C6ED53A58BD8B065074A6B572A7CA89FA), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.DELEGATECALL( gas=0x3D090, - address=0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -150,41 +149,27 @@ def test_static_callcallcallcode_001( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x82D1FD8C6ED53A58BD8B065074A6B572A7CA89FA), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (SSTORE 4 (CALLER)) (SSTORE 7 (CALLVALUE)) (SSTORE 330 (ADDRESS)) (SSTORE 332 (ORIGIN)) (SSTORE 336 (CALLDATASIZE)) (SSTORE 338 (CODESIZE)) (SSTORE 340 (GASPRICE)) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.SSTORE(key=0x4, value=Op.CALLER) - + Op.SSTORE(key=0x7, value=Op.CALLVALUE) - + Op.SSTORE(key=0x14A, value=Op.ADDRESS) - + Op.SSTORE(key=0x14C, value=Op.ORIGIN) - + Op.SSTORE(key=0x150, value=Op.CALLDATASIZE) - + Op.SSTORE(key=0x152, value=Op.CODESIZE) - + Op.SSTORE(key=0x154, value=Op.GASPRICE) - + Op.STOP, - nonce=0, - address=Address(0x7E63847AAD8CA50FB7C04777DCE6871A6BF8DE0C), # noqa: E501 + address=Address(0xF18DDE9381A558C4BE0B84B0F3A17E22B3F9FFCE), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x69CE59F2414271F3E079542EF3893A021D7D68EA, + # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x493E0, + address=0x82D1FD8C6ED53A58BD8B065074A6B572A7CA89FA, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 + address=Address(0x5CCB387AB81F41F0B490664795E7004D5D14BF91), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 )(MSTORE 3 1) } # noqa: E501 @@ -207,33 +192,44 @@ def test_static_callcallcallcode_001( address=Address(0x69CE59F2414271F3E079542EF3893A021D7D68EA), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x3D090, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0x5CCB387AB81F41F0B490664795E7004D5D14BF91, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF18DDE9381A558C4BE0B84B0F3A17E22B3F9FFCE), # noqa: E501 + address=Address(0x9121E482ADD3986513A14639DB36D5EC5AE41FB8), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0x69CE59F2414271F3E079542EF3893A021D7D68EA, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_2.py index 20eb1b6d1f5..f76a30dbfa5 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcallcode_001_2( ) -> None: """Test_static_callcallcallcode_001_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,42 +90,18 @@ def test_static_callcallcallcode_001_2( address=Address(0xE4552FDC3736D39144E64AD1A1E8253017B0C974), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x52BC8086D7F6AC48937CF1B98DFC6F4BE0F75112, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 1 0x11223344) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x11223344) + Op.STOP, nonce=0, - address=Address(0x2F9EC0AFCB4EDCD7D38C6A48F5E36038263CA3CD), # noqa: E501 + address=Address(0x2881A083EA775F78057A93F73110241FDB7398A9), # noqa: E501 ) # Source: lll - # { (STATICCALL 300000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=0x493E0, - address=0xFFFFAEB931552E5F094CA96A70BE612DA56B887, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 3 1) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x52BC8086D7F6AC48937CF1B98DFC6F4BE0F75112), # noqa: E501 + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) # Source: lll # { [[ 2 ]] (CALLCODE 250000 3 0 64 0 64 ) } # noqa: E501 @@ -151,30 +124,44 @@ def test_static_callcallcallcode_001_2( address=Address(0x0FFFFAEB931552E5F094CA96A70BE612DA56B887), # noqa: E501 ) # Source: lll - # { (MSTORE 1 0x11223344) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x11223344) + Op.STOP, + # { (MSTORE 4 1) (CALLCODE 250000 0 0 64 0 64 ) (MSTORE 6 1) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x4, value=0x1) + + Op.POP( + Op.CALLCODE( + gas=0x3D090, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x6, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2881A083EA775F78057A93F73110241FDB7398A9), # noqa: E501 + address=Address(0x5517C40699CEB16C4EB71F2B0D841078C198560E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0xB4631A307A08ABC5D5A582549B23CB98A7C5BEB2, + # { (STATICCALL 300000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.STATICCALL( + gas=0x493E0, + address=0xFFFFAEB931552E5F094CA96A70BE612DA56B887, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 + address=Address(0x52BC8086D7F6AC48937CF1B98DFC6F4BE0F75112), # noqa: E501 ) # Source: lll # { (STATICCALL 300000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 @@ -196,34 +183,43 @@ def test_static_callcallcallcode_001_2( address=Address(0xB4631A307A08ABC5D5A582549B23CB98A7C5BEB2), # noqa: E501 ) # Source: lll - # { (MSTORE 4 1) (CALLCODE 250000 0 0 64 0 64 ) (MSTORE 6 1) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x4, value=0x1) - + Op.POP( - Op.CALLCODE( - gas=0x3D090, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - value=0x0, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0x52BC8086D7F6AC48937CF1B98DFC6F4BE0F75112, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x6, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5517C40699CEB16C4EB71F2B0D841078C198560E), # noqa: E501 + address=Address(0x2F9EC0AFCB4EDCD7D38C6A48F5E36038263CA3CD), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0xB4631A307A08ABC5D5A582549B23CB98A7C5BEB2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xBF23F3306533431B2EE5E4CA95E0A0834C090105), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge.py index 952b23aec34..948a7ec6d19 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcallcode_001_ooge( ) -> None: """Test_static_callcallcallcode_001_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,36 @@ def test_static_callcallcallcode_001_ooge( ) # Source: lll - # { [[ 0 ]] (STATICCALL 600000 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x927C0, - address=0x6F80B859BA9392B2C26E5930C330D4A7247FBA4F, + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) )} + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=0x1D4D4, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x563F06D1277F7CB092689AC2168D6EECD1ACB499), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 @@ -74,7 +83,7 @@ def test_static_callcallcallcode_001_ooge( + Op.POP( Op.STATICCALL( gas=0x493E0, - address=0xA3E14608664E4A0229F96C49500F83F0FDBF3DCB, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,43 +93,26 @@ def test_static_callcallcallcode_001_ooge( + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x6F80B859BA9392B2C26E5930C330D4A7247FBA4F), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x1D4D4, - address=0xE574F7EC5305BE91332B5B8B12DEB8966E05F42D, + # { [[ 0 ]] (STATICCALL 600000 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x927C0, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA3E14608664E4A0229F96C49500F83F0FDBF3DCB), # noqa: E501 - ) - # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) )} - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) - ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST - + Op.STOP, - nonce=0, - address=Address(0xE574F7EC5305BE91332B5B8B12DEB8966E05F42D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge_2.py index 26c5e80244e..970133882b1 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcallcallcode_001_ooge_2( ) -> None: """Test_static_callcallcallcode_001_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -90,38 +87,28 @@ def test_static_callcallcallcode_001_ooge_2( address=Address(0xC0E4183389EB57F779A986D8C878F89B9401DC8E), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x7A120, - address=0xBDA9155E6214FE759004E6FCBE736289EF800528, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) + # { (SSTORE 3 1) (MSTORE 3 1)} + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x071587C3E5F2EBF88B2A5B048733778605ADDB28), # noqa: E501 + address=Address(0x9D41CA9233D19D3202BEFCEF33F16AF7201F0EAA), # noqa: E501 ) # Source: lll - # { (STATICCALL 300000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x493E0, - address=0xFEE7D85F02F84CE8917FA8300FEA57FF41AD47D7, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0xBDA9155E6214FE759004E6FCBE736289EF800528), # noqa: E501 + address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 ) # Source: lll # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 @@ -140,32 +127,35 @@ def test_static_callcallcallcode_001_ooge_2( address=Address(0xFEE7D85F02F84CE8917FA8300FEA57FF41AD47D7), # noqa: E501 ) # Source: lll - # { (SSTORE 3 1) (MSTORE 3 1)} - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.MSTORE(offset=0x3, value=0x1) + # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x1D4D4, + address=0x609E4DFE6190235B9A0362084C741D9EC330FB1E, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + Op.STOP, nonce=0, - address=Address(0x9D41CA9233D19D3202BEFCEF33F16AF7201F0EAA), # noqa: E501 + address=Address(0xA7C64824C59E4295A3868A2B275AD46B38F7846D), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x7A120, - address=0x2DB6829F13013D6280C5BE4F6A5E87DE274A3C47, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (STATICCALL 300000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x493E0, + address=0xFEE7D85F02F84CE8917FA8300FEA57FF41AD47D7, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xED9009ABB678FB6E7898148DC46FA339EA580CBD), # noqa: E501 + address=Address(0xBDA9155E6214FE759004E6FCBE736289EF800528), # noqa: E501 ) # Source: lll # { (STATICCALL 300000 0 64 0 64 ) } # noqa: E501 @@ -183,37 +173,43 @@ def test_static_callcallcallcode_001_ooge_2( address=Address(0x2DB6829F13013D6280C5BE4F6A5E87DE274A3C47), # noqa: E501 ) # Source: lll - # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x1D4D4, - address=0x609E4DFE6190235B9A0362084C741D9EC330FB1E, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x7A120, + address=0xBDA9155E6214FE759004E6FCBE736289EF800528, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA7C64824C59E4295A3868A2B275AD46B38F7846D), # noqa: E501 + address=Address(0x071587C3E5F2EBF88B2A5B048733778605ADDB28), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + # { [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x7A120, + address=0x2DB6829F13013D6280C5BE4F6A5E87DE274A3C47, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 + address=Address(0xED9009ABB678FB6E7898148DC46FA339EA580CBD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after.py index f4c7bea28aa..01e13ccf801 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcallcode_001_oogm_after( ) -> None: """Test_static_callcallcallcode_001_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,23 +89,30 @@ def test_static_callcallcallcode_001_oogm_after( address=Address(0xF1F083974FD68B961E68130C27FC5EF37B49C1DF), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 400085 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( - Op.STATICCALL( - gas=0x61AD5, - address=0x265EEB9A84FEA22DA8B58252402B03BAFE1A6324, + Op.DELEGATECALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.SSTORE(key=0x3, value=0x1) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, nonce=0, - address=Address(0x4CD868420CBC0E9D9BA63455A2D0A36CE0FABF2C), # noqa: E501 + address=Address(0x265EEB9A84FEA22DA8B58252402B03BAFE1A6324), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 400085 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } # noqa: E501 @@ -137,32 +141,24 @@ def test_static_callcallcallcode_001_oogm_after( address=Address(0xEE8F7E38BE79A20210BA7860A51507505984E4ED), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) (STATICCALL 400085 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( - Op.DELEGATECALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + Op.STATICCALL( + gas=0x61AD5, + address=0x265EEB9A84FEA22DA8B58252402B03BAFE1A6324, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x265EEB9A84FEA22DA8B58252402B03BAFE1A6324), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x4CD868420CBC0E9D9BA63455A2D0A36CE0FABF2C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after2.py index 353ab10b86c..51cf5aacb27 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcallcode_001_oogm_after2( ) -> None: """Test_static_callcallcallcode_001_oogm_after2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,6 +89,29 @@ def test_static_callcallcallcode_001_oogm_after2( address=Address(0xF1F083974FD68B961E68130C27FC5EF37B49C1DF), # noqa: E501 ) # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0xC26255D9FCF9D7D38D2734CD4E980B8C00ECEEF6), # noqa: E501 + ) + # Source: lll # { (STATICCALL 400080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -134,30 +154,6 @@ def test_static_callcallcallcode_001_oogm_after2( nonce=0, address=Address(0x171A4477DFE54503DD5F21DAF90429FD2F22D654), # noqa: E501 ) - # Source: lll - # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0xC26255D9FCF9D7D38D2734CD4E980B8C00ECEEF6), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_2.py index 73b11d49b25..355583438ec 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcallcode_001_oogm_after_2( ) -> None: """Test_static_callcallcallcode_001_oogm_after_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,6 +89,28 @@ def test_static_callcallcallcode_001_oogm_after_2( address=Address(0xF346244D7B72784053A685F7B1531B0D914911CA), # noqa: E501 ) # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (DELEGATECALL 120020 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x1067D2B507295358055ED9F68F74245839D6339F), # noqa: E501 + ) + # Source: lll # { (STATICCALL 400085 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -134,29 +153,6 @@ def test_static_callcallcallcode_001_oogm_after_2( nonce=0, address=Address(0x4FDE3A9B8985C447BC5071EE2818F0FEEE56052F), # noqa: E501 ) - # Source: lll - # { (DELEGATECALL 120020 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x1067D2B507295358055ED9F68F74245839D6339F), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_3.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_3.py index 9423d61c55c..2c4db1f7baf 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_3.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_after_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcallcode_001_oogm_after_3( ) -> None: """Test_static_callcallcallcode_001_oogm_after_3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,6 +89,29 @@ def test_static_callcallcallcode_001_oogm_after_3( address=Address(0xF1F083974FD68B961E68130C27FC5EF37B49C1DF), # noqa: E501 ) # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0xC26255D9FCF9D7D38D2734CD4E980B8C00ECEEF6), # noqa: E501 + ) + # Source: lll # { (STATICCALL 400080 0 64 0 64 ) (SSTORE 3 1)} # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -134,30 +154,6 @@ def test_static_callcallcallcode_001_oogm_after_3( nonce=0, address=Address(0x813986A928F9829BA2BD6633D33083759F1990A3), # noqa: E501 ) - # Source: lll - # { (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0xC26255D9FCF9D7D38D2734CD4E980B8C00ECEEF6), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before.py index 58af3033e34..15838bdb067 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcallcode_001_oogm_before( ) -> None: """Test_static_callcallcallcode_001_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,32 @@ def test_static_callcallcallcode_001_oogm_before( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 400080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x61AD0, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x20, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x10F374FCA091CACD3E57E847BA123BC16695C44E), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 600000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -93,23 +116,23 @@ def test_static_callcallcallcode_001_oogm_before( address=Address(0xC6DF53AF8AAF7C046B42CF493D4C6819EBEC7994), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 400080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + # { (SSTORE 1 1) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + Op.POP( - Op.STATICCALL( - gas=0x61AD0, - address=Op.CALLDATALOAD(offset=0x0), + Op.DELEGATECALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x10F374FCA091CACD3E57E847BA123BC16695C44E), # noqa: E501 + address=Address(0xEB89BE27EB1850F5F46204E0609023F43C2EDC35), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1) ) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 @@ -137,33 +160,6 @@ def test_static_callcallcallcode_001_oogm_before( nonce=0, address=Address(0x8214B87BB9FD41ED6C19255D74B7FCC66178C4D5), # noqa: E501 ) - # Source: lll - # { (SSTORE 1 1) (DELEGATECALL 120020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xEB89BE27EB1850F5F46204E0609023F43C2EDC35), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before2.py index 93c55903a15..d9c0470221b 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_oogm_before2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcallcode_001_oogm_before2( ) -> None: """Test_static_callcallcallcode_001_oogm_before2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,27 +68,6 @@ def test_static_callcallcallcode_001_oogm_before2( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 600000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x927C0, - address=0x7BECA6585C70E19A4A6B3B0452A8C8867FEC95E8, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC8CB56ED2B3BB8CB3E2F8CE276C85AD35D9AC1BF), # noqa: E501 - ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) (STATICCALL 400080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -112,21 +88,32 @@ def test_static_callcallcallcode_001_oogm_before2( address=Address(0x7BECA6585C70E19A4A6B3B0452A8C8867FEC95E8), # noqa: E501 ) # Source: lll - # { (SSTORE 1 1) (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.CALLCODE( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 600000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x927C0, + address=0x7BECA6585C70E19A4A6B3B0452A8C8867FEC95E8, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEA6E38EC4F121597EEA4BAB20E02865062D20101), # noqa: E501 + address=Address(0xC8CB56ED2B3BB8CB3E2F8CE276C85AD35D9AC1BF), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 @@ -153,13 +140,22 @@ def test_static_callcallcallcode_001_oogm_before2( address=Address(0xCF0670B1AA38B467E493459F12AC3B22FDC4A12B), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (SSTORE 1 1) (CALLCODE 120020 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.CALLCODE( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xEA6E38EC4F121597EEA4BAB20E02865062D20101), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end.py index bcd660b470e..a10e903b3f6 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcallcode_001_suicide_end( ) -> None: """Test_static_callcallcallcode_001_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcallcode_001_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -104,15 +109,6 @@ def test_static_callcallcallcode_001_suicide_end( nonce=0, address=Address(0x4A31DD3A8C3C9A793AC0B3C234A4DBAC2F201404), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end2.py index f2b2ae89a3a..18eb7c39182 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcallcode_001_suicide_end2( ) -> None: """Test_static_callcallcallcode_001_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcallcode_001_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -105,15 +110,6 @@ def test_static_callcallcallcode_001_suicide_end2( nonce=0, address=Address(0x90E9B92C59A0E93D8AB0B7AFBC945D6999A50A9B), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle.py index 1724215796a..ad2000d94ca 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcallcode_001_suicide_middle( ) -> None: """Test_static_callcallcallcode_001_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcallcode_001_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_static_callcallcallcode_001_suicide_middle( nonce=0, address=Address(0xB40862EB0C1F073048AC62D867277B80B57BF6E0), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle2.py index ec4bef22a8c..a61da985eaa 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_001_suicide_middle2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcallcode_001_suicide_middle2( ) -> None: """Test_static_callcallcallcode_001_suicide_middle2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcallcode_001_suicide_middle2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_static_callcallcallcode_001_suicide_middle2( nonce=0, address=Address(0x2DFE35A60D7DE3D8EEB1D7A015541C76B0E00E9F), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive.py index 4f7c6e61031..a354022133e 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcallcode_abcb_recursive( ) -> None: """Test_static_callcallcallcode_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -109,7 +106,6 @@ def test_static_callcallcallcode_abcb_recursive( nonce=0, address=Address(0x458E20B622EC33A82F2A43A90EDC52A429639916), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive2.py b/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive2.py index 017d9a98abf..10b220ca55d 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcallcode_abcb_recursive2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcallcode_abcb_recursive2( ) -> None: """Test_static_callcallcallcode_abcb_recursive2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -110,7 +107,6 @@ def test_static_callcallcallcode_abcb_recursive2( nonce=0, address=Address(0x812297C04813FEA96B943B246D9D17EA17545526), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcode_01_2.py b/tests/ported_static/stStaticCall/test_static_callcallcode_01_2.py index 6aa62646e8f..66ab50c76f3 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcode_01_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcode_01_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcode_01_2( ) -> None: """Test_static_callcallcode_01_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -94,20 +91,18 @@ def test_static_callcallcode_01_2( address=Address(0xAAB59F13D96113334FAB5C68E4E62B61F6CBF647), # noqa: E501 ) # Source: lll - # { (STATICCALL 350000 0 32 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x55730, - address=0xC42C1601B039F8BB80A155B5B6AFB4CFFEB430A, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 0 0x11223344) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x11223344) + Op.STOP, nonce=0, - address=Address(0xFBE34B488C83765DE2F7FEFC646710B8F1DCB303), # noqa: E501 + address=Address(0x8AD8D964B0888C5016605939DD13E1BDCF679F05), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 0x11223344) } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x11223344) + Op.STOP, + nonce=0, + address=Address(0x2FCC143C5267B6C6CE4E1ABD936E84EEDFFD6A4E), # noqa: E501 ) # Source: lll # { (CALLCODE 250000 2 0 32 0 64 ) } # noqa: E501 @@ -127,18 +122,29 @@ def test_static_callcallcode_01_2( address=Address(0x0C42C1601B039F8BB80A155B5B6AFB4CFFEB430A), # noqa: E501 ) # Source: lll - # { (MSTORE 0 0x11223344) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x11223344) + Op.STOP, + # { (MSTORE 0 (CALLDATALOAD 0)) (CALLCODE 250000 0 0 32 0 64 ) } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.CALLCODE( + gas=0x3D090, + address=0x2FCC143C5267B6C6CE4E1ABD936E84EEDFFD6A4E, + value=0x0, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8AD8D964B0888C5016605939DD13E1BDCF679F05), # noqa: E501 + address=Address(0xF686A2E0E79C5FBB3407D5E53F3AB6B0AB21A51A), # noqa: E501 ) # Source: lll - # { (STATICCALL 350000 0 32 0 64 ) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 350000 0 32 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( gas=0x55730, - address=0xF686A2E0E79C5FBB3407D5E53F3AB6B0AB21A51A, + address=0xC42C1601B039F8BB80A155B5B6AFB4CFFEB430A, args_offset=0x0, args_size=0x20, ret_offset=0x0, @@ -147,16 +153,14 @@ def test_static_callcallcode_01_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC766DCC7257DD2AF2B6A354FC922D43D3AD9A390), # noqa: E501 + address=Address(0xFBE34B488C83765DE2F7FEFC646710B8F1DCB303), # noqa: E501 ) # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) (CALLCODE 250000 0 0 32 0 64 ) } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.CALLCODE( - gas=0x3D090, - address=0x2FCC143C5267B6C6CE4E1ABD936E84EEDFFD6A4E, - value=0x0, + # { (STATICCALL 350000 0 32 0 64 ) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x55730, + address=0xF686A2E0E79C5FBB3407D5E53F3AB6B0AB21A51A, args_offset=0x0, args_size=0x20, ret_offset=0x0, @@ -165,16 +169,8 @@ def test_static_callcallcode_01_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF686A2E0E79C5FBB3407D5E53F3AB6B0AB21A51A), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0x11223344) } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x11223344) + Op.STOP, - nonce=0, - address=Address(0x2FCC143C5267B6C6CE4E1ABD936E84EEDFFD6A4E), # noqa: E501 + address=Address(0xC766DCC7257DD2AF2B6A354FC922D43D3AD9A390), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcode_01_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcallcode_01_ooge_2.py index 748fa769b0d..118b967f0dd 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcode_01_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcode_01_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcallcode_01_ooge_2( ) -> None: """Test_static_callcallcode_01_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,27 +66,6 @@ def test_static_callcallcode_01_ooge_2( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x249F0, - address=0x85DDAAC1762B4B9A01861C244947C3D6F40FD709, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC4C9495535A13D71C26E498898C90576F7C64218), # noqa: E501 - ) # Source: lll # { (CALLCODE 20020 (CALLDATALOAD 0) 0 0 64 0 64 ) } addr = pre.deploy_contract( # noqa: F841 @@ -130,7 +106,27 @@ def test_static_callcallcode_01_ooge_2( nonce=0, address=Address(0x609E4DFE6190235B9A0362084C741D9EC330FB1E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x249F0, + address=0x85DDAAC1762B4B9A01861C244947C3D6F40FD709, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xC4C9495535A13D71C26E498898C90576F7C64218), # noqa: E501 + ) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end.py index 8ae8c36e2ac..8d063a6dc55 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcode_01_suicide_end( ) -> None: """Test_static_callcallcode_01_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_callcallcode_01_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -86,15 +91,6 @@ def test_static_callcallcode_01_suicide_end( nonce=0, address=Address(0x0F25670A9CA7BFA523E8B216478051E908ECE142), # noqa: E501 ) - # Source: lll - # { (MSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end2.py index ec2e5bc44ef..3523798982a 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcode_01_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcode_01_suicide_end2( ) -> None: """Test_static_callcallcode_01_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_callcallcode_01_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,15 +92,6 @@ def test_static_callcallcode_01_suicide_end2( nonce=0, address=Address(0x5DE1C119E1FC3598726F4D9411DEBD7ED1402187), # noqa: E501 ) - # Source: lll - # { (MSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010.py index c4bb1d40ffb..e0b2ba42ed1 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcodecall_010( ) -> None: """Test_static_callcallcodecall_010.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,29 @@ def test_static_callcallcodecall_010( ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x8BD89F495B3F37357D15A16D7B0F72470ABE929F, + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x46DF4A924470CB27A2F8700239656C40DD4794C8), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (DELEGATECALL 300000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 @@ -74,7 +76,7 @@ def test_static_callcallcodecall_010( + Op.POP( Op.DELEGATECALL( gas=0x493E0, - address=0x5AAEF6827794656B94367D6130F40D34B219F1FD, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,36 +87,26 @@ def test_static_callcallcodecall_010( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8BD89F495B3F37357D15A16D7B0F72470ABE929F), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x3, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5AAEF6827794656B94367D6130F40D34B219F1FD), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_2.py index c84ff19ab31..fbd6b903580 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcodecall_010_2( ) -> None: """Test_static_callcallcodecall_010_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,12 +90,18 @@ def test_static_callcallcodecall_010_2( address=Address(0x04FEBA02513BFA1CF1456A0F32838B186775D8D4), # noqa: E501 ) # Source: lll - # { (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x493E0, - address=0xEF859513AE36C397C43170A2980741575916167B, - value=0x2, + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x3D090, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -107,7 +110,7 @@ def test_static_callcallcodecall_010_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6B21D14FFAE42852FC3A6F98DA6275E551C07008), # noqa: E501 + address=Address(0xEF859513AE36C397C43170A2980741575916167B), # noqa: E501 ) # Source: lll # { (CALLCODE 300000 0 0 64 0 64 ) } # noqa: E501 @@ -127,11 +130,12 @@ def test_static_callcallcodecall_010_2( address=Address(0xD450D1D19AEFB5A30DC4A483DB88E86C215C67A0), # noqa: E501 ) # Source: lll - # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x3D090, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { (CALLCODE 300000 2 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x493E0, + address=0xEF859513AE36C397C43170A2980741575916167B, + value=0x2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -140,16 +144,8 @@ def test_static_callcallcodecall_010_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEF859513AE36C397C43170A2980741575916167B), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x6B21D14FFAE42852FC3A6F98DA6275E551C07008), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge.py index 65d3a0b358c..ba5737462ae 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcallcodecall_010_ooge( ) -> None: """Test_static_callcallcodecall_010_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,6 +66,31 @@ def test_static_callcallcodecall_010_ooge( gas_limit=30000000, ) + # Source: lll + # { (DELEGATECALL 300000 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 1 1) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.DELEGATECALL( + gas=0x493E0, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x1, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x39C3AAD8C9ECF3BE71828CAFFEEE06727FDA4679), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -91,22 +113,22 @@ def test_static_callcallcodecall_010_ooge( address=Address(0x33344FF747B678F9E86028B0C745D8AB0E0D1792), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 300000 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 1 1) } - addr = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 120020 0 64 0 64 ) (SSTORE 1 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.POP( - Op.DELEGATECALL( - gas=0x493E0, - address=Op.CALLDATALOAD(offset=0x0), + Op.STATICCALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.MSTORE(offset=0x1, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x39C3AAD8C9ECF3BE71828CAFFEEE06727FDA4679), # noqa: E501 + address=Address(0xC45FE363C9AC4E1FEED02B03A212FDF979A74505), # noqa: E501 ) # Source: lll # { (STATICCALL 120020 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -133,32 +155,6 @@ def test_static_callcallcodecall_010_ooge( nonce=0, address=Address(0x0D195FCCF4102D8B6B6798768727AE0915C88ED7), # noqa: E501 ) - # Source: lll - # { (STATICCALL 120020 0 64 0 64 ) (SSTORE 1 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xC45FE363C9AC4E1FEED02B03A212FDF979A74505), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge_2.py index 7e4c489ef97..ab06fb60786 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcallcodecall_010_ooge_2( ) -> None: """Test_static_callcallcodecall_010_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,44 +66,6 @@ def test_static_callcallcodecall_010_ooge_2( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 350000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x87B79D9A4C004A23C7A12074BA8DA784E201EA8C, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x519393D984BEAF4FD226309E9F0704B2DB3164B5), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) (CALLCODE 200000 0 0 32 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.CALLCODE( - gas=0x30D40, - address=0x77E67836C6A30F95E117469CAEFB6C1FDCAD0C2E, - value=0x0, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x87B79D9A4C004A23C7A12074BA8DA784E201EA8C), # noqa: E501 - ) # Source: lll # { (STATICCALL 120020 (CALLDATALOAD 0) 0 64 0 64 ) } addr_2 = pre.deploy_contract( # noqa: F841 @@ -144,7 +103,44 @@ def test_static_callcallcodecall_010_ooge_2( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) (CALLCODE 200000 0 0 32 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.CALLCODE( + gas=0x30D40, + address=0x77E67836C6A30F95E117469CAEFB6C1FDCAD0C2E, + value=0x0, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x87B79D9A4C004A23C7A12074BA8DA784E201EA8C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 350000 0 32 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=0x87B79D9A4C004A23C7A12074BA8DA784E201EA8C, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x519393D984BEAF4FD226309E9F0704B2DB3164B5), # noqa: E501 + ) tx_data = [ Hash(addr_3, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after.py index e85db624c08..9cc19c3222d 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecall_010_oogm_after( ) -> None: """Test_static_callcallcodecall_010_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,22 +89,26 @@ def test_static_callcallcodecall_010_oogm_after( address=Address(0xF1F083974FD68B961E68130C27FC5EF37B49C1DF), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 400080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.DELEGATECALL( - gas=0x61AD0, - address=0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 120040 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x1D4E8, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0xC00FBA9C86D497814A90912F8F6C63801EA59908), # noqa: E501 + address=Address(0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435), # noqa: E501 ) # Source: lll # { (DELEGATECALL 400080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -135,28 +136,23 @@ def test_static_callcallcodecall_010_oogm_after( address=Address(0x3A2FB8850EEA3CBD892BB77FF68DA146EAD9C49D), # noqa: E501 ) # Source: lll - # { (STATICCALL 120040 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x1D4E8, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { (DELEGATECALL 400080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.DELEGATECALL( + gas=0x61AD0, + address=0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) ) + + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xC00FBA9C86D497814A90912F8F6C63801EA59908), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after2.py index eba102b6f35..2a2ed4e6b12 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecall_010_oogm_after2( ) -> None: """Test_static_callcallcodecall_010_oogm_after2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,8 +89,30 @@ def test_static_callcallcodecall_010_oogm_after2( address=Address(0x652A62E8338E91A46AA8387A2C205F35F79347AB), # noqa: E501 ) # Source: lll - # { (CALLCODE 400080 0 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x6F67C62FA385EDFE7BD280594EFF367F33E51438), # noqa: E501 + ) + # Source: lll + # { (CALLCODE 400080 0 0 64 0 64 ) (SSTORE 1 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0x61AD0, @@ -105,21 +124,14 @@ def test_static_callcallcodecall_010_oogm_after2( ret_size=0x40, ) ) - + Op.JUMPDEST - + Op.JUMPI( - pc=0x41, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) - ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x25) - + Op.JUMPDEST + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x4C57F5C93FEB3AF1807980230371459B773A1F88), # noqa: E501 + address=Address(0xCE0959EC3EC0C6527232DB11B856879585AFB0BB), # noqa: E501 ) # Source: lll - # { (CALLCODE 400080 0 0 64 0 64 ) (SSTORE 1 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (CALLCODE 400080 0 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0x61AD0, @@ -131,34 +143,18 @@ def test_static_callcallcodecall_010_oogm_after2( ret_size=0x40, ) ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xCE0959EC3EC0C6527232DB11B856879585AFB0BB), # noqa: E501 - ) - # Source: lll - # { (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + + Op.JUMPDEST + + Op.JUMPI( + pc=0x41, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x25) + + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x6F67C62FA385EDFE7BD280594EFF367F33E51438), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x4C57F5C93FEB3AF1807980230371459B773A1F88), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_2.py index 9f6d9cb873d..1ab56099a4e 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecall_010_oogm_after_2( ) -> None: """Test_static_callcallcodecall_010_oogm_after_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,22 +89,26 @@ def test_static_callcallcodecall_010_oogm_after_2( address=Address(0xF1F083974FD68B961E68130C27FC5EF37B49C1DF), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 400080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.DELEGATECALL( - gas=0x61AD0, - address=0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 120040 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x1D4E8, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0xC00FBA9C86D497814A90912F8F6C63801EA59908), # noqa: E501 + address=Address(0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435), # noqa: E501 ) # Source: lll # { (DELEGATECALL 400080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -135,28 +136,23 @@ def test_static_callcallcodecall_010_oogm_after_2( address=Address(0x3A2FB8850EEA3CBD892BB77FF68DA146EAD9C49D), # noqa: E501 ) # Source: lll - # { (STATICCALL 120040 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x1D4E8, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { (DELEGATECALL 400080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.DELEGATECALL( + gas=0x61AD0, + address=0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) ) + + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x5AD1F77E14FE15F07A2F5DF1480DCABA5B4B6435), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xC00FBA9C86D497814A90912F8F6C63801EA59908), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_3.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_3.py index 189f11e2686..1ad57cf628e 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_3.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_after_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecall_010_oogm_after_3( ) -> None: """Test_static_callcallcodecall_010_oogm_after_3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,6 +89,28 @@ def test_static_callcallcodecall_010_oogm_after_3( address=Address(0xF1F083974FD68B961E68130C27FC5EF37B49C1DF), # noqa: E501 ) # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x6F67C62FA385EDFE7BD280594EFF367F33E51438), # noqa: E501 + ) + # Source: lll # { (CALLCODE 400080 0 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -136,29 +155,6 @@ def test_static_callcallcodecall_010_oogm_after_3( nonce=0, address=Address(0x4C57F5C93FEB3AF1807980230371459B773A1F88), # noqa: E501 ) - # Source: lll - # { (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x6F67C62FA385EDFE7BD280594EFF367F33E51438), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before.py index 532b1199a50..ff5d85c14b8 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecall_010_oogm_before( ) -> None: """Test_static_callcallcodecall_010_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,28 @@ def test_static_callcallcodecall_010_oogm_before( gas_limit=30000000, ) + # Source: lll + # { (DELEGATECALL 400080 (CALLDATALOAD 0) 0 64 0 64 ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=0x61AD0, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0xE7B982648E452964FB0AC2B867EFA7C7B5B93D91), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 500000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -93,37 +112,6 @@ def test_static_callcallcodecall_010_oogm_before( address=Address(0x33344FF747B678F9E86028B0C745D8AB0E0D1792), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 400080 (CALLDATALOAD 0) 0 64 0 64 ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=0x61AD0, - address=Op.CALLDATALOAD(offset=0x0), - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0xE7B982648E452964FB0AC2B867EFA7C7B5B93D91), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0xC5B28F694C0E1BEFB55BDFBEC30BE55455897729), # noqa: E501 - ) - # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 addr_3 = pre.deploy_contract( # noqa: F841 code=Op.JUMPDEST @@ -147,13 +135,21 @@ def test_static_callcallcodecall_010_oogm_before( address=Address(0xF32619344056AD22A07F10433F70165CE82D9273), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (SSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + + Op.STATICCALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0xC5B28F694C0E1BEFB55BDFBEC30BE55455897729), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before2.py index a1b0382ed4f..2adc6629ce5 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_oogm_before2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecall_010_oogm_before2( ) -> None: """Test_static_callcallcodecall_010_oogm_before2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,29 @@ def test_static_callcallcodecall_010_oogm_before2( gas_limit=30000000, ) + # Source: lll + # { (CALLCODE 400080 (CALLDATALOAD 0) 0 0 64 0 64 ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x61AD0, + address=Op.CALLDATALOAD(offset=0x0), + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x21BE848CB68A95437A4928ED657B6D5F17DD3B03), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 800000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -93,22 +113,6 @@ def test_static_callcallcodecall_010_oogm_before2( address=Address(0x045BC6E334B0570CC84FBC4B86847063456E7C99), # noqa: E501 ) # Source: lll - # { (CALLCODE 400080 (CALLDATALOAD 0) 0 0 64 0 64 ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x61AD0, - address=Op.CALLDATALOAD(offset=0x0), - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x21BE848CB68A95437A4928ED657B6D5F17DD3B03), # noqa: E501 - ) - # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.JUMPDEST @@ -147,14 +151,6 @@ def test_static_callcallcodecall_010_oogm_before2( nonce=0, address=Address(0x698F17D55BFC6351C73D397D5DF71D8A1A1D694D), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end.py index ae366f0be5a..a24f9488aec 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecall_010_suicide_end( ) -> None: """Test_static_callcallcodecall_010_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecall_010_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -104,15 +109,6 @@ def test_static_callcallcodecall_010_suicide_end( nonce=0, address=Address(0xB7770360E0B87603E3D9C87C866451760C95ABCA), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end2.py index f2a251053c1..9c532bc1315 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecall_010_suicide_end2( ) -> None: """Test_static_callcallcodecall_010_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecall_010_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -105,15 +110,6 @@ def test_static_callcallcodecall_010_suicide_end2( nonce=0, address=Address(0xB7770360E0B87603E3D9C87C866451760C95ABCA), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle.py index b3695a0a09f..2354250e5cb 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecall_010_suicide_middle( ) -> None: """Test_static_callcallcodecall_010_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecall_010_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -104,15 +109,6 @@ def test_static_callcallcodecall_010_suicide_middle( nonce=0, address=Address(0x408F1ACEFFEC7BDAA35D77006CDCAEAD563BB694), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle2.py index afd8d610d62..3fd310c1261 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_010_suicide_middle2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecall_010_suicide_middle2( ) -> None: """Test_static_callcallcodecall_010_suicide_middle2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecall_010_suicide_middle2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -105,15 +110,6 @@ def test_static_callcallcodecall_010_suicide_middle2( nonce=0, address=Address(0x408F1ACEFFEC7BDAA35D77006CDCAEAD563BB694), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive.py index 5c01339715a..da1bee5f6fd 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecall_abcb_recursive( ) -> None: """Test_static_callcallcodecall_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_static_callcallcodecall_abcb_recursive( nonce=0, address=Address(0xE07076B3A07FF8E567E4F8451DAC25BACEFB88B2), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive2.py index 0e076189bbe..c85fe757e18 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecall_abcb_recursive2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecall_abcb_recursive2( ) -> None: """Test_static_callcallcodecall_abcb_recursive2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -102,7 +99,6 @@ def test_static_callcallcodecall_abcb_recursive2( nonce=0, address=Address(0x1E2229D0F325B81B81B8B14F2D239FF9742683C0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011.py index da4ad467c2a..a2f2dadbf77 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcallcodecallcode_011( ) -> None: """Test_static_callcallcodecallcode_011.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,29 @@ def test_static_callcallcodecallcode_011( ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x2BF6D23C6CDD3A7712AD150DFA2680ADABDA8B82, + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 11 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 11 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0xB, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0xB, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5CD189BC46453773DD75BDA72E7A7EEE97D63BCE), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) (DELEGATECALL 300000 0 64 0 64 ) (MSTORE 1 1) } # noqa: E501 @@ -74,7 +76,7 @@ def test_static_callcallcodecallcode_011( + Op.POP( Op.DELEGATECALL( gas=0x493E0, - address=0x86ADD32E31AA6E47126BC308CF85B29D0C9A4234, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,36 +87,26 @@ def test_static_callcallcodecallcode_011( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2BF6D23C6CDD3A7712AD150DFA2680ADABDA8B82), # noqa: E501 ) # Source: lll - # { (MSTORE 11 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 11 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0xB, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0xB, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x86ADD32E31AA6E47126BC308CF85B29D0C9A4234), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_2.py index 28f2c9099cd..a9751f80768 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcallcodecallcode_011_2( ) -> None: """Test_static_callcallcodecallcode_011_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -72,6 +69,30 @@ def test_static_callcallcodecallcode_011_2( gas_limit=30000000, ) + # Source: lll + # { (CALLCODE 300000 (CALLDATALOAD 0) 0 0 64 0 64 ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x493E0, + address=Op.CALLDATALOAD(offset=0x0), + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x21A2D07156B4F874F3B25DFD175145C9CCEC1E19), # noqa: E501 + ) + # Source: lll + # { (MSTORE 1 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -94,23 +115,6 @@ def test_static_callcallcodecallcode_011_2( address=Address(0x023AE6338FBE9709A6449BFB0821F5AA83987B26), # noqa: E501 ) # Source: lll - # { (CALLCODE 300000 (CALLDATALOAD 0) 0 0 64 0 64 ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x493E0, - address=Op.CALLDATALOAD(offset=0x0), - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x21A2D07156B4F874F3B25DFD175145C9CCEC1E19), # noqa: E501 - ) - # Source: lll # { (CALLCODE 250000 0 0 64 0 64 ) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.CALLCODE( @@ -144,14 +148,6 @@ def test_static_callcallcodecallcode_011_2( nonce=0, address=Address(0x3CEA889FD03A922CC673D25E5DB4E72743AA4878), # noqa: E501 ) - # Source: lll - # { (MSTORE 1 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge.py index 556de5b40bc..255691213b7 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecallcode_011_ooge( ) -> None: """Test_static_callcallcodecallcode_011_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,43 +68,6 @@ def test_static_callcallcodecallcode_011_ooge( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x249F0, - address=0x630155B633B8B8F4BCB63E94E0BAAE0197C824EB, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x6E143211E9D36EAEEBE65F6ED69D6C28500040D6), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) (DELEGATECALL 100000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.DELEGATECALL( - gas=0x186A0, - address=0x77612608C7A22F8929F6F1C9462A9954621AEEFD, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x630155B633B8B8F4BCB63E94E0BAAE0197C824EB), # noqa: E501 - ) # Source: lll # { (DELEGATECALL 20020 (CALLDATALOAD 0) 0 64 0 64 ) } addr_2 = pre.deploy_contract( # noqa: F841 @@ -145,7 +105,43 @@ def test_static_callcallcodecallcode_011_ooge( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) (DELEGATECALL 100000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.DELEGATECALL( + gas=0x186A0, + address=0x77612608C7A22F8929F6F1C9462A9954621AEEFD, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x630155B633B8B8F4BCB63E94E0BAAE0197C824EB), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x249F0, + address=0x630155B633B8B8F4BCB63E94E0BAAE0197C824EB, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x6E143211E9D36EAEEBE65F6ED69D6C28500040D6), # noqa: E501 + ) tx_data = [ Hash(addr_3, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge_2.py index ffbdcfebc2c..9b73ceaab58 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_static_callcallcodecallcode_011_ooge_2( ) -> None: """Test_static_callcallcodecallcode_011_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -74,6 +71,33 @@ def test_static_callcallcodecallcode_011_ooge_2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) (CALLCODE 100000 (CALLDATALOAD 0) 0 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.CALLCODE( + gas=0x186A0, + address=Op.CALLDATALOAD(offset=0x0), + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x11A4A9DAD43E6ED44E108EAF7FB160F9835068F4), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -96,26 +120,6 @@ def test_static_callcallcodecallcode_011_ooge_2( address=Address(0x6E143211E9D36EAEEBE65F6ED69D6C28500040D6), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (CALLCODE 100000 (CALLDATALOAD 0) 0 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.CALLCODE( - gas=0x186A0, - address=Op.CALLDATALOAD(offset=0x0), - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x11A4A9DAD43E6ED44E108EAF7FB160F9835068F4), # noqa: E501 - ) - # Source: lll # { (MSTORE 3 11) (CALLCODE 20020 0 0 64 0 64 ) (MSTORE 13 1)} # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0xB) @@ -155,14 +159,6 @@ def test_static_callcallcodecallcode_011_ooge_2( nonce=0, address=Address(0xF43B4E8B779078758104039080947F8F74E663D3), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after.py index d38ae9044ff..f2dd613dedf 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecallcode_011_oogm_after( ) -> None: """Test_static_callcallcodecallcode_011_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,23 +89,30 @@ def test_static_callcallcodecallcode_011_oogm_after( address=Address(0xB4D115B5309A03FEBD836ABB6456BCE43CEC037B), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) (DELEGATECALL 40080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 1 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 1 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.POP( Op.DELEGATECALL( - gas=0x9C90, - address=0xFECF0806036B619896DA47F661DFCE85C0107E9D, + gas=0x4E34, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.SSTORE(key=0x3, value=0x1) + + Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x476564431E8A9C2C934EF7712A1182EEBB46B872), # noqa: E501 + address=Address(0xFECF0806036B619896DA47F661DFCE85C0107E9D), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) (DELEGATECALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -137,32 +141,24 @@ def test_static_callcallcodecallcode_011_oogm_after( address=Address(0xD678D9A03433A246D441A9A225553D3E4E760C5F), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 1 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 1 1) (DELEGATECALL 40080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.POP( Op.DELEGATECALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + gas=0x9C90, + address=0xFECF0806036B619896DA47F661DFCE85C0107E9D, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.MSTORE(offset=0x1, value=0x1) + + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0xFECF0806036B619896DA47F661DFCE85C0107E9D), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x476564431E8A9C2C934EF7712A1182EEBB46B872), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after2.py index 990955e3558..91e9a676fb2 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecallcode_011_oogm_after2( ) -> None: """Test_static_callcallcodecallcode_011_oogm_after2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,23 +89,27 @@ def test_static_callcallcodecallcode_011_oogm_after2( address=Address(0x652A62E8338E91A46AA8387A2C205F35F79347AB), # noqa: E501 ) # Source: lll - # { (CALLCODE 40080 0 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.CALLCODE( - gas=0x9C90, - address=0x25D69E6A677BD6D872F436BAD807C3244A268673, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (CALLCODE 20020 0 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x4E34, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x0973E7675CA57F8E6DEB10CC07DE5D8B53956212), # noqa: E501 + address=Address(0x25D69E6A677BD6D872F436BAD807C3244A268673), # noqa: E501 ) # Source: lll # { (CALLCODE 40080 0 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -137,29 +138,24 @@ def test_static_callcallcodecallcode_011_oogm_after2( address=Address(0x13A5EB6FC2CF111FBA5DE5C336A9510E8229A44C), # noqa: E501 ) # Source: lll - # { (CALLCODE 20020 0 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { (CALLCODE 40080 0 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.CALLCODE( + gas=0x9C90, + address=0x25D69E6A677BD6D872F436BAD807C3244A268673, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) ) + + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x25D69E6A677BD6D872F436BAD807C3244A268673), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x0973E7675CA57F8E6DEB10CC07DE5D8B53956212), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_1.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_1.py index 4bd426bacd3..bfbc6735e35 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_1.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecallcode_011_oogm_after_1( ) -> None: """Test_static_callcallcodecallcode_011_oogm_after_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,6 +89,32 @@ def test_static_callcallcodecallcode_011_oogm_after_1( address=Address(0xB4D115B5309A03FEBD836ABB6456BCE43CEC037B), # noqa: E501 ) # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=0x4E34, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x02C0BFFB833F0BD1BDCB227A4FE215CF640316BB), # noqa: E501 + ) + # Source: lll # { (MSTORE 3 1) (DELEGATECALL 40080 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) @@ -136,33 +159,6 @@ def test_static_callcallcodecallcode_011_oogm_after_1( nonce=0, address=Address(0x037BF0D28AF83352E42A45CD844899EE7C948A7C), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x02C0BFFB833F0BD1BDCB227A4FE215CF640316BB), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_2.py index 52404fc0bae..a8854ec54cc 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_after_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecallcode_011_oogm_after_2( ) -> None: """Test_static_callcallcodecallcode_011_oogm_after_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -92,13 +89,20 @@ def test_static_callcallcodecallcode_011_oogm_after_2( address=Address(0x652A62E8338E91A46AA8387A2C205F35F79347AB), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (CALLCODE 40080 0 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) (CALLCODE 20020 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.CALLCODE( - gas=0x9C90, - address=0x1E28DAA61AD32AAC8383A1F7B17986C69F0C3273, + gas=0x4E34, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, value=0x0, args_offset=0x0, args_size=0x40, @@ -106,10 +110,10 @@ def test_static_callcallcodecallcode_011_oogm_after_2( ret_size=0x40, ) ) - + Op.SSTORE(key=0x3, value=0x1) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, nonce=0, - address=Address(0x7DA35806C36EF9661EFA1128809B18A8ED9C78F0), # noqa: E501 + address=Address(0x1E28DAA61AD32AAC8383A1F7B17986C69F0C3273), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (CALLCODE 40080 0 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -139,13 +143,13 @@ def test_static_callcallcodecallcode_011_oogm_after_2( address=Address(0x45445092B290295FB6C954103FF2CE24CF3CFAF5), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (CALLCODE 20020 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) (CALLCODE 40080 0 0 64 0 64 ) (SSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x3, value=0x1) + Op.POP( Op.CALLCODE( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + gas=0x9C90, + address=0x1E28DAA61AD32AAC8383A1F7B17986C69F0C3273, value=0x0, args_offset=0x0, args_size=0x40, @@ -153,19 +157,11 @@ def test_static_callcallcodecallcode_011_oogm_after_2( ret_size=0x40, ) ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.SSTORE(key=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x1E28DAA61AD32AAC8383A1F7B17986C69F0C3273), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x7DA35806C36EF9661EFA1128809B18A8ED9C78F0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before.py index a084bc0c56e..9c95f6777cf 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcallcodecallcode_011_oogm_before( ) -> None: """Test_static_callcallcodecallcode_011_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,32 @@ def test_static_callcallcodecallcode_011_oogm_before( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) (DELEGATECALL 40080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=0x9C90, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0xF752172F60D0024AF14BEE497ED232AB3A215362), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -93,25 +116,6 @@ def test_static_callcallcodecallcode_011_oogm_before( address=Address(0xD28B8E27785DDEE975645E09E8631D7BCB4133F3), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 40080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x9C90, - address=Op.CALLDATALOAD(offset=0x0), - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xF752172F60D0024AF14BEE497ED232AB3A215362), # noqa: E501 - ) - # Source: lll # { (SSTORE 3 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x3, value=0x1) @@ -156,14 +160,6 @@ def test_static_callcallcodecallcode_011_oogm_before( nonce=0, address=Address(0x9D3E6C1D2BC6290F0E7161ADBB3AD1EC4770D0D3), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before2.py index 209c0d32b7d..b0ff081f608 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_oogm_before2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -67,9 +66,7 @@ def test_static_callcallcodecallcode_011_oogm_before2( ) -> None: """Test_static_callcallcodecallcode_011_oogm_before2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -80,6 +77,33 @@ def test_static_callcallcodecallcode_011_oogm_before2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 32 1) (CALLCODE 40080 (CALLDATALOAD 0) 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x20, value=0x1) + + Op.POP( + Op.CALLCODE( + gas=0x9C90, + address=Op.CALLDATALOAD(offset=0x0), + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x20, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x8BDE6A10A1792232FD09B528800D9AC2A6835424), # noqa: E501 + ) + # Source: lll + # { (MSTORE 32 1) } + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, + nonce=0, + address=Address(0xD4286AC3FCAC436406BC95F5B0176AD49AED7F7C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -102,13 +126,13 @@ def test_static_callcallcodecallcode_011_oogm_before2( address=Address(0x6E143211E9D36EAEEBE65F6ED69D6C28500040D6), # noqa: E501 ) # Source: lll - # { (MSTORE 32 1) (CALLCODE 40080 (CALLDATALOAD 0) 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x20, value=0x1) + # { (SSTORE 3 1) (CALLCODE 20020 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.POP( Op.CALLCODE( - gas=0x9C90, - address=Op.CALLDATALOAD(offset=0x0), + gas=0x4E34, + address=0xD4286AC3FCAC436406BC95F5B0176AD49AED7F7C, value=0x0, args_offset=0x0, args_size=0x40, @@ -119,17 +143,16 @@ def test_static_callcallcodecallcode_011_oogm_before2( + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, nonce=0, - address=Address(0x8BDE6A10A1792232FD09B528800D9AC2A6835424), # noqa: E501 + address=Address(0x87F0BB05316A8D8146646A151A64F38AE9D25176), # noqa: E501 ) # Source: lll - # { (SSTORE 3 1) (CALLCODE 20020 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.POP( + # { (CALLCODE 20020 1 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.POP( Op.CALLCODE( gas=0x4E34, address=0xD4286AC3FCAC436406BC95F5B0176AD49AED7F7C, - value=0x0, + value=0x1, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -138,8 +161,9 @@ def test_static_callcallcodecallcode_011_oogm_before2( ) + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, + balance=10, nonce=0, - address=Address(0x87F0BB05316A8D8146646A151A64F38AE9D25176), # noqa: E501 + address=Address(0x94C82267A4E8333AFB80073FBAED3FE5973ADC7C), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (CALLCODE 20020 0 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 @@ -168,34 +192,6 @@ def test_static_callcallcodecallcode_011_oogm_before2( nonce=0, address=Address(0x1DFFDBFBE33709F17B6E90137242C109917A994B), # noqa: E501 ) - # Source: lll - # { (CALLCODE 20020 1 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.CALLCODE( - gas=0x4E34, - address=0xD4286AC3FCAC436406BC95F5B0176AD49AED7F7C, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x20, value=0x1) - + Op.STOP, - balance=10, - nonce=0, - address=Address(0x94C82267A4E8333AFB80073FBAED3FE5973ADC7C), # noqa: E501 - ) - # Source: lll - # { (MSTORE 32 1) } - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xD4286AC3FCAC436406BC95F5B0176AD49AED7F7C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end.py index 37679cc9d73..225136cbccb 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecallcode_011_suicide_end( ) -> None: """Test_static_callcallcodecallcode_011_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecallcode_011_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -104,15 +109,6 @@ def test_static_callcallcodecallcode_011_suicide_end( nonce=0, address=Address(0x4A31DD3A8C3C9A793AC0B3C234A4DBAC2F201404), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end2.py index f7434d31144..d1821e6f7a5 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecallcode_011_suicide_end2( ) -> None: """Test_static_callcallcodecallcode_011_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecallcode_011_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_static_callcallcodecallcode_011_suicide_end2( nonce=0, address=Address(0x13B9EDFF99AE7B562C9292952C1E67E8FA0A3E03), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle.py index 5615d596d57..c7417f94074 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecallcode_011_suicide_middle( ) -> None: """Test_static_callcallcodecallcode_011_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecallcode_011_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -104,15 +109,6 @@ def test_static_callcallcodecallcode_011_suicide_middle( nonce=0, address=Address(0xECA01D36DBE4F4AB283A49016EFA370BAC7E7346), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle2.py index 2e4cb91900c..0234bc00b51 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_011_suicide_middle2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecallcode_011_suicide_middle2( ) -> None: """Test_static_callcallcodecallcode_011_suicide_middle2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcallcodecallcode_011_suicide_middle2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -112,15 +117,6 @@ def test_static_callcallcodecallcode_011_suicide_middle2( nonce=0, address=Address(0xDCAD05283EB3153CA2200073454E8303C30805EC), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive.py index 6d4671b3856..2d76b12e3ba 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecallcode_abcb_recursive( ) -> None: """Test_static_callcallcodecallcode_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_static_callcallcodecallcode_abcb_recursive( nonce=0, address=Address(0xAB5C6018CF3368381E283C1DE7F906C456188BC3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive2.py b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive2.py index 15773391f13..606cc541ecf 100644 --- a/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive2.py +++ b/tests/ported_static/stStaticCall/test_static_callcallcodecallcode_abcb_recursive2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcallcodecallcode_abcb_recursive2( ) -> None: """Test_static_callcallcodecallcode_abcb_recursive2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -103,7 +100,6 @@ def test_static_callcallcodecallcode_abcb_recursive2( nonce=0, address=Address(0x1A3C543695D7CA3A7D5522E9C7AABE5512571706), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcode_check_pc.py b/tests/ported_static/stStaticCall/test_static_callcode_check_pc.py index 43e505afa53..c05cb8532bc 100644 --- a/tests/ported_static/stStaticCall/test_static_callcode_check_pc.py +++ b/tests/ported_static/stStaticCall/test_static_callcode_check_pc.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcode_check_pc( ) -> None: """Test_static_callcode_check_pc.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,13 +44,20 @@ def test_static_callcode_check_pc( gas_limit=3000000000, ) + # Source: lll + # {} + addr = pre.deploy_contract( # noqa: F841 + code=Op.STOP, + balance=0x2540BE400, + nonce=0, + ) # Source: lll # { (STATICCALL 1000000 0 64 0 64 ) [[3]] (PC)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0xF4240, - address=0xFA032348694AD238CCCC23B44FE450999CDC0FE, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -64,17 +68,7 @@ def test_static_callcode_check_pc( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6A1BC409E9C1914F80D4A72653F9D1C4A53C0343), # noqa: E501 - ) - # Source: lll - # {} - addr = pre.deploy_contract( # noqa: F841 - code=Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x0FA032348694AD238CCCC23B44FE450999CDC0FE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecall_10.py b/tests/ported_static/stStaticCall/test_static_callcodecall_10.py index 34472009770..14ed9be49e3 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecall_10.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecall_10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcodecall_10( ) -> None: """Test_static_callcodecall_10.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,10 @@ def test_static_callcodecall_10( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x732757BD540487F3FCFA3342F95106BC67684091, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 1 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x4EEF7E2B5AE9BE0FC5B43DC4FE39195A1AE10FC4), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 1 1) } # noqa: E501 @@ -74,7 +57,7 @@ def test_static_callcodecall_10( + Op.POP( Op.STATICCALL( gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,16 +68,26 @@ def test_static_callcodecall_10( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x732757BD540487F3FCFA3342F95106BC67684091), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecall_10_2.py b/tests/ported_static/stStaticCall/test_static_callcodecall_10_2.py index 847fbf8693d..28bc158d0e5 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecall_10_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecall_10_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcodecall_10_2( ) -> None: """Test_static_callcodecall_10_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,32 +45,17 @@ def test_static_callcodecall_10_2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x620B442C84D5068E6B57D390A1AC99130205406E, - value=0x1, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 1 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x1C60BD6C18EAA7C07312B755979E9B2C2F2802D4), # noqa: E501 ) # Source: lll # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -82,16 +64,27 @@ def test_static_callcodecall_10_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x620B442C84D5068E6B57D390A1AC99130205406E), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + # { [[ 0 ]] (CALLCODE 350000 1 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=0x1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge.py b/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge.py index e7093742577..52635e65517 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecall_10_ooge( ) -> None: """Test_static_callcodecall_10_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,27 +66,6 @@ def test_static_callcodecall_10_ooge( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x249F0, - address=0x33E1AD2A3AE944798E9ED4689B85D9136B59EBD2, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xDCFF1EF291EC7B6A606AC4284680DB5A06F33054), # noqa: E501 - ) # Source: lll # { (STATICCALL 20020 (CALLDATALOAD 0) 0 64 0 64 ) } addr = pre.deploy_contract( # noqa: F841 @@ -127,7 +103,27 @@ def test_static_callcodecall_10_ooge( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x249F0, + address=0x33E1AD2A3AE944798E9ED4689B85D9136B59EBD2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xDCFF1EF291EC7B6A606AC4284680DB5A06F33054), # noqa: E501 + ) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge_2.py index eb311ee0b0c..a81f4ac172c 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecall_10_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecall_10_ooge_2( ) -> None: """Test_static_callcodecall_10_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,28 +66,6 @@ def test_static_callcodecall_10_ooge_2( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0xE7BF411C5F7EA351927579255740C4BD69BD01F5, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xECEB2D7DC716950B2877389DC5B8CF7000305255), # noqa: E501 - ) # Source: lll # { (MSTORE 2 1) (STATICCALL 20020 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -132,7 +107,28 @@ def test_static_callcodecall_10_ooge_2( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=0xE7BF411C5F7EA351927579255740C4BD69BD01F5, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xECEB2D7DC716950B2877389DC5B8CF7000305255), # noqa: E501 + ) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end.py index f16e28b4e46..5fecaa2fdc8 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecall_10_suicide_end( ) -> None: """Test_static_callcodecall_10_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,6 +66,22 @@ def test_static_callcodecall_10_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 + ) + # Source: lll + # { (SSTORE 2 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,23 +122,6 @@ def test_static_callcodecall_10_suicide_end( nonce=0, address=Address(0xDC07FFF80D888EBA04EAB962D37897F6C923462B), # noqa: E501 ) - # Source: lll - # { (MSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 - ) - # Source: lll - # { (SSTORE 2 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x703B936FD4D674F0FF5D6957F61097152F8781B8), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end2.py index 8fc977c4056..92fe9bf3b88 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecall_10_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_callcodecall_10_suicide_end2( ) -> None: """Test_static_callcodecall_10_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -72,6 +69,14 @@ def test_static_callcodecall_10_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 2 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -112,15 +117,6 @@ def test_static_callcodecall_10_suicide_end2( nonce=0, address=Address(0xB60789F240AC9F12FCDE1E4BBD5042A7F30932D4), # noqa: E501 ) - # Source: lll - # { (MSTORE 2 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x2, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0xCFB5784A5E49924BECC2D5C5D2EE0A9B141E6216), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100.py index 466ffeabecb..9a4881aff50 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcodecallcall_100( ) -> None: """Test_static_callcodecallcall_100.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,25 @@ def test_static_callcodecallcall_100( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x37BEB0DDA966430210BAED14C311DB5B8237B9E7, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 1 1)} + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x3D090, + address=addr_3, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4BE61408125D759DFF8CAEAE4704D8C7ACA6099A), # noqa: E501 ) # Source: lll # { (STATICCALL 300000 0 64 0 64 ) (MSTORE 5 (CALLER))} # noqa: E501 @@ -73,7 +71,7 @@ def test_static_callcodecallcall_100( code=Op.POP( Op.STATICCALL( gas=0x493E0, - address=0xEF859513AE36C397C43170A2980741575916167B, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -84,32 +82,26 @@ def test_static_callcodecallcall_100( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x37BEB0DDA966430210BAED14C311DB5B8237B9E7), # noqa: E501 ) # Source: lll - # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x3D090, - address=0x7E3FA59AE6C821631A70F75A54FBE9A1085102C7, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEF859513AE36C397C43170A2980741575916167B), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1)} - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x7E3FA59AE6C821631A70F75A54FBE9A1085102C7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_2.py index fc1eee3d52b..6c9a236711a 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecallcall_100_2( ) -> None: """Test_static_callcodecallcall_100_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -70,32 +67,17 @@ def test_static_callcodecallcall_100_2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x47F2744D161ACE12CC52A51922D3CEE2E8AB3B89, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x9F233647D252A405337C598A262F95052C23F7EE), # noqa: E501 ) # Source: lll - # { (STATICCALL 300000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( - gas=0x493E0, - address=0xEF859513AE36C397C43170A2980741575916167B, + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -104,14 +86,13 @@ def test_static_callcodecallcall_100_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x47F2744D161ACE12CC52A51922D3CEE2E8AB3B89), # noqa: E501 ) # Source: lll - # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 300000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + gas=0x493E0, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -120,16 +101,27 @@ def test_static_callcodecallcall_100_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEF859513AE36C397C43170A2980741575916167B), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + # { [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge.py index 71ccf237f91..2a349847b34 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecallcall_100_ooge( ) -> None: """Test_static_callcodecallcall_100_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,46 +66,6 @@ def test_static_callcodecallcall_100_ooge( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x249F0, - address=0xC4961FC5BDC17DA68E909D07947A5E030952891E, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xDCFF1EF291EC7B6A606AC4284680DB5A06F33054), # noqa: E501 - ) - # Source: lll - # { (MSTORE 32 (CALLDATALOAD 0)) (STATICCALL 100000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x20, value=Op.CALLDATALOAD(offset=0x0)) - + Op.POP( - Op.STATICCALL( - gas=0x186A0, - address=0x5AC4EE179ABD5EA5F60962E651DED51161A55B6E, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0xC4961FC5BDC17DA68E909D07947A5E030952891E), # noqa: E501 - ) # Source: lll # { (STATICCALL 20020 (CALLDATALOAD 32) 0 64 0 64 ) (MSTORE 3 1) } addr_2 = pre.deploy_contract( # noqa: F841 @@ -149,7 +106,46 @@ def test_static_callcodecallcall_100_ooge( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 32 (CALLDATALOAD 0)) (STATICCALL 100000 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x20, value=Op.CALLDATALOAD(offset=0x0)) + + Op.POP( + Op.STATICCALL( + gas=0x186A0, + address=0x5AC4EE179ABD5EA5F60962E651DED51161A55B6E, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0xC4961FC5BDC17DA68E909D07947A5E030952891E), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x249F0, + address=0xC4961FC5BDC17DA68E909D07947A5E030952891E, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xDCFF1EF291EC7B6A606AC4284680DB5A06F33054), # noqa: E501 + ) tx_data = [ Hash(addr_3, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge2.py index 9476ab23f76..ddc828b6da4 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_ooge2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecallcall_100_ooge2( ) -> None: """Test_static_callcodecallcall_100_ooge2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,44 +66,6 @@ def test_static_callcodecallcall_100_ooge2( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0x3C7AEF27501FCE796222312BCD7A4546DD60637, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xBA1D112A3EA7A5149E304FCEA53D3F6A76BD4CB9), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) (STATICCALL 100000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.STATICCALL( - gas=0x186A0, - address=0x33E1AD2A3AE944798E9ED4689B85D9136B59EBD2, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x03C7AEF27501FCE796222312BCD7A4546DD60637), # noqa: E501 - ) # Source: lll # { (STATICCALL 20020 (CALLDATALOAD 0) 0 64 0 64 ) } addr_2 = pre.deploy_contract( # noqa: F841 @@ -144,7 +103,44 @@ def test_static_callcodecallcall_100_ooge2( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) (STATICCALL 100000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.STATICCALL( + gas=0x186A0, + address=0x33E1AD2A3AE944798E9ED4689B85D9136B59EBD2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x03C7AEF27501FCE796222312BCD7A4546DD60637), # noqa: E501 + ) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=0x3C7AEF27501FCE796222312BCD7A4546DD60637, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0xBA1D112A3EA7A5149E304FCEA53D3F6A76BD4CB9), # noqa: E501 + ) tx_data = [ Hash(addr_3, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after.py index 3cdcb06e481..aa3f374072f 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcall_100_oogm_after( ) -> None: """Test_static_callcodecallcall_100_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,24 +47,28 @@ def test_static_callcodecallcall_100_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xEAF6, - address=0x2865FD3572B0B77173E5ED91E968ACAD55701151, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 20020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x4E34, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE79AEE563C83547F229D955ECDCCA0F01FED9AA9), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -76,7 +77,7 @@ def test_static_callcodecallcall_100_oogm_after( + Op.POP( Op.STATICCALL( gas=0x9C90, - address=0x694B007C276285E1A2424A78288ABF42FDDA6E71, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -93,35 +94,26 @@ def test_static_callcodecallcall_100_oogm_after( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x2865FD3572B0B77173E5ED91E968ACAD55701151), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 20020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xEAF6, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x694B007C276285E1A2424A78288ABF42FDDA6E71), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after2.py index 40d80114a76..655f6dd9441 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcall_100_oogm_after2( ) -> None: """Test_static_callcodecallcall_100_oogm_after2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,6 +90,28 @@ def test_static_callcodecallcall_100_oogm_after2( address=Address(0x8B3623C74BBF83102ADC34299D32B5CD0E7D8CB9), # noqa: E501 ) # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x444DF104EA3853BFEAA91A755136F33385D12EEA), # noqa: E501 + ) + # Source: lll # { (STATICCALL 400080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.POP( @@ -117,29 +136,6 @@ def test_static_callcodecallcall_100_oogm_after2( nonce=0, address=Address(0xF4645C150A8060778AD94DFFE302081FC222DEDB), # noqa: E501 ) - # Source: lll - # { (STATICCALL 120020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x444DF104EA3853BFEAA91A755136F33385D12EEA), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_2.py index 925ac1cbddf..d3288a69630 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcall_100_oogm_after_2( ) -> None: """Test_static_callcodecallcall_100_oogm_after_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,24 +47,28 @@ def test_static_callcodecallcall_100_oogm_after_2( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 601500 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x92D9C, - address=0xA4306100C983E6928DEBC547240D7FE9DEDF2EF8, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x1D4D4, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x0BC6FE23B1C8D7E29532373698CDF5BA4A4E7B88), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 400080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -76,7 +77,7 @@ def test_static_callcodecallcall_100_oogm_after_2( + Op.POP( Op.STATICCALL( gas=0x61AD0, - address=0x12C33B5028F0A7D7777501A5E899D92B2EC75B9A, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -93,35 +94,26 @@ def test_static_callcodecallcall_100_oogm_after_2( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0xA4306100C983E6928DEBC547240D7FE9DEDF2EF8), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 120020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (DELEGATECALL 601500 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x92D9C, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x3, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x12C33B5028F0A7D7777501A5E899D92B2EC75B9A), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_3.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_3.py index 981570ea381..c4003605e60 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_3.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_after_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_static_callcodecallcall_100_oogm_after_3( ) -> None: """Test_static_callcodecallcall_100_oogm_after_3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -75,25 +72,28 @@ def test_static_callcodecallcall_100_oogm_after_3( ) # Source: lll - # { [[ 0 ]] (CALLCODE 60150 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xEAF6, - address=0x2865FD3572B0B77173E5ED91E968ACAD55701151, - value=Op.CALLVALUE, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 20020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x4E34, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x20, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x62B278A07428F1FF97EE7C884B711F6DF3340707), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -102,7 +102,7 @@ def test_static_callcodecallcall_100_oogm_after_3( + Op.POP( Op.STATICCALL( gas=0x9C90, - address=0x694B007C276285E1A2424A78288ABF42FDDA6E71, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -119,35 +119,27 @@ def test_static_callcodecallcall_100_oogm_after_3( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x2865FD3572B0B77173E5ED91E968ACAD55701151), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 20020 0 64 0 64 ) (MSTORE 32 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (CALLCODE 60150 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xEAF6, + address=addr, + value=Op.CALLVALUE, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x20, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x694B007C276285E1A2424A78288ABF42FDDA6E71), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before.py index 3a95de7f19b..894c008a900 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcall_100_oogm_before( ) -> None: """Test_static_callcodecallcall_100_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,31 @@ def test_static_callcodecallcall_100_oogm_before( gas_limit=30000000, ) + # Source: lll + # { (STATICCALL 40080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 3 1) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.STATICCALL( + gas=0x9C90, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x570B7A7EB7D0539D77442B6262127229B9B6C19F), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -93,24 +115,6 @@ def test_static_callcodecallcall_100_oogm_before( address=Address(0xB1DDDCE88104538F48811F8E62AF99666E0C3A4E), # noqa: E501 ) # Source: lll - # { (STATICCALL 40080 (CALLDATALOAD 0) 0 64 0 64 ) (MSTORE 3 1) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=0x9C90, - address=Op.CALLDATALOAD(offset=0x0), - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x570B7A7EB7D0539D77442B6262127229B9B6C19F), # noqa: E501 - ) - # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.JUMPDEST @@ -152,14 +156,6 @@ def test_static_callcodecallcall_100_oogm_before( nonce=0, address=Address(0x4670334E92C4D14771FAADB3C90C987CB337ACCA), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before2.py index 0f513f095fb..791b780df05 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_oogm_before2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -70,9 +69,7 @@ def test_static_callcodecallcall_100_oogm_before2( ) -> None: """Test_static_callcodecallcall_100_oogm_before2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -83,6 +80,29 @@ def test_static_callcodecallcall_100_oogm_before2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) (STATICCALL 40080 (CALLDATALOAD 0) 0 64 0 64 ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.STATICCALL( + gas=0x9C90, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + address=Address(0x99FE987D98B818ED5AF6AE7B1A91A3BE35956195), # noqa: E501 + ) + # Source: lll + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -106,12 +126,12 @@ def test_static_callcodecallcall_100_oogm_before2( address=Address(0xF7520E9898ED4E699844182C95EFECAB5D06AD13), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (STATICCALL 40080 (CALLDATALOAD 0) 0 64 0 64 ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + # { (SSTORE 3 1) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STATICCALL( - gas=0x9C90, - address=Op.CALLDATALOAD(offset=0x0), + gas=0x4E34, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -119,7 +139,7 @@ def test_static_callcodecallcall_100_oogm_before2( ) + Op.STOP, nonce=0, - address=Address(0x99FE987D98B818ED5AF6AE7B1A91A3BE35956195), # noqa: E501 + address=Address(0x28124C297E97622ED1D89A53F804C178AEAF3BBF), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 @@ -144,30 +164,6 @@ def test_static_callcodecallcall_100_oogm_before2( nonce=0, address=Address(0x6224E12321037BF1B980D03FDC3E8AFB95E9E794), # noqa: E501 ) - # Source: lll - # { (SSTORE 3 1) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) - + Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - nonce=0, - address=Address(0x28124C297E97622ED1D89A53F804C178AEAF3BBF), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end.py index 07557a7944b..3afb781fa8b 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcall_100_suicide_end( ) -> None: """Test_static_callcodecallcall_100_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcall_100_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -109,15 +114,6 @@ def test_static_callcodecallcall_100_suicide_end( nonce=0, address=Address(0x8C800ABF2A49CA6FFAC93555AF4B5C7F9A3A8186), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end2.py index f48c9e87062..0752d84ae55 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcall_100_suicide_end2( ) -> None: """Test_static_callcodecallcall_100_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcall_100_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -110,15 +115,6 @@ def test_static_callcodecallcall_100_suicide_end2( nonce=0, address=Address(0x8C800ABF2A49CA6FFAC93555AF4B5C7F9A3A8186), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle.py index 580cac95a91..59fae6d7aa5 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcall_100_suicide_middle( ) -> None: """Test_static_callcodecallcall_100_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcall_100_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_static_callcodecallcall_100_suicide_middle( nonce=0, address=Address(0x408F1ACEFFEC7BDAA35D77006CDCAEAD563BB694), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle2.py index 0a5324c482b..909f0b2e455 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_100_suicide_middle2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcall_100_suicide_middle2( ) -> None: """Test_static_callcodecallcall_100_suicide_middle2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,14 @@ def test_static_callcodecallcall_100_suicide_middle2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -125,15 +130,6 @@ def test_static_callcodecallcall_100_suicide_middle2( nonce=0, address=Address(0x408F1ACEFFEC7BDAA35D77006CDCAEAD563BB694), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive.py index d6b08afa293..81fd2f9a0c9 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcall_abcb_recursive( ) -> None: """Test_static_callcodecallcall_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_static_callcodecallcall_abcb_recursive( nonce=0, address=Address(0x1E2229D0F325B81B81B8B14F2D239FF9742683C0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive2.py index 518adcd9cae..4e7a099956b 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcall_abcb_recursive2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcall_abcb_recursive2( ) -> None: """Test_static_callcodecallcall_abcb_recursive2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -124,7 +121,6 @@ def test_static_callcodecallcall_abcb_recursive2( nonce=0, address=Address(0x1E2229D0F325B81B81B8B14F2D239FF9742683C0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101.py index ae839ce0b2d..d15dada4249 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcodecallcallcode_101( ) -> None: """Test_static_callcodecallcallcode_101.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,29 @@ def test_static_callcodecallcallcode_101( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0xF553D6B8627C39028BD1E05A4F55E2A4B3042A1D, + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 1 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 31 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x1F, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4EEF7E2B5AE9BE0FC5B43DC4FE39195A1AE10FC4), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) (STATICCALL 300000 0 64 0 64 ) (MSTORE 31 1) } # noqa: E501 @@ -74,7 +76,7 @@ def test_static_callcodecallcallcode_101( + Op.POP( Op.STATICCALL( gas=0x493E0, - address=0x999E3C988E5FDF24ADF774E3502F0095E6530B72, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,36 +87,26 @@ def test_static_callcodecallcallcode_101( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF553D6B8627C39028BD1E05A4F55E2A4B3042A1D), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) (DELEGATECALL 250000 0 64 0 64 ) (MSTORE 31 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x1F, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x999E3C988E5FDF24ADF774E3502F0095E6530B72), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_2.py index 30d73188050..e8cb16990aa 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_callcodecallcallcode_101_2( ) -> None: """Test_static_callcodecallcallcode_101_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,6 +66,29 @@ def test_static_callcodecallcallcode_101_2( gas_limit=30000000, ) + # Source: lll + # { (STATICCALL 300000 (CALLDATALOAD 0) 0 64 0 64 ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x493E0, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x1B78AFBE56D4678CFA8DC79DF079BAD5585B8D3A), # noqa: E501 + ) + # Source: lll + # { (MSTORE 1 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 + ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -92,22 +112,6 @@ def test_static_callcodecallcallcode_101_2( address=Address(0x3F13B55C156D810BC161E971891180011E088E6F), # noqa: E501 ) # Source: lll - # { (STATICCALL 300000 (CALLDATALOAD 0) 0 64 0 64 ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x493E0, - address=Op.CALLDATALOAD(offset=0x0), - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x1B78AFBE56D4678CFA8DC79DF079BAD5585B8D3A), # noqa: E501 - ) - # Source: lll # { (CALLCODE 250000 0 0 64 0 64 ) } # noqa: E501 addr_2 = pre.deploy_contract( # noqa: F841 code=Op.CALLCODE( @@ -141,14 +145,6 @@ def test_static_callcodecallcallcode_101_2( nonce=0, address=Address(0x3CEA889FD03A922CC673D25E5DB4E72743AA4878), # noqa: E501 ) - # Source: lll - # { (MSTORE 1 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge.py index 9634a7bc2ac..68174dec990 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcallcode_101_ooge( ) -> None: """Test_static_callcodecallcallcode_101_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,31 +47,25 @@ def test_static_callcodecallcallcode_101_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0xAF91DF7B32C8778F1428F893F7356F90CFC2CBB7, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4EEF7E2B5AE9BE0FC5B43DC4FE39195A1AE10FC4), # noqa: E501 ) # Source: lll - # { (STATICCALL 200000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x30D40, - address=0x9126E4F25CC411A2D9D393AFEDB321EEF8A5AC94, + # { (DELEGATECALL 120020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=0x1D4D4, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -82,14 +73,13 @@ def test_static_callcodecallcallcode_101_ooge( ) + Op.STOP, nonce=0, - address=Address(0xAF91DF7B32C8778F1428F893F7356F90CFC2CBB7), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 120020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=0x1D4D4, - address=0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954, + # { (STATICCALL 200000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x30D40, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -97,24 +87,26 @@ def test_static_callcodecallcallcode_101_ooge( ) + Op.STOP, nonce=0, - address=Address(0x9126E4F25CC411A2D9D393AFEDB321EEF8A5AC94), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge_2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge_2.py index 237eb4aae76..bd879aec938 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_ooge_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcallcode_101_ooge_2( ) -> None: """Test_static_callcodecallcallcode_101_ooge_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,32 +47,26 @@ def test_static_callcodecallcallcode_101_ooge_2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0x13DDAC4297B5C0FB95BBC6D982184549393A980D, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x66227CF0A560E1F6F9E94345DD1B5C6758923BA6), # noqa: E501 ) # Source: lll - # { (STATICCALL 100000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x186A0, - address=0x25D69E6A677BD6D872F436BAD807C3244A268673, + # { (CALLCODE 20020 0 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x4E34, + address=addr_3, + value=0x0, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -83,15 +74,13 @@ def test_static_callcodecallcallcode_101_ooge_2( ) + Op.STOP, nonce=0, - address=Address(0x13DDAC4297B5C0FB95BBC6D982184549393A980D), # noqa: E501 ) # Source: lll - # { (CALLCODE 20020 0 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x4E34, - address=0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954, - value=0x0, + # { (STATICCALL 100000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x186A0, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -99,24 +88,27 @@ def test_static_callcodecallcallcode_101_ooge_2( ) + Op.STOP, nonce=0, - address=Address(0x25D69E6A677BD6D872F436BAD807C3244A268673), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + # { [[ 0 ]] (CALLCODE 150000 0 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after.py index 8d4da18661a..80bbe4d391a 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcallcode_101_oogm_after( ) -> None: """Test_static_callcodecallcallcode_101_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,24 +47,28 @@ def test_static_callcodecallcallcode_101_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xEAF6, - address=0x2865FD3572B0B77173E5ED91E968ACAD55701151, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.DELEGATECALL( + gas=0x4E34, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE79AEE563C83547F229D955ECDCCA0F01FED9AA9), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -76,7 +77,7 @@ def test_static_callcodecallcallcode_101_oogm_after( + Op.POP( Op.STATICCALL( gas=0x9C90, - address=0x2C0BFFB833F0BD1BDCB227A4FE215CF640316BB, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -93,35 +94,26 @@ def test_static_callcodecallcallcode_101_oogm_after( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x2865FD3572B0B77173E5ED91E968ACAD55701151), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.DELEGATECALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xEAF6, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x3, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x02C0BFFB833F0BD1BDCB227A4FE215CF640316BB), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after2.py index 6a290e5d3fa..22aa6944777 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_static_callcodecallcallcode_101_oogm_after2( contract_1 = Address(0x1000000000000000000000000000000000000001) contract_2 = Address(0x1000000000000000000000000000000000000002) contract_3 = Address(0x1000000000000000000000000000000000000003) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -76,25 +73,26 @@ def test_static_callcodecallcallcode_101_oogm_after2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 60150 0x1000000000000000000000000000000000000001 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xEAF6, - address=0x1000000000000000000000000000000000000001, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 3 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 3 1) (CALLCODE 20020 0x1000000000000000000000000000000000000003 0 0 64 0 64 ) } # noqa: E501 + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.CALLCODE( + gas=0x4E34, + address=contract_3, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll # { (MSTORE 3 1) (STATICCALL 40080 0x1000000000000000000000000000000000000002 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -103,7 +101,7 @@ def test_static_callcodecallcallcode_101_oogm_after2( + Op.POP( Op.STATICCALL( gas=0x9C90, - address=0x1000000000000000000000000000000000000002, + address=contract_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -120,33 +118,27 @@ def test_static_callcodecallcallcode_101_oogm_after2( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) (CALLCODE 20020 0x1000000000000000000000000000000000000003 0 0 64 0 64 ) } # noqa: E501 - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.CALLCODE( - gas=0x4E34, - address=0x1000000000000000000000000000000000000003, - value=0x0, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (CALLCODE 60150 0x1000000000000000000000000000000000000001 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xEAF6, + address=contract_1, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1000000000000000000000000000000000000002), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_1.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_1.py index 874506f1f4e..6822affea21 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_1.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcallcode_101_oogm_after_1( ) -> None: """Test_static_callcodecallcallcode_101_oogm_after_1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -93,12 +90,26 @@ def test_static_callcodecallcallcode_101_oogm_after_1( address=Address(0xAAB59F13D96113334FAB5C68E4E62B61F6CBF647), # noqa: E501 ) # Source: lll - # { (CALLCODE 700150 0 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + ) + # Source: lll + # { (SSTORE 3 1) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 + ) + # Source: lll + # { (CALLCODE 120020 0 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( - gas=0xAAEF6, - address=0xF4645C150A8060778AD94DFFE302081FC222DEDB, + gas=0x1D4D4, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, value=0x0, args_offset=0x0, args_size=0x40, @@ -108,9 +119,27 @@ def test_static_callcodecallcallcode_101_oogm_after_1( ) + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB9ABD0EF44AE2DF9F408D150C5B6FB6A181BE9CF), # noqa: E501 + address=Address(0x858DB7418C9E1C32811E5BC39366BDF6E2ED2492), # noqa: E501 + ) + # Source: lll + # { (CALLCODE 120020 0 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.CALLCODE( + gas=0x1D4D4, + address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + value=0x0, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + address=Address(0x677DB155FAB75972F19732AFB328A0EA6472A6AB), # noqa: E501 ) # Source: lll # { (STATICCALL 400080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -138,13 +167,12 @@ def test_static_callcodecallcallcode_101_oogm_after_1( address=Address(0xF4645C150A8060778AD94DFFE302081FC222DEDB), # noqa: E501 ) # Source: lll - # { (CALLCODE 120020 0 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 400080 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_6 = pre.deploy_contract( # noqa: F841 code=Op.POP( - Op.CALLCODE( - gas=0x1D4D4, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - value=0x0, + Op.STATICCALL( + gas=0x61AD0, + address=0x677DB155FAB75972F19732AFB328A0EA6472A6AB, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -154,22 +182,15 @@ def test_static_callcodecallcallcode_101_oogm_after_1( + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x858DB7418C9E1C32811E5BC39366BDF6E2ED2492), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x18DC408F6983F318529A93583EE12F590C537820), # noqa: E501 ) # Source: lll - # { (CALLCODE 700150 0 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 + # { (CALLCODE 700150 0 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( gas=0xAAEF6, - address=0x18DC408F6983F318529A93583EE12F590C537820, + address=0xF4645C150A8060778AD94DFFE302081FC222DEDB, value=0x0, args_offset=0x0, args_size=0x40, @@ -181,33 +202,15 @@ def test_static_callcodecallcallcode_101_oogm_after_1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6486B0CD8779006E5CD706484B0D890B9A220805), # noqa: E501 - ) - # Source: lll - # { (STATICCALL 400080 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=0x61AD0, - address=0x677DB155FAB75972F19732AFB328A0EA6472A6AB, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, - nonce=0, - address=Address(0x18DC408F6983F318529A93583EE12F590C537820), # noqa: E501 + address=Address(0xB9ABD0EF44AE2DF9F408D150C5B6FB6A181BE9CF), # noqa: E501 ) # Source: lll - # { (CALLCODE 120020 0 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 + # { (CALLCODE 700150 0 0 64 0 64 ) (MSTORE 3 1)} # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALLCODE( - gas=0x1D4D4, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + gas=0xAAEF6, + address=0x18DC408F6983F318529A93583EE12F590C537820, value=0x0, args_offset=0x0, args_size=0x40, @@ -217,17 +220,10 @@ def test_static_callcodecallcallcode_101_oogm_after_1( ) + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x677DB155FAB75972F19732AFB328A0EA6472A6AB), # noqa: E501 - ) - # Source: lll - # { (SSTORE 3 1) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 + address=Address(0x6486B0CD8779006E5CD706484B0D890B9A220805), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_3.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_3.py index 05d104dd747..7b3110cfe17 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_3.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_after_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_static_callcodecallcallcode_101_oogm_after_3( ) -> None: """Test_static_callcodecallcallcode_101_oogm_after_3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -96,57 +93,44 @@ def test_static_callcodecallcallcode_101_oogm_after_3( address=Address(0xAAB59F13D96113334FAB5C68E4E62B61F6CBF647), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xEAF6, - address=0xB867C4BF480D6DCD06716BCDB0F9BCF3BB5710BF, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=Op.GAS) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 3 1) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x77D2ECB3F4D887934C7C8F304831EA89E08CB30D), # noqa: E501 + address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) # Source: lll - # { (STATICCALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 + # { (SSTORE 3 1) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + nonce=0, + address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 + ) + # Source: lll + # { (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 code=Op.POP( - Op.STATICCALL( - gas=0x9C90, - address=0x96BBA71C203B7339624A350FE004F71C3D669AEE, + Op.DELEGATECALL( + gas=0x4E34, + address=0x335C5531B84765A7626E6E76688F18B81BE5259C, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, ) ) - + Op.JUMPDEST - + Op.JUMPI( - pc=0x3E, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) - ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x22) - + Op.JUMPDEST + + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0xB867C4BF480D6DCD06716BCDB0F9BCF3BB5710BF), # noqa: E501 + address=Address(0x96BBA71C203B7339624A350FE004F71C3D669AEE), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 + # { (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr_7 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.DELEGATECALL( gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + address=0xB126C622075B1189FB6C45E851641CFADDF65B36, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -156,34 +140,32 @@ def test_static_callcodecallcallcode_101_oogm_after_3( + Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x96BBA71C203B7339624A350FE004F71C3D669AEE), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 + address=Address(0x65BE40505E6165809F16BFC5CDBA14169BC97614), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xEAF6, - address=0x2ABA60E14F876DAC315953942316A9A2F80C3AD5, + # { (STATICCALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.STATICCALL( + gas=0x9C90, + address=0x96BBA71C203B7339624A350FE004F71C3D669AEE, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.JUMPDEST + + Op.JUMPI( + pc=0x3E, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x22) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE2FA228586F5C62A6728D17728F4622D05D84E45), # noqa: E501 + address=Address(0xB867C4BF480D6DCD06716BCDB0F9BCF3BB5710BF), # noqa: E501 ) # Source: lll # { (STATICCALL 40080 0 64 0 64 ) } # noqa: E501 @@ -201,31 +183,45 @@ def test_static_callcodecallcallcode_101_oogm_after_3( address=Address(0x2ABA60E14F876DAC315953942316A9A2F80C3AD5), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 20020 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.DELEGATECALL( - gas=0x4E34, - address=0xB126C622075B1189FB6C45E851641CFADDF65B36, + # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xEAF6, + address=0xB867C4BF480D6DCD06716BCDB0F9BCF3BB5710BF, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x3, value=0x1) + + Op.SSTORE(key=0x1, value=Op.GAS) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x65BE40505E6165809F16BFC5CDBA14169BC97614), # noqa: E501 + address=Address(0x77D2ECB3F4D887934C7C8F304831EA89E08CB30D), # noqa: E501 ) # Source: lll - # { (SSTORE 3 1) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x3, value=0x1) + Op.STOP, + # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xEAF6, + address=0x2ABA60E14F876DAC315953942316A9A2F80C3AD5, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB126C622075B1189FB6C45E851641CFADDF65B36), # noqa: E501 + address=Address(0xE2FA228586F5C62A6728D17728F4622D05D84E45), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before.py index c0d22633ed3..5360979ac9c 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcallcode_101_oogm_before( ) -> None: """Test_static_callcodecallcallcode_101_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,43 +47,10 @@ def test_static_callcodecallcallcode_101_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x249F0, - address=0xEE49CA410D3886CC84D3177A1E14451F0669852F, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x31D06FAD70E2A598413824A9BC68D80A5D2B194E), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x9C90, - address=0x76C6DC23A4F29A65309C67CE40F50A05ED3409DA, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0xEE49CA410D3886CC84D3177A1E14451F0669852F), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (DELEGATECALL 20020 0 64 0 64 ) } # noqa: E501 @@ -101,7 +65,7 @@ def test_static_callcodecallcallcode_101_oogm_before( + Op.JUMPDEST + Op.DELEGATECALL( gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -109,16 +73,44 @@ def test_static_callcodecallcallcode_101_oogm_before( ) + Op.STOP, nonce=0, - address=Address(0x76C6DC23A4F29A65309C67CE40F50A05ED3409DA), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x9C90, + address=addr_2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x249F0, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before2.py index fc000496a57..ec321a4558a 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_oogm_before2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcallcode_101_oogm_before2( ) -> None: """Test_static_callcodecallcallcode_101_oogm_before2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -72,44 +69,10 @@ def test_static_callcodecallcallcode_101_oogm_before2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0xEE49CA410D3886CC84D3177A1E14451F0669852F, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xCC7B2C7C17E1DD7940B1AA2F4B3E55D7BD662608), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x9C90, - address=0xAC5AD3041E8D622A1F089496E5EE81C4F6F80471, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - ) - + Op.MSTORE(offset=0x3, value=0x1) - + Op.STOP, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0xEE49CA410D3886CC84D3177A1E14451F0669852F), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (CALLCODE 20020 0 0 64 0 64 ) } # noqa: E501 @@ -124,7 +87,7 @@ def test_static_callcodecallcallcode_101_oogm_before2( + Op.JUMPDEST + Op.CALLCODE( gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + address=addr_3, value=0x0, args_offset=0x0, args_size=0x40, @@ -133,16 +96,45 @@ def test_static_callcodecallcallcode_101_oogm_before2( ) + Op.STOP, nonce=0, - address=Address(0xAC5AD3041E8D622A1F089496E5EE81C4F6F80471), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (MSTORE 3 1) (STATICCALL 40080 0 64 0 64 ) (MSTORE 3 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x9C90, + address=addr_2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + ) + + Op.MSTORE(offset=0x3, value=0x1) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end.py index abd75d74a5f..6317c9fed48 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcallcode_101_suicide_end( ) -> None: """Test_static_callcodecallcallcode_101_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcallcode_101_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -108,15 +113,6 @@ def test_static_callcodecallcallcode_101_suicide_end( nonce=0, address=Address(0x4A31DD3A8C3C9A793AC0B3C234A4DBAC2F201404), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end2.py index 8ace7a8f459..c447ee9219f 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcallcode_101_suicide_end2( ) -> None: """Test_static_callcodecallcallcode_101_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,14 @@ def test_static_callcodecallcallcode_101_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -132,15 +137,6 @@ def test_static_callcodecallcallcode_101_suicide_end2( nonce=0, address=Address(0x90E9B92C59A0E93D8AB0B7AFBC945D6999A50A9B), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle.py index b659a53f210..b931e88c7ee 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -40,9 +39,7 @@ def test_static_callcodecallcallcode_101_suicide_middle( contract_1 = Address(0x1000000000000000000000000000000000000001) contract_2 = Address(0x1000000000000000000000000000000000000002) contract_3 = Address(0x1000000000000000000000000000000000000003) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -53,6 +50,14 @@ def test_static_callcodecallcallcode_101_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + contract_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0x1000000000000000000000000000000000000001 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -112,15 +117,6 @@ def test_static_callcodecallcallcode_101_suicide_middle( nonce=0, address=Address(0x1000000000000000000000000000000000000002), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - contract_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x1000000000000000000000000000000000000003), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle2.py index 6795cba2172..058d6ddc641 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_101_suicide_middle2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcallcode_101_suicide_middle2( ) -> None: """Test_static_callcodecallcallcode_101_suicide_middle2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,14 @@ def test_static_callcodecallcallcode_101_suicide_middle2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -132,15 +137,6 @@ def test_static_callcodecallcallcode_101_suicide_middle2( nonce=0, address=Address(0x3A5852E2F86BAE6627A307298C4BF906ADA12419), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive.py index 15eea22f49e..4c89a5d22f3 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcallcode_abcb_recursive( ) -> None: """Test_static_callcodecallcallcode_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_static_callcodecallcallcode_abcb_recursive( nonce=0, address=Address(0xAB5C6018CF3368381E283C1DE7F906C456188BC3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive2.py index 02670ea82c5..508e0dcf4ae 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcallcode_abcb_recursive2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -70,9 +69,7 @@ def test_static_callcodecallcallcode_abcb_recursive2( ) -> None: """Test_static_callcodecallcallcode_abcb_recursive2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -170,7 +167,6 @@ def test_static_callcodecallcallcode_abcb_recursive2( nonce=0, address=Address(0xB81EB378451B4361DF035AEA57913023DFFBF39A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110.py index fb4d9a18a63..3d41086e8cb 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_callcodecallcodecall_110( ) -> None: """Test_static_callcodecallcodecall_110.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,24 +45,29 @@ def test_static_callcodecallcodecall_110( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x55730, - address=0x2BF6D23C6CDD3A7712AD150DFA2680ADABDA8B82, + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 1 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 1 1)} # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4EEF7E2B5AE9BE0FC5B43DC4FE39195A1AE10FC4), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) (DELEGATECALL 300000 0 64 0 64 ) (MSTORE 1 1) } # noqa: E501 @@ -74,7 +76,7 @@ def test_static_callcodecallcodecall_110( + Op.POP( Op.DELEGATECALL( gas=0x493E0, - address=0xB10C519306D4D2ACCE66BE84C0EA086D816BA77C, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -85,36 +87,26 @@ def test_static_callcodecallcodecall_110( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2BF6D23C6CDD3A7712AD150DFA2680ADABDA8B82), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 1 1)} # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + # { [[ 0 ]] (DELEGATECALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x55730, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x1, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB10C519306D4D2ACCE66BE84C0EA086D816BA77C), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_1102.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_1102.py index d5fe4512c38..ce9f6e6b395 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_1102.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_1102.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_static_callcodecallcodecall_1102( ) -> None: """Test_static_callcodecallcodecall_1102.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -76,32 +73,32 @@ def test_static_callcodecallcodecall_1102( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x91645BC90F22C32A683BB049DCE8BCC61C541D82, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x3D090, + address=addr_3, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4BE1B24080B17ED1F5F4C0FF9CD820D764A32620), # noqa: E501 ) # Source: lll # { (CALLCODE 300000 (- (CALLVALUE) 1) 0 64 0 64 ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.CALLCODE( gas=0x493E0, - address=0xEF859513AE36C397C43170A2980741575916167B, + address=addr_2, value=Op.SUB(Op.CALLVALUE, 0x1), args_offset=0x0, args_size=0x40, @@ -111,32 +108,27 @@ def test_static_callcodecallcodecall_1102( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x91645BC90F22C32A683BB049DCE8BCC61C541D82), # noqa: E501 ) # Source: lll - # { (STATICCALL 250000 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEF859513AE36C397C43170A2980741575916167B), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_2.py index a8ca706bfe7..e35bbea0fb4 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_static_callcodecallcodecall_110_2( ) -> None: """Test_static_callcodecallcodecall_110_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -76,25 +73,29 @@ def test_static_callcodecallcodecall_110_2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x55730, - address=0x611CB29449C75E44440DB4985DBB84732BC18342, - value=Op.CALLVALUE, + # { (MSTORE 1 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (MSTORE 1 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 31 1) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + + Op.POP( + Op.STATICCALL( + gas=0x3D090, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ), + ) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE(offset=0x1F, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4BE1B24080B17ED1F5F4C0FF9CD820D764A32620), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) (CALLCODE 300000 ( - (CALLVALUE) 1) 0 64 0 64 ) (MSTORE 31 1) } # noqa: E501 @@ -103,7 +104,7 @@ def test_static_callcodecallcodecall_110_2( + Op.POP( Op.CALLCODE( gas=0x493E0, - address=0xB1927ADAFCD3B2ECEF7B7508CB3A8D7B41FCAE73, + address=addr_2, value=Op.SUB(Op.CALLVALUE, 0x1), args_offset=0x0, args_size=0x40, @@ -115,36 +116,27 @@ def test_static_callcodecallcodecall_110_2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x611CB29449C75E44440DB4985DBB84732BC18342), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) (STATICCALL 250000 0 64 0 64 ) (MSTORE 31 1) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) - + Op.POP( - Op.STATICCALL( - gas=0x3D090, - address=0x2A142C79A9B097C111CE945214226126B75E332C, + # { [[ 0 ]] (CALLCODE 350000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x55730, + address=addr, + value=Op.CALLVALUE, args_offset=0x0, args_size=0x40, ret_offset=0x0, ret_size=0x40, - ) + ), ) - + Op.MSTORE(offset=0x1F, value=0x1) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xB1927ADAFCD3B2ECEF7B7508CB3A8D7B41FCAE73), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x2A142C79A9B097C111CE945214226126B75E332C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge.py index 98c955a94f2..fb9b691d681 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_ooge( ) -> None: """Test_static_callcodecallcodecall_110_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,31 +47,25 @@ def test_static_callcodecallcodecall_110_ooge( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x249F0, - address=0x7125DDB5E66B6BAB62B228F9D01C2F3AAA1BEF28, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x31D06FAD70E2A598413824A9BC68D80A5D2B194E), # noqa: E501 ) # Source: lll - # { (DELEGATECALL 100000 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=0x186A0, - address=0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D, + # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x4E34, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -82,14 +73,13 @@ def test_static_callcodecallcodecall_110_ooge( ) + Op.STOP, nonce=0, - address=Address(0x7125DDB5E66B6BAB62B228F9D01C2F3AAA1BEF28), # noqa: E501 ) # Source: lll - # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x4E34, - address=0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954, + # { (DELEGATECALL 100000 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=0x186A0, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -97,24 +87,26 @@ def test_static_callcodecallcodecall_110_ooge( ) + Op.STOP, nonce=0, - address=Address(0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x249F0, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge2.py index 8c0b2e3f125..7c371ac945e 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_ooge2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,9 +63,7 @@ def test_static_callcodecallcodecall_110_ooge2( ) -> None: """Test_static_callcodecallcodecall_110_ooge2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -78,33 +75,25 @@ def test_static_callcodecallcodecall_110_ooge2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0x90390F435B22C948FBEA0C86C37ECBFEC700CF9D, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) - + Op.SSTORE(key=0x1, value=0x1) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCC7B2C7C17E1DD7940B1AA2F4B3E55D7BD662608), # noqa: E501 ) # Source: lll - # { (CALLCODE 100000 (- (CALLVALUE) 1) 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x186A0, - address=0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D, - value=Op.SUB(Op.CALLVALUE, 0x1), + # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x4E34, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -112,14 +101,14 @@ def test_static_callcodecallcodecall_110_ooge2( ) + Op.STOP, nonce=0, - address=Address(0x90390F435B22C948FBEA0C86C37ECBFEC700CF9D), # noqa: E501 ) # Source: lll - # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x4E34, - address=0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954, + # { (CALLCODE 100000 (- (CALLVALUE) 1) 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x186A0, + address=addr_2, + value=Op.SUB(Op.CALLVALUE, 0x1), args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -127,24 +116,27 @@ def test_static_callcodecallcodecall_110_ooge2( ) + Op.STOP, nonce=0, - address=Address(0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D), # noqa: E501 ) # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after.py index 4e0bc6ef511..b121cac4afb 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_oogm_after( ) -> None: """Test_static_callcodecallcodecall_110_oogm_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,24 +47,24 @@ def test_static_callcodecallcodecall_110_oogm_after( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xEAF6, - address=0x669F2CA35C01EE9379D6003704074AC1EEAA914D, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x4E34, + address=addr_3, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE79AEE563C83547F229D955ECDCCA0F01FED9AA9), # noqa: E501 ) # Source: lll # { (DELEGATECALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -75,7 +72,7 @@ def test_static_callcodecallcodecall_110_oogm_after( code=Op.POP( Op.DELEGATECALL( gas=0x9C90, - address=0x1BDD0B2B81CB603F436225D2B20054C3D0593DE3, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -92,31 +89,26 @@ def test_static_callcodecallcodecall_110_oogm_after( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x669F2CA35C01EE9379D6003704074AC1EEAA914D), # noqa: E501 ) # Source: lll - # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xEAF6, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1BDD0B2B81CB603F436225D2B20054C3D0593DE3), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after2.py index d752a818b29..6bfd84549df 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,9 +63,7 @@ def test_static_callcodecallcodecall_110_oogm_after2( ) -> None: """Test_static_callcodecallcodecall_110_oogm_after2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -78,25 +75,24 @@ def test_static_callcodecallcodecall_110_oogm_after2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 60150 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xEAF6, - address=0x5132347436F7BD136E83BF55270D821E276C2E51, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x4E34, + address=addr_3, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x62B278A07428F1FF97EE7C884B711F6DF3340707), # noqa: E501 ) # Source: lll # { (CALLCODE 40080 ( - (CALLVALUE) 1) 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -104,7 +100,7 @@ def test_static_callcodecallcodecall_110_oogm_after2( code=Op.POP( Op.CALLCODE( gas=0x9C90, - address=0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D, + address=addr_2, value=Op.SUB(Op.CALLVALUE, 0x1), args_offset=0x0, args_size=0x40, @@ -122,31 +118,27 @@ def test_static_callcodecallcodecall_110_oogm_after2( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x5132347436F7BD136E83BF55270D821E276C2E51), # noqa: E501 ) # Source: lll - # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (CALLCODE 60150 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xEAF6, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_2.py index 453a65a45d6..90496314497 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_oogm_after_2( ) -> None: """Test_static_callcodecallcodecall_110_oogm_after_2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,24 +47,24 @@ def test_static_callcodecallcodecall_110_oogm_after_2( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0xEAF6, - address=0x669F2CA35C01EE9379D6003704074AC1EEAA914D, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x4E34, + address=addr_3, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE79AEE563C83547F229D955ECDCCA0F01FED9AA9), # noqa: E501 ) # Source: lll # { (DELEGATECALL 40080 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -75,7 +72,7 @@ def test_static_callcodecallcodecall_110_oogm_after_2( code=Op.POP( Op.DELEGATECALL( gas=0x9C90, - address=0x1BDD0B2B81CB603F436225D2B20054C3D0593DE3, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -92,31 +89,26 @@ def test_static_callcodecallcodecall_110_oogm_after_2( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x669F2CA35C01EE9379D6003704074AC1EEAA914D), # noqa: E501 ) # Source: lll - # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (DELEGATECALL 60150 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0xEAF6, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x1BDD0B2B81CB603F436225D2B20054C3D0593DE3), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_3.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_3.py index 86c330ff9cd..cbc5beb1ba3 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_3.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_after_3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_oogm_after_3( ) -> None: """Test_static_callcodecallcodecall_110_oogm_after_3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,25 +47,24 @@ def test_static_callcodecallcodecall_110_oogm_after_3( ) # Source: lll - # { [[ 0 ]] (CALLCODE 60150 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0xEAF6, - address=0xDF60CB36BCF8892D8A68903B2D2E455037149E48, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x4E34, + address=addr_3, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, ) - + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, - balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x81450E6893351D2C0C43648338C0F2AE8D435BC1), # noqa: E501 ) # Source: lll # { (CALLCODE 40080 (- (CALLVALUE) 1) 0 64 0 64 ) (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } # noqa: E501 @@ -76,7 +72,7 @@ def test_static_callcodecallcodecall_110_oogm_after_3( code=Op.POP( Op.CALLCODE( gas=0x9C90, - address=0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D, + address=addr_2, value=Op.SUB(Op.CALLVALUE, 0x1), args_offset=0x0, args_size=0x40, @@ -94,31 +90,27 @@ def test_static_callcodecallcodecall_110_oogm_after_3( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0xDF60CB36BCF8892D8A68903B2D2E455037149E48), # noqa: E501 ) # Source: lll - # { (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, + # { [[ 0 ]] (CALLCODE 60150 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0xEAF6, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEEDCBAC77FBD73BF2D0D7FEDD710D089B466138D), # noqa: E501 - ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before.py index d56a43447ba..139114b474a 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_oogm_before( ) -> None: """Test_static_callcodecallcodecall_110_oogm_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -50,39 +47,10 @@ def test_static_callcodecallcodecall_110_oogm_before( ) # Source: lll - # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.DELEGATECALL( - gas=0x249F0, - address=0x401580462C2CA97FC4F16B066D6249250A227AFB, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x31D06FAD70E2A598413824A9BC68D80A5D2B194E), # noqa: E501 - ) - # Source: lll - # { (DELEGATECALL 40080 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.DELEGATECALL( - gas=0x9C90, - address=0xF32619344056AD22A07F10433F70165CE82D9273, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x401580462C2CA97FC4F16B066D6249250A227AFB), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 @@ -97,7 +65,7 @@ def test_static_callcodecallcodecall_110_oogm_before( + Op.JUMPDEST + Op.STATICCALL( gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -105,16 +73,40 @@ def test_static_callcodecallcodecall_110_oogm_before( ) + Op.STOP, nonce=0, - address=Address(0xF32619344056AD22A07F10433F70165CE82D9273), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (DELEGATECALL 40080 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.DELEGATECALL( + gas=0x9C90, + address=addr_2, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.DELEGATECALL( + gas=0x249F0, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before2.py index c4bd259ef6a..972eaf216e2 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_oogm_before2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -64,9 +63,7 @@ def test_static_callcodecallcodecall_110_oogm_before2( ) -> None: """Test_static_callcodecallcodecall_110_oogm_before2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -78,41 +75,10 @@ def test_static_callcodecallcodecall_110_oogm_before2( ) # Source: lll - # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALLCODE( - gas=0x249F0, - address=0x861E86C681836FF531A2F84C5CDDE43E28E1D234, - value=Op.CALLVALUE, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x45F35E7E68477A74B163DD6E4EB2833FB1979873), # noqa: E501 - ) - # Source: lll - # { (CALLCODE 40080 (- (CALLVALUE) 1) 0 64 0 64 ) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x9C90, - address=0xF32619344056AD22A07F10433F70165CE82D9273, - value=Op.SUB(Op.CALLVALUE, 0x1), - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, nonce=0, - address=Address(0x861E86C681836FF531A2F84C5CDDE43E28E1D234), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) (STATICCALL 20020 0 64 0 64 ) } # noqa: E501 @@ -127,7 +93,7 @@ def test_static_callcodecallcodecall_110_oogm_before2( + Op.JUMPDEST + Op.STATICCALL( gas=0x4E34, - address=0x335C5531B84765A7626E6E76688F18B81BE5259C, + address=addr_3, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -135,16 +101,42 @@ def test_static_callcodecallcodecall_110_oogm_before2( ) + Op.STOP, nonce=0, - address=Address(0xF32619344056AD22A07F10433F70165CE82D9273), # noqa: E501 ) # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + # { (CALLCODE 40080 (- (CALLVALUE) 1) 0 64 0 64 ) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x9C90, + address=addr_2, + value=Op.SUB(Op.CALLVALUE, 0x1), + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] 1} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALLCODE( + gas=0x249F0, + address=addr, + value=Op.CALLVALUE, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x335C5531B84765A7626E6E76688F18B81BE5259C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end.py index 7f87f8c354c..773ac82c6cf 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcodecall_110_suicide_end( ) -> None: """Test_static_callcodecallcodecall_110_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -71,6 +68,14 @@ def test_static_callcodecallcodecall_110_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -126,15 +131,6 @@ def test_static_callcodecallcodecall_110_suicide_end( nonce=0, address=Address(0xB7770360E0B87603E3D9C87C866451760C95ABCA), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end2.py index 4d3c9663fab..6843361d732 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_end2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -61,9 +60,7 @@ def test_static_callcodecallcodecall_110_suicide_end2( ) -> None: """Test_static_callcodecallcodecall_110_suicide_end2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -74,6 +71,14 @@ def test_static_callcodecallcodecall_110_suicide_end2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -131,15 +136,6 @@ def test_static_callcodecallcodecall_110_suicide_end2( nonce=0, address=Address(0xB7770360E0B87603E3D9C87C866451760C95ABCA), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle.py index eec16c708e9..f8b3e2afe93 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_suicide_middle( ) -> None: """Test_static_callcodecallcodecall_110_suicide_middle.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcodecall_110_suicide_middle( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -103,15 +108,6 @@ def test_static_callcodecallcodecall_110_suicide_middle( nonce=0, address=Address(0x408F1ACEFFEC7BDAA35D77006CDCAEAD563BB694), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle2.py index d1375ae7e56..99e37c0ec3a 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_110_suicide_middle2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_110_suicide_middle2( ) -> None: """Test_static_callcodecallcodecall_110_suicide_middle2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcodecall_110_suicide_middle2( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (CALLCODE 150000 (CALLVALUE) 0 64 0 64 ) [[ 1 ]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -106,15 +111,6 @@ def test_static_callcodecallcodecall_110_suicide_middle2( nonce=0, address=Address(0x408F1ACEFFEC7BDAA35D77006CDCAEAD563BB694), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive.py index 0f8b2d643d1..31a0c89588f 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecall_abcb_recursive( ) -> None: """Test_static_callcodecallcodecall_abcb_recursive.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_static_callcodecallcodecall_abcb_recursive( nonce=0, address=Address(0x1E2229D0F325B81B81B8B14F2D239FF9742683C0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive2.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive2.py index 18a24fee771..481fa2e4dba 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive2.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecall_abcb_recursive2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_callcodecallcodecall_abcb_recursive2( ) -> None: """Test_static_callcodecallcodecall_abcb_recursive2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -125,7 +122,6 @@ def test_static_callcodecallcodecall_abcb_recursive2( nonce=0, address=Address(0x1E2229D0F325B81B81B8B14F2D239FF9742683C0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Bytes(""), diff --git a/tests/ported_static/stStaticCall/test_static_callcodecallcodecallcode_111_suicide_end.py b/tests/ported_static/stStaticCall/test_static_callcodecallcodecallcode_111_suicide_end.py index 69f709b8cf2..c01d8f5be61 100644 --- a/tests/ported_static/stStaticCall/test_static_callcodecallcodecallcode_111_suicide_end.py +++ b/tests/ported_static/stStaticCall/test_static_callcodecallcodecallcode_111_suicide_end.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_callcodecallcodecallcode_111_suicide_end( ) -> None: """Test_static_callcodecallcodecallcode_111_suicide_end.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,14 @@ def test_static_callcodecallcodecallcode_111_suicide_end( gas_limit=30000000, ) + # Source: lll + # { (MSTORE 3 1) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, + balance=0x2540BE400, + nonce=0, + address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -105,15 +110,6 @@ def test_static_callcodecallcodecallcode_111_suicide_end( nonce=0, address=Address(0x90E9B92C59A0E93D8AB0B7AFBC945D6999A50A9B), # noqa: E501 ) - # Source: lll - # { (MSTORE 3 1) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x3, value=0x1) + Op.STOP, - balance=0x2540BE400, - nonce=0, - address=Address(0x48E2D4C0B593BFEBE5DDB4F13AA355B8BD83DDD3), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_calldelcode_01.py b/tests/ported_static/stStaticCall/test_static_calldelcode_01.py index 369bf95275f..d25b603853a 100644 --- a/tests/ported_static/stStaticCall/test_static_calldelcode_01.py +++ b/tests/ported_static/stStaticCall/test_static_calldelcode_01.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_calldelcode_01( ) -> None: """Test_static_calldelcode_01.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,31 +45,17 @@ def test_static_calldelcode_01( ) # Source: lll - # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x55730, - address=0x91836819E5DD0646F8619EB31C67258FA7CA0A32, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, + # { (MSTORE 1 0x11223344) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x11223344) + Op.STOP, nonce=0, - address=Address(0x46DF4A924470CB27A2F8700239656C40DD4794C8), # noqa: E501 ) # Source: lll # { (DELEGATECALL 250000 0 64 0 64 ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.DELEGATECALL( gas=0x3D090, - address=0x2881A083EA775F78057A93F73110241FDB7398A9, + address=addr_2, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -80,16 +63,26 @@ def test_static_calldelcode_01( ) + Op.STOP, nonce=0, - address=Address(0x91836819E5DD0646F8619EB31C67258FA7CA0A32), # noqa: E501 ) # Source: lll - # { (MSTORE 1 0x11223344) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x11223344) + Op.STOP, + # { [[ 0 ]] (STATICCALL 350000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x55730, + address=addr, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2881A083EA775F78057A93F73110241FDB7398A9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_calldelcode_01_ooge.py b/tests/ported_static/stStaticCall/test_static_calldelcode_01_ooge.py index c96224c66d6..5e85db2b185 100644 --- a/tests/ported_static/stStaticCall/test_static_calldelcode_01_ooge.py +++ b/tests/ported_static/stStaticCall/test_static_calldelcode_01_ooge.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_calldelcode_01_ooge( ) -> None: """Test_static_calldelcode_01_ooge.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -69,27 +66,6 @@ def test_static_calldelcode_01_ooge( gas_limit=30000000, ) - # Source: lll - # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) - + Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0x249F0, - address=0x77612608C7A22F8929F6F1C9462A9954621AEEFD, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x6E143211E9D36EAEEBE65F6ED69D6C28500040D6), # noqa: E501 - ) # Source: lll # { (DELEGATECALL 20020 (CALLDATALOAD 0) 0 64 0 64 ) } addr = pre.deploy_contract( # noqa: F841 @@ -129,7 +105,27 @@ def test_static_calldelcode_01_ooge( nonce=0, address=Address(0xFBEF21C5A6C2ADCF3D769F085E0CC9FE9A8DF954), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (MSTORE 0 (CALLDATALOAD 0)) [[ 0 ]] (STATICCALL 150000 0 64 0 64 ) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.CALLDATALOAD(offset=0x0)) + + Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0x249F0, + address=0x77612608C7A22F8929F6F1C9462A9954621AEEFD, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + address=Address(0x6E143211E9D36EAEEBE65F6ED69D6C28500040D6), # noqa: E501 + ) tx_data = [ Hash(addr_2, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_callto_return2.py b/tests/ported_static/stStaticCall/test_static_callto_return2.py index 301d52de5d0..409bd9e2136 100644 --- a/tests/ported_static/stStaticCall/test_static_callto_return2.py +++ b/tests/ported_static/stStaticCall/test_static_callto_return2.py @@ -47,6 +47,16 @@ def test_static_callto_return2( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (STATICCALL 5000 0 64 0 2 ) [[ 1 ]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,7 +72,7 @@ def test_static_callto_return2( key=0x0, value=Op.STATICCALL( gas=0x1388, - address=0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -75,16 +85,6 @@ def test_static_callto_return2( nonce=0, address=Address(0x547D0A349CCAB317152D172E2F2AE7556C334CF3), # noqa: E501 ) - # Source: raw - # 0x603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_check_call_cost_oog.py b/tests/ported_static/stStaticCall/test_static_check_call_cost_oog.py index ccc8541f5ec..9514f5b8828 100644 --- a/tests/ported_static/stStaticCall/test_static_check_call_cost_oog.py +++ b/tests/ported_static/stStaticCall/test_static_check_call_cost_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_check_call_cost_oog( ) -> None: """Check balance in blackbox, just fill the balance consumed.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x3327048BBC0B8C348A6352BE62994144E64B8FF2CEC68D9FF4CA4E911ECD5D22 - ) + sender = pre.fund_eoa(amount=0x5AF3107A4000) env = Environment( fee_recipient=coinbase, @@ -69,13 +66,20 @@ def test_static_check_call_cost_oog( gas_limit=10000000, ) - pre[sender] = Account(balance=0x5AF3107A4000) + # Source: lll + # { (MSTORE 1 1) (KECCAK256 0x00 0x2fffff) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + + Op.STOP, + nonce=0, + ) # Source: lll # { (STATICCALL 100 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.STATICCALL( gas=0x64, - address=0xEBE7ED7A6E995C9843A6DF04E332981EBB2772E0, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -83,16 +87,6 @@ def test_static_check_call_cost_oog( ) + Op.STOP, nonce=0, - address=Address(0xB59292B3A630476ADBC4A3643C0815B682A5009A), # noqa: E501 - ) - # Source: lll - # { (MSTORE 1 1) (KECCAK256 0x00 0x2fffff) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) - + Op.SHA3(offset=0x0, size=0x2FFFFF) - + Op.STOP, - nonce=0, - address=Address(0xEBE7ED7A6E995C9843A6DF04E332981EBB2772E0), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stStaticCall/test_static_check_opcodes3.py b/tests/ported_static/stStaticCall/test_static_check_opcodes3.py index f57c2b4f594..67c36145697 100644 --- a/tests/ported_static/stStaticCall/test_static_check_opcodes3.py +++ b/tests/ported_static/stStaticCall/test_static_check_opcodes3.py @@ -140,6 +140,30 @@ def test_static_check_opcodes3( address=Address(0x50F628D871A69F2DB31E98D7FBF8AE6F1FC0D55C), # noqa: E501 ) # Source: lll + # { (MSTORE 0 (STATICCALL 100000 (CALLDATALOAD 0) 0 0 0 0)) (if (= 1 (MLOAD 0)) (MSTORE 1 1) (SSTORE 1 2)) } # noqa: E501 + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=Op.STATICCALL( + gas=0x186A0, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.JUMPI(pc=0x24, condition=Op.EQ(0x1, Op.MLOAD(offset=0x0))) + + Op.SSTORE(key=0x1, value=0x2) + + Op.JUMP(pc=0x2A) + + Op.JUMPDEST + + Op.MSTORE(offset=0x1, value=0x1) + + Op.JUMPDEST + + Op.STOP, + nonce=0, + address=Address(0x2E5DC1C94AF89D7C115126FCEBAD7A5C50F5FE35), # noqa: E501 + ) + # Source: lll # { (MSTORE 0 ) (MSTORE 0 (CALL 100000 0 0 32 0 0)) (if (= 1 (MLOAD 0)) (MSTORE 1 1) (SSTORE 1 2) ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.MSTORE( @@ -280,30 +304,6 @@ def test_static_check_opcodes3( address=Address(0x8113F9FC0868700534ECBECF1120A812CB1AF0AC), # noqa: E501 ) # Source: lll - # { (MSTORE 0 (STATICCALL 100000 (CALLDATALOAD 0) 0 0 0 0)) (if (= 1 (MLOAD 0)) (MSTORE 1 1) (SSTORE 1 2)) } # noqa: E501 - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=Op.STATICCALL( - gas=0x186A0, - address=Op.CALLDATALOAD(offset=0x0), - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.JUMPI(pc=0x24, condition=Op.EQ(0x1, Op.MLOAD(offset=0x0))) - + Op.SSTORE(key=0x1, value=0x2) - + Op.JUMP(pc=0x2A) - + Op.JUMPDEST - + Op.MSTORE(offset=0x1, value=0x1) - + Op.JUMPDEST - + Op.STOP, - nonce=0, - address=Address(0x2E5DC1C94AF89D7C115126FCEBAD7A5C50F5FE35), # noqa: E501 - ) - # Source: lll # { (if (= (ORIGIN)) (MSTORE 1 1) (SSTORE 1 2) ) (if (= (CALLER)) (MSTORE 1 1) (SSTORE 1 2) ) (if (= (ADDRESS)) (MSTORE 1 1) (SSTORE 1 2) ) (if (= 0 (CALLVALUE)) (MSTORE 1 1) (SSTORE 1 2) ) } # noqa: E501 addr_7 = pre.deploy_contract( # noqa: F841 code=Op.JUMPI( diff --git a/tests/ported_static/stStaticCall/test_static_check_opcodes4.py b/tests/ported_static/stStaticCall/test_static_check_opcodes4.py index 251fd1ea1bf..d212aec2a60 100644 --- a/tests/ported_static/stStaticCall/test_static_check_opcodes4.py +++ b/tests/ported_static/stStaticCall/test_static_check_opcodes4.py @@ -218,13 +218,7 @@ def test_static_check_opcodes4( "result": { sender: Account(nonce=1), target: Account( - storage={ - 1: 1, - 2: 1, - 3: 0xFAA10B404AB607779993C016CD5DA73AE1F29D7E, - 5: 0xFAA10B404AB607779993C016CD5DA73AE1F29D7E, - 6: 0x3350A62DDDDD0FF0E39CD82E2D185FE06B5FCF49, - }, + storage={1: 1, 2: 1, 3: sender, 5: sender, 6: target}, ), }, }, @@ -245,10 +239,10 @@ def test_static_check_opcodes4( storage={ 1: 1, 2: 1, - 3: 0xFAA10B404AB607779993C016CD5DA73AE1F29D7E, + 3: sender, 4: 100, - 5: 0xFAA10B404AB607779993C016CD5DA73AE1F29D7E, - 6: 0x3350A62DDDDD0FF0E39CD82E2D185FE06B5FCF49, + 5: sender, + 6: target, }, ), }, diff --git a/tests/ported_static/stStaticCall/test_static_check_opcodes5.py b/tests/ported_static/stStaticCall/test_static_check_opcodes5.py index b10dda3bdd9..253610f1dc7 100644 --- a/tests/ported_static/stStaticCall/test_static_check_opcodes5.py +++ b/tests/ported_static/stStaticCall/test_static_check_opcodes5.py @@ -201,6 +201,24 @@ def test_static_check_opcodes5( address=Address(0x1FE115F5D840CD62E113B09755C50D8F3F358B96), # noqa: E501 ) # Source: lll + # { [[ 0 ]] (STATICCALL 50000 (CALLDATALOAD 0) 0 0 0 0) } + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.STATICCALL( + gas=0xC350, + address=Op.CALLDATALOAD(offset=0x0), + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + nonce=0, + address=Address(0x8EEB303E1E7E2BB67D778526E009014A5DAEAD81), # noqa: E501 + ) + # Source: lll # { (MSTORE 0 ) (CALL 100000 0 0 32 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 code=Op.MSTORE( @@ -299,24 +317,6 @@ def test_static_check_opcodes5( address=Address(0x09FCE828CBD5C5BDC742FE5A63776E2A76A111E5), # noqa: E501 ) # Source: lll - # { [[ 0 ]] (STATICCALL 50000 (CALLDATALOAD 0) 0 0 0 0) } - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.STATICCALL( - gas=0xC350, - address=Op.CALLDATALOAD(offset=0x0), - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - nonce=0, - address=Address(0x8EEB303E1E7E2BB67D778526E009014A5DAEAD81), # noqa: E501 - ) - # Source: lll # { (if (= (ORIGIN)) (MSTORE 1 1) (SSTORE 1 2) ) (if (= (CALLER)) (MSTORE 1 1) (SSTORE 1 2) ) (if (= (ADDRESS)) (MSTORE 1 1) (SSTORE 1 2) ) (if (= 0 (CALLVALUE)) (MSTORE 1 1) (SSTORE 1 2) ) } # noqa: E501 addr_7 = pre.deploy_contract( # noqa: F841 code=Op.JUMPI( diff --git a/tests/ported_static/stStaticCall/test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py b/tests/ported_static/stStaticCall/test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py index b8498d6f638..82b1fe9027c 100644 --- a/tests/ported_static/stStaticCall/test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py +++ b/tests/ported_static/stStaticCall/test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_provided.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -80,9 +79,7 @@ def test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_p contract_4 = Address(0x4000000000000000000000000000000000000001) contract_5 = Address(0x5000000000000000000000000000000000000001) contract_6 = Address(0x4000000000000000000000000000000000000004) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x10C8E0) env = Environment( fee_recipient=coinbase, @@ -93,30 +90,12 @@ def test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_p gas_limit=100000000, ) - pre[sender] = Account(balance=0x10C8E0) - # Source: lll - # {(STATICCALL 50000 0x1000000000000000000000000000000000000001 0 64 0 64)} - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0xC350, - address=0x1000000000000000000000000000000000000001, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) # Source: lll # {(SSTORE 1 1)} contract_1 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll # {(MSTORE 1 1)} @@ -124,7 +103,6 @@ def test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_p code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x2000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } @@ -140,31 +118,35 @@ def test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_p + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x3000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll - # { (CALLCODE 1000 0x4000000000000000000000000000000000000004 0 0 0 0 0) } - contract_4 = pre.deploy_contract( # noqa: F841 - code=Op.CALLCODE( - gas=0x3E8, - address=0x4000000000000000000000000000000000000004, - value=0x0, + # { (MSTORE 1 1) } + contract_6 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + balance=0x186A0, + nonce=0, + ) + # Source: lll + # {(STATICCALL 50000 0x1000000000000000000000000000000000000001 0 64 0 64)} + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0xC350, + address=contract_1, args_offset=0x0, - args_size=0x0, + args_size=0x40, ret_offset=0x0, - ret_size=0x0, + ret_size=0x40, ) + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x4000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll # { (CALLCODE 1000000 0x4000000000000000000000000000000000000004 0 0 0 0 0) } # noqa: E501 contract_5 = pre.deploy_contract( # noqa: F841 code=Op.CALLCODE( gas=0xF4240, - address=0x4000000000000000000000000000000000000004, + address=contract_6, value=0x0, args_offset=0x0, args_size=0x0, @@ -174,15 +156,22 @@ def test_static_contract_creation_make_call_that_ask_more_gas_then_transaction_p + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x5000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) } - contract_6 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + # { (CALLCODE 1000 0x4000000000000000000000000000000000000004 0 0 0 0 0) } + contract_4 = pre.deploy_contract( # noqa: F841 + code=Op.CALLCODE( + gas=0x3E8, + address=contract_6, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, balance=0x186A0, nonce=0, - address=Address(0x4000000000000000000000000000000000000004), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stStaticCall/test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py b/tests/ported_static/stStaticCall/test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py index 3e735f9db5c..eb6c5fd6f03 100644 --- a/tests/ported_static/stStaticCall/test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py +++ b/tests/ported_static/stStaticCall/test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -39,9 +38,7 @@ def test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction( contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0x1000000000000000000000000000000000000001) contract_2 = Address(0x2000000000000000000000000000000000000001) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x10C8E0) env = Environment( fee_recipient=coinbase, @@ -52,29 +49,11 @@ def test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction( gas_limit=1000000, ) - pre[sender] = Account(balance=0x10C8E0) - # Source: lll - # {(STATICCALL 50000 0x1000000000000000000000000000000000000001 0 64 0 64)} - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0xC350, - address=0x1000000000000000000000000000000000000001, - args_offset=0x0, - args_size=0x40, - ret_offset=0x0, - ret_size=0x40, - ) - + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) # Source: lll # {(MSTORE 1 1)} contract_1 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } @@ -89,7 +68,21 @@ def test_static_contract_creation_oo_gdont_leave_empty_contract_via_transaction( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x2000000000000000000000000000000000000001), # noqa: E501 + ) + # Source: lll + # {(STATICCALL 50000 0x1000000000000000000000000000000000000001 0 64 0 64)} + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0xC350, + address=contract_1, + args_offset=0x0, + args_size=0x40, + ret_offset=0x0, + ret_size=0x40, + ) + + Op.STOP, + balance=0x186A0, + nonce=0, ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init.py b/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init.py index 1090a23cfaa..abdb26f1df3 100644 --- a/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init.py +++ b/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -74,9 +73,7 @@ def test_static_create_contract_suicide_during_init( contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_2 = Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_3 = Address(0xE94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -87,13 +84,11 @@ def test_static_create_contract_suicide_during_init( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (MSTORE 1 1) } contract_0 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } @@ -109,7 +104,6 @@ def test_static_create_contract_suicide_during_init( + Op.STOP, balance=11, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (SSTORE 1 1) } @@ -117,14 +111,13 @@ def test_static_create_contract_suicide_during_init( code=Op.SSTORE(key=0x1, value=0x1) + Op.STOP, balance=11, nonce=0, - address=Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (CALL 100 0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b 1 0 0 0 0) } contract_3 = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x64, - address=0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_0, value=0x1, args_offset=0x0, args_size=0x0, @@ -134,7 +127,6 @@ def test_static_create_contract_suicide_during_init( + Op.STOP, balance=11, nonce=0, - address=Address(0xE94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_then_store_then_return.py b/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_then_store_then_return.py index e167563d30c..c6915b5ce3a 100644 --- a/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_then_store_then_return.py +++ b/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_then_store_then_return.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_static_create_contract_suicide_during_init_then_store_then_return( contract_1 = Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_2 = Address(0x094F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_3 = Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -75,34 +72,29 @@ def test_static_create_contract_suicide_during_init_then_store_then_return( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # {[[1]]12} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # {[[1]]12} contract_1 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, nonce=0, - address=Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) } contract_2 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x094F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # {(MSTORE 1 1) } contract_3 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_with_value.py b/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_with_value.py index 4192b76403e..a094c7576c5 100644 --- a/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_with_value.py +++ b/tests/ported_static/stStaticCall/test_static_create_contract_suicide_during_init_with_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_static_create_contract_suicide_during_init_with_value( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -73,20 +70,17 @@ def test_static_create_contract_suicide_during_init_with_value( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # {[[1]]12} contract_0 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x1, value=0xC) + Op.STOP, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (MSTORE 1 1) } contract_1 = pre.deploy_contract( # noqa: F841 code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stStaticCall/test_static_create_empty_contract_and_call_it_0wei.py b/tests/ported_static/stStaticCall/test_static_create_empty_contract_and_call_it_0wei.py index e0447f422ca..06c2269aa0d 100644 --- a/tests/ported_static/stStaticCall/test_static_create_empty_contract_and_call_it_0wei.py +++ b/tests/ported_static/stStaticCall/test_static_create_empty_contract_and_call_it_0wei.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -38,9 +37,7 @@ def test_static_create_empty_contract_and_call_it_0wei( """Test_static_create_empty_contract_and_call_it_0wei.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -51,7 +48,6 @@ def test_static_create_empty_contract_and_call_it_0wei( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) [[1]] (CREATE 0 0 32) [[2]](GAS) [[3]] (STATICCALL 60000 (SLOAD 1) 0 0 0 0) [[100]] (GAS) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -86,7 +82,7 @@ def test_static_create_empty_contract_and_call_it_0wei( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x7ABF8, 3: 1, 100: 0x6FE6E, diff --git a/tests/ported_static/stStaticCall/test_static_create_empty_contract_with_storage_and_call_it_0wei.py b/tests/ported_static/stStaticCall/test_static_create_empty_contract_with_storage_and_call_it_0wei.py index 0773334b4eb..42399b955b1 100644 --- a/tests/ported_static/stStaticCall/test_static_create_empty_contract_with_storage_and_call_it_0wei.py +++ b/tests/ported_static/stStaticCall/test_static_create_empty_contract_with_storage_and_call_it_0wei.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -39,9 +38,7 @@ def test_static_create_empty_contract_with_storage_and_call_it_0wei( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -52,7 +49,6 @@ def test_static_create_empty_contract_with_storage_and_call_it_0wei( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[0]](GAS) (MSTORE 0 0x600c6000556000600060006000600073c94f5374fce5edbc8e2a8697c1533167) (MSTORE 32 0x7e6ebf0b61ea60f1000000000000000000000000000000000000000000000000) [[1]] (CREATE 0 0 64) [[2]] (GAS) [[3]] (STATICCALL 60000 (SLOAD 1) 0 0 0 0) [[100]] (GAS) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -103,7 +99,7 @@ def test_static_create_empty_contract_with_storage_and_call_it_0wei( contract_0: Account( storage={ 0: 0x8D5B6, - 1: 0xF1ECF98489FA9ED60A664FC4998DB699CFA39D40, + 1: compute_create_address(address=contract_0, nonce=0), 2: 0x6F4F0, 3: 1, 100: 0x64766, diff --git a/tests/ported_static/stStaticCall/test_static_execute_call_that_ask_fore_gas_then_trabsaction_has.py b/tests/ported_static/stStaticCall/test_static_execute_call_that_ask_fore_gas_then_trabsaction_has.py index c6d266f8f0a..c48d9cfe3d4 100644 --- a/tests/ported_static/stStaticCall/test_static_execute_call_that_ask_fore_gas_then_trabsaction_has.py +++ b/tests/ported_static/stStaticCall/test_static_execute_call_that_ask_fore_gas_then_trabsaction_has.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -67,9 +66,7 @@ def test_static_execute_call_that_ask_fore_gas_then_trabsaction_has( ) -> None: """Test_static_execute_call_that_ask_fore_gas_then_trabsaction_has.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDC4EFA209AECDD4C2D5201A419EA27506151B4EC687F14A613229E310932491B - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -80,7 +77,6 @@ def test_static_execute_call_that_ask_fore_gas_then_trabsaction_has( gas_limit=10000000, ) - pre[sender] = Account(balance=0x989680) # Source: lll # { [[1]] (STATICCALL 600000 (CALLDATALOAD 0) 0 0 0 0) } target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit.py b/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit.py index 7ade131bec4..fa551114028 100644 --- a/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit.py +++ b/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_internal_call_hitting_gas_limit( ) -> None: """Test_static_internal_call_hitting_gas_limit.""" coinbase = Address(0x2ADF5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x7C857D62C76CE09F2E8EC3FA9277578C67B69C6547364568FDDB841071E5BD7 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -47,23 +44,6 @@ def test_static_internal_call_hitting_gas_limit( gas_limit=100000, ) - pre[sender] = Account(balance=0xF4240) - # Source: lll - # { (STATICCALL 5000 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.STATICCALL( - gas=0x1388, - address=0x285BB5C8A71646AB9A5796D4A718CC4826AF8D06, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0xF4240, - nonce=0, - address=Address(0x5A755EAD8F1201283F750B2F77AF7D03399D5FEB), # noqa: E501 - ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } addr = pre.deploy_contract( # noqa: F841 @@ -77,7 +57,21 @@ def test_static_internal_call_hitting_gas_limit( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x285BB5C8A71646AB9A5796D4A718CC4826AF8D06), # noqa: E501 + ) + # Source: lll + # { (STATICCALL 5000 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.STATICCALL( + gas=0x1388, + address=addr, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0xF4240, + nonce=0, ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit2.py b/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit2.py index 72adc72d954..420d8654ec1 100644 --- a/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit2.py +++ b/tests/ported_static/stStaticCall/test_static_internal_call_hitting_gas_limit2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_internal_call_hitting_gas_limit2( ) -> None: """Test_static_internal_call_hitting_gas_limit2.""" coinbase = Address(0x2ADF5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x7C857D62C76CE09F2E8EC3FA9277578C67B69C6547364568FDDB841071E5BD7 - ) + sender = pre.fund_eoa(amount=0xF4240) env = Environment( fee_recipient=coinbase, @@ -49,7 +46,20 @@ def test_static_internal_call_hitting_gas_limit2( gas_limit=47766, ) - pre[sender] = Account(balance=0xF4240) + # Source: lll + # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPDEST + + Op.JUMPI( + pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) + ) + + Op.POP(Op.EXTCODESIZE(address=0x1)) + + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) + + Op.JUMP(pc=0x0) + + Op.JUMPDEST + + Op.STOP, + nonce=0, + ) # Source: lll # { [[ 1 ]] (STATICCALL 25000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -57,7 +67,7 @@ def test_static_internal_call_hitting_gas_limit2( key=0x1, value=Op.STATICCALL( gas=0x61A8, - address=0x285BB5C8A71646AB9A5796D4A718CC4826AF8D06, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -66,22 +76,6 @@ def test_static_internal_call_hitting_gas_limit2( ) + Op.STOP, nonce=0, - address=Address(0xF0801B78978104BAE7D7D679F8E3990492825C3E), # noqa: E501 - ) - # Source: lll - # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) (EXTCODESIZE 1)) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST - + Op.JUMPI( - pc=0x1C, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) - ) - + Op.POP(Op.EXTCODESIZE(address=0x1)) - + Op.MSTORE(offset=0x80, value=Op.ADD(Op.MLOAD(offset=0x80), 0x1)) - + Op.JUMP(pc=0x0) - + Op.JUMPDEST - + Op.STOP, - nonce=0, - address=Address(0x285BB5C8A71646AB9A5796D4A718CC4826AF8D06), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_internal_call_store_clears_oog.py b/tests/ported_static/stStaticCall/test_static_internal_call_store_clears_oog.py index 5747003967c..e63ab3f633b 100644 --- a/tests/ported_static/stStaticCall/test_static_internal_call_store_clears_oog.py +++ b/tests/ported_static/stStaticCall/test_static_internal_call_store_clears_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_internal_call_store_clears_oog( coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_0 = Address(0x0000000000000000000000000000000000000000) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -78,7 +75,6 @@ def test_static_internal_call_store_clears_oog( nonce=0, address=Address(0x0000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) # Source: lll # { [[ 1 ]] (STATICCALL 40000 0 0 0 0 0) } contract_1 = pre.deploy_contract( # noqa: F841 @@ -124,7 +120,7 @@ def test_static_internal_call_store_clears_oog( balance=0, ), sender: Account(nonce=1), - contract_1: Account(storage={1: 0}, balance=20), + contract_1: Account(storage={1: contract_0}, balance=20), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stStaticCall/test_static_log0_empty_mem.py b/tests/ported_static/stStaticCall/test_static_log0_empty_mem.py index d25b1c99d05..544bf1cf1e6 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_empty_mem.py +++ b/tests/ported_static/stStaticCall/test_static_log0_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log0_empty_mem( ) -> None: """Test_static_log0_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,13 @@ def test_static_log0_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG0(offset=0x0, size=0x0) + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +58,7 @@ def test_static_log0_empty_mem( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0xC2A943E837808399D9C1B946C6188739D4D4475E, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -65,17 +69,7 @@ def test_static_log0_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xDE4EDFB3CE6BD32637813F22447DF168E9289CDD), # noqa: E501 - ) - # Source: lll - # { (LOG0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG0(offset=0x0, size=0x0) + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC2A943E837808399D9C1B946C6188739D4D4475E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log0_log_mem_start_too_high.py b/tests/ported_static/stStaticCall/test_static_log0_log_mem_start_too_high.py index ff7221fc8a6..1b8b29fde1c 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_log_mem_start_too_high.py +++ b/tests/ported_static/stStaticCall/test_static_log0_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log0_log_mem_start_too_high( ) -> None: """Test_static_log0_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,21 @@ def test_static_log0_log_mem_start_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x1, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +66,7 @@ def test_static_log0_log_mem_start_too_high( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x4E46DD6CCD823BBE05D8CEAF0CA778101F8D8E6B, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,25 +76,7 @@ def test_static_log0_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x1, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x4E46DD6CCD823BBE05D8CEAF0CA778101F8D8E6B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log0_log_memsize_too_high.py b/tests/ported_static/stStaticCall/test_static_log0_log_memsize_too_high.py index f0832ef1eb1..08be6f2f1ae 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_log_memsize_too_high.py +++ b/tests/ported_static/stStaticCall/test_static_log0_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log0_log_memsize_too_high( ) -> None: """Test_static_log0_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,21 @@ def test_static_log0_log_memsize_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0( + offset=0x1, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +66,7 @@ def test_static_log0_log_memsize_too_high( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x6573BB447199FC94C98AD0F26068653C70DA4044, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,25 +76,7 @@ def test_static_log0_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0( - offset=0x1, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x6573BB447199FC94C98AD0F26068653C70DA4044), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log0_log_memsize_zero.py b/tests/ported_static/stStaticCall/test_static_log0_log_memsize_zero.py index f3404e23524..d00b5fa1cae 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_log_memsize_zero.py +++ b/tests/ported_static/stStaticCall/test_static_log0_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log0_log_memsize_zero( ) -> None: """Test_static_log0_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,18 @@ def test_static_log0_log_memsize_zero( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0(offset=0x1, size=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +63,7 @@ def test_static_log0_log_memsize_zero( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x2F70A6BCEE18358A07F12FF4630E0A802D8C293A, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,22 +73,7 @@ def test_static_log0_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 1 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0(offset=0x1, size=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x2F70A6BCEE18358A07F12FF4630E0A802D8C293A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem.py b/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem.py index 448768e8712..e2fa4804a08 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem.py +++ b/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log0_non_empty_mem( ) -> None: """Test_static_log0_non_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,18 @@ def test_static_log0_non_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.LOG0(offset=0x0, size=0x20) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +63,7 @@ def test_static_log0_non_empty_mem( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x86BB6680BEC59591FA113B66365D1BF87A4C6910, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,22 +73,7 @@ def test_static_log0_non_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.LOG0(offset=0x0, size=0x20) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x86BB6680BEC59591FA113B66365D1BF87A4C6910), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1.py b/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1.py index 6d44de5ee04..ac79fbfd901 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1.py +++ b/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_log0_non_empty_mem_log_mem_size1( ) -> None: """Test_static_log0_non_empty_mem_log_mem_size1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,18 @@ def test_static_log0_non_empty_mem_log_mem_size1( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0(offset=0x0, size=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_static_log0_non_empty_mem_log_mem_size1( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x2DA68E115CD98F7D70E0B7CFABE76581FD2D667, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -66,22 +75,7 @@ def test_static_log0_non_empty_mem_log_mem_size1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 0 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0(offset=0x0, size=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x02DA68E115CD98F7D70E0B7CFABE76581FD2D667), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31.py b/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31.py index dc37f47154e..0485ad02595 100644 --- a/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31.py +++ b/tests/ported_static/stStaticCall/test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31( ) -> None: """Test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,18 @@ def test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 31 1) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG0(offset=0x1F, size=0x1) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +65,7 @@ def test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x897FEE72AFB437BE678EE00C486726DA08ADB887, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -66,22 +75,7 @@ def test_static_log0_non_empty_mem_log_mem_size1_log_mem_start31( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG0 31 1) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG0(offset=0x1F, size=0x1) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x897FEE72AFB437BE678EE00C486726DA08ADB887), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log1_empty_mem.py b/tests/ported_static/stStaticCall/test_static_log1_empty_mem.py index 240c00b9c78..ab6c4284320 100644 --- a/tests/ported_static/stStaticCall/test_static_log1_empty_mem.py +++ b/tests/ported_static/stStaticCall/test_static_log1_empty_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log1_empty_mem( ) -> None: """Test_static_log1_empty_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,13 @@ def test_static_log1_empty_mem( gas_limit=1000000, ) + # Source: lll + # { (LOG1 0 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.LOG1(offset=0x0, size=0x0, topic_1=0x0) + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +58,7 @@ def test_static_log1_empty_mem( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0xA86CBC14A38774A22B21CC067FF70DD74CC18E7F, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,17 +68,7 @@ def test_static_log1_empty_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (LOG1 0 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.LOG1(offset=0x0, size=0x0, topic_1=0x0) + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xA86CBC14A38774A22B21CC067FF70DD74CC18E7F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log1_log_mem_start_too_high.py b/tests/ported_static/stStaticCall/test_static_log1_log_mem_start_too_high.py index b8bd76e3639..bf18441054a 100644 --- a/tests/ported_static/stStaticCall/test_static_log1_log_mem_start_too_high.py +++ b/tests/ported_static/stStaticCall/test_static_log1_log_mem_start_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log1_log_mem_start_too_high( ) -> None: """Test_static_log1_log_mem_start_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_static_log1_log_mem_start_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x1, + topic_1=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +67,7 @@ def test_static_log1_log_mem_start_too_high( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x2884BD4A36D3BF28249C493EEFC971380A638684, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,26 +77,7 @@ def test_static_log1_log_mem_start_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x1, - topic_1=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x2884BD4A36D3BF28249C493EEFC971380A638684), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log1_log_memsize_too_high.py b/tests/ported_static/stStaticCall/test_static_log1_log_memsize_too_high.py index dc0635f44af..50f52419d3f 100644 --- a/tests/ported_static/stStaticCall/test_static_log1_log_memsize_too_high.py +++ b/tests/ported_static/stStaticCall/test_static_log1_log_memsize_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log1_log_memsize_too_high( ) -> None: """Test_static_log1_log_memsize_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_static_log1_log_memsize_too_high( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1( + offset=0x1, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + topic_1=0x0, + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +67,7 @@ def test_static_log1_log_memsize_too_high( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0x232172C10FC2B2CB5CCBC4349B5D177EB640EDC0, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,26 +77,7 @@ def test_static_log1_log_memsize_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1( - offset=0x1, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - topic_1=0x0, - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x232172C10FC2B2CB5CCBC4349B5D177EB640EDC0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log1_log_memsize_zero.py b/tests/ported_static/stStaticCall/test_static_log1_log_memsize_zero.py index 1703fb2387e..cfefd6fb414 100644 --- a/tests/ported_static/stStaticCall/test_static_log1_log_memsize_zero.py +++ b/tests/ported_static/stStaticCall/test_static_log1_log_memsize_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log1_log_memsize_zero( ) -> None: """Test_static_log1_log_memsize_zero.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,18 @@ def test_static_log1_log_memsize_zero( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0 0) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1(offset=0x1, size=0x0, topic_1=0x0) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +63,7 @@ def test_static_log1_log_memsize_zero( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0xC1F290174E61D4F7F40C5E11677591C31E0F63C7, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,22 +73,7 @@ def test_static_log1_log_memsize_zero( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 1 0 0) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1(offset=0x1, size=0x0, topic_1=0x0) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xC1F290174E61D4F7F40C5E11677591C31E0F63C7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log1_max_topic.py b/tests/ported_static/stStaticCall/test_static_log1_max_topic.py index f60ed2ff85a..0185bb60bc8 100644 --- a/tests/ported_static/stStaticCall/test_static_log1_max_topic.py +++ b/tests/ported_static/stStaticCall/test_static_log1_max_topic.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_log1_max_topic( ) -> None: """Test_static_log1_max_topic.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,22 @@ def test_static_log1_max_topic( gas_limit=1000000, ) + # Source: lll + # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 + ) + + Op.LOG1( + offset=0x0, + size=0x20, + topic_1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 1000 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +67,7 @@ def test_static_log1_max_topic( key=0x0, value=Op.STATICCALL( gas=0x3E8, - address=0xFAA3ACCE157A3DEDD9D750DD925F6067D252752E, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -64,26 +77,7 @@ def test_static_log1_max_topic( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE230B8D7763E30CA988447DAA182146B0BEA3764), # noqa: E501 - ) - # Source: lll - # { (MSTORE 0 0xaabbffffffffffffffffffffffffffffffffffffffffffffffffffffffffccdd) (LOG1 0 32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0xAABBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDD, # noqa: E501 - ) - + Op.LOG1( - offset=0x0, - size=0x20, - topic_1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xFAA3ACCE157A3DEDD9D750DD925F6067D252752E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_log_caller.py b/tests/ported_static/stStaticCall/test_static_log_caller.py index 8d84e90ff2a..067833c80d1 100644 --- a/tests/ported_static/stStaticCall/test_static_log_caller.py +++ b/tests/ported_static/stStaticCall/test_static_log_caller.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -74,9 +73,7 @@ def test_static_log_caller( ) -> None: """Test_static_log_caller.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -165,7 +162,6 @@ def test_static_log_caller( nonce=0, address=Address(0x586CFAA42DB8B743452A87549943AC07A09DE5CC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(addr, left_padding=True), diff --git a/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert.py b/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert.py index 17867abafa8..85426836d66 100644 --- a/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert.py +++ b/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_loop_calls_depth_then_revert( ) -> None: """Test_static_loop_calls_depth_then_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_static_loop_calls_depth_then_revert( gas_limit=100000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { [[ 0 ]] (CALL ( - (GAS) 100000) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert2.py b/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert2.py index 16397887970..56b5378b9e9 100644 --- a/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert2.py +++ b/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_static_loop_calls_depth_then_revert2( """Test_static_loop_calls_depth_then_revert2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x13426172C74D822B878FE800000000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_static_loop_calls_depth_then_revert2( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0x13426172C74D822B878FE800000000) # Source: raw # 0x6103ff60003514603d57600160003501600052600060006020600073a0000000000000000000000000000000000000005afa5061041a600051106051575b66600060006002f0600052600760196003f0505b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert3.py b/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert3.py index af2df18a0ef..8efe302527e 100644 --- a/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert3.py +++ b/tests/ported_static/stStaticCall/test_static_loop_calls_depth_then_revert3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_static_loop_calls_depth_then_revert3( """Test_static_loop_calls_depth_then_revert3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA000000000000000000000000000000000000000) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x13426172C74D822B878FE800000000) env = Environment( fee_recipient=coinbase, @@ -50,7 +47,6 @@ def test_static_loop_calls_depth_then_revert3( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0x13426172C74D822B878FE800000000) # Source: raw # 0x6103fe60003514603d57600160003501600052600060006020600073a0000000000000000000000000000000000000005afa5061041a600035106051575b66600060006002f0600052600760196003f0505b # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -91,8 +87,9 @@ def test_static_loop_calls_depth_then_revert3( compute_create_address( address=contract_0, nonce=0 ): Account.NONEXISTENT, - Address( - 0xCD6807039CAFFDDBD1C28A749EC91BEF15F448E5 + compute_create_address( + address=compute_create_address(address=contract_0, nonce=0), + nonce=1, ): Account.NONEXISTENT, } diff --git a/tests/ported_static/stStaticCall/test_static_loop_calls_then_revert.py b/tests/ported_static/stStaticCall/test_static_loop_calls_then_revert.py index 8451d21166b..32fdd9495db 100644 --- a/tests/ported_static/stStaticCall/test_static_loop_calls_then_revert.py +++ b/tests/ported_static/stStaticCall/test_static_loop_calls_then_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_loop_calls_then_revert( ) -> None: """Requires a separate pre-alloc group due to time required to fill...""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -72,27 +69,12 @@ def test_static_loop_calls_then_revert( gas_limit=100000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { (MSTORE 0 850) [[ 0 ]] (CALL (- (GAS) 10000) 0 0 32 0 0) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x352) - + Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=Op.SUB(Op.GAS, 0x2710), - address=0x7A2AF5CC0310371CCE006E472ED3B5D68E62F839, - value=0x0, - args_offset=0x0, - args_size=0x20, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) + # { (MSTORE 0 (ADD 1 (MLOAD 0))) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=Op.ADD(0x1, Op.MLOAD(offset=0x0))) + Op.STOP, nonce=0, - address=Address(0xD64495CBBA16D27A88B96F2A72417B957ED4CAE6), # noqa: E501 ) # Source: raw # 0x5b60016000350360005260006000600060007361c350fa50600051600057 # noqa: E501 @@ -102,7 +84,7 @@ def test_static_loop_calls_then_revert( + Op.POP( Op.STATICCALL( gas=0xC350, - address=0x59C89B27361FD637262B13489F28923C835E17B2, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -112,15 +94,26 @@ def test_static_loop_calls_then_revert( + Op.JUMPI(pc=0x0, condition=Op.MLOAD(offset=0x0)), storage={0: 850}, nonce=0, - address=Address(0x7A2AF5CC0310371CCE006E472ED3B5D68E62F839), # noqa: E501 ) # Source: lll - # { (MSTORE 0 (ADD 1 (MLOAD 0))) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=Op.ADD(0x1, Op.MLOAD(offset=0x0))) + # { (MSTORE 0 850) [[ 0 ]] (CALL (- (GAS) 10000) 0 0 32 0 0) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x352) + + Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=Op.SUB(Op.GAS, 0x2710), + address=addr, + value=0x0, + args_offset=0x0, + args_size=0x20, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x59C89B27361FD637262B13489F28923C835E17B2), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stStaticCall/test_static_make_money.py b/tests/ported_static/stStaticCall/test_static_make_money.py index 6bf4b5dbb9f..add8a413112 100644 --- a/tests/ported_static/stStaticCall/test_static_make_money.py +++ b/tests/ported_static/stStaticCall/test_static_make_money.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_make_money( ) -> None: """Test_static_make_money.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_make_money( gas_limit=1000000, ) + # Source: raw + # 0x600160015532600255 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.SSTORE(key=0x2, value=Op.ORIGIN), + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) (STATICCALL 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +61,7 @@ def test_static_make_money( ) + Op.STATICCALL( gas=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC, # noqa: E501 - address=0x802EDCCF6CDE9162A05FD89CDFCD8DC4A230B978, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -65,17 +70,6 @@ def test_static_make_money( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x52BA5AA5C6B8214DA66B53C9774F587F3EE4DBD0), # noqa: E501 - ) - pre[sender] = Account(balance=0x5F5E100) - # Source: raw - # 0x600160015532600255 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.SSTORE(key=0x2, value=Op.ORIGIN), - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0x802EDCCF6CDE9162A05FD89CDFCD8DC4A230B978), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_post_to_return1.py b/tests/ported_static/stStaticCall/test_static_post_to_return1.py index 68a6eb9e94d..c17835dc32d 100644 --- a/tests/ported_static/stStaticCall/test_static_post_to_return1.py +++ b/tests/ported_static/stStaticCall/test_static_post_to_return1.py @@ -47,6 +47,16 @@ def test_static_post_to_return1( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: raw + # 0x603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[1]](STATICCALL 30000 0 64 0 0 ) [[2]] (MLOAD 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -62,7 +72,7 @@ def test_static_post_to_return1( key=0x1, value=Op.STATICCALL( gas=0x7530, - address=0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -75,16 +85,6 @@ def test_static_post_to_return1( nonce=0, address=Address(0x89478090B7C5E4389217F9728EF82CC3535CC1DB), # noqa: E501 ) - # Source: raw - # 0x603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0xD5D9E9E0158920B17B6DF82FAC474B3E2691EE99), # noqa: E501 - ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stStaticCall/test_static_raw_call_gas_ask.py b/tests/ported_static/stStaticCall/test_static_raw_call_gas_ask.py index dd59c2108a1..0ea735ae867 100644 --- a/tests/ported_static/stStaticCall/test_static_raw_call_gas_ask.py +++ b/tests/ported_static/stStaticCall/test_static_raw_call_gas_ask.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -77,9 +76,7 @@ def test_static_raw_call_gas_ask( contract_3 = Address(0x2000000000000000000000000000000000000001) contract_4 = Address(0x3000000000000000000000000000000000000001) contract_5 = Address(0x4000000000000000000000000000000000000001) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -97,7 +94,6 @@ def test_static_raw_call_gas_ask( nonce=0, address=Address(0x094F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (CALL (GAS) (CALLDATALOAD 0) 0 0 0 0 0) } contract_1 = pre.deploy_contract( # noqa: F841 @@ -116,11 +112,11 @@ def test_static_raw_call_gas_ask( address=Address(0x1000000000000000000000000000000000000000), # noqa: E501 ) # Source: lll - # { (STATICCALL 3000000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0) [[1]] (GAS) } # noqa: E501 - contract_2 = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 130000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0) [[1]] (GAS) } # noqa: E501 + contract_3 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( - gas=0x2DC6C0, + gas=0x1FBD0, address=0x94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, args_offset=0x0, args_size=0x0, @@ -131,25 +127,25 @@ def test_static_raw_call_gas_ask( + Op.SSTORE(key=0x1, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 + address=Address(0x2000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll - # { (STATICCALL 130000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0) [[1]] (GAS) } # noqa: E501 - contract_3 = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 130000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 8000 0 8000) [[1]] (GAS) } # noqa: E501 + contract_5 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0x1FBD0, address=0x94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, args_offset=0x0, - args_size=0x0, + args_size=0x1F40, ret_offset=0x0, - ret_size=0x0, + ret_size=0x1F40, ) ) + Op.SSTORE(key=0x1, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x2000000000000000000000000000000000000001), # noqa: E501 + address=Address(0x4000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll # { (STATICCALL 3000000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 8000 0 8000) [[1]] (GAS) } # noqa: E501 @@ -170,22 +166,22 @@ def test_static_raw_call_gas_ask( address=Address(0x3000000000000000000000000000000000000001), # noqa: E501 ) # Source: lll - # { (STATICCALL 130000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 8000 0 8000) [[1]] (GAS) } # noqa: E501 - contract_5 = pre.deploy_contract( # noqa: F841 + # { (STATICCALL 3000000 0x094f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 0 0) [[1]] (GAS) } # noqa: E501 + contract_2 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( - gas=0x1FBD0, + gas=0x2DC6C0, address=0x94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, args_offset=0x0, - args_size=0x1F40, + args_size=0x0, ret_offset=0x0, - ret_size=0x1F40, + ret_size=0x0, ) ) + Op.SSTORE(key=0x1, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x4000000000000000000000000000000000000001), # noqa: E501 + address=Address(0x1000000000000000000000000000000000000001), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stStaticCall/test_static_refund_call_a.py b/tests/ported_static/stStaticCall/test_static_refund_call_a.py index 46133e6d70a..7b9e3701b24 100644 --- a/tests/ported_static/stStaticCall/test_static_refund_call_a.py +++ b/tests/ported_static/stStaticCall/test_static_refund_call_a.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_refund_call_a( ) -> None: """Test_static_refund_call_a.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xD28CE7E8C6CA72F9B2DD5AA5C41F48198119E86E443C50DE70F3FBA602247FE8 - ) + sender = pre.fund_eoa(amount=0xBEBC200) env = Environment( fee_recipient=coinbase, @@ -47,6 +44,14 @@ def test_static_refund_call_a( gas_limit=1000000, ) + # Source: lll + # { [[ 1 ]] 0 } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, + storage={1: 1}, + balance=0xDE0B6B3A7640000, + nonce=0, + ) # Source: lll # { [[ 0 ]] (STATICCALL 5500 0 0 0 0 ) [[ 1 ]] 1} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +59,7 @@ def test_static_refund_call_a( key=0x0, value=Op.STATICCALL( gas=0x157C, - address=0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -66,17 +71,6 @@ def test_static_refund_call_a( storage={1: 1}, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xD15BDAF597BADAA25173C995D18F65D1B514A062), # noqa: E501 - ) - pre[sender] = Account(balance=0xBEBC200) - # Source: lll - # { [[ 1 ]] 0 } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x0) + Op.STOP, - storage={1: 1}, - balance=0xDE0B6B3A7640000, - nonce=0, - address=Address(0xF4C9FC42FAEDA49049E3B8E2B97A17CC2FE95718), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_no_storage.py b/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_no_storage.py index 83c20607be4..80a792c152b 100644 --- a/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_no_storage.py +++ b/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_no_storage.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -58,9 +57,7 @@ def test_static_refund_call_to_suicide_no_storage( ) -> None: """Test_static_refund_call_to_suicide_no_storage.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x6F0117D3E9C684C7D6E1E6B79DC3880DA2BEBE77C765B171C062FDFFD38A673F - ) + sender = pre.fund_eoa(amount=0x2540BE400) env = Environment( fee_recipient=coinbase, @@ -92,7 +89,6 @@ def test_static_refund_call_to_suicide_no_storage( nonce=0, address=Address(0xA2A10D67C0F0864B703D90D9C36296AD8A547AE6), # noqa: E501 ) - pre[sender] = Account(balance=0x2540BE400) # Source: lll # { (SELFDESTRUCT ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_twice.py b/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_twice.py index f717ba102e7..6860878412f 100644 --- a/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_twice.py +++ b/tests/ported_static/stStaticCall/test_static_refund_call_to_suicide_twice.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,9 +58,7 @@ def test_static_refund_call_to_suicide_twice( ) -> None: """Test_static_refund_call_to_suicide_twice.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x5B7B8EFB6D003CD481E408D8759A25ADC79955092F1A380D8F8B57346C1D1342 - ) + sender = pre.fund_eoa(amount=0x174876E800) env = Environment( fee_recipient=coinbase, @@ -101,7 +98,6 @@ def test_static_refund_call_to_suicide_twice( nonce=0, address=Address(0x75DB2708826B7D5E8CD45002F9AE23C830C31EFD), # noqa: E501 ) - pre[sender] = Account(balance=0x174876E800) # Source: lll # { (SELFDESTRUCT ) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_static_return50000_2.py b/tests/ported_static/stStaticCall/test_static_return50000_2.py index f3667ea4cee..fbcec0e7291 100644 --- a/tests/ported_static/stStaticCall/test_static_return50000_2.py +++ b/tests/ported_static/stStaticCall/test_static_return50000_2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_return50000_2( ) -> None: """Test_static_return50000_2.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_static_return50000_2( gas_limit=89250000, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) # Source: lll # { (MSTORE 0 (CALLDATALOAD 49999)) (RETURN (MLOAD 0) 1) } addr = pre.deploy_contract( # noqa: F841 @@ -56,28 +52,6 @@ def test_static_return50000_2( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0x0D08FB89197BD8F97C770ED75E28ED610A3016E9), # noqa: E501 - ) - # Source: lll - # { [[ 0 ]] (CALL (GAS) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=Op.GAS, - address=0xDF43BBA207127B641624B20497FA07055F4A3939, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - balance=0xFFFFFFFFFFFFF, - nonce=0, - address=Address(0x9A8CA98B299A0220FAAD60948D01CE83CCC97831), # noqa: E501 ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (STATICCALL 1564 0 50000 0 0) ) [[ 1 ]] @i } # noqa: E501 @@ -90,7 +64,7 @@ def test_static_return50000_2( key=0x0, value=Op.STATICCALL( gas=0x61C, - address=0xD08FB89197BD8F97C770ED75E28ED610A3016E9, + address=addr, args_offset=0x0, args_size=0xC350, ret_offset=0x0, @@ -104,7 +78,26 @@ def test_static_return50000_2( + Op.STOP, balance=0xFFFFFFFFFFFFF, nonce=0, - address=Address(0xDF43BBA207127B641624B20497FA07055F4A3939), # noqa: E501 + ) + # Source: lll + # { [[ 0 ]] (CALL (GAS) 0 0 0 0 0) [[ 1 ]] 1 } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=Op.GAS, + address=addr_2, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.SSTORE(key=0x1, value=0x1) + + Op.STOP, + balance=0xFFFFFFFFFFFFF, + nonce=0, ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_return_bounds.py b/tests/ported_static/stStaticCall/test_static_return_bounds.py index b3a17243a63..c11d3b559b2 100644 --- a/tests/ported_static/stStaticCall/test_static_return_bounds.py +++ b/tests/ported_static/stStaticCall/test_static_return_bounds.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,8 +33,8 @@ def test_static_return_bounds( ) -> None: """Test_static_return_bounds.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -47,6 +46,121 @@ def test_static_return_bounds( gas_limit=9223372036854775807, ) + # Source: lll + # { (RETURN 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffff 0) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffff 0) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffff 0) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffffffffffffffffffffffff 0) } + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, size=0x0) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x0, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xfffffff) } + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffff) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffffffffffff) } + addr_9 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xfffffffffffffffffffffffffff) } + addr_10 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr_11 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0x0, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffff 0xfffffff) } + addr_12 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFF, size=0xFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffff 0xffffffff) } + addr_13 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFF, size=0xFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffff 0xffffffffffffffff) } + addr_14 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0xFFFFFFFFFFFFFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffffffffffffffffffffffff 0xfffffffffffffffffffffffffff) } + addr_15 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr_16 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + nonce=0, + ) # Source: lll # { [[1]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[2]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[3]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[4]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[5]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[6]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[7]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[8]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[9]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[10]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[11]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[12]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[13]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[14]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[15]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[16]] (STATICCALL 0x7ffffffffffffff 0 0 0 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -54,7 +168,7 @@ def test_static_return_bounds( key=0x1, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x5EFBF04D8E1CC5B6B3719B16B5744A09BACFC18B, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -65,7 +179,7 @@ def test_static_return_bounds( key=0x2, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xC7AA750FE05C7E38475A49FE98A301024D0C1D54, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -76,7 +190,7 @@ def test_static_return_bounds( key=0x3, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xFF6B6D23BE161344E86EB7B174ACEDD4B1DC6DC7, + address=addr_3, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -87,7 +201,7 @@ def test_static_return_bounds( key=0x4, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x7BBCF24C83493C4E733CB54079B51873D3211AD2, + address=addr_4, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -98,7 +212,7 @@ def test_static_return_bounds( key=0x5, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x7A4461AC9F9CD13F40F9514A7C60E23A71C1DFF3, + address=addr_5, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -109,7 +223,7 @@ def test_static_return_bounds( key=0x6, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -120,7 +234,7 @@ def test_static_return_bounds( key=0x7, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -131,7 +245,7 @@ def test_static_return_bounds( key=0x8, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -142,7 +256,7 @@ def test_static_return_bounds( key=0x9, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -153,7 +267,7 @@ def test_static_return_bounds( key=0xA, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -164,7 +278,7 @@ def test_static_return_bounds( key=0xB, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -175,7 +289,7 @@ def test_static_return_bounds( key=0xC, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -186,7 +300,7 @@ def test_static_return_bounds( key=0xD, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -197,7 +311,7 @@ def test_static_return_bounds( key=0xE, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -208,7 +322,7 @@ def test_static_return_bounds( key=0xF, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -219,7 +333,7 @@ def test_static_return_bounds( key=0x10, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -228,141 +342,6 @@ def test_static_return_bounds( ) + Op.STOP, nonce=0, - address=Address(0xDAAED08ADBA0DD97804C34DD17B55766D54FC392), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x5EFBF04D8E1CC5B6B3719B16B5744A09BACFC18B), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffff 0) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0xC7AA750FE05C7E38475A49FE98A301024D0C1D54), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffff 0) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0xFF6B6D23BE161344E86EB7B174ACEDD4B1DC6DC7), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffff 0) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x7BBCF24C83493C4E733CB54079B51873D3211AD2), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffffffffffffffffffffffff 0) } - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, size=0x0) - + Op.STOP, - nonce=0, - address=Address(0x7A4461AC9F9CD13F40F9514A7C60E23A71C1DFF3), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x0, - ) - + Op.STOP, - nonce=0, - address=Address(0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xfffffff) } - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x7266F1C07958D55CE36DE0592604F1A915BDF1C2), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffff) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x2CEB88D6C420E5C65593D9EBED9A25600AB9E113), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffffffffffff) } - addr_9 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x0B09CA4308585F026B8D02BE147FEA0739EC463A), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xfffffffffffffffffffffffffff) } - addr_10 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF) - + Op.STOP, - nonce=0, - address=Address(0xF519DE4DCB9AAA53F8F0DB9B18C715C928CAADE8), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr_11 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0x0, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - nonce=0, - address=Address(0x28463490948D21EFC49949B4D394989BF52C57F1), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffff 0xfffffff) } - addr_12 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFF, size=0xFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x07084994C5891B1467D74BEDB0477DA4909E4C0E), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffff 0xffffffff) } - addr_13 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFF, size=0xFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0xAD7754A8A56CC5AD4E319FA94194E435628DEE67), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffff 0xffffffffffffffff) } - addr_14 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0xFFFFFFFFFFFFFFFF) - + Op.STOP, - nonce=0, - address=Address(0x416408C1D7FDA274DDEB45FFE4817068808121CA), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffffffffffffffffffffffff 0xfffffffffffffffffffffffffff) } - addr_15 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, - ) - + Op.STOP, - nonce=0, - address=Address(0x2548BDA95A3831ABCD613F4D24E4634615A71CCA), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr_16 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - nonce=0, - address=Address(0x76006C948F3A0529479C6D18A6F95908426E8092), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_return_bounds_oog.py b/tests/ported_static/stStaticCall/test_static_return_bounds_oog.py index 0e44f30a174..f6d2df13154 100644 --- a/tests/ported_static/stStaticCall/test_static_return_bounds_oog.py +++ b/tests/ported_static/stStaticCall/test_static_return_bounds_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -59,8 +58,8 @@ def test_static_return_bounds_oog( ) -> None: """Test_static_return_bounds_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -72,6 +71,121 @@ def test_static_return_bounds_oog( gas_limit=9223372036854775807, ) + # Source: lll + # { (RETURN 0 0) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffff 0) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffff 0) } + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffff 0) } + addr_4 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0x0) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffffffffffffffffffffffff 0) } + addr_5 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, size=0x0) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 + addr_6 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0x0, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xfffffff) } + addr_7 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffff) } + addr_8 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffffffffffff) } + addr_9 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xfffffffffffffffffffffffffff) } + addr_10 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr_11 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0x0, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffff 0xfffffff) } + addr_12 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFF, size=0xFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffff 0xffffffff) } + addr_13 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFF, size=0xFFFFFFFF) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffff 0xffffffffffffffff) } + addr_14 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0xFFFFFFFFFFFFFFFF) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xfffffffffffffffffffffffffff 0xfffffffffffffffffffffffffff) } + addr_15 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, + ) + + Op.STOP, + nonce=0, + ) + # Source: lll + # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 + addr_16 = pre.deploy_contract( # noqa: F841 + code=Op.RETURN( + offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 + ) + + Op.STOP, + nonce=0, + ) # Source: lll # { [[1]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[2]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[3]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[4]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[5]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[6]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[7]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[8]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[9]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[10]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[11]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[12]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[13]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[14]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[15]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) [[16]] (STATICCALL 0x7ffffffffffffff 0 0 0 0) (IF (EQ (CALLDATALOAD 0) 0) (KECCAK256 0x00 0x2fffff) (GAS) ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -79,7 +193,7 @@ def test_static_return_bounds_oog( key=0x1, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x5EFBF04D8E1CC5B6B3719B16B5744A09BACFC18B, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -90,7 +204,7 @@ def test_static_return_bounds_oog( key=0x2, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xC7AA750FE05C7E38475A49FE98A301024D0C1D54, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -101,7 +215,7 @@ def test_static_return_bounds_oog( key=0x3, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0xFF6B6D23BE161344E86EB7B174ACEDD4B1DC6DC7, + address=addr_3, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -112,7 +226,7 @@ def test_static_return_bounds_oog( key=0x4, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x7BBCF24C83493C4E733CB54079B51873D3211AD2, + address=addr_4, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -123,7 +237,7 @@ def test_static_return_bounds_oog( key=0x5, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x7A4461AC9F9CD13F40F9514A7C60E23A71C1DFF3, + address=addr_5, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -134,7 +248,7 @@ def test_static_return_bounds_oog( key=0x6, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -145,7 +259,7 @@ def test_static_return_bounds_oog( key=0x7, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -156,7 +270,7 @@ def test_static_return_bounds_oog( key=0x8, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -167,7 +281,7 @@ def test_static_return_bounds_oog( key=0x9, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -178,7 +292,7 @@ def test_static_return_bounds_oog( key=0xA, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -189,7 +303,7 @@ def test_static_return_bounds_oog( key=0xB, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -200,7 +314,7 @@ def test_static_return_bounds_oog( key=0xC, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -211,7 +325,7 @@ def test_static_return_bounds_oog( key=0xD, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -222,7 +336,7 @@ def test_static_return_bounds_oog( key=0xE, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -233,7 +347,7 @@ def test_static_return_bounds_oog( key=0xF, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -244,7 +358,7 @@ def test_static_return_bounds_oog( key=0x10, value=Op.STATICCALL( gas=0x7FFFFFFFFFFFFFF, - address=0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63, + address=addr_6, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -259,141 +373,6 @@ def test_static_return_bounds_oog( + Op.JUMPDEST + Op.STOP, nonce=0, - address=Address(0x57545D218764BC417FDCBBC2C1F43B2A62105CE1), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x5EFBF04D8E1CC5B6B3719B16B5744A09BACFC18B), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffff 0) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0xC7AA750FE05C7E38475A49FE98A301024D0C1D54), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffff 0) } - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0xFF6B6D23BE161344E86EB7B174ACEDD4B1DC6DC7), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffff 0) } - addr_4 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0x0) + Op.STOP, - nonce=0, - address=Address(0x7BBCF24C83493C4E733CB54079B51873D3211AD2), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffffffffffffffffffffffff 0) } - addr_5 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, size=0x0) - + Op.STOP, - nonce=0, - address=Address(0x7A4461AC9F9CD13F40F9514A7C60E23A71C1DFF3), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } # noqa: E501 - addr_6 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0x0, - ) - + Op.STOP, - nonce=0, - address=Address(0x4912BC7B66A3BF27ADFA54AB049E90E8C9C4DC63), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xfffffff) } - addr_7 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x7266F1C07958D55CE36DE0592604F1A915BDF1C2), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffff) } - addr_8 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x2CEB88D6C420E5C65593D9EBED9A25600AB9E113), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffffffffffff) } - addr_9 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x0B09CA4308585F026B8D02BE147FEA0739EC463A), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xfffffffffffffffffffffffffff) } - addr_10 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0x0, size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF) - + Op.STOP, - nonce=0, - address=Address(0xF519DE4DCB9AAA53F8F0DB9B18C715C928CAADE8), # noqa: E501 - ) - # Source: lll - # { (RETURN 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr_11 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0x0, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - nonce=0, - address=Address(0x28463490948D21EFC49949B4D394989BF52C57F1), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffff 0xfffffff) } - addr_12 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFF, size=0xFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0x07084994C5891B1467D74BEDB0477DA4909E4C0E), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffff 0xffffffff) } - addr_13 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFF, size=0xFFFFFFFF) + Op.STOP, - nonce=0, - address=Address(0xAD7754A8A56CC5AD4E319FA94194E435628DEE67), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffff 0xffffffffffffffff) } - addr_14 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN(offset=0xFFFFFFFFFFFFFFFF, size=0xFFFFFFFFFFFFFFFF) - + Op.STOP, - nonce=0, - address=Address(0x416408C1D7FDA274DDEB45FFE4817068808121CA), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xfffffffffffffffffffffffffff 0xfffffffffffffffffffffffffff) } - addr_15 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFF, - ) - + Op.STOP, - nonce=0, - address=Address(0x2548BDA95A3831ABCD613F4D24E4634615A71CCA), # noqa: E501 - ) - # Source: lll - # { (RETURN 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } # noqa: E501 - addr_16 = pre.deploy_contract( # noqa: F841 - code=Op.RETURN( - offset=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - size=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, # noqa: E501 - ) - + Op.STOP, - nonce=0, - address=Address(0x76006C948F3A0529479C6D18A6F95908426E8092), # noqa: E501 - ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/stStaticCall/test_static_return_test.py b/tests/ported_static/stStaticCall/test_static_return_test.py index ba221d701f9..5f434c1bdc0 100644 --- a/tests/ported_static/stStaticCall/test_static_return_test.py +++ b/tests/ported_static/stStaticCall/test_static_return_test.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_return_test( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -49,13 +46,22 @@ def test_static_return_test( gas_limit=10000000, ) + # Source: lll + # {(MSTORE 0 0x15) (RETURN 31 1)} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x0, value=0x15) + + Op.RETURN(offset=0x1F, size=0x1) + + Op.STOP, + balance=0x186A0, + nonce=0, + ) # Source: lll # {(STATICCALL 2000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 30 1 31 1) [[0]](MLOAD 0) (RETURN 30 2)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.STATICCALL( gas=0x7D0, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, args_offset=0x1E, args_size=0x1, ret_offset=0x1F, @@ -66,18 +72,6 @@ def test_static_return_test( + Op.RETURN(offset=0x1E, size=0x2) + Op.STOP, nonce=0, - address=Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - pre[sender] = Account(balance=0x5F5E100) - # Source: lll - # {(MSTORE 0 0x15) (RETURN 31 1)} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x0, value=0x15) - + Op.RETURN(offset=0x1F, size=0x1) - + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_return_test2.py b/tests/ported_static/stStaticCall/test_static_return_test2.py index 5d839a4c38d..6b38a20d22c 100644 --- a/tests/ported_static/stStaticCall/test_static_return_test2.py +++ b/tests/ported_static/stStaticCall/test_static_return_test2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_static_return_test2( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -49,6 +46,17 @@ def test_static_return_test2( gas_limit=1000000000, ) + # Source: lll + # {(MSTORE 0 (MUL 3 (CALLDATALOAD 0)))(RETURN 0 32)} + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, value=Op.MUL(0x3, Op.CALLDATALOAD(offset=0x0)) + ) + + Op.RETURN(offset=0x0, size=0x20) + + Op.STOP, + balance=0x186A0, + nonce=0, + ) # Source: lll # {(MSTORE 0 0x15)(STATICCALL 7000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 32 32 32) [[0]](MLOAD 0) [[1]](MLOAD 32) (RETURN 0 64)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,7 +64,7 @@ def test_static_return_test2( + Op.POP( Op.STATICCALL( gas=0x1B58, - address=0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + address=contract_1, args_offset=0x0, args_size=0x20, ret_offset=0x20, @@ -68,20 +76,6 @@ def test_static_return_test2( + Op.RETURN(offset=0x0, size=0x40) + Op.STOP, nonce=0, - address=Address(0x194F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 - ) - pre[sender] = Account(balance=0x5F5E100) - # Source: lll - # {(MSTORE 0 (MUL 3 (CALLDATALOAD 0)))(RETURN 0 32)} - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, value=Op.MUL(0x3, Op.CALLDATALOAD(offset=0x0)) - ) - + Op.RETURN(offset=0x0, size=0x20) - + Op.STOP, - balance=0x186A0, - nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_revert_depth2.py b/tests/ported_static/stStaticCall/test_static_revert_depth2.py index 5bc03306a66..b37e0bb7174 100644 --- a/tests/ported_static/stStaticCall/test_static_revert_depth2.py +++ b/tests/ported_static/stStaticCall/test_static_revert_depth2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_revert_depth2( ) -> None: """Test_static_revert_depth2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,36 +44,28 @@ def test_static_revert_depth2( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll - # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (STATICCALL 150000 0 0 0 0) [[2]] (STATICCALL 150000 0 0 0 0)} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) - + Op.SSTORE( - key=0x1, - value=Op.STATICCALL( - gas=0x249F0, - address=0x5DD18F4768E54DE1443F70EC11AD95D5DB424293, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.SSTORE( - key=0x2, - value=Op.STATICCALL( - gas=0x249F0, - address=0xA61140A1C2699A13C619940208A513D42F654E98, + # { (MSTORE 1 1) } + addr_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, + nonce=0, + ) + # Source: lll + # { (STATICCALL 50000 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 + addr_3 = pre.deploy_contract( # noqa: F841 + code=Op.POP( + Op.STATICCALL( + gas=0xC350, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, ret_size=0x0, - ), + ) ) + + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0x57C111943C5E6F1817EE85FD1212409B7D1F7F26), # noqa: E501 ) # Source: lll # { (STATICCALL 50000 0 0 0 0) (MSTORE 1 1) } # noqa: E501 @@ -84,7 +73,7 @@ def test_static_revert_depth2( code=Op.POP( Op.STATICCALL( gas=0xC350, - address=0x15B1327FE926A2172ADFD10EFDEF1505C8E15461, + address=addr_2, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -94,32 +83,35 @@ def test_static_revert_depth2( + Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, nonce=0, - address=Address(0x5DD18F4768E54DE1443F70EC11AD95D5DB424293), # noqa: E501 ) # Source: lll - # { (MSTORE 1 1) } - addr_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE(offset=0x1, value=0x1) + Op.STOP, - nonce=0, - address=Address(0x15B1327FE926A2172ADFD10EFDEF1505C8E15461), # noqa: E501 - ) - # Source: lll - # { (STATICCALL 50000 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 - addr_3 = pre.deploy_contract( # noqa: F841 - code=Op.POP( - Op.STATICCALL( - gas=0xC350, - address=0x15B1327FE926A2172ADFD10EFDEF1505C8E15461, + # { [[0]] (ADD 1 (SLOAD 0)) [[1]] (STATICCALL 150000 0 0 0 0) [[2]] (STATICCALL 150000 0 0 0 0)} # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=Op.ADD(0x1, Op.SLOAD(key=0x0))) + + Op.SSTORE( + key=0x1, + value=Op.STATICCALL( + gas=0x249F0, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, ret_size=0x0, - ) + ), + ) + + Op.SSTORE( + key=0x2, + value=Op.STATICCALL( + gas=0x249F0, + address=addr_3, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), ) - + Op.SHA3(offset=0x0, size=0x2FFFFF) + Op.STOP, nonce=0, - address=Address(0xA61140A1C2699A13C619940208A513D42F654E98), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stStaticCall/test_static_revert_opcode_calls.py b/tests/ported_static/stStaticCall/test_static_revert_opcode_calls.py index e0e0d3eec06..80b13c69048 100644 --- a/tests/ported_static/stStaticCall/test_static_revert_opcode_calls.py +++ b/tests/ported_static/stStaticCall/test_static_revert_opcode_calls.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_static_revert_opcode_calls( ) -> None: """Test_static_revert_opcode_calls.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -69,7 +66,13 @@ def test_static_revert_opcode_calls( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + # Source: lll + # { (REVERT 0 1) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.REVERT(offset=0x0, size=0x1) + Op.STOP, + balance=1, + nonce=0, + ) # Source: lll # { [[0]] (STATICCALL 50000 0 0 0 0) [[1]] (RETURNDATASIZE)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -77,7 +80,7 @@ def test_static_revert_opcode_calls( key=0x0, value=Op.STATICCALL( gas=0xC350, - address=0xBE254B4ACEB5B7495F1A5646BE06FE5A158581EC, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -88,15 +91,6 @@ def test_static_revert_opcode_calls( + Op.STOP, balance=1, nonce=0, - address=Address(0x187C91277DEEEDF062A07B44DE3C96C6E7CBC7BB), # noqa: E501 - ) - # Source: lll - # { (REVERT 0 1) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.REVERT(offset=0x0, size=0x1) + Op.STOP, - balance=1, - nonce=0, - address=Address(0xBE254B4ACEB5B7495F1A5646BE06FE5A158581EC), # noqa: E501 ) tx_data = [ diff --git a/tests/ported_static/stStaticCall/test_static_zero_value_suicide_oog_revert.py b/tests/ported_static/stStaticCall/test_static_zero_value_suicide_oog_revert.py index 5c045440fa5..abee402ac2b 100644 --- a/tests/ported_static/stStaticCall/test_static_zero_value_suicide_oog_revert.py +++ b/tests/ported_static/stStaticCall/test_static_zero_value_suicide_oog_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_static_zero_value_suicide_oog_revert( ) -> None: """Test_static_zero_value_suicide_oog_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_static_zero_value_suicide_oog_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (STATICCALL 100000 0 0 0 0) (KECCAK256 0x00 0x2fffff) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_called_contract.py b/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_called_contract.py index 36d88acb23a..4331223b362 100644 --- a/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_called_contract.py +++ b/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_called_contract.py @@ -54,27 +54,7 @@ def test_staticcall_to_precompile_from_called_contract( gas_limit=10000000, ) - # Source: lll - # { - # [[ 0 ]] (CALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0 0 0 ) # noqa: E501 - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=Op.CALL( - gas=Op.GAS, - address=0xA000000000000000000000000000000000000000, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ), - ) - + Op.STOP, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ;; Recovery of ECDSA signature @@ -357,7 +337,27 @@ def test_staticcall_to_precompile_from_called_contract( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { + # [[ 0 ]] (CALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0 0 0 ) # noqa: E501 + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=Op.CALL( + gas=Op.GAS, + address=contract_1, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ), + ) + + Op.STOP, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) tx = Transaction( sender=sender, @@ -372,7 +372,7 @@ def test_staticcall_to_precompile_from_called_contract( contract_1: Account( storage={ 0: 1, - 1: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 1: sender, 2: 1, 3: 1, 4: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, diff --git a/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_contract_initialization.py b/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_contract_initialization.py index aef233731d8..1357cf578a1 100644 --- a/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_contract_initialization.py +++ b/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_contract_initialization.py @@ -53,6 +53,7 @@ def test_staticcall_to_precompile_from_contract_initialization( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # (CALLDATACOPY 0 0 (CALLDATASIZE)) @@ -73,7 +74,6 @@ def test_staticcall_to_precompile_from_contract_initialization( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -92,7 +92,7 @@ def test_staticcall_to_precompile_from_contract_initialization( Address(0xFAD204ED1275B429B66C9CE0614D62832D6B2580): Account( storage={ 0: 1, - 1: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 1: sender, 2: 1, 3: 1, 4: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, diff --git a/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_transaction.py b/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_transaction.py index 5b4eaec91ea..dd0bad3437f 100644 --- a/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_transaction.py +++ b/tests/ported_static/stStaticCall/test_staticcall_to_precompile_from_transaction.py @@ -53,6 +53,7 @@ def test_staticcall_to_precompile_from_transaction( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ;; Recovery of ECDSA signature @@ -335,7 +336,6 @@ def test_staticcall_to_precompile_from_transaction( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -349,7 +349,7 @@ def test_staticcall_to_precompile_from_transaction( contract_0: Account( storage={ 0: 1, - 1: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 1: sender, 2: 1, 3: 1, 4: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, diff --git a/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_called_contract.py b/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_called_contract.py index 28d0e8f8161..e9608c8f28e 100644 --- a/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_called_contract.py +++ b/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_called_contract.py @@ -56,139 +56,7 @@ def test_callcode_to_precompile_from_called_contract( gas_limit=10000000, ) - # Source: lll - # { - # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # (CALL (GAS) 0xb000000000000000000000000000000000000000 0 0 0 0 0) - # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.POP( - Op.CALL( - gas=Op.GAS, - address=0xB000000000000000000000000000000000000000, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - ) - + Op.SSTORE( - key=0x1, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.STOP, - storage={ - 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - }, - balance=1000, - nonce=0, - address=Address(0xC000000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { - # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 - # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # ;; save results to store - # [[ 0x0a00 ]] @0x0a0000 [[ 0x0b00 ]] @0x0b0000 - # [[ 0x0a01 ]] @0x0a0100 [[ 0x0b01 ]] @0x0b0100 - # [[ 0x0a02 ]] @0x0a0200 [[ 0x0b02 ]] @0x0b0200 - # [[ 0x0a03 ]] @0x0a0300 [[ 0x0b03 ]] @0x0b0300 - # [[ 0x0a04 ]] @0x0a0400 [[ 0x0b04 ]] @0x0b0400 - # [[ 0x0a05 ]] @0x0a0500 [[ 0x0b05 ]] @0x0b0500 - # [[ 0x0a06 ]] @0x0a0600 [[ 0x0b06 ]] @0x0b0600 - # [[ 0x0a07 ]] @0x0a0700 [[ 0x0b07 ]] @0x0b0700 - # [[ 0x0a08 ]] @0x0a0800 [[ 0x0b08 ]] @0x0b0800 - # [[ 0x0a09 ]] @0x0a0900 [[ 0x0b09 ]] @0x0b0900 - # [[ 0x0a10 ]] @0x0a1000 [[ 0x0b10 ]] @0x0b1000 - # [[ 0x0a11 ]] @0x0a1100 [[ 0x0b11 ]] @0x0b1100 - # [[ 0x0a12 ]] @0x0a1200 [[ 0x0b12 ]] @0x0b1200 - # [[ 0x0a13 ]] @0x0a1300 [[ 0x0b13 ]] @0x0b1300 - # [[ 0x0a14 ]] @0x0a1400 [[ 0x0b14 ]] @0x0b1400 - # [[ 0x0a15 ]] @0x0a1500 [[ 0x0b15 ]] @0x0b1500 - # [[ 0x0a16 ]] @0x0a1600 [[ 0x0b16 ]] @0x0b1600 - # [[ 0x0a17 ]] @0x0a1700 [[ 0x0b17 ]] @0x0b1700 - # [[ 0x0a18 ]] @0x0a1800 [[ 0x0b18 ]] @0x0b1800 - # [[ 0x0a19 ]] @0x0a1900 [[ 0x0b19 ]] @0x0b1900 - # [[ 0x0a20 ]] @0x0a2000 [[ 0x0b20 ]] @0x0b2000 - # } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xA000000000000000000000000000000000000000, - args_offset=0x0, - args_size=0x0, - ret_offset=0xA0000, - ret_size=0x12020, - ) - ) - + Op.SSTORE( - key=0x1, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) - + Op.SSTORE(key=0xB00, value=Op.MLOAD(offset=0xB0000)) - + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) - + Op.SSTORE(key=0xB01, value=Op.MLOAD(offset=0xB0100)) - + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) - + Op.SSTORE(key=0xB02, value=Op.MLOAD(offset=0xB0200)) - + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) - + Op.SSTORE(key=0xB03, value=Op.MLOAD(offset=0xB0300)) - + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) - + Op.SSTORE(key=0xB04, value=Op.MLOAD(offset=0xB0400)) - + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) - + Op.SSTORE(key=0xB05, value=Op.MLOAD(offset=0xB0500)) - + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) - + Op.SSTORE(key=0xB06, value=Op.MLOAD(offset=0xB0600)) - + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) - + Op.SSTORE(key=0xB07, value=Op.MLOAD(offset=0xB0700)) - + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) - + Op.SSTORE(key=0xB08, value=Op.MLOAD(offset=0xB0800)) - + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) - + Op.SSTORE(key=0xB09, value=Op.MLOAD(offset=0xB0900)) - + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) - + Op.SSTORE(key=0xB10, value=Op.MLOAD(offset=0xB1000)) - + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) - + Op.SSTORE(key=0xB11, value=Op.MLOAD(offset=0xB1100)) - + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) - + Op.SSTORE(key=0xB12, value=Op.MLOAD(offset=0xB1200)) - + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) - + Op.SSTORE(key=0xB13, value=Op.MLOAD(offset=0xB1300)) - + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) - + Op.SSTORE(key=0xB14, value=Op.MLOAD(offset=0xB1400)) - + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) - + Op.SSTORE(key=0xB15, value=Op.MLOAD(offset=0xB1500)) - + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) - + Op.SSTORE(key=0xB16, value=Op.MLOAD(offset=0xB1600)) - + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) - + Op.SSTORE(key=0xB17, value=Op.MLOAD(offset=0xB1700)) - + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) - + Op.SSTORE(key=0xB18, value=Op.MLOAD(offset=0xB1800)) - + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) - + Op.SSTORE(key=0xB19, value=Op.MLOAD(offset=0xB1900)) - + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) - + Op.SSTORE(key=0xB20, value=Op.MLOAD(offset=0xB2000)) - + Op.STOP, - storage={ - 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - }, - balance=1000, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ;; Recovery of ECDSA signature @@ -609,7 +477,139 @@ def test_callcode_to_precompile_from_called_contract( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { + # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 + # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # ;; save results to store + # [[ 0x0a00 ]] @0x0a0000 [[ 0x0b00 ]] @0x0b0000 + # [[ 0x0a01 ]] @0x0a0100 [[ 0x0b01 ]] @0x0b0100 + # [[ 0x0a02 ]] @0x0a0200 [[ 0x0b02 ]] @0x0b0200 + # [[ 0x0a03 ]] @0x0a0300 [[ 0x0b03 ]] @0x0b0300 + # [[ 0x0a04 ]] @0x0a0400 [[ 0x0b04 ]] @0x0b0400 + # [[ 0x0a05 ]] @0x0a0500 [[ 0x0b05 ]] @0x0b0500 + # [[ 0x0a06 ]] @0x0a0600 [[ 0x0b06 ]] @0x0b0600 + # [[ 0x0a07 ]] @0x0a0700 [[ 0x0b07 ]] @0x0b0700 + # [[ 0x0a08 ]] @0x0a0800 [[ 0x0b08 ]] @0x0b0800 + # [[ 0x0a09 ]] @0x0a0900 [[ 0x0b09 ]] @0x0b0900 + # [[ 0x0a10 ]] @0x0a1000 [[ 0x0b10 ]] @0x0b1000 + # [[ 0x0a11 ]] @0x0a1100 [[ 0x0b11 ]] @0x0b1100 + # [[ 0x0a12 ]] @0x0a1200 [[ 0x0b12 ]] @0x0b1200 + # [[ 0x0a13 ]] @0x0a1300 [[ 0x0b13 ]] @0x0b1300 + # [[ 0x0a14 ]] @0x0a1400 [[ 0x0b14 ]] @0x0b1400 + # [[ 0x0a15 ]] @0x0a1500 [[ 0x0b15 ]] @0x0b1500 + # [[ 0x0a16 ]] @0x0a1600 [[ 0x0b16 ]] @0x0b1600 + # [[ 0x0a17 ]] @0x0a1700 [[ 0x0b17 ]] @0x0b1700 + # [[ 0x0a18 ]] @0x0a1800 [[ 0x0b18 ]] @0x0b1800 + # [[ 0x0a19 ]] @0x0a1900 [[ 0x0b19 ]] @0x0b1900 + # [[ 0x0a20 ]] @0x0a2000 [[ 0x0b20 ]] @0x0b2000 + # } + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=contract_2, + args_offset=0x0, + args_size=0x0, + ret_offset=0xA0000, + ret_size=0x12020, + ) + ) + + Op.SSTORE( + key=0x1, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) + + Op.SSTORE(key=0xB00, value=Op.MLOAD(offset=0xB0000)) + + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) + + Op.SSTORE(key=0xB01, value=Op.MLOAD(offset=0xB0100)) + + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) + + Op.SSTORE(key=0xB02, value=Op.MLOAD(offset=0xB0200)) + + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) + + Op.SSTORE(key=0xB03, value=Op.MLOAD(offset=0xB0300)) + + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) + + Op.SSTORE(key=0xB04, value=Op.MLOAD(offset=0xB0400)) + + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) + + Op.SSTORE(key=0xB05, value=Op.MLOAD(offset=0xB0500)) + + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) + + Op.SSTORE(key=0xB06, value=Op.MLOAD(offset=0xB0600)) + + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) + + Op.SSTORE(key=0xB07, value=Op.MLOAD(offset=0xB0700)) + + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) + + Op.SSTORE(key=0xB08, value=Op.MLOAD(offset=0xB0800)) + + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) + + Op.SSTORE(key=0xB09, value=Op.MLOAD(offset=0xB0900)) + + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) + + Op.SSTORE(key=0xB10, value=Op.MLOAD(offset=0xB1000)) + + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) + + Op.SSTORE(key=0xB11, value=Op.MLOAD(offset=0xB1100)) + + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) + + Op.SSTORE(key=0xB12, value=Op.MLOAD(offset=0xB1200)) + + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) + + Op.SSTORE(key=0xB13, value=Op.MLOAD(offset=0xB1300)) + + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) + + Op.SSTORE(key=0xB14, value=Op.MLOAD(offset=0xB1400)) + + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) + + Op.SSTORE(key=0xB15, value=Op.MLOAD(offset=0xB1500)) + + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) + + Op.SSTORE(key=0xB16, value=Op.MLOAD(offset=0xB1600)) + + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) + + Op.SSTORE(key=0xB17, value=Op.MLOAD(offset=0xB1700)) + + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) + + Op.SSTORE(key=0xB18, value=Op.MLOAD(offset=0xB1800)) + + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) + + Op.SSTORE(key=0xB19, value=Op.MLOAD(offset=0xB1900)) + + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) + + Op.SSTORE(key=0xB20, value=Op.MLOAD(offset=0xB2000)) + + Op.STOP, + storage={ + 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + }, + balance=1000, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll + # { + # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # (CALL (GAS) 0xb000000000000000000000000000000000000000 0 0 0 0 0) + # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.POP( + Op.CALL( + gas=Op.GAS, + address=contract_1, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + ) + + Op.SSTORE( + key=0x1, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.STOP, + storage={ + 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + }, + balance=1000, + nonce=0, + address=Address(0xC000000000000000000000000000000000000000), # noqa: E501 + ) tx = Transaction( sender=sender, @@ -633,7 +633,7 @@ def test_callcode_to_precompile_from_called_contract( 0: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 1: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 2560: 1, - 2561: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2561: sender, 2562: 1, 2563: 1, 2564: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 @@ -654,7 +654,7 @@ def test_callcode_to_precompile_from_called_contract( 2585: 1, 2592: 1, 2816: 1, - 2817: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2817: sender, 2818: 1, 2819: 1, 2820: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 diff --git a/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_contract_initialization.py b/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_contract_initialization.py index 7e649f150b3..ae2ff697bbd 100644 --- a/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_contract_initialization.py +++ b/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_contract_initialization.py @@ -55,6 +55,7 @@ def test_callcode_to_precompile_from_contract_initialization( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 @@ -507,7 +508,6 @@ def test_callcode_to_precompile_from_contract_initialization( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -533,7 +533,7 @@ def test_callcode_to_precompile_from_contract_initialization( 0: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 1: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 2560: 1, - 2561: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2561: sender, 2562: 1, 2563: 1, 2564: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 @@ -554,7 +554,7 @@ def test_callcode_to_precompile_from_contract_initialization( 2585: 1, 2592: 1, 2816: 1, - 2817: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2817: sender, 2818: 1, 2819: 1, 2820: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 diff --git a/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_transaction.py b/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_transaction.py index d4f95e0fe07..634fa6832d9 100644 --- a/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_transaction.py +++ b/tests/ported_static/stStaticFlagEnabled/test_callcode_to_precompile_from_transaction.py @@ -54,104 +54,7 @@ def test_callcode_to_precompile_from_transaction( gas_limit=10000000, ) - # Source: lll - # { - # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 - # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # ;; save results to store - # [[ 0x0a00 ]] @0x0a0000 [[ 0x0b00 ]] @0x0b0000 - # [[ 0x0a01 ]] @0x0a0100 [[ 0x0b01 ]] @0x0b0100 - # [[ 0x0a02 ]] @0x0a0200 [[ 0x0b02 ]] @0x0b0200 - # [[ 0x0a03 ]] @0x0a0300 [[ 0x0b03 ]] @0x0b0300 - # [[ 0x0a04 ]] @0x0a0400 [[ 0x0b04 ]] @0x0b0400 - # [[ 0x0a05 ]] @0x0a0500 [[ 0x0b05 ]] @0x0b0500 - # [[ 0x0a06 ]] @0x0a0600 [[ 0x0b06 ]] @0x0b0600 - # [[ 0x0a07 ]] @0x0a0700 [[ 0x0b07 ]] @0x0b0700 - # [[ 0x0a08 ]] @0x0a0800 [[ 0x0b08 ]] @0x0b0800 - # [[ 0x0a09 ]] @0x0a0900 [[ 0x0b09 ]] @0x0b0900 - # [[ 0x0a10 ]] @0x0a1000 [[ 0x0b10 ]] @0x0b1000 - # [[ 0x0a11 ]] @0x0a1100 [[ 0x0b11 ]] @0x0b1100 - # [[ 0x0a12 ]] @0x0a1200 [[ 0x0b12 ]] @0x0b1200 - # [[ 0x0a13 ]] @0x0a1300 [[ 0x0b13 ]] @0x0b1300 - # [[ 0x0a14 ]] @0x0a1400 [[ 0x0b14 ]] @0x0b1400 - # [[ 0x0a15 ]] @0x0a1500 [[ 0x0b15 ]] @0x0b1500 - # [[ 0x0a16 ]] @0x0a1600 [[ 0x0b16 ]] @0x0b1600 - # [[ 0x0a17 ]] @0x0a1700 [[ 0x0b17 ]] @0x0b1700 - # [[ 0x0a18 ]] @0x0a1800 [[ 0x0b18 ]] @0x0b1800 - # [[ 0x0a19 ]] @0x0a1900 [[ 0x0b19 ]] @0x0b1900 - # [[ 0x0a20 ]] @0x0a2000 [[ 0x0b20 ]] @0x0b2000 - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xA000000000000000000000000000000000000000, - args_offset=0x0, - args_size=0x0, - ret_offset=0xA0000, - ret_size=0x12020, - ) - ) - + Op.SSTORE( - key=0x1, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) - + Op.SSTORE(key=0xB00, value=Op.MLOAD(offset=0xB0000)) - + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) - + Op.SSTORE(key=0xB01, value=Op.MLOAD(offset=0xB0100)) - + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) - + Op.SSTORE(key=0xB02, value=Op.MLOAD(offset=0xB0200)) - + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) - + Op.SSTORE(key=0xB03, value=Op.MLOAD(offset=0xB0300)) - + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) - + Op.SSTORE(key=0xB04, value=Op.MLOAD(offset=0xB0400)) - + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) - + Op.SSTORE(key=0xB05, value=Op.MLOAD(offset=0xB0500)) - + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) - + Op.SSTORE(key=0xB06, value=Op.MLOAD(offset=0xB0600)) - + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) - + Op.SSTORE(key=0xB07, value=Op.MLOAD(offset=0xB0700)) - + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) - + Op.SSTORE(key=0xB08, value=Op.MLOAD(offset=0xB0800)) - + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) - + Op.SSTORE(key=0xB09, value=Op.MLOAD(offset=0xB0900)) - + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) - + Op.SSTORE(key=0xB10, value=Op.MLOAD(offset=0xB1000)) - + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) - + Op.SSTORE(key=0xB11, value=Op.MLOAD(offset=0xB1100)) - + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) - + Op.SSTORE(key=0xB12, value=Op.MLOAD(offset=0xB1200)) - + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) - + Op.SSTORE(key=0xB13, value=Op.MLOAD(offset=0xB1300)) - + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) - + Op.SSTORE(key=0xB14, value=Op.MLOAD(offset=0xB1400)) - + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) - + Op.SSTORE(key=0xB15, value=Op.MLOAD(offset=0xB1500)) - + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) - + Op.SSTORE(key=0xB16, value=Op.MLOAD(offset=0xB1600)) - + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) - + Op.SSTORE(key=0xB17, value=Op.MLOAD(offset=0xB1700)) - + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) - + Op.SSTORE(key=0xB18, value=Op.MLOAD(offset=0xB1800)) - + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) - + Op.SSTORE(key=0xB19, value=Op.MLOAD(offset=0xB1900)) - + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) - + Op.SSTORE(key=0xB20, value=Op.MLOAD(offset=0xB2000)) - + Op.STOP, - storage={ - 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - }, - balance=1000, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ;; Recovery of ECDSA signature @@ -572,7 +475,104 @@ def test_callcode_to_precompile_from_transaction( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { + # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 + # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # ;; save results to store + # [[ 0x0a00 ]] @0x0a0000 [[ 0x0b00 ]] @0x0b0000 + # [[ 0x0a01 ]] @0x0a0100 [[ 0x0b01 ]] @0x0b0100 + # [[ 0x0a02 ]] @0x0a0200 [[ 0x0b02 ]] @0x0b0200 + # [[ 0x0a03 ]] @0x0a0300 [[ 0x0b03 ]] @0x0b0300 + # [[ 0x0a04 ]] @0x0a0400 [[ 0x0b04 ]] @0x0b0400 + # [[ 0x0a05 ]] @0x0a0500 [[ 0x0b05 ]] @0x0b0500 + # [[ 0x0a06 ]] @0x0a0600 [[ 0x0b06 ]] @0x0b0600 + # [[ 0x0a07 ]] @0x0a0700 [[ 0x0b07 ]] @0x0b0700 + # [[ 0x0a08 ]] @0x0a0800 [[ 0x0b08 ]] @0x0b0800 + # [[ 0x0a09 ]] @0x0a0900 [[ 0x0b09 ]] @0x0b0900 + # [[ 0x0a10 ]] @0x0a1000 [[ 0x0b10 ]] @0x0b1000 + # [[ 0x0a11 ]] @0x0a1100 [[ 0x0b11 ]] @0x0b1100 + # [[ 0x0a12 ]] @0x0a1200 [[ 0x0b12 ]] @0x0b1200 + # [[ 0x0a13 ]] @0x0a1300 [[ 0x0b13 ]] @0x0b1300 + # [[ 0x0a14 ]] @0x0a1400 [[ 0x0b14 ]] @0x0b1400 + # [[ 0x0a15 ]] @0x0a1500 [[ 0x0b15 ]] @0x0b1500 + # [[ 0x0a16 ]] @0x0a1600 [[ 0x0b16 ]] @0x0b1600 + # [[ 0x0a17 ]] @0x0a1700 [[ 0x0b17 ]] @0x0b1700 + # [[ 0x0a18 ]] @0x0a1800 [[ 0x0b18 ]] @0x0b1800 + # [[ 0x0a19 ]] @0x0a1900 [[ 0x0b19 ]] @0x0b1900 + # [[ 0x0a20 ]] @0x0a2000 [[ 0x0b20 ]] @0x0b2000 + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=contract_1, + args_offset=0x0, + args_size=0x0, + ret_offset=0xA0000, + ret_size=0x12020, + ) + ) + + Op.SSTORE( + key=0x1, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) + + Op.SSTORE(key=0xB00, value=Op.MLOAD(offset=0xB0000)) + + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) + + Op.SSTORE(key=0xB01, value=Op.MLOAD(offset=0xB0100)) + + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) + + Op.SSTORE(key=0xB02, value=Op.MLOAD(offset=0xB0200)) + + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) + + Op.SSTORE(key=0xB03, value=Op.MLOAD(offset=0xB0300)) + + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) + + Op.SSTORE(key=0xB04, value=Op.MLOAD(offset=0xB0400)) + + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) + + Op.SSTORE(key=0xB05, value=Op.MLOAD(offset=0xB0500)) + + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) + + Op.SSTORE(key=0xB06, value=Op.MLOAD(offset=0xB0600)) + + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) + + Op.SSTORE(key=0xB07, value=Op.MLOAD(offset=0xB0700)) + + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) + + Op.SSTORE(key=0xB08, value=Op.MLOAD(offset=0xB0800)) + + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) + + Op.SSTORE(key=0xB09, value=Op.MLOAD(offset=0xB0900)) + + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) + + Op.SSTORE(key=0xB10, value=Op.MLOAD(offset=0xB1000)) + + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) + + Op.SSTORE(key=0xB11, value=Op.MLOAD(offset=0xB1100)) + + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) + + Op.SSTORE(key=0xB12, value=Op.MLOAD(offset=0xB1200)) + + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) + + Op.SSTORE(key=0xB13, value=Op.MLOAD(offset=0xB1300)) + + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) + + Op.SSTORE(key=0xB14, value=Op.MLOAD(offset=0xB1400)) + + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) + + Op.SSTORE(key=0xB15, value=Op.MLOAD(offset=0xB1500)) + + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) + + Op.SSTORE(key=0xB16, value=Op.MLOAD(offset=0xB1600)) + + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) + + Op.SSTORE(key=0xB17, value=Op.MLOAD(offset=0xB1700)) + + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) + + Op.SSTORE(key=0xB18, value=Op.MLOAD(offset=0xB1800)) + + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) + + Op.SSTORE(key=0xB19, value=Op.MLOAD(offset=0xB1900)) + + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) + + Op.SSTORE(key=0xB20, value=Op.MLOAD(offset=0xB2000)) + + Op.STOP, + storage={ + 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + }, + balance=1000, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) tx = Transaction( sender=sender, @@ -589,7 +589,7 @@ def test_callcode_to_precompile_from_transaction( 0: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 1: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 2560: 1, - 2561: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2561: sender, 2562: 1, 2563: 1, 2564: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 @@ -610,7 +610,7 @@ def test_callcode_to_precompile_from_transaction( 2585: 1, 2592: 1, 2816: 1, - 2817: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2817: sender, 2818: 1, 2819: 1, 2820: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 diff --git a/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_called_contract.py b/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_called_contract.py index 369aff83331..8dcdce66aaf 100644 --- a/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_called_contract.py +++ b/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_called_contract.py @@ -56,108 +56,7 @@ def test_delegatecall_to_precompile_from_called_contract( gas_limit=10000000, ) - # Source: lll - # { - # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # (CALL (GAS) 0xb000000000000000000000000000000000000000 0 0 0 0 0) - # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.POP( - Op.CALL( - gas=Op.GAS, - address=0xB000000000000000000000000000000000000000, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - ) - + Op.SSTORE( - key=0x1, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.STOP, - storage={ - 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - }, - balance=1000, - nonce=0, - address=Address(0xC000000000000000000000000000000000000000), # noqa: E501 - ) - # Source: lll - # { - # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 - # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # ;; save results to store - # [[ 0x0a00 ]] @0x0a0000 [[ 0x0a11 ]] @0x0a1100 - # [[ 0x0a01 ]] @0x0a0100 [[ 0x0a12 ]] @0x0a1200 - # [[ 0x0a02 ]] @0x0a0200 [[ 0x0a13 ]] @0x0a1300 - # [[ 0x0a03 ]] @0x0a0300 [[ 0x0a14 ]] @0x0a1400 - # [[ 0x0a04 ]] @0x0a0400 [[ 0x0a15 ]] @0x0a1500 - # [[ 0x0a05 ]] @0x0a0500 [[ 0x0a16 ]] @0x0a1600 - # [[ 0x0a06 ]] @0x0a0600 [[ 0x0a17 ]] @0x0a1700 - # [[ 0x0a07 ]] @0x0a0700 [[ 0x0a18 ]] @0x0a1800 - # [[ 0x0a08 ]] @0x0a0800 [[ 0x0a19 ]] @0x0a1900 - # [[ 0x0a09 ]] @0x0a0900 [[ 0x0a20 ]] @0x0a2000 - # [[ 0x0a10 ]] @0x0a1000 - # } - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xA000000000000000000000000000000000000000, - args_offset=0x0, - args_size=0x0, - ret_offset=0xA0000, - ret_size=0x12020, - ) - ) - + Op.SSTORE( - key=0x1, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) - + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) - + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) - + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) - + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) - + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) - + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) - + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) - + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) - + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) - + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) - + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) - + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) - + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) - + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) - + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) - + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) - + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) - + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) - + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) - + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) - + Op.STOP, - storage={ - 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - }, - balance=1000, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ;; Recovery of ECDSA signature @@ -446,7 +345,108 @@ def test_delegatecall_to_precompile_from_called_contract( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { + # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 + # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # ;; save results to store + # [[ 0x0a00 ]] @0x0a0000 [[ 0x0a11 ]] @0x0a1100 + # [[ 0x0a01 ]] @0x0a0100 [[ 0x0a12 ]] @0x0a1200 + # [[ 0x0a02 ]] @0x0a0200 [[ 0x0a13 ]] @0x0a1300 + # [[ 0x0a03 ]] @0x0a0300 [[ 0x0a14 ]] @0x0a1400 + # [[ 0x0a04 ]] @0x0a0400 [[ 0x0a15 ]] @0x0a1500 + # [[ 0x0a05 ]] @0x0a0500 [[ 0x0a16 ]] @0x0a1600 + # [[ 0x0a06 ]] @0x0a0600 [[ 0x0a17 ]] @0x0a1700 + # [[ 0x0a07 ]] @0x0a0700 [[ 0x0a18 ]] @0x0a1800 + # [[ 0x0a08 ]] @0x0a0800 [[ 0x0a19 ]] @0x0a1900 + # [[ 0x0a09 ]] @0x0a0900 [[ 0x0a20 ]] @0x0a2000 + # [[ 0x0a10 ]] @0x0a1000 + # } + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=contract_2, + args_offset=0x0, + args_size=0x0, + ret_offset=0xA0000, + ret_size=0x12020, + ) + ) + + Op.SSTORE( + key=0x1, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) + + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) + + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) + + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) + + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) + + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) + + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) + + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) + + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) + + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) + + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) + + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) + + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) + + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) + + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) + + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) + + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) + + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) + + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) + + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) + + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) + + Op.STOP, + storage={ + 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + }, + balance=1000, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) + # Source: lll + # { + # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # (CALL (GAS) 0xb000000000000000000000000000000000000000 0 0 0 0 0) + # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.POP( + Op.CALL( + gas=Op.GAS, + address=contract_1, + value=0x0, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + ) + + Op.SSTORE( + key=0x1, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.STOP, + storage={ + 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + }, + balance=1000, + nonce=0, + address=Address(0xC000000000000000000000000000000000000000), # noqa: E501 + ) tx = Transaction( sender=sender, @@ -470,7 +470,7 @@ def test_delegatecall_to_precompile_from_called_contract( 0: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 1: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 2560: 1, - 2561: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2561: sender, 2562: 1, 2563: 1, 2564: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 diff --git a/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_contract_initialization.py b/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_contract_initialization.py index 461551da852..df7fecef5c6 100644 --- a/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_contract_initialization.py +++ b/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_contract_initialization.py @@ -54,6 +54,7 @@ def test_delegatecall_to_precompile_from_contract_initialization( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 @@ -377,7 +378,6 @@ def test_delegatecall_to_precompile_from_contract_initialization( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -403,7 +403,7 @@ def test_delegatecall_to_precompile_from_contract_initialization( 0: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 1: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 2560: 1, - 2561: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2561: sender, 2562: 1, 2563: 1, 2564: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 diff --git a/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_transaction.py b/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_transaction.py index 9d6cbaeba5a..427cc8978b5 100644 --- a/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_transaction.py +++ b/tests/ported_static/stStaticFlagEnabled/test_delegatecall_to_precompile_from_transaction.py @@ -54,73 +54,7 @@ def test_delegatecall_to_precompile_from_transaction( gas_limit=10000000, ) - # Source: lll - # { - # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 - # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 - # ;; save results to store - # [[ 0x0a00 ]] @0x0a0000 [[ 0x0a11 ]] @0x0a1100 - # [[ 0x0a01 ]] @0x0a0100 [[ 0x0a12 ]] @0x0a1200 - # [[ 0x0a02 ]] @0x0a0200 [[ 0x0a13 ]] @0x0a1300 - # [[ 0x0a03 ]] @0x0a0300 [[ 0x0a14 ]] @0x0a1400 - # [[ 0x0a04 ]] @0x0a0400 [[ 0x0a15 ]] @0x0a1500 - # [[ 0x0a05 ]] @0x0a0500 [[ 0x0a16 ]] @0x0a1600 - # [[ 0x0a06 ]] @0x0a0600 [[ 0x0a17 ]] @0x0a1700 - # [[ 0x0a07 ]] @0x0a0700 [[ 0x0a18 ]] @0x0a1800 - # [[ 0x0a08 ]] @0x0a0800 [[ 0x0a19 ]] @0x0a1900 - # [[ 0x0a09 ]] @0x0a0900 [[ 0x0a20 ]] @0x0a2000 - # [[ 0x0a10 ]] @0x0a1000 - # } - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE( - key=0x0, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.POP( - Op.STATICCALL( - gas=Op.GAS, - address=0xA000000000000000000000000000000000000000, - args_offset=0x0, - args_size=0x0, - ret_offset=0xA0000, - ret_size=0x12020, - ) - ) - + Op.SSTORE( - key=0x1, - value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 - ) - + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) - + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) - + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) - + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) - + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) - + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) - + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) - + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) - + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) - + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) - + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) - + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) - + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) - + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) - + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) - + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) - + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) - + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) - + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) - + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) - + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) - + Op.STOP, - storage={ - 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 - }, - balance=1000, - nonce=0, - address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 - ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { # ;; Recovery of ECDSA signature @@ -409,7 +343,73 @@ def test_delegatecall_to_precompile_from_transaction( nonce=0, address=Address(0xA000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { + # [[ 0x00 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # (STATICCALL (GAS) 0xa000000000000000000000000000000000000000 0 0 0x0a0000 0x012020) # noqa: E501 + # [[ 0x01 ]] 0xfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeedfeed # noqa: E501 + # ;; save results to store + # [[ 0x0a00 ]] @0x0a0000 [[ 0x0a11 ]] @0x0a1100 + # [[ 0x0a01 ]] @0x0a0100 [[ 0x0a12 ]] @0x0a1200 + # [[ 0x0a02 ]] @0x0a0200 [[ 0x0a13 ]] @0x0a1300 + # [[ 0x0a03 ]] @0x0a0300 [[ 0x0a14 ]] @0x0a1400 + # [[ 0x0a04 ]] @0x0a0400 [[ 0x0a15 ]] @0x0a1500 + # [[ 0x0a05 ]] @0x0a0500 [[ 0x0a16 ]] @0x0a1600 + # [[ 0x0a06 ]] @0x0a0600 [[ 0x0a17 ]] @0x0a1700 + # [[ 0x0a07 ]] @0x0a0700 [[ 0x0a18 ]] @0x0a1800 + # [[ 0x0a08 ]] @0x0a0800 [[ 0x0a19 ]] @0x0a1900 + # [[ 0x0a09 ]] @0x0a0900 [[ 0x0a20 ]] @0x0a2000 + # [[ 0x0a10 ]] @0x0a1000 + # } + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE( + key=0x0, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.POP( + Op.STATICCALL( + gas=Op.GAS, + address=contract_1, + args_offset=0x0, + args_size=0x0, + ret_offset=0xA0000, + ret_size=0x12020, + ) + ) + + Op.SSTORE( + key=0x1, + value=0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 + ) + + Op.SSTORE(key=0xA00, value=Op.MLOAD(offset=0xA0000)) + + Op.SSTORE(key=0xA11, value=Op.MLOAD(offset=0xA1100)) + + Op.SSTORE(key=0xA01, value=Op.MLOAD(offset=0xA0100)) + + Op.SSTORE(key=0xA12, value=Op.MLOAD(offset=0xA1200)) + + Op.SSTORE(key=0xA02, value=Op.MLOAD(offset=0xA0200)) + + Op.SSTORE(key=0xA13, value=Op.MLOAD(offset=0xA1300)) + + Op.SSTORE(key=0xA03, value=Op.MLOAD(offset=0xA0300)) + + Op.SSTORE(key=0xA14, value=Op.MLOAD(offset=0xA1400)) + + Op.SSTORE(key=0xA04, value=Op.MLOAD(offset=0xA0400)) + + Op.SSTORE(key=0xA15, value=Op.MLOAD(offset=0xA1500)) + + Op.SSTORE(key=0xA05, value=Op.MLOAD(offset=0xA0500)) + + Op.SSTORE(key=0xA16, value=Op.MLOAD(offset=0xA1600)) + + Op.SSTORE(key=0xA06, value=Op.MLOAD(offset=0xA0600)) + + Op.SSTORE(key=0xA17, value=Op.MLOAD(offset=0xA1700)) + + Op.SSTORE(key=0xA07, value=Op.MLOAD(offset=0xA0700)) + + Op.SSTORE(key=0xA18, value=Op.MLOAD(offset=0xA1800)) + + Op.SSTORE(key=0xA08, value=Op.MLOAD(offset=0xA0800)) + + Op.SSTORE(key=0xA19, value=Op.MLOAD(offset=0xA1900)) + + Op.SSTORE(key=0xA09, value=Op.MLOAD(offset=0xA0900)) + + Op.SSTORE(key=0xA20, value=Op.MLOAD(offset=0xA2000)) + + Op.SSTORE(key=0xA10, value=Op.MLOAD(offset=0xA1000)) + + Op.STOP, + storage={ + 0: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + 1: 0xDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAF, # noqa: E501 + }, + balance=1000, + nonce=0, + address=Address(0xB000000000000000000000000000000000000000), # noqa: E501 + ) tx = Transaction( sender=sender, @@ -426,7 +426,7 @@ def test_delegatecall_to_precompile_from_transaction( 0: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 1: 0xFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEEDFEED, # noqa: E501 2560: 1, - 2561: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 2561: sender, 2562: 1, 2563: 1, 2564: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000, # noqa: E501 diff --git a/tests/ported_static/stSystemOperationsTest/test_ab_acalls0.py b/tests/ported_static/stSystemOperationsTest/test_ab_acalls0.py index 848e0a4fb0b..863e937e7bb 100644 --- a/tests/ported_static/stSystemOperationsTest/test_ab_acalls0.py +++ b/tests/ported_static/stSystemOperationsTest/test_ab_acalls0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_ab_acalls0( ) -> None: """Test_ab_acalls0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -89,7 +86,6 @@ def test_ab_acalls0( nonce=0, address=Address(0x44EB1162303B6A60F2F8882D43D661787B3011E6), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_ab_acalls1.py b/tests/ported_static/stSystemOperationsTest/test_ab_acalls1.py index d66692566d6..cf256c209c9 100644 --- a/tests/ported_static/stSystemOperationsTest/test_ab_acalls1.py +++ b/tests/ported_static/stSystemOperationsTest/test_ab_acalls1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_ab_acalls1( ) -> None: """Test_ab_acalls1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -90,7 +87,6 @@ def test_ab_acalls1( nonce=0, address=Address(0x6236EA4EA8F3E5263ACB65A97ABE8683AB54D03A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_ab_acalls2.py b/tests/ported_static/stSystemOperationsTest/test_ab_acalls2.py index 5f84c8c62a9..879789fe147 100644 --- a/tests/ported_static/stSystemOperationsTest/test_ab_acalls2.py +++ b/tests/ported_static/stSystemOperationsTest/test_ab_acalls2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_ab_acalls2( ) -> None: """Test_ab_acalls2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -82,7 +79,6 @@ def test_ab_acalls2( nonce=0, address=Address(0xA890CEB693666313E0A5A1BE4F59F06C1E33F5C9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_ab_acalls3.py b/tests/ported_static/stSystemOperationsTest/test_ab_acalls3.py index 178bebebbd2..8f2b77d0966 100644 --- a/tests/ported_static/stSystemOperationsTest/test_ab_acalls3.py +++ b/tests/ported_static/stSystemOperationsTest/test_ab_acalls3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_ab_acalls3( ) -> None: """Test_ab_acalls3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -81,7 +78,6 @@ def test_ab_acalls3( nonce=0, address=Address(0xA890CEB693666313E0A5A1BE4F59F06C1E33F5C9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide0.py b/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide0.py index 984879a7704..a8876a5fd6a 100644 --- a/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide0.py +++ b/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_ab_acalls_suicide0( ) -> None: """Test_ab_acalls_suicide0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -90,7 +87,6 @@ def test_ab_acalls_suicide0( nonce=0, address=Address(0x24940009F045E4134ED2AB242BE610D312FE9A29), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide1.py b/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide1.py index f9d95b4f17f..a21d870ec37 100644 --- a/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide1.py +++ b/tests/ported_static/stSystemOperationsTest/test_ab_acalls_suicide1.py @@ -70,6 +70,7 @@ def test_ab_acalls_suicide1( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) [[ (PC) ]] (CALL (CALLDATALOAD 0) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 32 0 0) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -116,7 +117,6 @@ def test_ab_acalls_suicide1( nonce=0, address=Address(0x945304EB96065B2A98B57A48A06AE28D285A71B5), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx_data = [ Hash(0x186A0), diff --git a/tests/ported_static/stSystemOperationsTest/test_balance_input_address_too_big.py b/tests/ported_static/stSystemOperationsTest/test_balance_input_address_too_big.py index 2f3fc8f2825..30f5fa1470b 100644 --- a/tests/ported_static/stSystemOperationsTest/test_balance_input_address_too_big.py +++ b/tests/ported_static/stSystemOperationsTest/test_balance_input_address_too_big.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_balance_input_address_too_big( ) -> None: """Test_balance_input_address_too_big.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,9 +57,7 @@ def test_balance_input_address_too_big( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7B25BEF255E5917C960AEF5CEB690DCAA1C9EFF8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call10.py b/tests/ported_static/stSystemOperationsTest/test_call10.py index 340fbcfa9a7..dd81ff55302 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call10.py +++ b/tests/ported_static/stSystemOperationsTest/test_call10.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_call10( ) -> None: """Test_call10.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - addr = Address(0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0) - sender = EOA( - key=0xE7C72B378297589ACEE4E0BA3272841BCFC5E220F86DE253F890274CFEE9E474 - ) + sender = pre.fund_eoa(amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) env = Environment( fee_recipient=coinbase, @@ -47,8 +43,7 @@ def test_call10( gas_limit=9223372036854775807, ) - pre[sender] = Account(balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - pre[addr] = Account(balance=7000) + addr = pre.fund_eoa(amount=7000) # noqa: F841 # Source: lll # { (def 'i 0x80) (for {} (< @i 10) [i](+ @i 1) [[ 0 ]](CALL 0xfffffffffff 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -60,7 +55,7 @@ def test_call10( key=0x0, value=Op.CALL( gas=0xFFFFFFFFFFF, - address=0xD9B97C712EBCE43F3C19179BBEF44B550F9E8BC0, + address=addr, value=0x1, args_offset=0x0, args_size=0xC350, @@ -75,7 +70,6 @@ def test_call10( + Op.STOP, balance=1000, nonce=0, - address=Address(0xFDA03FA18CBDA0970E18071F363BEA4C9C90DFB6), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0.py index 3935cafb05d..908cfbee6d0 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_call_recursive_bomb0( ) -> None: """Test_call_recursive_bomb0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,23 +44,6 @@ def test_call_recursive_bomb0( gas_limit=11000000000, ) - # Source: lll - # { (CALL 100000000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=0x5F5E100, - address=0x783516813E6366B978F7101A6A12B4C8498B0283, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0x77359400, - nonce=0, - address=Address(0x6904E15F2A58E4C22DBB37FFEB39AB1F64002EB4), # noqa: E501 - ) # Source: lll # { [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 11000) (ADDRESS) 0 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -83,9 +63,23 @@ def test_call_recursive_bomb0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x783516813E6366B978F7101A6A12B4C8498B0283), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (CALL 100000000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=0x5F5E100, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0x77359400, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0_oog_at_max_call_depth.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0_oog_at_max_call_depth.py index 7f5b0f97019..36b1bca2d55 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0_oog_at_max_call_depth.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb0_oog_at_max_call_depth.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -36,9 +35,7 @@ def test_call_recursive_bomb0_oog_at_max_call_depth( ) -> None: """Test_call_recursive_bomb0_oog_at_max_call_depth.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -76,9 +73,7 @@ def test_call_recursive_bomb0_oog_at_max_call_depth( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x44872316EF00E0CD82E980900E6B85077B65E32F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb1.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb1.py index cec751bbdeb..e08a6fe1999 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb1.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_call_recursive_bomb1( ) -> None: """Test_call_recursive_bomb1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -66,9 +63,7 @@ def test_call_recursive_bomb1( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x3987AB80FA45389CE475FA3EDD3D507BEBC5EC3D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb2.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb2.py index e17103ce953..5fd784cedcc 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb2.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_call_recursive_bomb2( ) -> None: """Test_call_recursive_bomb2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -66,9 +63,7 @@ def test_call_recursive_bomb2( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0x3987AB80FA45389CE475FA3EDD3D507BEBC5EC3D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb3.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb3.py index e0531ead56f..ee666d8bf61 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb3.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_recursive_bomb3( ) -> None: """Test_call_recursive_bomb3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -65,9 +62,7 @@ def test_call_recursive_bomb3( + Op.STOP, balance=0x1312D00, nonce=0, - address=Address(0xBAA8243D50FDDB48ABD93764BBD97972DC654F67), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log.py index 6c1225f090a..1c6670b6d98 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_call_recursive_bomb_log( ) -> None: """Test_call_recursive_bomb_log.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,23 +44,6 @@ def test_call_recursive_bomb_log( gas_limit=100000000000, ) - # Source: lll - # { (CALL 100000000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=0x5F5E100, - address=0x5FE917D1EF791E524F7CB24CD012B5E5EC17000C, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0xD2E8FBE36BD16B24A1D34E4C06EC0741BD71C452), # noqa: E501 - ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (LOG0 0 32) [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 25000) (ADDRESS) 0 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -88,9 +68,23 @@ def test_call_recursive_bomb_log( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x5FE917D1EF791E524F7CB24CD012B5E5EC17000C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (CALL 100000000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=0x5F5E100, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log2.py b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log2.py index 6ab13415fc4..622f0ba202e 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log2.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_recursive_bomb_log2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_call_recursive_bomb_log2( ) -> None: """Test_call_recursive_bomb_log2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -47,23 +44,6 @@ def test_call_recursive_bomb_log2( gas_limit=11000000000, ) - # Source: lll - # { (CALL 100000000 23 0 0 0 0) } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.CALL( - gas=0x5F5E100, - address=0x4F046F9952C30DE8430278A978358E998784A4CA, - value=0x17, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, - ) - + Op.STOP, - balance=0x1312D00, - nonce=0, - address=Address(0xD2E8FBE36BD16B24A1D34E4C06EC0741BD71C452), # noqa: E501 - ) # Source: lll # { (MSTORE 0 (GAS)) (LOG0 0 32) [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 25000) (ADDRESS) 0 0 0 0 0) } # noqa: E501 addr = pre.deploy_contract( # noqa: F841 @@ -85,9 +65,23 @@ def test_call_recursive_bomb_log2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x4F046F9952C30DE8430278A978358E998784A4CA), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) + # Source: lll + # { (CALL 100000000 23 0 0 0 0) } # noqa: E501 + target = pre.deploy_contract( # noqa: F841 + code=Op.CALL( + gas=0x5F5E100, + address=addr, + value=0x17, + args_offset=0x0, + args_size=0x0, + ret_offset=0x0, + ret_size=0x0, + ) + + Op.STOP, + balance=0x1312D00, + nonce=0, + ) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator0.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator0.py index 771235eeab1..891c3e8626a 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator0.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_to_name_registrator0( ) -> None: """Test_call_to_name_registrator0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,21 @@ def test_call_to_name_registrator0( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100000 23 0 64 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +73,7 @@ def test_call_to_name_registrator0( key=0x0, value=Op.CALL( gas=0x186A0, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -72,25 +84,7 @@ def test_call_to_name_registrator0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF32CBF847E357D4AC1A41D8202AA2EE516DC32D1), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_left.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_left.py index 72ab989003a..74d9a7cdb21 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_left.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_left.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_address_too_big_left( ) -> None: """Test_call_to_name_registrator_address_too_big_left.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,7 +51,6 @@ def test_call_to_name_registrator_address_too_big_left( code="", balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC8266873D1C906E93364246E671C3D9802AABE37), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,9 +66,7 @@ def test_call_to_name_registrator_address_too_big_left( ), balance=23, nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_right.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_right.py index e145368f9a1..2d9970a1547 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_right.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_address_too_big_right.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_address_too_big_right( ) -> None: """Test_call_to_name_registrator_address_too_big_right.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -74,7 +71,6 @@ def test_call_to_name_registrator_address_too_big_right( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2308DA9C42E252155BAED45BCA437EF6CF3FB0B2), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -90,9 +86,7 @@ def test_call_to_name_registrator_address_too_big_right( ), balance=23, nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_mem_oog_and_insufficient_balance.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_mem_oog_and_insufficient_balance.py index fc2cb7a07ef..6a4037f580f 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_mem_oog_and_insufficient_balance.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_mem_oog_and_insufficient_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_mem_oog_and_insufficient_balance( ) -> None: """Test_call_to_name_registrator_mem_oog_and_insufficient_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_mem_oog_and_insufficient_balance( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 0xffffffffff 23 0 0xffffffffffff 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_mem_oog_and_insufficient_balance( key=0x0, value=Op.CALL( gas=0xFFFFFFFFFF, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0xFFFFFFFFFFFF, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_mem_oog_and_insufficient_balance( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x74859A27DC2F1EE153CF9B4E4BAC1133F3B01B17), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory0.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory0.py index 789935362f5..cb77992a35a 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory0.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_not_much_memory0( ) -> None: """Test_call_to_name_registrator_not_much_memory0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_not_much_memory0( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 23 0 64 987654 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_not_much_memory0( key=0x0, value=Op.CALL( gas=0x1F4, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_not_much_memory0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x410DCC04FB8FC328D8EB131B4D9EA4204FBDAF2F), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory1.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory1.py index fec6734b3a1..4d0137b3f55 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory1.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_not_much_memory1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_not_much_memory1( ) -> None: """Test_call_to_name_registrator_not_much_memory1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_not_much_memory1( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 23 987654 0 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_not_much_memory1( key=0x0, value=Op.CALL( gas=0x1F4, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0xF1206, args_size=0x0, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_not_much_memory1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8E2AF1ED48CB5567A2BC09CDE959DC7B5E5557BA), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_out_of_gas.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_out_of_gas.py index 33032494655..ea3c2132fff 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_out_of_gas.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_out_of_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_out_of_gas( ) -> None: """Test_call_to_name_registrator_out_of_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_out_of_gas( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100 23 0 64 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_out_of_gas( key=0x0, value=Op.CALL( gas=0x64, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_out_of_gas( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x9B360D4F319B3F0A24F02939650CF93BBDB82022), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory0.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory0.py index e0b931163fd..bc845d4f41c 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory0.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_too_much_memory0( ) -> None: """Test_call_to_name_registrator_too_much_memory0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_too_much_memory0( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 23 987654321 64 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_too_much_memory0( key=0x0, value=Op.CALL( gas=0x1F4, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x3ADE68B1, args_size=0x40, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_too_much_memory0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x00154EF29A79F34CF1B7A570C5DF358EB7CD5108), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory1.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory1.py index fd2999e5e28..1c7a8f05f29 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory1.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_too_much_memory1( ) -> None: """Test_call_to_name_registrator_too_much_memory1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_too_much_memory1( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 23 0 9865432 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_too_much_memory1( key=0x0, value=Op.CALL( gas=0x1F4, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x9688D8, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_too_much_memory1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x375D9C49DD17C920398B81BA030BF150BC16AF59), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory2.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory2.py index 26d1a537adf..a7d91e4f5fc 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory2.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_too_much_memory2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_name_registrator_too_much_memory2( ) -> None: """Test_call_to_name_registrator_too_much_memory2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_call_to_name_registrator_too_much_memory2( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 23 0 64 987654 1) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_call_to_name_registrator_too_much_memory2( key=0x0, value=Op.CALL( gas=0x1F4, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -74,25 +86,7 @@ def test_call_to_name_registrator_too_much_memory2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x12798480F9B1E6534F2D528F84EF12BDA7F49A71), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_zeor_size_mem_expansion.py b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_zeor_size_mem_expansion.py index 310aba43cc6..9fabe5dbf41 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_zeor_size_mem_expansion.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_name_registrator_zeor_size_mem_expansion.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_call_to_name_registrator_zeor_size_mem_expansion( ) -> None: """Test_call_to_name_registrator_zeor_size_mem_expansion.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,6 +70,21 @@ def test_call_to_name_registrator_zeor_size_mem_expansion( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 5000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,7 +100,7 @@ def test_call_to_name_registrator_zeor_size_mem_expansion( key=0x0, value=Op.CALL( gas=0x1388, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -99,25 +111,7 @@ def test_call_to_name_registrator_zeor_size_mem_expansion( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x04C4CBDF0B0877C4619B10524DC13744EE0B69F6), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_return1.py b/tests/ported_static/stSystemOperationsTest/test_call_to_return1.py index 32450e9fb9b..b3529534548 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_return1.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_return1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_to_return1( ) -> None: """Test_call_to_return1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_call_to_return1( gas_limit=10000000, ) + # Source: raw + # 0x6001600155602a601f536001601ff3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x1F, value=0x2A) + + Op.RETURN(offset=0x1F, size=0x1), + balance=23, + nonce=0, + ) # Source: lll # { [[ 0 ]] (CALL 1000 23 0 0 31 1) [[ 1 ]] @0 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +59,7 @@ def test_call_to_return1( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x64963D42A3DFF7BF49CE946E12F6C9034C746888, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -65,19 +71,7 @@ def test_call_to_return1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xE31AFA4922F77F6C0EC198294B373D2AB9DE47D2), # noqa: E501 - ) - # Source: raw - # 0x6001600155602a601f536001601ff3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x1F, value=0x2A) - + Op.RETURN(offset=0x1F, size=0x1), - balance=23, - nonce=0, - address=Address(0x64963D42A3DFF7BF49CE946E12F6C9034C746888), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump0.py b/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump0.py index 4e9b48bd915..ae214e384d9 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump0.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_return1_for_dynamic_jump0( ) -> None: """Test_call_to_return1_for_dynamic_jump0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_call_to_return1_for_dynamic_jump0( gas_limit=10000000, ) + # Source: raw + # 0x6001600155602a601f536001601ff3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x1F, value=0x2A) + + Op.RETURN(offset=0x1F, size=0x1), + balance=23, + nonce=0, + ) # Source: raw # 0x6001601f600060006017736103e8f1600055600051565b6023602355 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +61,7 @@ def test_call_to_return1_for_dynamic_jump0( key=0x0, value=Op.CALL( gas=0x3E8, - address=0x64963D42A3DFF7BF49CE946E12F6C9034C746888, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -68,19 +74,7 @@ def test_call_to_return1_for_dynamic_jump0( + Op.SSTORE(key=0x23, value=0x23), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x6D968BCF609007EC874B2AC0216C27E131C3BE4C), # noqa: E501 - ) - # Source: raw - # 0x6001600155602a601f536001601ff3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x1F, value=0x2A) - + Op.RETURN(offset=0x1F, size=0x1), - balance=23, - nonce=0, - address=Address(0x64963D42A3DFF7BF49CE946E12F6C9034C746888), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump1.py b/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump1.py index 9b20b5dff92..af3c9931b0c 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump1.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_to_return1_for_dynamic_jump1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_call_to_return1_for_dynamic_jump1( ) -> None: """Test_call_to_return1_for_dynamic_jump1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,15 @@ def test_call_to_return1_for_dynamic_jump1( gas_limit=10000000, ) + # Source: raw + # 0x6001600155602b601f536001601ff3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x1F, value=0x2B) + + Op.RETURN(offset=0x1F, size=0x1), + balance=23, + nonce=0, + ) # Source: raw # 0x6001601f600060006017736103e8f160005560005156605b6023602355 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +61,7 @@ def test_call_to_return1_for_dynamic_jump1( key=0x0, value=Op.CALL( gas=0x3E8, - address=0xD43411A40A68E9CBA15440E3C34A74A4DC5F79DD, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -68,19 +74,7 @@ def test_call_to_return1_for_dynamic_jump1( + Op.SSTORE(key=0x23, value=0x23), balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x7BC307EC814CE37F4553993AC5612B763F18165D), # noqa: E501 - ) - # Source: raw - # 0x6001600155602b601f536001601ff3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x1F, value=0x2B) - + Op.RETURN(offset=0x1F, size=0x1), - balance=23, - nonce=0, - address=Address(0xD43411A40A68E9CBA15440E3C34A74A4DC5F79DD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_call_value.py b/tests/ported_static/stSystemOperationsTest/test_call_value.py index 2a1cfb7f123..5d9854f17dd 100644 --- a/tests/ported_static/stSystemOperationsTest/test_call_value.py +++ b/tests/ported_static/stSystemOperationsTest/test_call_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_call_value( ) -> None: """Test_call_value.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_call_value( code=Op.SSTORE(key=0x0, value=Op.CALLVALUE) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xF7CF560CCB3853B2D9E5C4A647FB7CC7C7F935D3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_callcode_to0.py b/tests/ported_static/stSystemOperationsTest/test_callcode_to0.py index 0d9c13b1cf8..36358ca65e4 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callcode_to0.py +++ b/tests/ported_static/stSystemOperationsTest/test_callcode_to0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_to0( ) -> None: """Test_callcode_to0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -64,9 +61,7 @@ def test_callcode_to0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xEC64B74B6AF4B537E54DE566819D04D55F6E8CD9), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator0.py b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator0.py index e4d2c631b57..facb2c858a8 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator0.py +++ b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_to_name_registrator0( ) -> None: """Test_callcode_to_name_registrator0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,6 +45,21 @@ def test_callcode_to_name_registrator0( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 23 0 64 64 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -63,7 +75,7 @@ def test_callcode_to_name_registrator0( key=0x0, value=Op.CALLCODE( gas=0x3E8, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -74,25 +86,7 @@ def test_callcode_to_name_registrator0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC390A3ED1719280F32A2A74CBB1F8A3E7B1F002E), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_left.py b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_left.py index fd7d66b197a..e1ae55fb0ec 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_left.py +++ b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_left.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_to_name_registrator_addres_too_big_left( ) -> None: """Test_callcode_to_name_registrator_addres_too_big_left.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,7 +51,6 @@ def test_callcode_to_name_registrator_addres_too_big_left( code="", balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCF5A2A9C286222B44BB932D847C4E05A2353B673), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -70,9 +66,7 @@ def test_callcode_to_name_registrator_addres_too_big_left( ), balance=23, nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_right.py b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_right.py index af2439075a1..218e07731d1 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_right.py +++ b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_addres_too_big_right.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_callcode_to_name_registrator_addres_too_big_right( ) -> None: """Test_callcode_to_name_registrator_addres_too_big_right.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -74,7 +71,6 @@ def test_callcode_to_name_registrator_addres_too_big_right( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xC8DE9EA9779E64CF3E682F2157A7D38205AF9444), # noqa: E501 ) # Source: raw # 0x6000355415600957005b60203560003555 @@ -90,9 +86,7 @@ def test_callcode_to_name_registrator_addres_too_big_right( ), balance=23, nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_zero_mem_expanion.py b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_zero_mem_expanion.py index ce8e642f657..e00c3e9847b 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_zero_mem_expanion.py +++ b/tests/ported_static/stSystemOperationsTest/test_callcode_to_name_registrator_zero_mem_expanion.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -60,9 +59,7 @@ def test_callcode_to_name_registrator_zero_mem_expanion( ) -> None: """Test_callcode_to_name_registrator_zero_mem_expanion.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,6 +70,21 @@ def test_callcode_to_name_registrator_zero_mem_expanion( gas_limit=10000000, ) + # Source: raw + # 0x6000355415600957005b60203560003555 + addr = pre.deploy_contract( # noqa: F841 + code=Op.JUMPI( + pc=0x9, + condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), + ) + + Op.STOP + + Op.JUMPDEST + + Op.SSTORE( + key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) + ), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 5000 23 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -88,7 +100,7 @@ def test_callcode_to_name_registrator_zero_mem_expanion( key=0x0, value=Op.CALLCODE( gas=0x1388, - address=0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E, + address=addr, value=0x17, args_offset=0x0, args_size=0x0, @@ -99,25 +111,7 @@ def test_callcode_to_name_registrator_zero_mem_expanion( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x82F454DEA4D0958BCED42315A0E580848B2C440C), # noqa: E501 - ) - # Source: raw - # 0x6000355415600957005b60203560003555 - addr = pre.deploy_contract( # noqa: F841 - code=Op.JUMPI( - pc=0x9, - condition=Op.ISZERO(Op.SLOAD(key=Op.CALLDATALOAD(offset=0x0))), - ) - + Op.STOP - + Op.JUMPDEST - + Op.SSTORE( - key=Op.CALLDATALOAD(offset=0x0), value=Op.CALLDATALOAD(offset=0x20) - ), - balance=23, - nonce=0, - address=Address(0x15EB18969E0925C8E4A76FD7CBCE36A2B056B27E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stSystemOperationsTest/test_callcode_to_return1.py b/tests/ported_static/stSystemOperationsTest/test_callcode_to_return1.py index 1096f97d7a0..0b59d077378 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callcode_to_return1.py +++ b/tests/ported_static/stSystemOperationsTest/test_callcode_to_return1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callcode_to_return1( ) -> None: """Test_callcode_to_return1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,15 @@ def test_callcode_to_return1( gas_limit=30000000, ) + # Source: raw + # 0x6001600155603760005360026000f3 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.RETURN(offset=0x0, size=0x2), + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 50000 23 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +67,7 @@ def test_callcode_to_return1( key=0x0, value=Op.CALLCODE( gas=0xC350, - address=0x896F13E800125C0CCEC44F3C434335F0A97BC1B, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -72,19 +78,7 @@ def test_callcode_to_return1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8B09C7AB22E22458D6DC0756D12127E14CBD6A50), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f3 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.RETURN(offset=0x0, size=0x2), - balance=23, - nonce=0, - address=Address(0x0896F13E800125C0CCEC44F3C434335F0A97BC1B), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_caller_account_balance.py b/tests/ported_static/stSystemOperationsTest/test_caller_account_balance.py index f4da1bef24e..9e98caf0590 100644 --- a/tests/ported_static/stSystemOperationsTest/test_caller_account_balance.py +++ b/tests/ported_static/stSystemOperationsTest/test_caller_account_balance.py @@ -46,6 +46,7 @@ def test_caller_account_balance( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[0]] (balance (caller)) } target = pre.deploy_contract( # noqa: F841 @@ -54,7 +55,6 @@ def test_caller_account_balance( nonce=0, address=Address(0x13AB36BAF5501D0A3C5CD05BE4788496F99A4E34), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_callto_return2.py b/tests/ported_static/stSystemOperationsTest/test_callto_return2.py index 1397ed5e9b9..8eac5f4191f 100644 --- a/tests/ported_static/stSystemOperationsTest/test_callto_return2.py +++ b/tests/ported_static/stSystemOperationsTest/test_callto_return2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_callto_return2( ) -> None: """Test_callto_return2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,17 @@ def test_callto_return2( gas_limit=10000000, ) + # Source: raw + # 0x6001600155603760005360026000f2 + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x1) + + Op.MSTORE8(offset=0x0, value=0x37) + + Op.PUSH1[0x2] + + Op.PUSH1[0x0] + + Op.CALLCODE, + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 5000 23 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +69,7 @@ def test_callto_return2( key=0x0, value=Op.CALL( gas=0x1388, - address=0x2B45331C406DF38B99656C3ED3A97EF219979232, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -72,21 +80,7 @@ def test_callto_return2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xBD44C6EB4F918AA9AB1DA6BCA875839B1250E4E9), # noqa: E501 - ) - # Source: raw - # 0x6001600155603760005360026000f2 - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x1) - + Op.MSTORE8(offset=0x0, value=0x37) - + Op.PUSH1[0x2] - + Op.PUSH1[0x0] - + Op.CALLCODE, - balance=23, - nonce=0, - address=Address(0x2B45331C406DF38B99656C3ED3A97EF219979232), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_create_hash_collision.py b/tests/ported_static/stSystemOperationsTest/test_create_hash_collision.py index 347dbd520fb..c05c75a9bd4 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_hash_collision.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_hash_collision.py @@ -48,6 +48,7 @@ def test_create_hash_collision( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (MSTORE 0 0x601080600c6000396000f3006000355415600957005b60203560003555) [[ 0 ]] (CREATE 23 3 29) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -63,7 +64,6 @@ def test_create_hash_collision( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x60016001016055 contract_1 = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator.py index acef43618f1..8aceb541019 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -34,9 +34,7 @@ def test_create_name_registrator( """Test_create_name_registrator.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,9 +58,7 @@ def test_create_name_registrator( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -74,7 +70,9 @@ def test_create_name_registrator( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), } diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_oog_mem_expansion_oov.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_oog_mem_expansion_oov.py index 9ab05eb2347..24c66dc8788 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_oog_mem_expansion_oov.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_oog_mem_expansion_oov.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_name_registrator_oog_mem_expansion_oov( ) -> None: """Test_create_name_registrator_oog_mem_expansion_oov.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -64,9 +61,7 @@ def test_create_name_registrator_oog_mem_expansion_oov( + Op.STOP, balance=10000, nonce=0, - address=Address(0xB8D613D3333F8CE34BC851256B3096FFA7932F6E), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds0.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds0.py index c6bc0bce003..b65dfdacd85 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds0.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_name_registrator_out_of_memory_bonds0( ) -> None: """Test_create_name_registrator_out_of_memory_bonds0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,9 +59,7 @@ def test_create_name_registrator_out_of_memory_bonds0( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8593273FE085739B33E6A5D293BB84F3224BA9AD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds1.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds1.py index 2a95b0d1bf5..4fd27bfd082 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds1.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_out_of_memory_bonds1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_name_registrator_out_of_memory_bonds1( ) -> None: """Test_create_name_registrator_out_of_memory_bonds1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -62,9 +59,7 @@ def test_create_name_registrator_out_of_memory_bonds1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x2D0C02BA282D613FFACB6BA383F709ADE6E7522C), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_value_too_high.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_value_too_high.py index d2b38884cf5..3b5b41459ef 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_value_too_high.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_value_too_high.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_create_name_registrator_value_too_high( """Test_create_name_registrator_value_too_high.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -64,9 +61,7 @@ def test_create_name_registrator_value_too_high( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem.py index b3f84a01d73..fc00fef4328 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -36,9 +36,7 @@ def test_create_name_registrator_zero_mem( """Test_create_name_registrator_zero_mem.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,9 +58,7 @@ def test_create_name_registrator_zero_mem( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -74,7 +70,9 @@ def test_create_name_registrator_zero_mem( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), } diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem2.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem2.py index 33b90d91205..874b1f517c4 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem2.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -36,9 +36,7 @@ def test_create_name_registrator_zero_mem2( """Test_create_name_registrator_zero_mem2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -67,9 +65,7 @@ def test_create_name_registrator_zero_mem2( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -81,7 +77,9 @@ def test_create_name_registrator_zero_mem2( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), } diff --git a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem_expansion.py b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem_expansion.py index 7e55ce0a91f..fa489f7aa9e 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem_expansion.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_name_registrator_zero_mem_expansion.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -15,6 +14,7 @@ Environment, StateTestFiller, Transaction, + compute_create_address, ) from execution_testing.vm import Op @@ -36,9 +36,7 @@ def test_create_name_registrator_zero_mem_expansion( """Test_create_name_registrator_zero_mem_expansion.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -60,9 +58,7 @@ def test_create_name_registrator_zero_mem_expansion( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -74,7 +70,9 @@ def test_create_name_registrator_zero_mem_expansion( post = { contract_0: Account( - storage={0: 0xD2571607E241ECF590ED94B12D87C94BABE36DB6}, + storage={ + 0: compute_create_address(address=contract_0, nonce=0), + }, nonce=1, ), } diff --git a/tests/ported_static/stSystemOperationsTest/test_create_with_invalid_opcode.py b/tests/ported_static/stSystemOperationsTest/test_create_with_invalid_opcode.py index ce25374333f..922a8460afc 100644 --- a/tests/ported_static/stSystemOperationsTest/test_create_with_invalid_opcode.py +++ b/tests/ported_static/stSystemOperationsTest/test_create_with_invalid_opcode.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_create_with_invalid_opcode( ) -> None: """Test_create_with_invalid_opcode.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -56,9 +53,7 @@ def test_create_with_invalid_opcode( + Op.CREATE, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xCC73F3508071F505FB5A5C6108B9444FE05FDD4D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_current_account_balance.py b/tests/ported_static/stSystemOperationsTest/test_current_account_balance.py index bd143302c5c..f61a6e27b87 100644 --- a/tests/ported_static/stSystemOperationsTest/test_current_account_balance.py +++ b/tests/ported_static/stSystemOperationsTest/test_current_account_balance.py @@ -46,6 +46,7 @@ def test_current_account_balance( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[0]] (balance (address)) } target = pre.deploy_contract( # noqa: F841 @@ -55,7 +56,6 @@ def test_current_account_balance( nonce=0, address=Address(0xFA1ADC30EF8A61E7996FA659B532621C0816E14D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_test.py b/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_test.py index 757a04dd409..49d06c563b2 100644 --- a/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_test.py +++ b/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_test.py @@ -116,6 +116,7 @@ def test_double_selfdestruct_test( gas_limit=10000000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) # Source: yul # berlin # { @@ -226,7 +227,6 @@ def test_double_selfdestruct_test( nonce=1, address=Address(0x000000000000000000000000000000000000C0DE), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_touch_paris.py b/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_touch_paris.py index 2f2cc390afd..26364936fba 100644 --- a/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_touch_paris.py +++ b/tests/ported_static/stSystemOperationsTest/test_double_selfdestruct_touch_paris.py @@ -85,6 +85,23 @@ def test_double_selfdestruct_touch_paris( ) pre[sender] = Account(balance=0x5F5E102) + pre[empty_account_1] = Account(balance=10) + pre[empty_account_2] = Account(balance=10) + # Source: yul + # berlin + # { + # let index := add(sload(0), 1) + # sstore(0, index) + # selfdestruct(sload(index)) + # } + addr = pre.deploy_contract( # noqa: F841 + code=Op.ADD(Op.SLOAD(key=0x0), 0x1) + + Op.SSTORE(key=0x0, value=Op.DUP1) + + Op.SELFDESTRUCT(address=Op.SLOAD), + storage={0: 0, 1: empty_account_1, 2: empty_account_2}, + nonce=0, + address=Address(0x29E4504A3D2A0E0AE0EBBBEFEDD4570639B3EBEE), # noqa: E501 + ) # Source: yul # berlin # { @@ -119,27 +136,6 @@ def test_double_selfdestruct_touch_paris( nonce=0, address=Address(0x8EC7465877D3957084DC907C0F6D8F2911A17A52), # noqa: E501 ) - # Source: yul - # berlin - # { - # let index := add(sload(0), 1) - # sstore(0, index) - # selfdestruct(sload(index)) - # } - addr = pre.deploy_contract( # noqa: F841 - code=Op.ADD(Op.SLOAD(key=0x0), 0x1) - + Op.SSTORE(key=0x0, value=Op.DUP1) - + Op.SELFDESTRUCT(address=Op.SLOAD), - storage={ - 0: 0, - 1: 0x68FA59E127B7526718EB0A4E113DF5793628CB91, - 2: 0x76FAE819612A29489A1A43208613D8F8557B8898, - }, - nonce=0, - address=Address(0x29E4504A3D2A0E0AE0EBBBEFEDD4570639B3EBEE), # noqa: E501 - ) - pre[empty_account_1] = Account(balance=10) - pre[empty_account_2] = Account(balance=10) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stSystemOperationsTest/test_extcodecopy.py b/tests/ported_static/stSystemOperationsTest/test_extcodecopy.py index 4b098947105..4e673f6ee76 100644 --- a/tests/ported_static/stSystemOperationsTest/test_extcodecopy.py +++ b/tests/ported_static/stSystemOperationsTest/test_extcodecopy.py @@ -46,6 +46,7 @@ def test_extcodecopy( gas_limit=1478962728, ) + pre[sender] = Account(balance=0x4F6CA7B90CEB5FD4) # Source: raw # 0x7f15688566a82f5f946c68028bf626b349e495daa43e33529a76437ac416cd1b7d6e7dae7454bb193b1c28e64a6a935bc373cea0c5cc171fa61277e5604a3bc8aef4de3d38820658600b80797ada6e82e95f6520383f95f5c7dae56b4dc13b6f22ecabfce07c3cff51 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -138,7 +139,6 @@ def test_extcodecopy( nonce=221, address=Address(0x5B400827141A956CEB3E889AD3E1707AEE1A575C), # noqa: E501 ) - pre[sender] = Account(balance=0x4F6CA7B90CEB5FD4) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_multi_selfdestruct.py b/tests/ported_static/stSystemOperationsTest/test_multi_selfdestruct.py index ff1e290c226..3ce56c97495 100644 --- a/tests/ported_static/stSystemOperationsTest/test_multi_selfdestruct.py +++ b/tests/ported_static/stSystemOperationsTest/test_multi_selfdestruct.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -81,9 +80,7 @@ def test_multi_selfdestruct( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x000000000000000000000000000000000000DEAD) contract_1 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -179,7 +176,7 @@ def test_multi_selfdestruct( key=0x0, value=Op.CALL( gas=Op.GAS, - address=0xDEAD, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP2, args_size=0x3, @@ -188,7 +185,7 @@ def test_multi_selfdestruct( ), ) + Op.SSTORE(key=0x1, value=Op.BALANCE(address=0x1000)) - + Op.SSTORE(key=0x2, value=Op.BALANCE(address=0xDEAD)) + + Op.SSTORE(key=0x2, value=Op.BALANCE(address=contract_0)) + Op.SHR(0xF8, Op.CALLDATALOAD(offset=0x0)) + Op.JUMPI(pc=0xCE, condition=Op.EQ(0x1, Op.DUP1)) + Op.JUMPI(pc=0xBC, condition=Op.EQ(0x2, Op.DUP1)) @@ -202,7 +199,7 @@ def test_multi_selfdestruct( + Op.MSTORE8(offset=0x2, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xDEAD, + address=contract_0, value=0x2, args_offset=Op.DUP2, args_size=0x3, @@ -213,7 +210,7 @@ def test_multi_selfdestruct( + Op.PUSH1[0x10] + Op.SSTORE + Op.SSTORE(key=0x11, value=Op.BALANCE(address=0x1000)) - + Op.SSTORE(key=0x12, value=Op.BALANCE(address=0xDEAD)) + + Op.SSTORE(key=0x12, value=Op.BALANCE(address=contract_0)) + Op.SSTORE(key=0x13, value=Op.BALANCE(address=0x1001)) + Op.STOP + Op.JUMPDEST @@ -222,7 +219,7 @@ def test_multi_selfdestruct( + Op.MSTORE8(offset=0x2, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xDEAD, + address=contract_0, value=Op.DUP1, args_offset=Op.DUP2, args_size=0x3, @@ -235,7 +232,7 @@ def test_multi_selfdestruct( + Op.MSTORE8(offset=0x2, value=0x1) + Op.CALL( gas=Op.GAS, - address=0xDEAD, + address=contract_0, value=0x2, args_offset=Op.DUP2, args_size=0x3, @@ -247,7 +244,7 @@ def test_multi_selfdestruct( + Op.POP + Op.CALL( gas=Op.GAS, - address=0xDEAD, + address=contract_0, value=0x2, args_offset=Op.DUP2, args_size=0x3, @@ -259,7 +256,7 @@ def test_multi_selfdestruct( + Op.POP + Op.CALL( gas=Op.GAS, - address=0xDEAD, + address=contract_0, value=0x2, args_offset=Op.DUP1, args_size=0x3, @@ -277,9 +274,7 @@ def test_multi_selfdestruct( }, balance=0x5F5E100, nonce=1, - address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stSystemOperationsTest/test_post_to_return1.py b/tests/ported_static/stSystemOperationsTest/test_post_to_return1.py index 8dfb7fd0f46..d267cc95973 100644 --- a/tests/ported_static/stSystemOperationsTest/test_post_to_return1.py +++ b/tests/ported_static/stSystemOperationsTest/test_post_to_return1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_post_to_return1( ) -> None: """Test_post_to_return1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,16 @@ def test_post_to_return1( gas_limit=10000000, ) + # Source: raw + # 0x603760005360026000f2 + addr = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE8(offset=0x0, value=0x37) + + Op.PUSH1[0x2] + + Op.PUSH1[0x0] + + Op.CALLCODE, + balance=23, + nonce=0, + ) # Source: lll # { (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[1]](CALL 30000 23 0 64 0 0 ) [[2]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -61,7 +68,7 @@ def test_post_to_return1( key=0x1, value=Op.CALL( gas=0x7530, - address=0x1EC76F80449BF4D3EDF503813E06C0D4373FDF3D, + address=addr, value=0x17, args_offset=0x0, args_size=0x40, @@ -73,20 +80,7 @@ def test_post_to_return1( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3AE2F90D9F77554F1E03D5A4868CA5F0C4E14039), # noqa: E501 - ) - # Source: raw - # 0x603760005360026000f2 - addr = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE8(offset=0x0, value=0x37) - + Op.PUSH1[0x2] - + Op.PUSH1[0x0] - + Op.CALLCODE, - balance=23, - nonce=0, - address=Address(0x1EC76F80449BF4D3EDF503813E06C0D4373FDF3D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_return0.py b/tests/ported_static/stSystemOperationsTest/test_return0.py index 487a7573958..e9072df5790 100644 --- a/tests/ported_static/stSystemOperationsTest/test_return0.py +++ b/tests/ported_static/stSystemOperationsTest/test_return0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_return0( ) -> None: """Test_return0.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_return0( + Op.STOP, balance=23, nonce=0, - address=Address(0xB594E8F0AFCE73D002C12C76050E15BEAA8B21F7), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_return1.py b/tests/ported_static/stSystemOperationsTest/test_return1.py index 7be9ddf697b..aa776c0a646 100644 --- a/tests/ported_static/stSystemOperationsTest/test_return1.py +++ b/tests/ported_static/stSystemOperationsTest/test_return1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_return1( ) -> None: """Test_return1.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_return1( + Op.STOP, balance=23, nonce=0, - address=Address(0xE50C84B8B720A23E1BFB8BFAAEE5F44B6DD44139), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_return2.py b/tests/ported_static/stSystemOperationsTest/test_return2.py index bc4e623e529..3ccc5f27fea 100644 --- a/tests/ported_static/stSystemOperationsTest/test_return2.py +++ b/tests/ported_static/stSystemOperationsTest/test_return2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_return2( ) -> None: """Test_return2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_return2( + Op.STOP, balance=23, nonce=0, - address=Address(0x230FCB597DD38307E287C745B56DEB09A8A93EC0), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_address.py b/tests/ported_static/stSystemOperationsTest/test_suicide_address.py index e2c9c6aa486..d381dea5437 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_address.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_address.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_suicide_address( ) -> None: """Test_suicide_address.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_suicide_address( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xAB0CEFFAA4BD275F5819261E06029439647112C1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_caller.py b/tests/ported_static/stSystemOperationsTest/test_suicide_caller.py index df46e450717..34f17745993 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_caller.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_caller.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_suicide_caller( ) -> None: """Test_suicide_caller.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_suicide_caller( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x26A4C0125CC2AC853D5C04C3A710E7628EE352A3), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -68,11 +63,7 @@ def test_suicide_caller( post = { sender: Account(nonce=1), - target: Account( - storage={0: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297}, - balance=0, - nonce=0, - ), + target: Account(storage={0: sender}, balance=0, nonce=0), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_left.py b/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_left.py index 3527b32bbe2..10c4ff37394 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_left.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_left.py @@ -49,6 +49,7 @@ def test_suicide_caller_addres_too_big_left( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[0]] (CALLER) (SELFDESTRUCT 0xaaa94f5374fce5edbc8e2a8697c15331677e6ebf0b)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +60,6 @@ def test_suicide_caller_addres_too_big_left( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -71,11 +71,7 @@ def test_suicide_caller_addres_too_big_left( post = { sender: Account(nonce=1), - contract_0: Account( - storage={0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B}, - balance=0, - nonce=0, - ), + contract_0: Account(storage={0: sender}, balance=0, nonce=0), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_right.py b/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_right.py index d15d2aae98d..84f360bf6b1 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_right.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_caller_addres_too_big_right.py @@ -49,6 +49,7 @@ def test_suicide_caller_addres_too_big_right( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { [[0]] (CALLER) (SELFDESTRUCT 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0baa)} # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -59,7 +60,6 @@ def test_suicide_caller_addres_too_big_right( nonce=0, address=Address(0x095E7BAEA6A6C7C4C2DFEB977EFAC326AF552D87), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_not_existing_account.py b/tests/ported_static/stSystemOperationsTest/test_suicide_not_existing_account.py index ca54e97a1da..64c792c14a9 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_not_existing_account.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_not_existing_account.py @@ -48,6 +48,7 @@ def test_suicide_not_existing_account( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: lll # { (SELFDESTRUCT 0xaa1722f3947def4cf144679da39c4c32bdc35681 )} target = pre.deploy_contract( # noqa: F841 @@ -59,7 +60,6 @@ def test_suicide_not_existing_account( nonce=0, address=Address(0x70C22830049F2678C8AA93D0060683CD67696495), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_origin.py b/tests/ported_static/stSystemOperationsTest/test_suicide_origin.py index 1dbd9045edc..5f785f6a0e5 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_origin.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_origin.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_suicide_origin( ) -> None: """Test_suicide_origin.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -54,9 +51,7 @@ def test_suicide_origin( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x8A448E5835BBDD139B8A2053EE6FE895522048A1), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -68,11 +63,7 @@ def test_suicide_origin( post = { sender: Account(nonce=1), - target: Account( - storage={0: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297}, - balance=0, - nonce=0, - ), + target: Account(storage={0: sender}, balance=0, nonce=0), } state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_post_death.py b/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_post_death.py index 5837e3f5c3c..767c6a21ad5 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_post_death.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_post_death.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_suicide_send_ether_post_death( ) -> None: """Test_suicide_send_ether_post_death.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xB1F4CBC3A50042184425A6F9E996D0910F7BA879457CE5DAC5C71E498AD3C005 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -162,9 +159,7 @@ def test_suicide_send_ether_post_death( + Op.JUMP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0xA997455DCA526734F5607F7C452DE0CFB9AF19F4), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_to_me.py b/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_to_me.py index 1236f981735..effeb06c200 100644 --- a/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_to_me.py +++ b/tests/ported_static/stSystemOperationsTest/test_suicide_send_ether_to_me.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_suicide_send_ether_to_me( ) -> None: """Test_suicide_send_ether_to_me.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -52,9 +49,7 @@ def test_suicide_send_ether_to_me( code=Op.SELFDESTRUCT(address=Op.ADDRESS) + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x3B11A41D66B30B30D4D5BE673F7D5C7D72C9FCA8), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_test_name_registrator.py b/tests/ported_static/stSystemOperationsTest/test_test_name_registrator.py index 62f6185178f..49801340bd3 100644 --- a/tests/ported_static/stSystemOperationsTest/test_test_name_registrator.py +++ b/tests/ported_static/stSystemOperationsTest/test_test_name_registrator.py @@ -46,6 +46,7 @@ def test_test_name_registrator( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x6000355415600957005b60203560003555 target = pre.deploy_contract( # noqa: F841 @@ -62,7 +63,6 @@ def test_test_name_registrator( nonce=0, address=Address(0xFD6034FF12FAD248C17CA3C09F0D7B19243275CD), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stSystemOperationsTest/test_test_random_test.py b/tests/ported_static/stSystemOperationsTest/test_test_random_test.py index 90d7fe39d4a..4ce34dd1cf8 100644 --- a/tests/ported_static/stSystemOperationsTest/test_test_random_test.py +++ b/tests/ported_static/stSystemOperationsTest/test_test_random_test.py @@ -47,6 +47,7 @@ def test_test_random_test( gas_limit=1000000, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: raw # 0x424443444243434383f0155af055 contract_0 = pre.deploy_contract( # noqa: F841 @@ -68,7 +69,6 @@ def test_test_random_test( nonce=0, address=Address(0x0F572E5295C57F15886F9B263E2F6D2D6C7B5EC6), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stTimeConsuming/test_sstore_combinations_initial.py b/tests/ported_static/stTimeConsuming/test_sstore_combinations_initial.py deleted file mode 100644 index 1dd2d27e0af..00000000000 --- a/tests/ported_static/stTimeConsuming/test_sstore_combinations_initial.py +++ /dev/null @@ -1,251 +0,0 @@ -""" -SSTORE combination tests for all initial storage states. - -Exercises every combination of call types across four call slots, -varying the update-contract's initial storage state (0, 1, or 2). - -Ported from all ``sstore_combinations_initial*_ParisFiller.json`` -in ``state_tests/stTimeConsuming/``. -""" - -from enum import StrEnum - -import pytest -from execution_testing import ( - Account, - Alloc, - Bytecode, - StateTestFiller, - Transaction, - compute_create_address, -) -from execution_testing.forks import Fork -from execution_testing.vm import Op - -REFERENCE_SPEC_GIT_PATH = "N/A" -REFERENCE_SPEC_VERSION = "N/A" - -pytestmark = [ - pytest.mark.ported_from( - "state_tests/stTimeConsuming/sstore_combinations_initial00_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial00_2_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial01_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial01_2_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial10_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial10_2_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial11_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial11_2_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial20_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial20_2_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial21_ParisFiller.json", - "state_tests/stTimeConsuming/sstore_combinations_initial21_2_ParisFiller.json", - ), - pytest.mark.valid_from("Byzantium"), - pytest.mark.slow, -] - - -class MidContractActions(StrEnum): - """List of actions the middle contracts can perform.""" - - NOOP = "noop" - SSTORE_TOGGLE = "sstore-toggle" - REVERT = "revert" - - -# Middle-action combinations: (call_opcode, side_contract_index). -# Side-contract indices: 0=noop, 1=sstore-toggle, 2=reverting. -MIDDLE_ACTIONS = [ - (op, t) - for op in [ - Op.CALL, - Op.CALLCODE, - Op.DELEGATECALL, - Op.STATICCALL, - ] - for t in MidContractActions -] - - -@pytest.mark.parametrize( - "update_storage_initial_value", - range(3), - ids=["initial0", "initial1", "initial2"], -) -@pytest.mark.parametrize( - "call_4, call_4_target", - MIDDLE_ACTIONS, - ids=[f"call_4_{op}_{target}" for op, target in MIDDLE_ACTIONS], -) -@pytest.mark.parametrize( - "call_3", - [Op.STATICCALL, Op.CALL, Op.CALLCODE, Op.DELEGATECALL], -) -@pytest.mark.parametrize( - "call_2, call_2_target", - MIDDLE_ACTIONS, - ids=[f"call_2_{op}_{target}" for op, target in MIDDLE_ACTIONS], -) -@pytest.mark.parametrize( - "call_1", - [Op.CALL, Op.CALLCODE, Op.DELEGATECALL], -) -def test_sstore_combinations_initial( - state_test: StateTestFiller, - pre: Alloc, - fork: Fork, - update_storage_initial_value: int, - call_1: Op, - call_2: Op, - call_2_target: MidContractActions, - call_3: Op, - call_4: Op, - call_4_target: MidContractActions, -) -> None: - """Test SSTORE with four interleaved calls.""" - sender = pre.fund_eoa() - side = { - # Noop / balance-only (no executable code) - MidContractActions.NOOP: pre.deploy_contract( - Bytecode(), - balance=10, - storage={0: 1, 1: 1, 2: 1}, - ), - # SSTORE-toggle: flip slots 1..16, then set slot 1 = 1 - MidContractActions.SSTORE_TOGGLE: pre.deploy_contract( - code=sum( - Op.SSTORE(key=i, value=0x1) + Op.SSTORE(key=i, value=0x0) - for i in range(0x1, 0x10 + 1) - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - ), - # Reverting contract - MidContractActions.REVERT: pre.deploy_contract( - code=Op.REVERT(offset=0x0, size=0x20) + Op.STOP, - storage={0: 2, 1: 2, 2: 2}, - ), - } - - update_contract = pre.deploy_contract( - code=Op.SSTORE(key=0x0, value=0x0) - + Op.SSTORE(key=0x1, value=0x1) - + Op.SSTORE(key=0x2, value=0x2) - + Op.STOP, - storage={ - 0: update_storage_initial_value, - 1: update_storage_initial_value, - 2: update_storage_initial_value, - } - if update_storage_initial_value > 0 - else {}, - ) - sstore_toggle = side[MidContractActions.SSTORE_TOGGLE] - - call_gas = 0x493E0 - - initcode = ( - Op.MSTORE(offset=0x64, value=0x0) - + Op.POP( - call_1( - gas=call_gas, - address=update_contract, - args_size=0x20, - ) - ) - + Op.POP(call_2(gas=call_gas, address=side[call_2_target])) - + Op.POP( - call_3( - gas=call_gas, - address=update_contract, - args_size=0x20, - ) - ) - + Op.POP(call_4(gas=call_gas, address=side[call_4_target])) - + Op.CALL(gas=call_gas * 2, address=sstore_toggle) - + Op.STOP - ) - - tx = Transaction( - sender=sender, - to=None, - data=initcode, - gas_limit=2_000_000, - value=1, - protected=fork.supports_protected_txs(), - ) - - post = { - sstore_toggle: Account(storage={1: 1}), - compute_create_address(address=sender, nonce=0): Account(nonce=1), - } - - state_test(pre=pre, post=post, tx=tx) - - -@pytest.mark.parametrize( - "update_storage_initial_value", - range(3), - ids=["initial0", "initial1", "initial2"], -) -def test_sstore_combinations_initial_staticcall_only( - state_test: StateTestFiller, - pre: Alloc, - fork: Fork, - update_storage_initial_value: int, -) -> None: - """Base case: STATICCALL to update-contract only.""" - sender = pre.fund_eoa() - - update_contract = pre.deploy_contract( - code=Op.SSTORE(key=0x0, value=0x0) - + Op.SSTORE(key=0x1, value=0x1) - + Op.SSTORE(key=0x2, value=0x2) - + Op.STOP, - storage={ - 0: update_storage_initial_value, - 1: update_storage_initial_value, - 2: update_storage_initial_value, - } - if update_storage_initial_value > 0 - else {}, - ) - sstore_toggle = pre.deploy_contract( - code=sum( - Op.SSTORE(key=i, value=0x1) + Op.SSTORE(key=i, value=0x0) - for i in range(0x1, 0x10 + 1) - ) - + Op.SSTORE(key=0x1, value=0x1) - + Op.STOP, - ) - - call_gas = 0x493E0 - - initcode = ( - Op.MSTORE(offset=0x64, value=0x0) - + Op.POP( - Op.STATICCALL( - gas=call_gas, - address=update_contract, - args_size=0x20, - ) - ) - + Op.CALL(gas=call_gas * 2, address=sstore_toggle) - + Op.STOP - ) - - tx = Transaction( - sender=sender, - to=None, - data=initcode, - gas_limit=2_000_000, - value=1, - protected=fork.supports_protected_txs(), - ) - - post = { - sstore_toggle: Account(storage={1: 1}), - compute_create_address(address=sender, nonce=0): Account(nonce=1), - } - - state_test(pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stTransactionTest/test_contract_store_clears_oog.py b/tests/ported_static/stTransactionTest/test_contract_store_clears_oog.py index 8d5b3d6606c..7446fbd4b0b 100644 --- a/tests/ported_static/stTransactionTest/test_contract_store_clears_oog.py +++ b/tests/ported_static/stTransactionTest/test_contract_store_clears_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_contract_store_clears_oog( ) -> None: """Test_contract_store_clears_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x2B75D0C814EB07C075FCCBDD9A036FAF651D9C46D7477D6C4F30772CFCA90D38 - ) + sender = pre.fund_eoa(amount=0x1C9C380) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_contract_store_clears_oog( gas_limit=100000, ) - pre[sender] = Account(balance=0x1C9C380) # Source: lll # {(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 12)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -74,7 +70,6 @@ def test_contract_store_clears_oog( 9: 12, }, nonce=0, - address=Address(0xC9C8CE4628BDA9F8BC4A2CAAEBB3616F83C4305D), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_contract_store_clears_success.py b/tests/ported_static/stTransactionTest/test_contract_store_clears_success.py index 70b0aff8e9c..90f1ca0d067 100644 --- a/tests/ported_static/stTransactionTest/test_contract_store_clears_success.py +++ b/tests/ported_static/stTransactionTest/test_contract_store_clears_success.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_contract_store_clears_success( ) -> None: """Test_contract_store_clears_success.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xE624AFC0DCCEAD9A7C59F0007C5C5C3B3DD36EED1CFD8F309A68C9BA3D07769B - ) + sender = pre.fund_eoa(amount=0x8583B00) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_contract_store_clears_success( gas_limit=10000000, ) - pre[sender] = Account(balance=0x8583B00) # Source: lll # {(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -74,7 +70,6 @@ def test_contract_store_clears_success( 9: 12, }, nonce=0, - address=Address(0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_create_message_reverted.py b/tests/ported_static/stTransactionTest/test_create_message_reverted.py index ee63a3efc6a..df437e572c1 100644 --- a/tests/ported_static/stTransactionTest/test_create_message_reverted.py +++ b/tests/ported_static/stTransactionTest/test_create_message_reverted.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_create_message_reverted( ) -> None: """Test_create_message_reverted.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x2B75D0C814EB07C075FCCBDD9A036FAF651D9C46D7477D6C4F30772CFCA90D38 - ) + sender = pre.fund_eoa(amount=0x1C9C380) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_create_message_reverted( gas_limit=1000000000000, ) - pre[sender] = Account(balance=0x1C9C380) # Source: lll # {(MSTORE 0 0x600c600055) (CREATE 0 27 5)} target = pre.deploy_contract( # noqa: F841 @@ -54,7 +50,6 @@ def test_create_message_reverted( + Op.CREATE(value=0x0, offset=0x1B, size=0x5) + Op.STOP, nonce=0, - address=Address(0xC9B0CA064C8B73A1D845547CD28D4E97FE4EC8A0), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_create_message_success.py b/tests/ported_static/stTransactionTest/test_create_message_success.py index 3071eb607df..6f311c8c6e5 100644 --- a/tests/ported_static/stTransactionTest/test_create_message_success.py +++ b/tests/ported_static/stTransactionTest/test_create_message_success.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_create_message_success( """Test_create_message_success.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x17D78400) env = Environment( fee_recipient=coinbase, @@ -48,7 +45,6 @@ def test_create_message_success( gas_limit=1000000000000, ) - pre[sender] = Account(balance=0x17D78400) # Source: lll # {(MSTORE 0 0x600c600055) (CREATE 0 27 5)} contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,7 +52,6 @@ def test_create_message_success( + Op.CREATE(value=0x0, offset=0x1B, size=0x5) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_create_transaction_success.py b/tests/ported_static/stTransactionTest/test_create_transaction_success.py index b85a080c7f3..522b2fdc141 100644 --- a/tests/ported_static/stTransactionTest/test_create_transaction_success.py +++ b/tests/ported_static/stTransactionTest/test_create_transaction_success.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stTransactionTest/CreateTransactionSuccessFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_transaction_success( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_create_transaction_success.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_create_transaction_success( gas_limit=1000000000000, ) - pre[sender] = Account(balance=0x5F5E100) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stTransactionTest/test_empty_transaction3.py b/tests/ported_static/stTransactionTest/test_empty_transaction3.py index 5b6f9bf0c54..1fb6202c846 100644 --- a/tests/ported_static/stTransactionTest/test_empty_transaction3.py +++ b/tests/ported_static/stTransactionTest/test_empty_transaction3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stTransactionTest/EmptyTransaction3Filler.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_empty_transaction3( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_empty_transaction3.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_empty_transaction3( gas_limit=1000000, ) - pre[sender] = Account(balance=0x5F5E100) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stTransactionTest/test_high_gas_price_paris.py b/tests/ported_static/stTransactionTest/test_high_gas_price_paris.py index fbf997b8261..8c6398c3164 100644 --- a/tests/ported_static/stTransactionTest/test_high_gas_price_paris.py +++ b/tests/ported_static/stTransactionTest/test_high_gas_price_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -27,17 +26,13 @@ ) @pytest.mark.valid_from("Cancun") @pytest.mark.exception_test -@pytest.mark.pre_alloc_mutable def test_high_gas_price_paris( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_high_gas_price_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -48,8 +43,7 @@ def test_high_gas_price_paris( gas_limit=89128960, ) - pre[sender] = Account(balance=0x3B9ACA00) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit.py b/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit.py index 5fc9e5ac58b..d2cce97dd88 100644 --- a/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit.py +++ b/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_internal_call_hitting_gas_limit( ) -> None: """Test_internal_call_hitting_gas_limit.""" coinbase = Address(0x2ADF5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -46,13 +43,18 @@ def test_internal_call_hitting_gas_limit( gas_limit=100000, ) - pre[sender] = Account(balance=0x3B9ACA00) + # Source: lll + # {[[1]]55} + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x37) + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 5000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x1388, - address=0x9F499A40CBC961C5230197401CE369D5C53ED896, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -62,14 +64,6 @@ def test_internal_call_hitting_gas_limit( + Op.STOP, balance=0xF4240, nonce=0, - address=Address(0xB208128346FE6A0C4EFA386C0C411A56E4557E2A), # noqa: E501 - ) - # Source: lll - # {[[1]]55} - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x37) + Op.STOP, - nonce=0, - address=Address(0x9F499A40CBC961C5230197401CE369D5C53ED896), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit2.py b/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit2.py index dfde0b9cb7b..78bcdfa205f 100644 --- a/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit2.py +++ b/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_internal_call_hitting_gas_limit2( ) -> None: """Test_internal_call_hitting_gas_limit2.""" coinbase = Address(0x2ADF5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -46,13 +43,18 @@ def test_internal_call_hitting_gas_limit2( gas_limit=47766, ) - pre[sender] = Account(balance=0x3B9ACA00) + # Source: lll + # {[[1]]55} + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x37) + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 25000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x61A8, - address=0x9F499A40CBC961C5230197401CE369D5C53ED896, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -61,14 +63,6 @@ def test_internal_call_hitting_gas_limit2( ) + Op.STOP, nonce=0, - address=Address(0x786A1AB68BB1C7EB88A1B844D6F4D4A51022DE2C), # noqa: E501 - ) - # Source: lll - # {[[1]]55} - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x37) + Op.STOP, - nonce=0, - address=Address(0x9F499A40CBC961C5230197401CE369D5C53ED896), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit_success.py b/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit_success.py index 83d23517ea3..89723d06162 100644 --- a/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit_success.py +++ b/tests/ported_static/stTransactionTest/test_internal_call_hitting_gas_limit_success.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_internal_call_hitting_gas_limit_success( ) -> None: """Test_internal_call_hitting_gas_limit_success.""" coinbase = Address(0x2ADF5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -48,13 +45,18 @@ def test_internal_call_hitting_gas_limit_success( gas_limit=220000, ) - pre[sender] = Account(balance=0x3B9ACA00) + # Source: lll + # {[[1]]55} + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=0x37) + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 25000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x61A8, - address=0x9F499A40CBC961C5230197401CE369D5C53ED896, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -63,14 +65,6 @@ def test_internal_call_hitting_gas_limit_success( ) + Op.STOP, nonce=0, - address=Address(0x786A1AB68BB1C7EB88A1B844D6F4D4A51022DE2C), # noqa: E501 - ) - # Source: lll - # {[[1]]55} - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=0x37) + Op.STOP, - nonce=0, - address=Address(0x9F499A40CBC961C5230197401CE369D5C53ED896), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_internal_call_store_clears_oog.py b/tests/ported_static/stTransactionTest/test_internal_call_store_clears_oog.py index 4f1bb709c68..d8227b78df4 100644 --- a/tests/ported_static/stTransactionTest/test_internal_call_store_clears_oog.py +++ b/tests/ported_static/stTransactionTest/test_internal_call_store_clears_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_internal_call_store_clears_oog( ) -> None: """Test_internal_call_store_clears_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -73,15 +70,13 @@ def test_internal_call_store_clears_oog( 9: 12, }, nonce=0, - address=Address(0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) # Source: lll # { (CALL 40000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x9C40, - address=0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -91,7 +86,6 @@ def test_internal_call_store_clears_oog( + Op.STOP, balance=10, nonce=0, - address=Address(0x30BFE899EF735D5AACA102952664A74B1DE046AF), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_internal_call_store_clears_success.py b/tests/ported_static/stTransactionTest/test_internal_call_store_clears_success.py index c6b040c11fa..bdd47e999a2 100644 --- a/tests/ported_static/stTransactionTest/test_internal_call_store_clears_success.py +++ b/tests/ported_static/stTransactionTest/test_internal_call_store_clears_success.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_internal_call_store_clears_success( ) -> None: """Test_internal_call_store_clears_success.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -75,15 +72,13 @@ def test_internal_call_store_clears_success( 9: 12, }, nonce=0, - address=Address(0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8), # noqa: E501 ) - pre[sender] = Account(balance=0x3B9ACA00) # Source: lll # { (CALL 100000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.CALL( gas=0x186A0, - address=0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -93,7 +88,6 @@ def test_internal_call_store_clears_success( + Op.STOP, balance=10, nonce=0, - address=Address(0x4583A4F45BCB657469D752196A99ED546C8464EF), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_no_src_account.py b/tests/ported_static/stTransactionTest/test_no_src_account.py index f7464c0f42b..1a5c3d9e625 100644 --- a/tests/ported_static/stTransactionTest/test_no_src_account.py +++ b/tests/ported_static/stTransactionTest/test_no_src_account.py @@ -273,7 +273,6 @@ def test_no_src_account( target = pre.deploy_contract( # noqa: F841 code=Op.STOP, nonce=0, - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -424,13 +423,13 @@ def test_no_src_account( 2: [], 3: [ AccessList( - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), + address=target, storage_keys=[], ), ], 4: [ AccessList( - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stTransactionTest/test_no_src_account1559.py b/tests/ported_static/stTransactionTest/test_no_src_account1559.py index 57a6d11a95d..d87e3e0e0be 100644 --- a/tests/ported_static/stTransactionTest/test_no_src_account1559.py +++ b/tests/ported_static/stTransactionTest/test_no_src_account1559.py @@ -189,7 +189,6 @@ def test_no_src_account1559( target = pre.deploy_contract( # noqa: F841 code=Op.STOP, nonce=0, - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -250,13 +249,13 @@ def test_no_src_account1559( 0: [], 1: [ AccessList( - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), + address=target, storage_keys=[], ), ], 2: [ AccessList( - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), + address=target, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stTransactionTest/test_no_src_account_create.py b/tests/ported_static/stTransactionTest/test_no_src_account_create.py index 4f1774b43fa..eb70f1d3636 100644 --- a/tests/ported_static/stTransactionTest/test_no_src_account_create.py +++ b/tests/ported_static/stTransactionTest/test_no_src_account_create.py @@ -273,7 +273,6 @@ def test_no_src_account_create( addr = pre.deploy_contract( # noqa: F841 code=Op.STOP, nonce=0, - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), # noqa: E501 ) expect_entries_: list[dict] = [ @@ -386,13 +385,13 @@ def test_no_src_account_create( 2: [], 3: [ AccessList( - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), + address=addr, storage_keys=[], ), ], 4: [ AccessList( - address=Address(0x4D7B154E5BF8310A4D8220C8EED80020E4B8F86F), + address=addr, storage_keys=[ Hash( "0x0000000000000000000000000000000000000000000000000000000000000000" # noqa: E501 diff --git a/tests/ported_static/stTransactionTest/test_no_src_account_create1559.py b/tests/ported_static/stTransactionTest/test_no_src_account_create1559.py index cce70772d2d..8438ccb8900 100644 --- a/tests/ported_static/stTransactionTest/test_no_src_account_create1559.py +++ b/tests/ported_static/stTransactionTest/test_no_src_account_create1559.py @@ -8,7 +8,6 @@ import pytest from execution_testing import ( AccessList, - Account, Address, Alloc, Environment, @@ -162,7 +161,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_no_src_account_create1559( state_test: StateTestFiller, pre: Alloc, @@ -173,7 +171,6 @@ def test_no_src_account_create1559( ) -> None: """Test_no_src_account_create1559.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0xC22941800A5A392672DC35D8E088BA1BC90891B1) sender = pre.fund_eoa(amount=0) env = Environment( @@ -185,7 +182,7 @@ def test_no_src_account_create1559( gas_limit=89128960, ) - pre[addr] = Account(balance=0, nonce=24743) + addr = pre.fund_eoa(amount=0) # noqa: F841 expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/stTransactionTest/test_overflow_gas_require2.py b/tests/ported_static/stTransactionTest/test_overflow_gas_require2.py index 10476e24cec..6b78f079f48 100644 --- a/tests/ported_static/stTransactionTest/test_overflow_gas_require2.py +++ b/tests/ported_static/stTransactionTest/test_overflow_gas_require2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -30,7 +29,6 @@ ) @pytest.mark.valid_from("Cancun") @pytest.mark.valid_until("Prague") -@pytest.mark.pre_alloc_mutable def test_overflow_gas_require2( state_test: StateTestFiller, pre: Alloc, @@ -38,8 +36,8 @@ def test_overflow_gas_require2( ) -> None: """Test_overflow_gas_require2.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x50EADFB1030587AB3A993A6ECC073041FC3B45E119DAA31A13D78C7E209631A5 + sender = pre.fund_eoa( + amount=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 ) env = Environment( @@ -51,10 +49,6 @@ def test_overflow_gas_require2( gas_limit=9223372036854775807, ) - pre[sender] = Account( - balance=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # noqa: E501 - ) - expect_entries_: list[dict] = [ { "network": ["Cancun"], diff --git a/tests/ported_static/stTransactionTest/test_point_at_infinity_ec_recover.py b/tests/ported_static/stTransactionTest/test_point_at_infinity_ec_recover.py index 3463557259e..59842816a0a 100644 --- a/tests/ported_static/stTransactionTest/test_point_at_infinity_ec_recover.py +++ b/tests/ported_static/stTransactionTest/test_point_at_infinity_ec_recover.py @@ -45,6 +45,7 @@ def test_point_at_infinity_ec_recover( gas_limit=89128960, ) + pre[sender] = Account(balance=0xDE0B6B3A7640000) # Source: yul # berlin { mstore(0, 0x6b8d2c81b11b2d699528dde488dbdf2f94293d0d33c32e347f255fa4a6c1f0a9) mstore(32, 0x1b) mstore(64, 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798) mstore(96, 0x6b8d2c81b11b2d699528dde488dbdf2f94293d0d33c32e347f255fa4a6c1f0a9) sstore(0, call(1000000, 1, 0, 0, 128, 0, 32)) sstore(1, mload(0)) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -55,7 +56,6 @@ def test_point_at_infinity_ec_recover( nonce=0, address=Address(0xB9F36F1CB467544974BB7E0F5E1F0A499D4E6D7D), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_oog.py b/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_oog.py index 85d6e337e9e..4a239006cf5 100644 --- a/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_oog.py +++ b/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_store_clears_and_internal_call_store_clears_oog( ) -> None: """Test_store_clears_and_internal_call_store_clears_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x96C07046493EC8728482079AB999D2994420D9CF4D3491DFD06871B106D9D87B - ) + sender = pre.fund_eoa(amount=0x1DCD6500) env = Environment( fee_recipient=coinbase, @@ -75,9 +72,7 @@ def test_store_clears_and_internal_call_store_clears_oog( 9: 12, }, nonce=0, - address=Address(0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8), # noqa: E501 ) - pre[sender] = Account(balance=0x1DCD6500) # Source: lll # {(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0) (CALL 20000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +82,7 @@ def test_store_clears_and_internal_call_store_clears_oog( + Op.SSTORE(key=0x3, value=0x0) + Op.CALL( gas=0x4E20, - address=0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -98,7 +93,6 @@ def test_store_clears_and_internal_call_store_clears_oog( storage={0: 12, 1: 12, 2: 12, 3: 12, 4: 12}, balance=10, nonce=0, - address=Address(0xF6694E843901AE9F4C9303557D000708DF9581DC), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_success.py b/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_success.py index bfd9ce583fd..3af9a80d962 100644 --- a/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_success.py +++ b/tests/ported_static/stTransactionTest/test_store_clears_and_internal_call_store_clears_success.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_store_clears_and_internal_call_store_clears_success( ) -> None: """Test_store_clears_and_internal_call_store_clears_success.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x96C07046493EC8728482079AB999D2994420D9CF4D3491DFD06871B106D9D87B - ) + sender = pre.fund_eoa(amount=0x1DCD6500) env = Environment( fee_recipient=coinbase, @@ -75,9 +72,7 @@ def test_store_clears_and_internal_call_store_clears_success( 9: 12, }, nonce=0, - address=Address(0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8), # noqa: E501 ) - pre[sender] = Account(balance=0x1DCD6500) # Source: lll # {(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0) (CALL 50000 1 0 0 0 0) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -87,7 +82,7 @@ def test_store_clears_and_internal_call_store_clears_success( + Op.SSTORE(key=0x3, value=0x0) + Op.CALL( gas=0xC350, - address=0xD61E0564FAB2B0DA5136F75DB579B663BD9F2BD8, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -98,7 +93,6 @@ def test_store_clears_and_internal_call_store_clears_success( storage={0: 12, 1: 12, 2: 12, 3: 12, 4: 12}, balance=10, nonce=0, - address=Address(0x8989E867016031A6730F2B84D5E47E1F0F83BDD9), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_store_gas_on_create.py b/tests/ported_static/stTransactionTest/test_store_gas_on_create.py index cfccee01193..2d97f61d885 100644 --- a/tests/ported_static/stTransactionTest/test_store_gas_on_create.py +++ b/tests/ported_static/stTransactionTest/test_store_gas_on_create.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_store_gas_on_create( ) -> None: """Test_store_gas_on_create.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x17D78400) env = Environment( fee_recipient=coinbase, @@ -47,7 +44,6 @@ def test_store_gas_on_create( gas_limit=1000000, ) - pre[sender] = Account(balance=0x17D78400) # Source: lll # { (MSTORE 0 0x5a60fd55) (CREATE 0 28 4)} coinbase = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call.py b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call.py index f9da244dc8f..8bbb8885c03 100644 --- a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call.py +++ b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call.py @@ -50,6 +50,7 @@ def test_suicides_and_internal_call_suicides_bonus_gas_at_call( gas_limit=1000000, ) + pre[sender] = Account(balance=0x5F5E100) # Source: lll # {(SELFDESTRUCT 0x0000000000000000000000000000000000000001)} contract_0 = pre.deploy_contract( # noqa: F841 @@ -57,22 +58,21 @@ def test_suicides_and_internal_call_suicides_bonus_gas_at_call( nonce=0, address=Address(0x0000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) # Source: lll # {(CALL 0 0x0000000000000000000000000000000000000000 1 0 0 0 0) (SELFDESTRUCT 0)} # noqa: E501 contract_1 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( - gas=0x0, - address=0x0, + gas=contract_0, + address=contract_0, value=0x1, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, + args_offset=contract_0, + args_size=contract_0, + ret_offset=contract_0, + ret_size=contract_0, ) ) - + Op.SELFDESTRUCT(address=0x0) + + Op.SELFDESTRUCT(address=contract_0) + Op.STOP, balance=10, nonce=0, diff --git a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call_failed.py b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call_failed.py index 5abd6bcf419..a69e70b1e99 100644 --- a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call_failed.py +++ b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_bonus_gas_at_call_failed.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -37,9 +36,7 @@ def test_suicides_and_internal_call_suicides_bonus_gas_at_call_failed( coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_0 = Address(0x0000000000000000000000000000000000000000) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -57,26 +54,24 @@ def test_suicides_and_internal_call_suicides_bonus_gas_at_call_failed( nonce=0, address=Address(0x0000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) # Source: lll # {(CALL 0 0x0000000000000000000000000000000000000000 0 0 0 0 0) (SELFDESTRUCT 0)} # noqa: E501 contract_1 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( - gas=0x0, - address=0x0, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, + gas=contract_0, + address=contract_0, + value=contract_0, + args_offset=contract_0, + args_size=contract_0, + ret_offset=contract_0, + ret_size=contract_0, ) ) - + Op.SELFDESTRUCT(address=0x0) + + Op.SELFDESTRUCT(address=contract_0) + Op.STOP, balance=10, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_oog.py b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_oog.py index 8c637faa2e0..3e090d4ef5f 100644 --- a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_oog.py +++ b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_suicides_and_internal_call_suicides_oog( ) -> None: """Test_suicides_and_internal_call_suicides_oog.""" coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0xA2333EEF5630066B928DEA5FD85A239F511B5B067D1441EE7AC290D0122B917B - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -53,16 +50,14 @@ def test_suicides_and_internal_call_suicides_oog( addr = pre.deploy_contract( # noqa: F841 code=Op.SELFDESTRUCT(address=0x1) + Op.STOP, nonce=0, - address=Address(0x5F0D8CD21C9026A32A4E8D15257B1801458989F3), # noqa: E501 ) - pre[sender] = Account(balance=0x5F5E100) # Source: lll # {(CALL 22000 1 0 0 0 0) (SELFDESTRUCT 0)} # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0x55F0, - address=0x5F0D8CD21C9026A32A4E8D15257B1801458989F3, + address=addr, value=0x1, args_offset=0x0, args_size=0x0, @@ -74,7 +69,6 @@ def test_suicides_and_internal_call_suicides_oog( + Op.STOP, balance=10, nonce=0, - address=Address(0x78F15BA0ABC5CC1AAA5A0AC6ADD5D28DD9AB8E1E), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_success.py b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_success.py index 0877f4e936a..d0240ef8265 100644 --- a/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_success.py +++ b/tests/ported_static/stTransactionTest/test_suicides_and_internal_call_suicides_success.py @@ -75,6 +75,7 @@ def test_suicides_and_internal_call_suicides_success( gas_limit=10000000, ) + pre[sender] = Account(balance=0xABA9500) # Source: lll # {(SELFDESTRUCT 0x0000000000000000000000000000000000000001)} contract_0 = pre.deploy_contract( # noqa: F841 @@ -82,22 +83,21 @@ def test_suicides_and_internal_call_suicides_success( nonce=0, address=Address(0x0000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0xABA9500) # Source: lll # {(CALL (CALLDATALOAD 0) 0x0000000000000000000000000000000000000000 1 0 0 0 0) (SELFDESTRUCT 0)} # noqa: E501 contract_1 = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( - gas=Op.CALLDATALOAD(offset=0x0), - address=0x0, + gas=Op.CALLDATALOAD(offset=contract_0), + address=contract_0, value=0x1, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, + args_offset=contract_0, + args_size=contract_0, + ret_offset=contract_0, + ret_size=contract_0, ) ) - + Op.SELFDESTRUCT(address=0x0) + + Op.SELFDESTRUCT(address=contract_0) + Op.STOP, balance=1000, nonce=0, diff --git a/tests/ported_static/stTransactionTest/test_suicides_and_send_money_to_itself_ether_destroyed.py b/tests/ported_static/stTransactionTest/test_suicides_and_send_money_to_itself_ether_destroyed.py index 36ccb0e218a..b1ff4c8109a 100644 --- a/tests/ported_static/stTransactionTest/test_suicides_and_send_money_to_itself_ether_destroyed.py +++ b/tests/ported_static/stTransactionTest/test_suicides_and_send_money_to_itself_ether_destroyed.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_suicides_and_send_money_to_itself_ether_destroyed( ) -> None: """Test_suicides_and_send_money_to_itself_ether_destroyed.""" coinbase = Address(0xEB201D2887816E041F6E807E804F64F3A7A226FE) - sender = EOA( - key=0xD066C5DB28BDA8940CFC5CBEFD1556CBC89C69B19F6D1AAA9FAC69AEE4B4A1BF - ) + sender = pre.fund_eoa(amount=0x7459280) env = Environment( fee_recipient=coinbase, @@ -49,7 +46,6 @@ def test_suicides_and_send_money_to_itself_ether_destroyed( ) pre[coinbase] = Account(balance=0, nonce=1) - pre[sender] = Account(balance=0x7459280) # Source: lll # {(SELFDESTRUCT )} # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stTransactionTest/test_suicides_stop_after_suicide.py b/tests/ported_static/stTransactionTest/test_suicides_stop_after_suicide.py index 5a221300202..4eb7033f9fb 100644 --- a/tests/ported_static/stTransactionTest/test_suicides_stop_after_suicide.py +++ b/tests/ported_static/stTransactionTest/test_suicides_stop_after_suicide.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_suicides_stop_after_suicide( coinbase = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_0 = Address(0x0000000000000000000000000000000000000000) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x7459280) env = Environment( fee_recipient=coinbase, @@ -56,24 +53,22 @@ def test_suicides_stop_after_suicide( nonce=0, address=Address(0x0000000000000000000000000000000000000000), # noqa: E501 ) - pre[sender] = Account(balance=0x7459280) # Source: lll # {(SELFDESTRUCT 0) (CALL 30000 0x0000000000000000000000000000000000000000 0 0 0 0 0) } # noqa: E501 contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT(address=0x0) + code=Op.SELFDESTRUCT(address=contract_0) + Op.CALL( gas=0x7530, - address=0x0, - value=0x0, - args_offset=0x0, - args_size=0x0, - ret_offset=0x0, - ret_size=0x0, + address=contract_0, + value=contract_0, + args_offset=contract_0, + args_size=contract_0, + ret_offset=contract_0, + ret_size=contract_0, ) + Op.STOP, balance=10000, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) tx = Transaction( diff --git a/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py b/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py index 59cc379d427..eead8f124ba 100644 --- a/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py +++ b/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -43,7 +42,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_transaction_data_costs652( state_test: StateTestFiller, pre: Alloc, @@ -54,9 +52,7 @@ def test_transaction_data_costs652( ) -> None: """Test_transaction_data_costs652.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xDC4EFA209AECDD4C2D5201A419EA27506151B4EC687F14A613229E310932491B - ) + sender = pre.fund_eoa(amount=0x989680) env = Environment( fee_recipient=coinbase, @@ -67,8 +63,6 @@ def test_transaction_data_costs652( gas_limit=10000000, ) - pre[sender] = Account(balance=0x989680) - tx_data = [ Bytes("00000000000000000000112233445566778f32"), ] diff --git a/tests/ported_static/stTransactionTest/test_transaction_sending_to_empty.py b/tests/ported_static/stTransactionTest/test_transaction_sending_to_empty.py index a361bb2fc24..b7ca2fb7c9e 100644 --- a/tests/ported_static/stTransactionTest/test_transaction_sending_to_empty.py +++ b/tests/ported_static/stTransactionTest/test_transaction_sending_to_empty.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stTransactionTest/TransactionSendingToEmptyFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_transaction_sending_to_empty( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_transaction_sending_to_empty.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x5F5E100) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_transaction_sending_to_empty( gas_limit=1000000, ) - pre[sender] = Account(balance=0x5F5E100) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stTransactionTest/test_transaction_to_itself.py b/tests/ported_static/stTransactionTest/test_transaction_to_itself.py index 3ba8a85d2a6..320a0073f09 100644 --- a/tests/ported_static/stTransactionTest/test_transaction_to_itself.py +++ b/tests/ported_static/stTransactionTest/test_transaction_to_itself.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -25,16 +24,13 @@ ["state_tests/stTransactionTest/TransactionToItselfFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_transaction_to_itself( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_transaction_to_itself.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF79127A3004ABDE26A4CBD80C428CB10F829FA11B54D36E7B326F4F4A5927ACF - ) + sender = pre.fund_eoa(amount=0x3B9ACA00) env = Environment( fee_recipient=coinbase, @@ -45,8 +41,6 @@ def test_transaction_to_itself( gas_limit=1000000, ) - pre[sender] = Account(balance=0x3B9ACA00) - tx = Transaction( sender=sender, to=sender, diff --git a/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_after.py b/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_after.py index 1be81d45e6e..4819a4961d2 100644 --- a/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_after.py +++ b/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_after.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -28,16 +27,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_name_registrator_per_txs_after( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_create_name_registrator_per_txs_after.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,6 @@ def test_create_name_registrator_per_txs_after( gas_limit=10000000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_at.py b/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_at.py index 5908f4cca80..3065cd7ade6 100644 --- a/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_at.py +++ b/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_at.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,16 +25,13 @@ ["state_tests/stTransitionTest/createNameRegistratorPerTxsAtFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_name_registrator_per_txs_at( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_create_name_registrator_per_txs_at.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,8 +42,6 @@ def test_create_name_registrator_per_txs_at( gas_limit=10000000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_before.py b/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_before.py index b39a90250be..6f4102cdf9c 100644 --- a/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_before.py +++ b/tests/ported_static/stTransitionTest/test_create_name_registrator_per_txs_before.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -28,16 +27,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_create_name_registrator_per_txs_before( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_create_name_registrator_per_txs_before.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -48,8 +44,6 @@ def test_create_name_registrator_per_txs_before( gas_limit=10000000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stTransitionTest/test_delegatecall_after_transition.py b/tests/ported_static/stTransitionTest/test_delegatecall_after_transition.py index 6c09a4be145..7eb47e04fbd 100644 --- a/tests/ported_static/stTransitionTest/test_delegatecall_after_transition.py +++ b/tests/ported_static/stTransitionTest/test_delegatecall_after_transition.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_delegatecall_after_transition( ) -> None: """Test_delegatecall_after_transition.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,16 @@ def test_delegatecall_after_transition( gas_limit=30000000, ) + # Source: lll + # {[[ 1 ]] (CALLER) [[ 2 ]] (CALLVALUE) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=Op.CALLER) + + Op.SSTORE(key=0x2, value=Op.CALLVALUE) + + Op.STOP, + balance=23, + nonce=0, + address=Address(0x000D3F6E432D6891A965FC56D39E729652A0762A), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 500000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +60,7 @@ def test_delegatecall_after_transition( key=0x0, value=Op.DELEGATECALL( gas=0x7A120, - address=0xD3F6E432D6891A965FC56D39E729652A0762A, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,19 +70,7 @@ def test_delegatecall_after_transition( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x55BB8A8658B848EBBBB73CBF6AC9D59D715AEC58), # noqa: E501 - ) - # Source: lll - # {[[ 1 ]] (CALLER) [[ 2 ]] (CALLVALUE) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=Op.CALLER) - + Op.SSTORE(key=0x2, value=Op.CALLVALUE) - + Op.STOP, - balance=23, - nonce=0, - address=Address(0x000D3F6E432D6891A965FC56D39E729652A0762A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -84,13 +79,6 @@ def test_delegatecall_after_transition( gas_limit=3000000, ) - post = { - target: Account( - storage={ - 0: 1, - 1: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), - } + post = {target: Account(storage={0: 1, 1: sender})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stTransitionTest/test_delegatecall_at_transition.py b/tests/ported_static/stTransitionTest/test_delegatecall_at_transition.py index bd67176cf93..ba6f1f7d9ec 100644 --- a/tests/ported_static/stTransitionTest/test_delegatecall_at_transition.py +++ b/tests/ported_static/stTransitionTest/test_delegatecall_at_transition.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_delegatecall_at_transition( ) -> None: """Test_delegatecall_at_transition.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,16 @@ def test_delegatecall_at_transition( gas_limit=30000000, ) + # Source: lll + # {[[ 1 ]] (CALLER) [[ 2 ]] (CALLVALUE) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=Op.CALLER) + + Op.SSTORE(key=0x2, value=Op.CALLVALUE) + + Op.STOP, + balance=23, + nonce=0, + address=Address(0x000D3F6E432D6891A965FC56D39E729652A0762A), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 500000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +60,7 @@ def test_delegatecall_at_transition( key=0x0, value=Op.DELEGATECALL( gas=0x7A120, - address=0xD3F6E432D6891A965FC56D39E729652A0762A, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,19 +70,7 @@ def test_delegatecall_at_transition( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x55BB8A8658B848EBBBB73CBF6AC9D59D715AEC58), # noqa: E501 - ) - # Source: lll - # {[[ 1 ]] (CALLER) [[ 2 ]] (CALLVALUE) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=Op.CALLER) - + Op.SSTORE(key=0x2, value=Op.CALLVALUE) - + Op.STOP, - balance=23, - nonce=0, - address=Address(0x000D3F6E432D6891A965FC56D39E729652A0762A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -84,13 +79,6 @@ def test_delegatecall_at_transition( gas_limit=3000000, ) - post = { - target: Account( - storage={ - 0: 1, - 1: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), - } + post = {target: Account(storage={0: 1, 1: sender})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stTransitionTest/test_delegatecall_before_transition.py b/tests/ported_static/stTransitionTest/test_delegatecall_before_transition.py index 3efa5083323..d4bbf366f36 100644 --- a/tests/ported_static/stTransitionTest/test_delegatecall_before_transition.py +++ b/tests/ported_static/stTransitionTest/test_delegatecall_before_transition.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_delegatecall_before_transition( ) -> None: """Test_delegatecall_before_transition.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xE04D1AC7DDDA0C98397D56A0B501E960D4CD325A39286919AC23C1A07009A869 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -46,6 +43,16 @@ def test_delegatecall_before_transition( gas_limit=30000000, ) + # Source: lll + # {[[ 1 ]] (CALLER) [[ 2 ]] (CALLVALUE) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x1, value=Op.CALLER) + + Op.SSTORE(key=0x2, value=Op.CALLVALUE) + + Op.STOP, + balance=23, + nonce=0, + address=Address(0x000D3F6E432D6891A965FC56D39E729652A0762A), # noqa: E501 + ) # Source: lll # { [[ 0 ]] (DELEGATECALL 500000 0 64 0 2 ) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -53,7 +60,7 @@ def test_delegatecall_before_transition( key=0x0, value=Op.DELEGATECALL( gas=0x7A120, - address=0xD3F6E432D6891A965FC56D39E729652A0762A, + address=addr, args_offset=0x0, args_size=0x40, ret_offset=0x0, @@ -63,19 +70,7 @@ def test_delegatecall_before_transition( + Op.STOP, balance=0xDE0B6B3A7640000, nonce=0, - address=Address(0x55BB8A8658B848EBBBB73CBF6AC9D59D715AEC58), # noqa: E501 - ) - # Source: lll - # {[[ 1 ]] (CALLER) [[ 2 ]] (CALLVALUE) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x1, value=Op.CALLER) - + Op.SSTORE(key=0x2, value=Op.CALLVALUE) - + Op.STOP, - balance=23, - nonce=0, - address=Address(0x000D3F6E432D6891A965FC56D39E729652A0762A), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) tx = Transaction( sender=sender, @@ -84,13 +79,6 @@ def test_delegatecall_before_transition( gas_limit=3000000, ) - post = { - target: Account( - storage={ - 0: 1, - 1: 0xEBAF50DEBF10E08302FE4280C32DF010463CA297, - }, - ), - } + post = {target: Account(storage={0: 1, 1: sender})} state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/ported_static/stWalletTest/test_day_limit_construction.py b/tests/ported_static/stWalletTest/test_day_limit_construction.py index 9a10a78a2c4..4206fa7b772 100644 --- a/tests/ported_static/stWalletTest/test_day_limit_construction.py +++ b/tests/ported_static/stWalletTest/test_day_limit_construction.py @@ -93,7 +93,7 @@ def test_day_limit_construction( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 263: 0, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_day_limit_construction_oog.py b/tests/ported_static/stWalletTest/test_day_limit_construction_oog.py index 9bf883cb2e7..7f48e931a50 100644 --- a/tests/ported_static/stWalletTest/test_day_limit_construction_oog.py +++ b/tests/ported_static/stWalletTest/test_day_limit_construction_oog.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -32,9 +31,7 @@ def test_day_limit_construction_oog( ) -> None: """Test_day_limit_construction_oog.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A75EF08F, nonce=1) env = Environment( fee_recipient=coinbase, @@ -45,8 +42,6 @@ def test_day_limit_construction_oog( gas_limit=10000000, ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stWalletTest/test_day_limit_construction_partial.py b/tests/ported_static/stWalletTest/test_day_limit_construction_partial.py index 810cf7967c4..0cd3bb580e1 100644 --- a/tests/ported_static/stWalletTest/test_day_limit_construction_partial.py +++ b/tests/ported_static/stWalletTest/test_day_limit_construction_partial.py @@ -65,7 +65,7 @@ def test_day_limit_construction_partial( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_day_limit_reset_spent_today.py b/tests/ported_static/stWalletTest/test_day_limit_reset_spent_today.py index 0429cb95850..8ca44bb9093 100644 --- a/tests/ported_static/stWalletTest/test_day_limit_reset_spent_today.py +++ b/tests/ported_static/stWalletTest/test_day_limit_reset_spent_today.py @@ -56,7 +56,7 @@ def test_day_limit_reset_spent_today( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 261: 2, 263: 0xC22E4, @@ -82,7 +82,7 @@ def test_day_limit_reset_spent_today( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 2, 261: 2, 263: 0xC22E4, diff --git a/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit.py b/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit.py index 0d6f7e329ca..7001d5c4d51 100644 --- a/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit.py +++ b/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit.py @@ -57,7 +57,7 @@ def test_day_limit_set_daily_limit( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 263: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, @@ -81,7 +81,7 @@ def test_day_limit_set_daily_limit( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 261: 2, 263: 0xC22E4, diff --git a/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit_no_data.py b/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit_no_data.py index 50ecda4f17e..9f315b1ee78 100644 --- a/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit_no_data.py +++ b/tests/ported_static/stWalletTest/test_day_limit_set_daily_limit_no_data.py @@ -56,7 +56,7 @@ def test_day_limit_set_daily_limit_no_data( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 263: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, @@ -80,7 +80,7 @@ def test_day_limit_set_daily_limit_no_data( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 263: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_multi_owned_add_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_add_owner.py index b0c190b6df0..71b81edd443 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_add_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_add_owner.py @@ -47,6 +47,7 @@ def test_multi_owned_add_owner( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_add_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -80,7 +80,7 @@ def test_multi_owned_add_owner( storage={ 0: 1, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 0xD3E69D8C7F41F7AEAF8130DDC53047AEEE8CB46A73D6BAE86B7E7D6BF8312E6B: 2, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_multi_owned_add_owner_add_myself.py b/tests/ported_static/stWalletTest/test_multi_owned_add_owner_add_myself.py index 069ec89c9fb..da52d06e983 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_add_owner_add_myself.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_add_owner_add_myself.py @@ -47,6 +47,7 @@ def test_multi_owned_add_owner_add_myself( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_add_owner_add_myself( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -79,7 +79,7 @@ def test_multi_owned_add_owner_add_myself( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_change_owner.py index 2c5d814fab0..7f24fa0623c 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_owner.py @@ -47,6 +47,7 @@ def test_multi_owned_change_owner( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_change_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_owner_from_not_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_change_owner_from_not_owner.py index 264af9fef9c..cdd7d00fd01 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_owner_from_not_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_owner_from_not_owner.py @@ -47,6 +47,7 @@ def test_multi_owned_change_owner_from_not_owner( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_change_owner_from_not_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -81,7 +81,7 @@ def test_multi_owned_change_owner_from_not_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_owner_no_argument.py b/tests/ported_static/stWalletTest/test_multi_owned_change_owner_no_argument.py index 19ffb07c6ad..abd28c4ca20 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_owner_no_argument.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_owner_no_argument.py @@ -46,6 +46,7 @@ def test_multi_owned_change_owner_no_argument( gas_limit=10000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -55,14 +56,13 @@ def test_multi_owned_change_owner_no_argument( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -78,7 +78,7 @@ def test_multi_owned_change_owner_no_argument( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_owner_to_is_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_change_owner_to_is_owner.py index 83a1ac1d860..aedd0a4dc9f 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_owner_to_is_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_owner_to_is_owner.py @@ -47,6 +47,7 @@ def test_multi_owned_change_owner_to_is_owner( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_change_owner_to_is_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -81,7 +81,7 @@ def test_multi_owned_change_owner_to_is_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to0.py b/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to0.py index cd81be47afb..48c0a59ad40 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to0.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to0.py @@ -47,6 +47,7 @@ def test_multi_owned_change_requirement_to0( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_change_requirement_to0( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -78,7 +78,7 @@ def test_multi_owned_change_requirement_to0( contract_0: Account( storage={ 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to1.py b/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to1.py index 58574695eed..e29e02486a2 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to1.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to1.py @@ -47,6 +47,7 @@ def test_multi_owned_change_requirement_to1( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_change_requirement_to1( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -79,7 +79,7 @@ def test_multi_owned_change_requirement_to1( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to2.py b/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to2.py index 37ef850e805..9724b0cad39 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to2.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_change_requirement_to2.py @@ -47,6 +47,7 @@ def test_multi_owned_change_requirement_to2( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_change_requirement_to2( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -79,7 +79,7 @@ def test_multi_owned_change_requirement_to2( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_construction_correct.py b/tests/ported_static/stWalletTest/test_multi_owned_construction_correct.py index df4f050384b..e8358ff7f7c 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_construction_correct.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_construction_correct.py @@ -63,7 +63,7 @@ def test_multi_owned_construction_correct( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas.py b/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas.py index a1363dfcf33..d6be5724357 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -25,16 +24,13 @@ ["state_tests/stWalletTest/multiOwnedConstructionNotEnoughGasFiller.json"], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_multi_owned_construction_not_enough_gas( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_multi_owned_construction_not_enough_gas.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -45,8 +41,6 @@ def test_multi_owned_construction_not_enough_gas( gas_limit=1000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - tx = Transaction( sender=sender, to=None, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas_partial.py b/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas_partial.py index bc84adb55f0..22e4a3b9a29 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas_partial.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_construction_not_enough_gas_partial.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -49,7 +48,6 @@ ), ], ) -@pytest.mark.pre_alloc_mutable def test_multi_owned_construction_not_enough_gas_partial( state_test: StateTestFiller, pre: Alloc, @@ -60,9 +58,7 @@ def test_multi_owned_construction_not_enough_gas_partial( ) -> None: """Test_multi_owned_construction_not_enough_gas_partial.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000) env = Environment( fee_recipient=coinbase, @@ -73,8 +69,6 @@ def test_multi_owned_construction_not_enough_gas_partial( gas_limit=10000000, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000) - expect_entries_: list[dict] = [ { "indexes": {"data": -1, "gas": 0, "value": -1}, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_is_owner_false.py b/tests/ported_static/stWalletTest/test_multi_owned_is_owner_false.py index 0113979f70a..4b84b80aaf0 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_is_owner_false.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_is_owner_false.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -34,9 +33,7 @@ def test_multi_owned_is_owner_false( """Test_multi_owned_is_owner_false.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A75EF08F, nonce=1) env = Environment( fee_recipient=coinbase, @@ -56,14 +53,12 @@ def test_multi_owned_is_owner_false( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, - address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -80,7 +75,7 @@ def test_multi_owned_is_owner_false( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_multi_owned_is_owner_true.py b/tests/ported_static/stWalletTest/test_multi_owned_is_owner_true.py index 358b2a4a5b5..aeec0e20a27 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_is_owner_true.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_is_owner_true.py @@ -47,6 +47,7 @@ def test_multi_owned_is_owner_true( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_is_owner_true( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -79,7 +79,7 @@ def test_multi_owned_is_owner_true( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner.py index e017ed9dbb5..9947931cf21 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner.py @@ -48,6 +48,7 @@ def test_multi_owned_remove_owner( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056 # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -831,7 +832,7 @@ def test_multi_owned_remove_owner( storage={ 0: 1, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 0xD3E69D8C7F41F7AEAF8130DDC53047AEEE8CB46A73D6BAE86B7E7D6BF8312E6B: 2, # noqa: E501 @@ -840,7 +841,6 @@ def test_multi_owned_remove_owner( nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_by_non_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_by_non_owner.py index 46762788de2..646b72dc0d8 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_by_non_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_by_non_owner.py @@ -58,7 +58,7 @@ def test_multi_owned_remove_owner_by_non_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: contract_1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, @@ -89,7 +89,7 @@ def test_multi_owned_remove_owner_by_non_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: contract_1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_my_self.py b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_my_self.py index 187c70793ba..c71db42578f 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_my_self.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_my_self.py @@ -47,6 +47,7 @@ def test_multi_owned_remove_owner_my_self( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_remove_owner_my_self( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -79,7 +79,7 @@ def test_multi_owned_remove_owner_my_self( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_owner_is_not_owner.py b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_owner_is_not_owner.py index 883a6cb445e..1462457ee5d 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_owner_is_not_owner.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_remove_owner_owner_is_not_owner.py @@ -49,6 +49,7 @@ def test_multi_owned_remove_owner_owner_is_not_owner( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -58,14 +59,13 @@ def test_multi_owned_remove_owner_owner_is_not_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -82,7 +82,7 @@ def test_multi_owned_remove_owner_owner_is_not_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_multi_owned_revoke_nothing.py b/tests/ported_static/stWalletTest/test_multi_owned_revoke_nothing.py index 486af5b7585..35e97313538 100644 --- a/tests/ported_static/stWalletTest/test_multi_owned_revoke_nothing.py +++ b/tests/ported_static/stWalletTest/test_multi_owned_revoke_nothing.py @@ -47,6 +47,7 @@ def test_multi_owned_revoke_nothing( gas_limit=100000000, ) + pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,14 +57,13 @@ def test_multi_owned_revoke_nothing( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, address=Address(0x6295EE1B4F6DD65047762F924ECD367C17EABF8F), # noqa: E501 ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) tx = Transaction( sender=sender, @@ -82,7 +82,7 @@ def test_multi_owned_revoke_nothing( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, code=bytes.fromhex( diff --git a/tests/ported_static/stWalletTest/test_wallet_add_owner_remove_pending_transaction.py b/tests/ported_static/stWalletTest/test_wallet_add_owner_remove_pending_transaction.py index 2ecaae0031b..ac91046d380 100644 --- a/tests/ported_static/stWalletTest/test_wallet_add_owner_remove_pending_transaction.py +++ b/tests/ported_static/stWalletTest/test_wallet_add_owner_remove_pending_transaction.py @@ -68,8 +68,8 @@ def test_wallet_add_owner_remove_pending_transaction( storage={ 0: 1, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 260: 1, 263: 0xC22E4, 0x3736DCA762B6FCB9A97D5EAFDA4032FDBA21DBFA25F875001D51E03EFF955FB2: 1, # noqa: E501 @@ -100,8 +100,8 @@ def test_wallet_add_owner_remove_pending_transaction( storage={ 0: 1, 1: 3, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 5: 0xBBB1CD2CD96C6D5C0B5EB3322D807B34482481D4, 263: 0xC22E4, 0x3412A0F379BAD2D2F891E4DB16A42D964DD63A031E22596F10B4DAB2AAA1D252: 3, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_wallet_change_owner_remove_pending_transaction.py b/tests/ported_static/stWalletTest/test_wallet_change_owner_remove_pending_transaction.py index 4341d8b15b2..a3f01e84bbb 100644 --- a/tests/ported_static/stWalletTest/test_wallet_change_owner_remove_pending_transaction.py +++ b/tests/ported_static/stWalletTest/test_wallet_change_owner_remove_pending_transaction.py @@ -68,8 +68,8 @@ def test_wallet_change_owner_remove_pending_transaction( storage={ 0: 1, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 260: 1, 263: 0xC22E4, 0x3736DCA762B6FCB9A97D5EAFDA4032FDBA21DBFA25F875001D51E03EFF955FB2: 1, # noqa: E501 @@ -102,7 +102,7 @@ def test_wallet_change_owner_remove_pending_transaction( 0: 1, 1: 2, 3: 0xAAAF5374FCE5EDBC8E2A8697C15331677E6EBAAA, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 4: sender, 263: 0xC22E4, 0x62CE4F671906BE9A217487BB98E428B08E12100FB0007DF10572CA00206E7D73: 1, # noqa: E501 0xD3E69D8C7F41F7AEAF8130DDC53047AEEE8CB46A73D6BAE86B7E7D6BF8312E6B: 2, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_wallet_change_requirement_remove_pending_transaction.py b/tests/ported_static/stWalletTest/test_wallet_change_requirement_remove_pending_transaction.py index 98756462e16..86a14063092 100644 --- a/tests/ported_static/stWalletTest/test_wallet_change_requirement_remove_pending_transaction.py +++ b/tests/ported_static/stWalletTest/test_wallet_change_requirement_remove_pending_transaction.py @@ -68,8 +68,8 @@ def test_wallet_change_requirement_remove_pending_transaction( storage={ 0: 1, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 260: 1, 263: 0xC22E4, 0x3736DCA762B6FCB9A97D5EAFDA4032FDBA21DBFA25F875001D51E03EFF955FB2: 1, # noqa: E501 @@ -99,8 +99,8 @@ def test_wallet_change_requirement_remove_pending_transaction( storage={ 0: 2, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 263: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 0xD3E69D8C7F41F7AEAF8130DDC53047AEEE8CB46A73D6BAE86B7E7D6BF8312E6B: 2, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_wallet_confirm.py b/tests/ported_static/stWalletTest/test_wallet_confirm.py index 7044c682df9..addf5a88ad6 100644 --- a/tests/ported_static/stWalletTest/test_wallet_confirm.py +++ b/tests/ported_static/stWalletTest/test_wallet_confirm.py @@ -66,8 +66,8 @@ def test_wallet_confirm( storage={ 0: 2, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 260: 1, 263: 0xC22E4, 0x3736DCA762B6FCB9A97D5EAFDA4032FDBA21DBFA25F875001D51E03EFF955FB2: 1, # noqa: E501 @@ -103,8 +103,8 @@ def test_wallet_confirm( storage={ 0: 2, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 260: 1, 263: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_wallet_construction.py b/tests/ported_static/stWalletTest/test_wallet_construction.py index 98e1d81013d..3127da7cf6b 100644 --- a/tests/ported_static/stWalletTest/test_wallet_construction.py +++ b/tests/ported_static/stWalletTest/test_wallet_construction.py @@ -93,7 +93,7 @@ def test_wallet_construction( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 263: 0, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_wallet_construction_oog.py b/tests/ported_static/stWalletTest/test_wallet_construction_oog.py index e12f3594319..d10fa9cb910 100644 --- a/tests/ported_static/stWalletTest/test_wallet_construction_oog.py +++ b/tests/ported_static/stWalletTest/test_wallet_construction_oog.py @@ -93,7 +93,7 @@ def test_wallet_construction_oog( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 263: 0, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_wallet_construction_partial.py b/tests/ported_static/stWalletTest/test_wallet_construction_partial.py index 5db84bc9cef..90aaebc9d2f 100644 --- a/tests/ported_static/stWalletTest/test_wallet_construction_partial.py +++ b/tests/ported_static/stWalletTest/test_wallet_construction_partial.py @@ -65,7 +65,7 @@ def test_wallet_construction_partial( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 263: 0, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_wallet_default.py b/tests/ported_static/stWalletTest/test_wallet_default.py index 0dd71c4e1d6..92582b8fc42 100644 --- a/tests/ported_static/stWalletTest/test_wallet_default.py +++ b/tests/ported_static/stWalletTest/test_wallet_default.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_wallet_default( """Test_wallet_default.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xEC0E71AD0A90FFE1909D27DAC207F7680ABBA42D) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A75EF08F, nonce=1) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_wallet_default( gas_limit=100000000, ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,13 +52,12 @@ def test_wallet_default( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, - address=Address(0xEC0E71AD0A90FFE1909D27DAC207F7680ABBA42D), # noqa: E501 ) tx = Transaction( @@ -80,7 +75,7 @@ def test_wallet_default( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_wallet_default_with_out_value.py b/tests/ported_static/stWalletTest/test_wallet_default_with_out_value.py index 8694af8452a..944b60d6d4f 100644 --- a/tests/ported_static/stWalletTest/test_wallet_default_with_out_value.py +++ b/tests/ported_static/stWalletTest/test_wallet_default_with_out_value.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_wallet_default_with_out_value( """Test_wallet_default_with_out_value.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xEC0E71AD0A90FFE1909D27DAC207F7680ABBA42D) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A75EF08F, nonce=1) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_wallet_default_with_out_value( gas_limit=100000000, ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: raw # 0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -56,13 +52,12 @@ def test_wallet_default_with_out_value( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, - address=Address(0xEC0E71AD0A90FFE1909D27DAC207F7680ABBA42D), # noqa: E501 ) tx = Transaction( @@ -79,7 +74,7 @@ def test_wallet_default_with_out_value( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_multi_owner.py b/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_multi_owner.py index 7638b1c8965..0b55aad076c 100644 --- a/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_multi_owner.py +++ b/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_multi_owner.py @@ -59,7 +59,7 @@ def test_wallet_execute_over_daily_limit_multi_owner( storage={ 0: 2, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 0xD3E69D8C7F41F7AEAF8130DDC53047AEEE8CB46A73D6BAE86B7E7D6BF8312E6B: 2, # noqa: E501 @@ -86,7 +86,7 @@ def test_wallet_execute_over_daily_limit_multi_owner( storage={ 0: 2, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, 260: 1, 263: 0, diff --git a/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner.py b/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner.py index f26d28872ba..444a6a1b747 100644 --- a/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner.py +++ b/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner.py @@ -59,7 +59,7 @@ def test_wallet_execute_over_daily_limit_only_one_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 261: 4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, @@ -85,7 +85,7 @@ def test_wallet_execute_over_daily_limit_only_one_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 261: 4, 263: 0, diff --git a/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner_new.py b/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner_new.py index 3389e6bd7f1..3cc6e54b407 100644 --- a/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner_new.py +++ b/tests/ported_static/stWalletTest/test_wallet_execute_over_daily_limit_only_one_owner_new.py @@ -59,7 +59,7 @@ def test_wallet_execute_over_daily_limit_only_one_owner_new( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 4, 263: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 @@ -86,7 +86,7 @@ def test_wallet_execute_over_daily_limit_only_one_owner_new( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 262: 4, 263: 0xC22E4, diff --git a/tests/ported_static/stWalletTest/test_wallet_execute_under_daily_limit.py b/tests/ported_static/stWalletTest/test_wallet_execute_under_daily_limit.py index a22312370ea..2399d447e41 100644 --- a/tests/ported_static/stWalletTest/test_wallet_execute_under_daily_limit.py +++ b/tests/ported_static/stWalletTest/test_wallet_execute_under_daily_limit.py @@ -57,7 +57,7 @@ def test_wallet_execute_under_daily_limit( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 261: 255, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 @@ -84,7 +84,7 @@ def test_wallet_execute_under_daily_limit( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 261: 255, 262: 0xC22E4, diff --git a/tests/ported_static/stWalletTest/test_wallet_kill.py b/tests/ported_static/stWalletTest/test_wallet_kill.py index 144f52e089d..9bd09c31dcf 100644 --- a/tests/ported_static/stWalletTest/test_wallet_kill.py +++ b/tests/ported_static/stWalletTest/test_wallet_kill.py @@ -57,7 +57,7 @@ def test_wallet_kill( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, @@ -81,7 +81,7 @@ def test_wallet_kill( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_wallet_kill_not_by_owner.py b/tests/ported_static/stWalletTest/test_wallet_kill_not_by_owner.py index 2023f062962..23e2f51e2aa 100644 --- a/tests/ported_static/stWalletTest/test_wallet_kill_not_by_owner.py +++ b/tests/ported_static/stWalletTest/test_wallet_kill_not_by_owner.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,9 +34,7 @@ def test_wallet_kill_not_by_owner( coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) contract_0 = Address(0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xEC0E71AD0A90FFE1909D27DAC207F7680ABBA42D) - sender = EOA( - key=0xA95DEFE70EBEA7804F9C3BE42D20D24375E2A92B9D9666B832069C5F3CD423DD - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A75EF08F, nonce=1) env = Environment( fee_recipient=coinbase, @@ -48,14 +45,12 @@ def test_wallet_kill_not_by_owner( gas_limit=100000000, ) - pre[sender] = Account(balance=0xDE0B6B3A75EF08F, nonce=1) # Source: hex # 0x contract_0 = pre.deploy_contract( # noqa: F841 code="", balance=0xDE0B6B3A75EF08F, nonce=1, - address=Address(0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: raw # 0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe # noqa: E501 @@ -66,13 +61,12 @@ def test_wallet_kill_not_by_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: contract_0, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, balance=100, nonce=0, - address=Address(0xEC0E71AD0A90FFE1909D27DAC207F7680ABBA42D), # noqa: E501 ) tx = Transaction( @@ -92,7 +86,7 @@ def test_wallet_kill_not_by_owner( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: contract_0, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, diff --git a/tests/ported_static/stWalletTest/test_wallet_kill_to_wallet.py b/tests/ported_static/stWalletTest/test_wallet_kill_to_wallet.py index fe65cfeb309..248a076edb5 100644 --- a/tests/ported_static/stWalletTest/test_wallet_kill_to_wallet.py +++ b/tests/ported_static/stWalletTest/test_wallet_kill_to_wallet.py @@ -57,7 +57,7 @@ def test_wallet_kill_to_wallet( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 }, @@ -81,7 +81,7 @@ def test_wallet_kill_to_wallet( storage={ 0: 1, 1: 1, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, + 3: sender, 260: 1, 262: 0xC22E4, 0x6E369836487C234B9E553EF3F787C2D8865520739D340C67B3D251A33986E58D: 1, # noqa: E501 diff --git a/tests/ported_static/stWalletTest/test_wallet_remove_owner_remove_pending_transaction.py b/tests/ported_static/stWalletTest/test_wallet_remove_owner_remove_pending_transaction.py index 7aa23367925..cc9fedeb207 100644 --- a/tests/ported_static/stWalletTest/test_wallet_remove_owner_remove_pending_transaction.py +++ b/tests/ported_static/stWalletTest/test_wallet_remove_owner_remove_pending_transaction.py @@ -68,8 +68,8 @@ def test_wallet_remove_owner_remove_pending_transaction( storage={ 0: 1, 1: 2, - 3: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B, - 4: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: contract_0, + 4: sender, 260: 1, 263: 0xC22E4, 0x3736DCA762B6FCB9A97D5EAFDA4032FDBA21DBFA25F875001D51E03EFF955FB2: 1, # noqa: E501 @@ -99,7 +99,7 @@ def test_wallet_remove_owner_remove_pending_transaction( storage={ 0: 1, 1: 1, - 3: 0x3FB1CD2CD96C6D5C0B5EB3322D807B34482481D4, + 3: sender, 263: 0xC22E4, 0xD3E69D8C7F41F7AEAF8130DDC53047AEEE8CB46A73D6BAE86B7E7D6BF8312E6B: 1, # noqa: E501 }, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_empty_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_empty_oog_revert_paris.py index dd8121a9474..8d1c014999b 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_empty_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_empty_oog_revert_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_call_to_empty_oog_revert_paris( ) -> None: """Test_zero_value_call_to_empty_oog_revert_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_call_to_empty_oog_revert_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALL 60000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_call_to_empty_oog_revert_paris( key=0x1, value=Op.CALL( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,9 +68,7 @@ def test_zero_value_call_to_empty_oog_revert_paris( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x3B02666BF6E822D04045C3AAE0D6B4D6A64249C3), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_non_zero_balance_oog_revert.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_non_zero_balance_oog_revert.py index cc0e58412d2..fafae7e0ec9 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_non_zero_balance_oog_revert.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_non_zero_balance_oog_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_call_to_non_zero_balance_oog_revert( ) -> None: """Test_zero_value_call_to_non_zero_balance_oog_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_call_to_non_zero_balance_oog_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALL 60000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_call_to_non_zero_balance_oog_revert( key=0x1, value=Op.CALL( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,9 +68,7 @@ def test_zero_value_call_to_non_zero_balance_oog_revert( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x3B02666BF6E822D04045C3AAE0D6B4D6A64249C3), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_one_storage_key_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_one_storage_key_oog_revert_paris.py index c91ea857bc4..341743b48e8 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_one_storage_key_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_call_to_one_storage_key_oog_revert_paris.py @@ -50,6 +50,7 @@ def test_zero_value_call_to_one_storage_key_oog_revert_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [[0]](GAS) [[1]] (CALL 60000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -74,7 +75,6 @@ def test_zero_value_call_to_one_storage_key_oog_revert_paris( nonce=0, address=Address(0x3B02666BF6E822D04045C3AAE0D6B4D6A64249C3), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_empty_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_empty_oog_revert_paris.py index bf5c6682deb..b036c66aa4b 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_empty_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_empty_oog_revert_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_callcode_to_empty_oog_revert_paris( ) -> None: """Test_zero_value_callcode_to_empty_oog_revert_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_callcode_to_empty_oog_revert_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALLCODE 60000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_callcode_to_empty_oog_revert_paris( key=0x1, value=Op.CALLCODE( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,9 +68,7 @@ def test_zero_value_callcode_to_empty_oog_revert_paris( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x17B72DD2BF680549809EB79D47A19391B362E383), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_non_zero_balance_oog_revert.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_non_zero_balance_oog_revert.py index 5761ddf2f8f..4d2f36c5dfa 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_non_zero_balance_oog_revert.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_non_zero_balance_oog_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_callcode_to_non_zero_balance_oog_revert( ) -> None: """Test_zero_value_callcode_to_non_zero_balance_oog_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_callcode_to_non_zero_balance_oog_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALLCODE 60000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_callcode_to_non_zero_balance_oog_revert( key=0x1, value=Op.CALLCODE( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -72,9 +68,7 @@ def test_zero_value_callcode_to_non_zero_balance_oog_revert( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0x17B72DD2BF680549809EB79D47A19391B362E383), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_one_storage_key_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_one_storage_key_oog_revert_paris.py index 4ee22bb10d8..b728eea6ee6 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_one_storage_key_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_callcode_to_one_storage_key_oog_revert_paris.py @@ -50,6 +50,7 @@ def test_zero_value_callcode_to_one_storage_key_oog_revert_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [[0]](GAS) [[1]] (CALLCODE 60000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -74,7 +75,6 @@ def test_zero_value_callcode_to_one_storage_key_oog_revert_paris( nonce=0, address=Address(0x17B72DD2BF680549809EB79D47A19391B362E383), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_empty_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_empty_oog_revert_paris.py index 53c5b35d6f5..5be02211c8d 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_empty_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_empty_oog_revert_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_delegatecall_to_empty_oog_revert_paris( ) -> None: """Test_zero_value_delegatecall_to_empty_oog_revert_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_delegatecall_to_empty_oog_revert_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_delegatecall_to_empty_oog_revert_paris( key=0x1, value=Op.DELEGATECALL( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -71,9 +67,7 @@ def test_zero_value_delegatecall_to_empty_oog_revert_paris( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xA58F691F4EA54DCE9588FBAD2B459893B055763A), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_non_zero_balance_oog_revert.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_non_zero_balance_oog_revert.py index ea338b669ee..b917c075c0b 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_non_zero_balance_oog_revert.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_non_zero_balance_oog_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_delegatecall_to_non_zero_balance_oog_revert( ) -> None: """Test_zero_value_delegatecall_to_non_zero_balance_oog_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_delegatecall_to_non_zero_balance_oog_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_delegatecall_to_non_zero_balance_oog_revert( key=0x1, value=Op.DELEGATECALL( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -71,9 +67,7 @@ def test_zero_value_delegatecall_to_non_zero_balance_oog_revert( + Op.SSTORE(key=0x64, value=Op.GAS) + Op.STOP, nonce=0, - address=Address(0xA58F691F4EA54DCE9588FBAD2B459893B055763A), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris.py index 9d6a3ec983e..9259f02ee2b 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris.py @@ -50,6 +50,7 @@ def test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [[0]](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]] (GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -73,7 +74,6 @@ def test_zero_value_delegatecall_to_one_storage_key_oog_revert_paris( nonce=0, address=Address(0xA58F691F4EA54DCE9588FBAD2B459893B055763A), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_oog_revert.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_oog_revert.py index a341f81aaba..b950651b252 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_oog_revert.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_oog_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_zero_value_suicide_oog_revert( ) -> None: """Test_zero_value_suicide_oog_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -46,7 +43,6 @@ def test_zero_value_suicide_oog_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) # Source: lll # { (CALL 40000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 [[100]](GAS) } # noqa: E501 target = pre.deploy_contract( # noqa: F841 diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_empty_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_empty_oog_revert_paris.py index d651a8c709d..2151d4af342 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_empty_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_empty_oog_revert_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_suicide_to_empty_oog_revert_paris( ) -> None: """Test_zero_value_suicide_to_empty_oog_revert_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr_2 = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,20 @@ def test_zero_value_suicide_to_empty_oog_revert_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr_2 = pre.fund_eoa(amount=10) # noqa: F841 + # Source: lll + # { (SELFDESTRUCT ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=addr_2) + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 50000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0xC350, - address=0x888748026558F849C1B2433EA5E1DAF1444DFC60, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,19 +71,7 @@ def test_zero_value_suicide_to_empty_oog_revert_paris( + Op.SSTORE(key=0x4, value=0xC) + Op.STOP, nonce=0, - address=Address(0xA2E25F47A24C66CFEF22D3304777A22D6DD7AD4A), # noqa: E501 - ) - # Source: lll - # { (SELFDESTRUCT ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x76FAE819612A29489A1A43208613D8F8557B8898 - ) - + Op.STOP, - nonce=0, - address=Address(0x888748026558F849C1B2433EA5E1DAF1444DFC60), # noqa: E501 ) - pre[addr_2] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_non_zero_balance_oog_revert.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_non_zero_balance_oog_revert.py index d46914d9ce8..8459e1da25d 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_non_zero_balance_oog_revert.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_non_zero_balance_oog_revert.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_suicide_to_non_zero_balance_oog_revert( ) -> None: """Test_zero_value_suicide_to_non_zero_balance_oog_revert.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr_2 = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,14 +45,20 @@ def test_zero_value_suicide_to_non_zero_balance_oog_revert( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr_2 = pre.fund_eoa(amount=100) # noqa: F841 + # Source: lll + # { (SELFDESTRUCT ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT(address=addr_2) + Op.STOP, + nonce=0, + ) # Source: lll # { (CALL 50000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 code=Op.POP( Op.CALL( gas=0xC350, - address=0x888748026558F849C1B2433EA5E1DAF1444DFC60, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,19 +71,7 @@ def test_zero_value_suicide_to_non_zero_balance_oog_revert( + Op.SSTORE(key=0x4, value=0xC) + Op.STOP, nonce=0, - address=Address(0xA2E25F47A24C66CFEF22D3304777A22D6DD7AD4A), # noqa: E501 - ) - # Source: lll - # { (SELFDESTRUCT ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x9089DA66E8BBC08846842A301905501BC8525DC4 - ) - + Op.STOP, - nonce=0, - address=Address(0x888748026558F849C1B2433EA5E1DAF1444DFC60), # noqa: E501 ) - pre[addr_2] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_one_storage_key_oog_revert_paris.py b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_one_storage_key_oog_revert_paris.py index 3ed2e53ab7e..1abcd40243d 100644 --- a/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_one_storage_key_oog_revert_paris.py +++ b/tests/ported_static/stZeroCallsRevert/test_zero_value_suicide_to_one_storage_key_oog_revert_paris.py @@ -50,6 +50,18 @@ def test_zero_value_suicide_to_one_storage_key_oog_revert_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr_2] = Account(balance=10, storage={0: 1}) + # Source: lll + # { (SELFDESTRUCT ) } + addr = pre.deploy_contract( # noqa: F841 + code=Op.SELFDESTRUCT( + address=0x4757608F18B70777AE788DD4056EEED52F7AA68F + ) + + Op.STOP, + storage={0: 1}, + nonce=0, + address=Address(0x8D444744833C9B79FDFE630F155CF1F3BBEB92E3), # noqa: E501 + ) # Source: lll # { (CALL 50000 0 0 0 0 0) [[2]]12 [[3]]12 [[4]]12 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -72,18 +84,6 @@ def test_zero_value_suicide_to_one_storage_key_oog_revert_paris( nonce=0, address=Address(0x1D63510FCD4F3069306EBAE45EC6910C0BC944C8), # noqa: E501 ) - # Source: lll - # { (SELFDESTRUCT ) } - addr = pre.deploy_contract( # noqa: F841 - code=Op.SELFDESTRUCT( - address=0x4757608F18B70777AE788DD4056EEED52F7AA68F - ) - + Op.STOP, - storage={0: 1}, - nonce=0, - address=Address(0x8D444744833C9B79FDFE630F155CF1F3BBEB92E3), # noqa: E501 - ) - pre[addr_2] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_empty_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_empty_paris.py index 04359d4d00a..9153b52e963 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_empty_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_zero_value_call_to_empty_paris( ) -> None: """Test_zero_value_call_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +43,7 @@ def test_zero_value_call_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALL 60000 0 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +52,7 @@ def test_zero_value_call_to_empty_paris( key=0x1, value=Op.CALL( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -67,9 +63,7 @@ def test_zero_value_call_to_empty_paris( + Op.SSTORE(key=0x64, value=0x1) + Op.STOP, nonce=0, - address=Address(0xF202BAE278AC09857F5A56991C7A4679632F5841), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_non_zero_balance.py b/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_non_zero_balance.py index ffcdfb6e038..50c861952c0 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_non_zero_balance.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,10 +32,7 @@ def test_zero_value_call_to_non_zero_balance( ) -> None: """Test_zero_value_call_to_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,7 +43,7 @@ def test_zero_value_call_to_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALL 60000 0 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -56,7 +52,7 @@ def test_zero_value_call_to_non_zero_balance( key=0x1, value=Op.CALL( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -67,9 +63,7 @@ def test_zero_value_call_to_non_zero_balance( + Op.SSTORE(key=0x64, value=0x1) + Op.STOP, nonce=0, - address=Address(0xF202BAE278AC09857F5A56991C7A4679632F5841), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_one_storage_key_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_one_storage_key_paris.py index 44075302b5e..a073612b73b 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_one_storage_key_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_call_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_zero_value_call_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [[0]](GAS) [[1]] (CALL 60000 0 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_zero_value_call_to_one_storage_key_paris( nonce=0, address=Address(0xF202BAE278AC09857F5A56991C7A4679632F5841), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_empty_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_empty_paris.py index a65b1d96d56..8117720261d 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_empty_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_callcode_to_empty_paris( ) -> None: """Test_zero_value_callcode_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_callcode_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALLCODE 60000 0 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_callcode_to_empty_paris( key=0x1, value=Op.CALLCODE( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,9 +65,7 @@ def test_zero_value_callcode_to_empty_paris( + Op.SSTORE(key=0x64, value=0x1) + Op.STOP, nonce=0, - address=Address(0xA93AE635B4FA4D618045C019AC32ED9ADC8F54EA), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_non_zero_balance.py b/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_non_zero_balance.py index 9e3780f2704..9b5ab5f0cae 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_non_zero_balance.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_callcode_to_non_zero_balance( ) -> None: """Test_zero_value_callcode_to_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_callcode_to_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (CALLCODE 60000 0 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_callcode_to_non_zero_balance( key=0x1, value=Op.CALLCODE( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, value=0x0, args_offset=0x0, args_size=0x0, @@ -69,9 +65,7 @@ def test_zero_value_callcode_to_non_zero_balance( + Op.SSTORE(key=0x64, value=0x1) + Op.STOP, nonce=0, - address=Address(0xA93AE635B4FA4D618045C019AC32ED9ADC8F54EA), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_one_storage_key_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_one_storage_key_paris.py index 5f615dbd305..6872e5b24d9 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_one_storage_key_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_callcode_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_zero_value_callcode_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [[0]](GAS) [[1]] (CALLCODE 60000 0 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -71,7 +72,6 @@ def test_zero_value_callcode_to_one_storage_key_paris( nonce=0, address=Address(0xA93AE635B4FA4D618045C019AC32ED9ADC8F54EA), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_empty_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_empty_paris.py index 665a556440b..a92303da1cc 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_empty_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_delegatecall_to_empty_paris( ) -> None: """Test_zero_value_delegatecall_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_delegatecall_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=10) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_delegatecall_to_empty_paris( key=0x1, value=Op.DELEGATECALL( gas=0xEA60, - address=0x76FAE819612A29489A1A43208613D8F8557B8898, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,9 +64,7 @@ def test_zero_value_delegatecall_to_empty_paris( + Op.SSTORE(key=0x64, value=0x1) + Op.STOP, nonce=0, - address=Address(0xC8881A7E48D37B4A4CDD6338CE7076D6A116283D), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_non_zero_balance.py b/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_non_zero_balance.py index 5430c258458..a02b7615016 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_non_zero_balance.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -35,10 +34,7 @@ def test_zero_value_delegatecall_to_non_zero_balance( ) -> None: """Test_zero_value_delegatecall_to_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -49,7 +45,7 @@ def test_zero_value_delegatecall_to_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) + addr = pre.fund_eoa(amount=100) # noqa: F841 # Source: lll # { [[0]](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -58,7 +54,7 @@ def test_zero_value_delegatecall_to_non_zero_balance( key=0x1, value=Op.DELEGATECALL( gas=0xEA60, - address=0x9089DA66E8BBC08846842A301905501BC8525DC4, + address=addr, args_offset=0x0, args_size=0x0, ret_offset=0x0, @@ -68,9 +64,7 @@ def test_zero_value_delegatecall_to_non_zero_balance( + Op.SSTORE(key=0x64, value=0x1) + Op.STOP, nonce=0, - address=Address(0xC8881A7E48D37B4A4CDD6338CE7076D6A116283D), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_one_storage_key_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_one_storage_key_paris.py index cc6f59d0cc4..d4e3d2fad43 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_one_storage_key_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_delegatecall_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_zero_value_delegatecall_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { [[0]](GAS) [[1]] (DELEGATECALL 60000 0 0 0 0) [[100]] 1 } # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -70,7 +71,6 @@ def test_zero_value_delegatecall_to_one_storage_key_paris( nonce=0, address=Address(0xC8881A7E48D37B4A4CDD6338CE7076D6A116283D), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_empty_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_empty_paris.py index a606727e91f..f82de945298 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_empty_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_empty_paris.py @@ -48,6 +48,7 @@ def test_zero_value_suicide_to_empty_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10) # Source: lll # { (SELFDESTRUCT ) } target = pre.deploy_contract( # noqa: F841 @@ -58,7 +59,6 @@ def test_zero_value_suicide_to_empty_paris( nonce=0, address=Address(0x888748026558F849C1B2433EA5E1DAF1444DFC60), # noqa: E501 ) - pre[addr] = Account(balance=10) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_non_zero_balance.py b/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_non_zero_balance.py index e7e358d1b9e..59a84123da5 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_non_zero_balance.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_non_zero_balance.py @@ -50,6 +50,7 @@ def test_zero_value_suicide_to_non_zero_balance( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=100) # Source: lll # { (SELFDESTRUCT ) } target = pre.deploy_contract( # noqa: F841 @@ -60,7 +61,6 @@ def test_zero_value_suicide_to_non_zero_balance( nonce=0, address=Address(0x888748026558F849C1B2433EA5E1DAF1444DFC60), # noqa: E501 ) - pre[addr] = Account(balance=100) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_one_storage_key_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_one_storage_key_paris.py index ce425aa0f3a..0b7f85d5370 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_one_storage_key_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_suicide_to_one_storage_key_paris.py @@ -50,6 +50,7 @@ def test_zero_value_suicide_to_one_storage_key_paris( ) pre[sender] = Account(balance=0xE8D4A51000) + pre[addr] = Account(balance=10, storage={0: 1}) # Source: lll # { (SELFDESTRUCT ) } target = pre.deploy_contract( # noqa: F841 @@ -61,7 +62,6 @@ def test_zero_value_suicide_to_one_storage_key_paris( nonce=0, address=Address(0x8D444744833C9B79FDFE630F155CF1F3BBEB92E3), # noqa: E501 ) - pre[addr] = Account(balance=10, storage={0: 1}) tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_empty_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_empty_paris.py index e7c20c3f3c1..8a9f12d67e4 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_empty_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,17 +25,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_zero_value_transaction_cal_lwith_data_to_empty_paris( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_zero_value_transaction_cal_lwith_data_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +42,7 @@ def test_zero_value_transaction_cal_lwith_data_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_non_zero_balance.py b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_non_zero_balance.py index a3b3873c2c6..861f03a1aa1 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_non_zero_balance.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_cal_lwith_data_to_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -26,17 +25,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_zero_value_transaction_cal_lwith_data_to_non_zero_balance( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_zero_value_transaction_cal_lwith_data_to_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -47,8 +42,7 @@ def test_zero_value_transaction_cal_lwith_data_to_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=100) + addr = pre.fund_eoa(amount=100) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_empty_paris.py b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_empty_paris.py index 719271c4801..62a4ac96ba2 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_empty_paris.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_empty_paris.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -27,17 +26,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_zero_value_transaction_call_to_empty_paris( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_zero_value_transaction_call_to_empty_paris.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x76FAE819612A29489A1A43208613D8F8557B8898) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,8 +43,7 @@ def test_zero_value_transaction_call_to_empty_paris( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=10) + addr = pre.fund_eoa(amount=10) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_non_zero_balance.py b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_non_zero_balance.py index b8fe07bca01..546b407404d 100644 --- a/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_non_zero_balance.py +++ b/tests/ported_static/stZeroCallsTest/test_zero_value_transaction_call_to_non_zero_balance.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -27,17 +26,13 @@ ], ) @pytest.mark.valid_from("Cancun") -@pytest.mark.pre_alloc_mutable def test_zero_value_transaction_call_to_non_zero_balance( state_test: StateTestFiller, pre: Alloc, ) -> None: """Test_zero_value_transaction_call_to_non_zero_balance.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - addr = Address(0x9089DA66E8BBC08846842A301905501BC8525DC4) - sender = EOA( - key=0x4F31B3206FBF0E0E598B9B1A7D8AC86302A0FF1D8930738F1BEBAE9B67173E52 - ) + sender = pre.fund_eoa(amount=0xE8D4A51000) env = Environment( fee_recipient=coinbase, @@ -48,8 +43,7 @@ def test_zero_value_transaction_call_to_non_zero_balance( gas_limit=10000000, ) - pre[sender] = Account(balance=0xE8D4A51000) - pre[addr] = Account(balance=100) + addr = pre.fund_eoa(amount=100) # noqa: F841 tx = Transaction( sender=sender, diff --git a/tests/ported_static/stZeroKnowledge/test_pairing_test.py b/tests/ported_static/stZeroKnowledge/test_pairing_test.py index 11ed3d532db..bf844166115 100644 --- a/tests/ported_static/stZeroKnowledge/test_pairing_test.py +++ b/tests/ported_static/stZeroKnowledge/test_pairing_test.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -193,9 +192,7 @@ def test_pairing_test( contract_0 = Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_1 = Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) contract_2 = Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xDE0B6B3A7640000, nonce=1) env = Environment( fee_recipient=coinbase, @@ -206,7 +203,6 @@ def test_pairing_test( gas_limit=14012015, ) - pre[sender] = Account(balance=0xDE0B6B3A7640000, nonce=1) # Source: lll # {(MSTORE 32 (CALLDATALOAD 32)) (MSTORE 64 (CALLDATALOAD 64)) (MSTORE 96 (CALLDATALOAD 96)) (MSTORE 128 (CALLDATALOAD 128)) (MSTORE 160 (CALLDATALOAD 160)) (MSTORE 192 (CALLDATALOAD 192)) (MSTORE 224 (CALLDATALOAD 224)) (MSTORE 256 (CALLDATALOAD 256)) (MSTORE 288 (CALLDATALOAD 288)) (MSTORE 320 (CALLDATALOAD 320)) (MSTORE 352 (CALLDATALOAD 352)) (MSTORE 384 (CALLDATALOAD 384)) (MSTORE 416 (CALLDATALOAD 416)) (MSTORE 448 (CALLDATALOAD 448)) (MSTORE 480 (CALLDATALOAD 480)) (MSTORE 512 (CALLDATALOAD 512)) (MSTORE 544 (CALLDATALOAD 544)) (MSTORE 576 (CALLDATALOAD 576)) (MSTORE 608 (CALLDATALOAD 608)) (MSTORE 640 (CALLDATALOAD 640)) (MSTORE 672 (CALLDATALOAD 672)) (MSTORE 704 (CALLDATALOAD 704)) (MSTORE 736 (CALLDATALOAD 736)) [[0]](CALLCODE 500000 8 0 32 (CALLDATALOAD 0) 1000 32) [[1]] (MLOAD 1000) } # noqa: E501 contract_0 = pre.deploy_contract( # noqa: F841 @@ -248,7 +244,6 @@ def test_pairing_test( + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x3E8)) + Op.STOP, nonce=0, - address=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) (MSTORE 32 (CALLDATALOAD 32)) (MSTORE 64 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000) [[0]](CALLCODE 5000000 7 0 0 96 1000 64) [[1]](MLOAD 1000) [[2]](MLOAD 1032) } # noqa: E501 @@ -275,7 +270,6 @@ def test_pairing_test( + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x408)) + Op.STOP, nonce=0, - address=Address(0xC94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) # Source: lll # { (MSTORE 0 (CALLDATALOAD 0)) (MSTORE 32 (CALLDATALOAD 32)) (MSTORE 64 (CALLDATALOAD 64)) (MSTORE 96 (CALLDATALOAD 96)) [[0]](CALLCODE 5000000 6 0 0 128 1000 64) [[1]](MLOAD 1000) [[2]](MLOAD 1032) } # noqa: E501 @@ -300,7 +294,6 @@ def test_pairing_test( + Op.SSTORE(key=0x2, value=Op.MLOAD(offset=0x408)) + Op.STOP, nonce=0, - address=Address(0xD94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), # noqa: E501 ) expect_entries_: list[dict] = [ diff --git a/tests/ported_static/vmArithmeticTest/test_add.py b/tests/ported_static/vmArithmeticTest/test_add.py index 0806f92e1fe..38a910bcf77 100644 --- a/tests/ported_static/vmArithmeticTest/test_add.py +++ b/tests/ported_static/vmArithmeticTest/test_add.py @@ -96,6 +96,7 @@ def test_add( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # ; -1+-1 = -2 @@ -201,7 +202,6 @@ def test_add( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_addmod.py b/tests/ported_static/vmArithmeticTest/test_addmod.py index 2d78b510024..122864ca167 100644 --- a/tests/ported_static/vmArithmeticTest/test_addmod.py +++ b/tests/ported_static/vmArithmeticTest/test_addmod.py @@ -173,6 +173,7 @@ def test_addmod( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (addmod 1 2 2) @@ -390,7 +391,6 @@ def test_addmod( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_arith.py b/tests/ported_static/vmArithmeticTest/test_arith.py index 18265c1f3f3..e482886f634 100644 --- a/tests/ported_static/vmArithmeticTest/test_arith.py +++ b/tests/ported_static/vmArithmeticTest/test_arith.py @@ -46,6 +46,7 @@ def test_arith( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: raw # 0x600160019001600702600501600290046004906021900560170160030260059007600303600960110A60005560086000F3 # noqa: E501 target = pre.deploy_contract( # noqa: F841 @@ -69,7 +70,6 @@ def test_arith( nonce=0, address=Address(0x14814D06E93EFB1102A15D5881432C9FF6C91362), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/vmArithmeticTest/test_div.py b/tests/ported_static/vmArithmeticTest/test_div.py index 8a478377d89..5a13e87254f 100644 --- a/tests/ported_static/vmArithmeticTest/test_div.py +++ b/tests/ported_static/vmArithmeticTest/test_div.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -104,9 +103,7 @@ def test_div( contract_6 = Address(0x0000000000000000000000000000000000001006) contract_7 = Address(0x0000000000000000000000000000000000001007) contract_8 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -236,7 +233,6 @@ def test_div( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_div_by_zero.py b/tests/ported_static/vmArithmeticTest/test_div_by_zero.py index a42490e493a..30720aeba88 100644 --- a/tests/ported_static/vmArithmeticTest/test_div_by_zero.py +++ b/tests/ported_static/vmArithmeticTest/test_div_by_zero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -632,9 +631,7 @@ def test_div_by_zero( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -711,9 +708,7 @@ def test_div_by_zero( + Op.STOP, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0x935E36EE6CD0F1602D1ABCA9A391C696CFA4C04D), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx_data = [ Bytes("1a8451e6") + Hash(0x4) + Hash(0x2), diff --git a/tests/ported_static/vmArithmeticTest/test_exp.py b/tests/ported_static/vmArithmeticTest/test_exp.py index 734f99ae030..5514c6d2f91 100644 --- a/tests/ported_static/vmArithmeticTest/test_exp.py +++ b/tests/ported_static/vmArithmeticTest/test_exp.py @@ -138,6 +138,7 @@ def test_exp( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (exp 2 2) @@ -280,7 +281,6 @@ def test_exp( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_exp_power2.py b/tests/ported_static/vmArithmeticTest/test_exp_power2.py index 252c1022462..9fb0bd5388c 100644 --- a/tests/ported_static/vmArithmeticTest/test_exp_power2.py +++ b/tests/ported_static/vmArithmeticTest/test_exp_power2.py @@ -47,6 +47,7 @@ def test_exp_power2( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # (def 'storageJump 0x10) @@ -149,7 +150,6 @@ def test_exp_power2( nonce=0, address=Address(0x5A18B275908AD6766155191A40654188FE012DC6), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/vmArithmeticTest/test_exp_power256.py b/tests/ported_static/vmArithmeticTest/test_exp_power256.py index 25a804fa0bf..37bb7b44bf3 100644 --- a/tests/ported_static/vmArithmeticTest/test_exp_power256.py +++ b/tests/ported_static/vmArithmeticTest/test_exp_power256.py @@ -47,6 +47,7 @@ def test_exp_power256( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # (def 'storageJump 0x10) @@ -323,7 +324,6 @@ def test_exp_power256( nonce=0, address=Address(0xE660D528E4A7AD36825F9D64F5F141596FEFF7AE), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/vmArithmeticTest/test_exp_power256_of256.py b/tests/ported_static/vmArithmeticTest/test_exp_power256_of256.py index 8183b190b38..3a4d820a4be 100644 --- a/tests/ported_static/vmArithmeticTest/test_exp_power256_of256.py +++ b/tests/ported_static/vmArithmeticTest/test_exp_power256_of256.py @@ -47,6 +47,7 @@ def test_exp_power256_of256( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # (def 'storageJump 0x10) @@ -1275,7 +1276,6 @@ def test_exp_power256_of256( nonce=0, address=Address(0x9F233EF2D697929EDF542064B125E7D620270363), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/vmArithmeticTest/test_fib.py b/tests/ported_static/vmArithmeticTest/test_fib.py index 27895062753..55d6b52f0d9 100644 --- a/tests/ported_static/vmArithmeticTest/test_fib.py +++ b/tests/ported_static/vmArithmeticTest/test_fib.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -33,9 +32,7 @@ def test_fib( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0x40AC0FC28C27E961EE46EC43355A094DE205856EDBD4654CF2577C2608D4EC1E - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -118,9 +115,7 @@ def test_fib( storage={0: 0, 1: 1}, balance=0xBA1A9CE0BA1A9CE, nonce=0, - address=Address(0xF8D9FF3E0CF16ACF51098C85F2CB8F082EF588C2), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/vmArithmeticTest/test_mod.py b/tests/ported_static/vmArithmeticTest/test_mod.py index 55c74f62a3b..44970acfe0f 100644 --- a/tests/ported_static/vmArithmeticTest/test_mod.py +++ b/tests/ported_static/vmArithmeticTest/test_mod.py @@ -103,6 +103,7 @@ def test_mod( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (% 2 3) @@ -207,7 +208,6 @@ def test_mod( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_mul.py b/tests/ported_static/vmArithmeticTest/test_mul.py index 163daa67afb..dd176fbf7cd 100644 --- a/tests/ported_static/vmArithmeticTest/test_mul.py +++ b/tests/ported_static/vmArithmeticTest/test_mul.py @@ -124,6 +124,7 @@ def test_mul( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (* 2 3) @@ -296,7 +297,6 @@ def test_mul( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_mulmod.py b/tests/ported_static/vmArithmeticTest/test_mulmod.py index 35c8ec19e9d..173ad89d1cc 100644 --- a/tests/ported_static/vmArithmeticTest/test_mulmod.py +++ b/tests/ported_static/vmArithmeticTest/test_mulmod.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -160,9 +159,7 @@ def test_mulmod( contract_14 = Address(0x000000000000000000000000000000000000100E) contract_15 = Address(0x000000000000000000000000000000000000100F) contract_16 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -441,7 +438,6 @@ def test_mulmod( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_not.py b/tests/ported_static/vmArithmeticTest/test_not.py index fd38fc7f33d..2bea92ca4e8 100644 --- a/tests/ported_static/vmArithmeticTest/test_not.py +++ b/tests/ported_static/vmArithmeticTest/test_not.py @@ -49,6 +49,7 @@ def test_not( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (not 0x0123456789abcdef) @@ -78,7 +79,6 @@ def test_not( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) tx = Transaction( sender=sender, diff --git a/tests/ported_static/vmArithmeticTest/test_sdiv.py b/tests/ported_static/vmArithmeticTest/test_sdiv.py index e5487c50cbf..7c360e52047 100644 --- a/tests/ported_static/vmArithmeticTest/test_sdiv.py +++ b/tests/ported_static/vmArithmeticTest/test_sdiv.py @@ -180,6 +180,7 @@ def test_sdiv( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { ; (0 - (-1)) / (-1) = 1/(-1) = -1 # ; @@ -520,7 +521,6 @@ def test_sdiv( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_signextend.py b/tests/ported_static/vmArithmeticTest/test_signextend.py index d3563a3c42f..d05e6c2c264 100644 --- a/tests/ported_static/vmArithmeticTest/test_signextend.py +++ b/tests/ported_static/vmArithmeticTest/test_signextend.py @@ -166,6 +166,7 @@ def test_signextend( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (signextend 80 0x126af4) @@ -386,7 +387,6 @@ def test_signextend( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_smod.py b/tests/ported_static/vmArithmeticTest/test_smod.py index 071f1a290e1..728f89a210b 100644 --- a/tests/ported_static/vmArithmeticTest/test_smod.py +++ b/tests/ported_static/vmArithmeticTest/test_smod.py @@ -103,6 +103,7 @@ def test_smod( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (smod 2 3) @@ -203,7 +204,6 @@ def test_smod( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmArithmeticTest/test_sub.py b/tests/ported_static/vmArithmeticTest/test_sub.py index 7f658b6ef98..2d8d2654766 100644 --- a/tests/ported_static/vmArithmeticTest/test_sub.py +++ b/tests/ported_static/vmArithmeticTest/test_sub.py @@ -96,6 +96,7 @@ def test_sub( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (- 23 1) @@ -185,7 +186,6 @@ def test_sub( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_and.py b/tests/ported_static/vmBitwiseLogicOperation/test_and.py index 2e1e6e6c5aa..919c2763837 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_and.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_and.py @@ -96,6 +96,7 @@ def test_and( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (and 2 2) @@ -187,7 +188,6 @@ def test_and( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_byte.py b/tests/ported_static/vmBitwiseLogicOperation/test_byte.py index cef895aa73f..56887a82b99 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_byte.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_byte.py @@ -145,6 +145,7 @@ def test_byte( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (byte (- 31 0) 0x8040201008040201) @@ -339,7 +340,6 @@ def test_byte( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_eq.py b/tests/ported_static/vmBitwiseLogicOperation/test_eq.py index 984a6ac969d..3c20ccd8773 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_eq.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_eq.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -69,9 +68,7 @@ def test_eq( contract_1 = Address(0x0000000000000000000000000000000000001001) contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -143,7 +140,6 @@ def test_eq( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_gt.py b/tests/ported_static/vmBitwiseLogicOperation/test_gt.py index cb2b7a338f9..06e1b39c681 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_gt.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_gt.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -76,9 +75,7 @@ def test_gt( contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0x0000000000000000000000000000000000001003) contract_4 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -168,7 +165,6 @@ def test_gt( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_iszero.py b/tests/ported_static/vmBitwiseLogicOperation/test_iszero.py index e5322abb38d..e83fe80b0d8 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_iszero.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_iszero.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -69,9 +68,7 @@ def test_iszero( contract_1 = Address(0x0000000000000000000000000000000000001001) contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -139,7 +136,6 @@ def test_iszero( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_lt.py b/tests/ported_static/vmBitwiseLogicOperation/test_lt.py index 919c01b21b5..d2be95c3d03 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_lt.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_lt.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -76,9 +75,7 @@ def test_lt( contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0x0000000000000000000000000000000000001003) contract_4 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -168,7 +165,6 @@ def test_lt( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_not.py b/tests/ported_static/vmBitwiseLogicOperation/test_not.py index a9140b8e8e7..4b4e07d8dd0 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_not.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_not.py @@ -103,6 +103,7 @@ def test_not( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (not 0) @@ -208,7 +209,6 @@ def test_not( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_or.py b/tests/ported_static/vmBitwiseLogicOperation/test_or.py index b6fb91037cd..7fc19e60d81 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_or.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_or.py @@ -103,6 +103,7 @@ def test_or( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (or 2 2) @@ -215,7 +216,6 @@ def test_or( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_sgt.py b/tests/ported_static/vmBitwiseLogicOperation/test_sgt.py index 9ef6611e112..5164480e359 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_sgt.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_sgt.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -76,9 +75,7 @@ def test_sgt( contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0x0000000000000000000000000000000000001003) contract_4 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -168,7 +165,6 @@ def test_sgt( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_slt.py b/tests/ported_static/vmBitwiseLogicOperation/test_slt.py index 08f97475d62..fc950a2787d 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_slt.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_slt.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -76,9 +75,7 @@ def test_slt( contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0x0000000000000000000000000000000000001003) contract_4 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -168,7 +165,6 @@ def test_slt( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmBitwiseLogicOperation/test_xor.py b/tests/ported_static/vmBitwiseLogicOperation/test_xor.py index 556ace51848..b5bdb7b26bf 100644 --- a/tests/ported_static/vmBitwiseLogicOperation/test_xor.py +++ b/tests/ported_static/vmBitwiseLogicOperation/test_xor.py @@ -103,6 +103,7 @@ def test_xor( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (xor 2 2) @@ -215,7 +216,6 @@ def test_xor( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_codecopy.py b/tests/ported_static/vmIOandFlowOperations/test_codecopy.py index b3fca1334fe..bfc509a4799 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_codecopy.py +++ b/tests/ported_static/vmIOandFlowOperations/test_codecopy.py @@ -96,6 +96,7 @@ def test_codecopy( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # ; Copy our code into [[0]] and [[1]] @@ -130,22 +131,6 @@ def test_codecopy( ) # Source: lll # { - # ; Copy our code into [[0]] and [[1]] - # (codecopy 0 0 0x1000) - # [[0]] @0 - # [[1]] @0x20 - # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.CODECOPY(dest_offset=0x0, offset=0x0, size=0x1000) - + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) - + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x20)) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000001002), # noqa: E501 - ) - # Source: lll - # { # ; Waste some space so we'll be over 0x20 bytes of code # [0x100] (+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) # @@ -289,7 +274,22 @@ def test_codecopy( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) + # Source: lll + # { + # ; Copy our code into [[0]] and [[1]] + # (codecopy 0 0 0x1000) + # [[0]] @0 + # [[1]] @0x20 + # } + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.CODECOPY(dest_offset=0x0, offset=0x0, size=0x1000) + + Op.SSTORE(key=0x0, value=Op.MLOAD(offset=0x0)) + + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x20)) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000001002), # noqa: E501 + ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_gas.py b/tests/ported_static/vmIOandFlowOperations/test_gas.py index 34d8c2f72cb..fdfe01710a7 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_gas.py +++ b/tests/ported_static/vmIOandFlowOperations/test_gas.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -63,9 +62,7 @@ def test_gas( contract_0 = Address(0x0000000000000000000000000000000000001000) contract_1 = Address(0x0000000000000000000000000000000000001001) contract_2 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -120,7 +117,6 @@ def test_gas( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_jump.py b/tests/ported_static/vmIOandFlowOperations/test_jump.py index ed898e71509..ba214f9deca 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_jump.py +++ b/tests/ported_static/vmIOandFlowOperations/test_jump.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -167,9 +166,7 @@ def test_jump( contract_15 = Address(0x000000000000000000000000000000000000100F) contract_16 = Address(0x0000000000000000000000000000000000001010) contract_17 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -402,7 +399,6 @@ def test_jump( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_jump_to_push.py b/tests/ported_static/vmIOandFlowOperations/test_jump_to_push.py index 8bc1c31d636..f3168e3b044 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_jump_to_push.py +++ b/tests/ported_static/vmIOandFlowOperations/test_jump_to_push.py @@ -624,26 +624,7 @@ def test_jump_to_push( gas_limit=100000000, ) - # Source: raw - # 0x6001600055600A56605B5B - contract_0 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.JUMP(pc=0xA) - + Op.PUSH1[0x5B] - + Op.JUMPDEST, - nonce=0, - address=Address(0x000000000000000000000000000000000000001A), # noqa: E501 - ) - # Source: raw - # 0x6001600055600956605B5B - contract_1 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.JUMP(pc=0x9) - + Op.PUSH1[0x5B] - + Op.JUMPDEST, - nonce=0, - address=Address(0x000000000000000000000000000000000000001B), # noqa: E501 - ) + pre[sender] = Account(balance=0x100000000000) # Source: raw # 0x6001600055600B56615B5B5B contract_2 = pre.deploy_contract( # noqa: F841 @@ -1095,16 +1076,6 @@ def test_jump_to_push( address=Address(0x000000000000000000000000000000000000010C), # noqa: E501 ) # Source: raw - # 0x6001600055601A56705B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B - contract_47 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.JUMP(pc=0x1A) - + Op.PUSH17[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] - + Op.JUMPDEST, - nonce=0, - address=Address(0x000000000000000000000000000000000000011A), # noqa: E501 - ) - # Source: raw # 0x6001600055600956705B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B contract_48 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -1125,16 +1096,6 @@ def test_jump_to_push( address=Address(0x000000000000000000000000000000000000011C), # noqa: E501 ) # Source: raw - # 0x6001600055601B56715B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B - contract_50 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.JUMP(pc=0x1B) - + Op.PUSH18[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] - + Op.JUMPDEST, - nonce=0, - address=Address(0x000000000000000000000000000000000000012A), # noqa: E501 - ) - # Source: raw # 0x6001600055600956715B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B contract_51 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -1145,16 +1106,6 @@ def test_jump_to_push( address=Address(0x000000000000000000000000000000000000012B), # noqa: E501 ) # Source: raw - # 0x6001600055601A56715B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B - contract_52 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.JUMP(pc=0x1A) - + Op.PUSH18[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] - + Op.JUMPDEST, - nonce=0, - address=Address(0x000000000000000000000000000000000000012C), # noqa: E501 - ) - # Source: raw # 0x6001600055601C56725B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B contract_53 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -1175,16 +1126,6 @@ def test_jump_to_push( address=Address(0x000000000000000000000000000000000000013B), # noqa: E501 ) # Source: raw - # 0x6001600055601B56725B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B - contract_55 = pre.deploy_contract( # noqa: F841 - code=Op.SSTORE(key=0x0, value=0x1) - + Op.JUMP(pc=0x1B) - + Op.PUSH19[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] - + Op.JUMPDEST, - nonce=0, - address=Address(0x000000000000000000000000000000000000013C), # noqa: E501 - ) - # Source: raw # 0x6001600055601D56735B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B contract_56 = pre.deploy_contract( # noqa: F841 code=Op.SSTORE(key=0x0, value=0x1) @@ -1617,7 +1558,66 @@ def test_jump_to_push( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) + # Source: raw + # 0x6001600055600956605B5B + contract_1 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.JUMP(pc=0x9) + + Op.PUSH1[0x5B] + + Op.JUMPDEST, + nonce=0, + address=Address(0x000000000000000000000000000000000000001B), # noqa: E501 + ) + # Source: raw + # 0x6001600055600A56605B5B + contract_0 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.JUMP(pc=0xA) + + Op.PUSH1[0x5B] + + Op.JUMPDEST, + nonce=0, + address=Address(0x000000000000000000000000000000000000001A), # noqa: E501 + ) + # Source: raw + # 0x6001600055601B56725B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B + contract_55 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.JUMP(pc=0x1B) + + Op.PUSH19[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] + + Op.JUMPDEST, + nonce=0, + address=Address(0x000000000000000000000000000000000000013C), # noqa: E501 + ) + # Source: raw + # 0x6001600055601B56715B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B + contract_50 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.JUMP(pc=0x1B) + + Op.PUSH18[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] + + Op.JUMPDEST, + nonce=0, + address=Address(0x000000000000000000000000000000000000012A), # noqa: E501 + ) + # Source: raw + # 0x6001600055601A56705B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B + contract_47 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.JUMP(pc=0x1A) + + Op.PUSH17[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] + + Op.JUMPDEST, + nonce=0, + address=Address(0x000000000000000000000000000000000000011A), # noqa: E501 + ) + # Source: raw + # 0x6001600055601A56715B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B + contract_52 = pre.deploy_contract( # noqa: F841 + code=Op.SSTORE(key=0x0, value=0x1) + + Op.JUMP(pc=0x1A) + + Op.PUSH18[0x5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B] + + Op.JUMPDEST, + nonce=0, + address=Address(0x000000000000000000000000000000000000012C), # noqa: E501 + ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_jumpi.py b/tests/ported_static/vmIOandFlowOperations/test_jumpi.py index 8fe20ed7ef8..c2da7dde412 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_jumpi.py +++ b/tests/ported_static/vmIOandFlowOperations/test_jumpi.py @@ -243,6 +243,7 @@ def test_jumpi( gas_limit=100000000, ) + pre[sender] = Account(balance=0x100000000000) # Source: lll # { # [[0]] 0x600D @@ -580,7 +581,6 @@ def test_jumpi( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_loop_stacklimit.py b/tests/ported_static/vmIOandFlowOperations/test_loop_stacklimit.py index d9b82c03b62..ec1cf83e0b3 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_loop_stacklimit.py +++ b/tests/ported_static/vmIOandFlowOperations/test_loop_stacklimit.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -56,9 +55,7 @@ def test_loop_stacklimit( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xA62D63F95900B04CCD3FEE13360DE78966F24695945E8B2C09E646352BC5AF94 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -138,7 +135,6 @@ def test_loop_stacklimit( nonce=0, address=Address(0xF9B46C1D708104B4E6007D17AE485B0A00D8E952), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) tx_data = [ Bytes("693c6139") + Hash(0x0), diff --git a/tests/ported_static/vmIOandFlowOperations/test_loops_conditionals.py b/tests/ported_static/vmIOandFlowOperations/test_loops_conditionals.py index fd2842c2cc3..ec091a54e3d 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_loops_conditionals.py +++ b/tests/ported_static/vmIOandFlowOperations/test_loops_conditionals.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -125,9 +124,7 @@ def test_loops_conditionals( contract_9 = Address(0x0000000000000000000000000000000000001009) contract_10 = Address(0x000000000000000000000000000000000000100A) contract_11 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -381,7 +378,6 @@ def test_loops_conditionals( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_mload.py b/tests/ported_static/vmIOandFlowOperations/test_mload.py index a70c6c7b6c1..cf11bf25816 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_mload.py +++ b/tests/ported_static/vmIOandFlowOperations/test_mload.py @@ -82,6 +82,7 @@ def test_mload( gas_limit=100000000, ) + pre[sender] = Account(balance=0x100000000000) # Source: lll # { # [0] 0x0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff # noqa: E501 @@ -140,7 +141,6 @@ def test_mload( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_msize.py b/tests/ported_static/vmIOandFlowOperations/test_msize.py index 053751fd9ce..5cc3faad9f2 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_msize.py +++ b/tests/ported_static/vmIOandFlowOperations/test_msize.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -91,9 +90,7 @@ def test_msize( contract_4 = Address(0x0000000000000000000000000000000000001004) contract_5 = Address(0x0000000000000000000000000000000000001005) contract_6 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -229,7 +226,6 @@ def test_msize( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_mstore.py b/tests/ported_static/vmIOandFlowOperations/test_mstore.py index 0ca59b2ff18..8ab043b473a 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_mstore.py +++ b/tests/ported_static/vmIOandFlowOperations/test_mstore.py @@ -96,6 +96,7 @@ def test_mstore( gas_limit=100000000, ) + pre[sender] = Account(balance=0x100000000000) # Source: lll # { # (mstore 1 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) # noqa: E501 @@ -189,7 +190,6 @@ def test_mstore( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_mstore8.py b/tests/ported_static/vmIOandFlowOperations/test_mstore8.py index 77b52f677e6..23cc67ce2c1 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_mstore8.py +++ b/tests/ported_static/vmIOandFlowOperations/test_mstore8.py @@ -82,6 +82,7 @@ def test_mstore8( gas_limit=100000000, ) + pre[sender] = Account(balance=0x100000000000) # Source: lll # { # ; It ignores all but one byte, the least significant one @@ -144,7 +145,6 @@ def test_mstore8( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_pc.py b/tests/ported_static/vmIOandFlowOperations/test_pc.py index 92cb22f05e4..fc3df94d285 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_pc.py +++ b/tests/ported_static/vmIOandFlowOperations/test_pc.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_pc( contract_0 = Address(0x0000000000000000000000000000000000001000) contract_1 = Address(0x0000000000000000000000000000000000001001) contract_2 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -117,7 +114,6 @@ def test_pc( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_pop.py b/tests/ported_static/vmIOandFlowOperations/test_pop.py index e419cc12536..9e49f6e31bc 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_pop.py +++ b/tests/ported_static/vmIOandFlowOperations/test_pop.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -62,9 +61,7 @@ def test_pop( contract_0 = Address(0x0000000000000000000000000000000000001000) contract_1 = Address(0x0000000000000000000000000000000000001001) contract_2 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -109,7 +106,6 @@ def test_pop( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_return.py b/tests/ported_static/vmIOandFlowOperations/test_return.py index c7b15bac935..17e39f195f8 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_return.py +++ b/tests/ported_static/vmIOandFlowOperations/test_return.py @@ -96,6 +96,7 @@ def test_return( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [0] 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef @@ -136,24 +137,6 @@ def test_return( # { # [0] 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef # [[0xFF]] 0x600D - # (return 0x00 0x1000) - # } - contract_2 = pre.deploy_contract( # noqa: F841 - code=Op.MSTORE( - offset=0x0, - value=0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF, # noqa: E501 - ) - + Op.SSTORE(key=0xFF, value=0x600D) - + Op.RETURN(offset=0x0, size=0x1000) - + Op.STOP, - balance=0xBA1A9CE0BA1A9CE, - nonce=0, - address=Address(0x0000000000000000000000000000000000001002), # noqa: E501 - ) - # Source: lll - # { - # [0] 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef - # [[0xFF]] 0x600D # (return 0x05 0x20) # } contract_3 = pre.deploy_contract( # noqa: F841 @@ -213,7 +196,24 @@ def test_return( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) + # Source: lll + # { + # [0] 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + # [[0xFF]] 0x600D + # (return 0x00 0x1000) + # } + contract_2 = pre.deploy_contract( # noqa: F841 + code=Op.MSTORE( + offset=0x0, + value=0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF, # noqa: E501 + ) + + Op.SSTORE(key=0xFF, value=0x600D) + + Op.RETURN(offset=0x0, size=0x1000) + + Op.STOP, + balance=0xBA1A9CE0BA1A9CE, + nonce=0, + address=Address(0x0000000000000000000000000000000000001002), # noqa: E501 + ) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmIOandFlowOperations/test_sstore_sload.py b/tests/ported_static/vmIOandFlowOperations/test_sstore_sload.py index 810c9dabdd4..21b82a91fe5 100644 --- a/tests/ported_static/vmIOandFlowOperations/test_sstore_sload.py +++ b/tests/ported_static/vmIOandFlowOperations/test_sstore_sload.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -69,9 +68,7 @@ def test_sstore_sload( contract_1 = Address(0x0000000000000000000000000000000000001001) contract_2 = Address(0x0000000000000000000000000000000000001002) contract_3 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -150,7 +147,6 @@ def test_sstore_sload( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmLogTest/test_log0.py b/tests/ported_static/vmLogTest/test_log0.py index dab95e1ab8e..d743762ab28 100644 --- a/tests/ported_static/vmLogTest/test_log0.py +++ b/tests/ported_static/vmLogTest/test_log0.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -104,9 +103,7 @@ def test_log0( contract_6 = Address(0x0000000000000000000000000000000000001006) contract_7 = Address(0x000000000000000000000000000000000000100A) contract_8 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -284,7 +281,6 @@ def test_log0( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmLogTest/test_log1.py b/tests/ported_static/vmLogTest/test_log1.py index c34f0bd9fae..b4309d454e6 100644 --- a/tests/ported_static/vmLogTest/test_log1.py +++ b/tests/ported_static/vmLogTest/test_log1.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -111,9 +110,7 @@ def test_log1( contract_7 = Address(0x0000000000000000000000000000000000001007) contract_8 = Address(0x0000000000000000000000000000000000001008) contract_9 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -308,7 +305,6 @@ def test_log1( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmLogTest/test_log2.py b/tests/ported_static/vmLogTest/test_log2.py index ccba83f956d..95fa656fe44 100644 --- a/tests/ported_static/vmLogTest/test_log2.py +++ b/tests/ported_static/vmLogTest/test_log2.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -111,9 +110,7 @@ def test_log2( contract_7 = Address(0x0000000000000000000000000000000000001007) contract_8 = Address(0x0000000000000000000000000000000000001008) contract_9 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -309,7 +306,6 @@ def test_log2( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmLogTest/test_log3.py b/tests/ported_static/vmLogTest/test_log3.py index d2157c11d13..a763ee5fd27 100644 --- a/tests/ported_static/vmLogTest/test_log3.py +++ b/tests/ported_static/vmLogTest/test_log3.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -118,9 +117,7 @@ def test_log3( contract_8 = Address(0x0000000000000000000000000000000000001008) contract_9 = Address(0x0000000000000000000000000000000000001009) contract_10 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -353,7 +350,6 @@ def test_log3( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmLogTest/test_log4.py b/tests/ported_static/vmLogTest/test_log4.py index 90163b8a93b..3266265017a 100644 --- a/tests/ported_static/vmLogTest/test_log4.py +++ b/tests/ported_static/vmLogTest/test_log4.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -118,9 +117,7 @@ def test_log4( contract_8 = Address(0x0000000000000000000000000000000000001008) contract_9 = Address(0x0000000000000000000000000000000000001009) contract_10 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0x100000000000) env = Environment( fee_recipient=coinbase, @@ -399,7 +396,6 @@ def test_log4( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmTests/test_block_info.py b/tests/ported_static/vmTests/test_block_info.py index 97511d5c869..57fc33cc47d 100644 --- a/tests/ported_static/vmTests/test_block_info.py +++ b/tests/ported_static/vmTests/test_block_info.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -83,9 +82,7 @@ def test_block_info( contract_3 = Address(0x0000000000000000000000000000000000001003) contract_4 = Address(0x0000000000000000000000000000000000001004) contract_5 = Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC) - sender = EOA( - key=0x45A915E4D060149EB4365960E6A7A45F334393093061116B197E3240065FF2D8 - ) + sender = pre.fund_eoa(amount=0xBA1A9CE0BA1A9CE) env = Environment( fee_recipient=coinbase, @@ -165,17 +162,12 @@ def test_block_info( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { "indexes": {"data": [0], "gas": -1, "value": -1}, "network": [">=Cancun"], - "result": { - contract_0: Account( - storage={0: 0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA}, - ), - }, + "result": {contract_0: Account(storage={0: coinbase})}, }, { "indexes": {"data": [1], "gas": -1, "value": -1}, diff --git a/tests/ported_static/vmTests/test_env_info.py b/tests/ported_static/vmTests/test_env_info.py index a2a3dd0f4f4..67c2e62f6d6 100644 --- a/tests/ported_static/vmTests/test_env_info.py +++ b/tests/ported_static/vmTests/test_env_info.py @@ -131,6 +131,7 @@ def test_env_info( gas_limit=100000000, ) + pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) # Source: lll # { # [[0]] (address) @@ -269,13 +270,12 @@ def test_env_info( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0xBA1A9CE0BA1A9CE) expect_entries_: list[dict] = [ { "indexes": {"data": [0], "gas": -1, "value": -1}, "network": [">=Cancun"], - "result": {contract_0: Account(storage={0: 4096})}, + "result": {contract_0: Account(storage={0: contract_0})}, }, { "indexes": {"data": [1], "gas": -1, "value": -1}, @@ -301,11 +301,7 @@ def test_env_info( { "indexes": {"data": [4], "gas": -1, "value": -1}, "network": [">=Cancun"], - "result": { - contract_4: Account( - storage={0: 0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC}, - ), - }, + "result": {contract_4: Account(storage={0: contract_10})}, }, { "indexes": {"data": [5], "gas": -1, "value": -1}, @@ -325,11 +321,7 @@ def test_env_info( { "indexes": {"data": [8], "gas": -1, "value": -1}, "network": [">=Cancun"], - "result": { - contract_8: Account( - storage={0: 0xA94F5374FCE5EDBC8E2A8697C15331677E6EBF0B}, - ), - }, + "result": {contract_8: Account(storage={0: sender})}, }, { "indexes": {"data": [9], "gas": -1, "value": -1}, diff --git a/tests/ported_static/vmTests/test_random.py b/tests/ported_static/vmTests/test_random.py index 6e042591b1b..5a64236ce99 100644 --- a/tests/ported_static/vmTests/test_random.py +++ b/tests/ported_static/vmTests/test_random.py @@ -7,7 +7,6 @@ import pytest from execution_testing import ( - EOA, Account, Address, Alloc, @@ -83,9 +82,7 @@ def test_random( ) -> None: """Ori Pomerantz qbzzt1@gmail.""" coinbase = Address(0x2ADC25665018AA1FE0E6BC666DAC8FC2697FF9BA) - sender = EOA( - key=0xF3630C36A29EC9AF814AE38E4D48056A3368BB1435C5C2B3289763E4C77A3DF0 - ) + sender = pre.fund_eoa(amount=0x10000000000000) env = Environment( fee_recipient=coinbase, @@ -179,7 +176,6 @@ def test_random( nonce=0, address=Address(0xA83DB56C7CE68C06129B80C7BE0D0F5E0869D536), # noqa: E501 ) - pre[sender] = Account(balance=0x10000000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmTests/test_sha3.py b/tests/ported_static/vmTests/test_sha3.py index e2e8ed1be05..a3805b31105 100644 --- a/tests/ported_static/vmTests/test_sha3.py +++ b/tests/ported_static/vmTests/test_sha3.py @@ -180,6 +180,7 @@ def test_sha3( gas_limit=100000000, ) + pre[sender] = Account(balance=0x100000000000) # Source: lll # { # [[0]] (sha3 0 0) @@ -401,7 +402,6 @@ def test_sha3( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x100000000000) expect_entries_: list[dict] = [ { diff --git a/tests/ported_static/vmTests/test_suicide.py b/tests/ported_static/vmTests/test_suicide.py index 8fc985adfd1..02c1db148af 100644 --- a/tests/ported_static/vmTests/test_suicide.py +++ b/tests/ported_static/vmTests/test_suicide.py @@ -82,6 +82,7 @@ def test_suicide( gas_limit=100000000, ) + pre[sender] = Account(balance=0x5AF3107A4000) # Source: lll # { # (selfdestruct (caller)) @@ -131,7 +132,6 @@ def test_suicide( nonce=0, address=Address(0xCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC), # noqa: E501 ) - pre[sender] = Account(balance=0x5AF3107A4000) expect_entries_: list[dict] = [ { From 93984e2567a7d69cff4fff6927643e86072d8a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 27 Apr 2026 11:45:10 +0200 Subject: [PATCH 046/186] feat(tests): port stPreCompiledContracts/modexp 128-byte carry cases (#2753) Add two MODEXP parametrizations with 128-byte (1024-bit) operands to test_modexp. Both use modulus 2**1024 - 0x69 and reduce to 9^exp mod m (in the first case, base = m + 9). The modulus size forces the implementation through the multi-word Montgomery/Barrett reduction path rather than any 256-bit specialization. Also bump the test's gas_limit from 500k to 2M so the Byzantium pre-EIP-2565 cost (~682k for a 128-byte modulus) fits. The bump is a no-op for every existing case: the "out-of-gas" params OOG on modexp's own gas formula (huge declared exp/mod lengths), not on the tx cap, so they stay OOG at 2M. Ported from two legacy fillers that the bulk static-filler import in #1442 did not pull in: - src/LegacyTests/Constantinople/GeneralStateTestsFiller/ stPreCompiledContracts/modexp_37120_37111_37111_1000000Filler.json - src/LegacyTests/Constantinople/GeneralStateTestsFiller/ stPreCompiledContracts/modexp_9_37111_37111_1000000Filler.json Those fillers live in the ethereum/tests LegacyTests submodule (ethereum/legacytests), which the original port did not descend into. --- .../eip198_modexp_precompile/test_modexp.py | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/byzantium/eip198_modexp_precompile/test_modexp.py b/tests/byzantium/eip198_modexp_precompile/test_modexp.py index 9d654c59c81..8e041d1a0a8 100644 --- a/tests/byzantium/eip198_modexp_precompile/test_modexp.py +++ b/tests/byzantium/eip198_modexp_precompile/test_modexp.py @@ -449,11 +449,40 @@ ), id="truncated_input_4", ), + # 128-byte (1024-bit) operands exercising the multi-word + # Montgomery/Barrett reduction carry path. Modulus is + # 2**1024 - 0x69, so neither operand hits any 256-bit + # specialization. Both cases reduce to 9^exp mod m (base=m+9 in + # the first case), and with this exp, 9^exp ≡ 9 mod m. + pytest.param( + ModExpInput( + base="ff" * 127 + "a0", + exponent="ff" * 127 + "97", + modulus="ff" * 127 + "97", + ), + ModExpOutput(returned_data="0x" + "00" * 127 + "09"), + id="modexp_37120_37111_37111_1000000", + ), + pytest.param( + ModExpInput( + base="09", + exponent="ff" * 127 + "97", + modulus="ff" * 127 + "97", + ), + ModExpOutput(returned_data="0x" + "00" * 127 + "09"), + id="modexp_9_37111_37111_1000000", + ), ], ids=lambda param: param.__repr__(), # only required to remove parameter # names (input/output) ) @pytest.mark.eels_base_coverage +@pytest.mark.ported_from( + [ + "https://github.com/ethereum/legacytests/blob/master/src/LegacyTests/Constantinople/GeneralStateTestsFiller/stPreCompiledContracts/modexp_37120_37111_37111_1000000Filler.json", + "https://github.com/ethereum/legacytests/blob/master/src/LegacyTests/Constantinople/GeneralStateTestsFiller/stPreCompiledContracts/modexp_9_37111_37111_1000000Filler.json", + ], +) def test_modexp( state_test: StateTestFiller, mod_exp_input: ModExpInput | Bytes, @@ -504,7 +533,7 @@ def test_modexp( ty=0x0, to=account, data=mod_exp_input, - gas_limit=500_000, + gas_limit=2_000_000, protected=True, sender=sender, ) From 1fdd7e327fc81fd3e79041d80b03330fe5b42bfb Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 27 Apr 2026 17:27:31 +0200 Subject: [PATCH 047/186] fix(spec): fix bad formatting indroduced by large refactor (#2763) --- .../forks/arrow_glacier/vm/precompiled_contracts/blake2f.py | 5 +---- src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py index 9d8c71b806d..ae53b1ab4b5 100644 --- a/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/arrow_glacier/vm/precompiled_contracts/blake2f.py @@ -35,10 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas( - evm, - GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds, - ) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py index 9d8c71b806d..ae53b1ab4b5 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/blake2f.py @@ -35,10 +35,7 @@ def blake2f(evm: Evm) -> None: blake2b = Blake2b() rounds, h, m, t_0, t_1, f = blake2b.get_blake2_parameters(data) - charge_gas( - evm, - GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds, - ) + charge_gas(evm, GasCosts.PRECOMPILE_BLAKE2F_PER_ROUND * rounds) if f not in [0, 1]: raise InvalidParameter From c48eceaca0082049e19ad75af00c56f63c128efe Mon Sep 17 00:00:00 2001 From: felipe Date: Tue, 28 Apr 2026 11:18:45 +0200 Subject: [PATCH 048/186] feat(test-tools): t8n file streaming optimizations (#2751) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(test-tools): file-based t8n stream; replacing in-memory stdout Replaces Python's stdout-buffered, multi-pass parse of t8n output (which held up to ~5 copies of the alloc in flight: raw stdout bytes, parsed dict, re-serialized string, re-parsed dict, validated Alloc) with a file-based LazyAllocFile that streams {address: account_dict} entries incrementally via ``ijson`` and validates each ``Account`` one at a time, preserving every existing Pydantic validator. This cuts per-test peak RSS on the unchunkified benchmark from 5.38 GB → 3.40 GB (measured, fixtures byte-identical) — ~2 GB of Python-heap pressure removed per xdist worker. * fix(test-tools): fix issues with evm-dump-dir and ijson updates * fix: updates from comments on PR #2751 * feat(test-tools): stream chained-block t8n input via file path * fix(test-client-clis): ensure output dir exists in evm-dump script * fix(test-tools): force GC in `LazyAllocFile` keepalive test under PyPy `test_lazy_alloc_file_keepalive_pins_temp_dir` asserted that `del lazy` immediately wipes the temp directory pinned by `LazyAllocFile._keepalive`. That holds on CPython, where reference-counted finalization runs `TemporaryDirectory.__del__` -> `cleanup()` synchronously when the last reference drops. PyPy uses a generational garbage collector with no refcounting, so after `del lazy` the `TemporaryDirectory` is unreachable but not yet finalized, and the directory is still on disk when the next assertion runs. Add an explicit `gc.collect()` to trigger the finalizer deterministically on both interpreters. * fix(test-client-clis): release `LazyAllocFile` keepalive on `OutputCache` insert The PR introducing the file-based t8n alloc streaming path pins each producing call's `TemporaryDirectory` onto the resulting `LazyAllocFile` via `_keepalive`, so the next chained block can read `output/alloc.json` directly without re-serialization. That lifetime is correct for the live, unchained-handoff path: the predecessor's temp dir is dropped as soon as the consumer call returns and the previous `TransitionToolOutput` falls out of scope. `OutputCache`, however, keeps every `TransitionToolOutput` produced during a single test alive for the duration of that test (single-key cache, cleared on key change). When chained-block tests run with caching enabled, every cached subcall retains its own `output/alloc.json` plus the entire surrounding `TemporaryDirectory` on `/tmp`. This is `O(N)` for an `N`-block chained test, where each `alloc.json` can be hundreds of MB to several GB; for the unchunkified benchmark scenario this could easily exhaust `/tmp` on shared CI runners. Materialize the streamed alloc into the cached `Alloc` and clear `_keepalive` before storing the result. By the time we cache, the chained handoff has already happened (the consumer block has finished its `subprocess.run`), so the on-disk file is no longer needed for zero-copy chaining: the only future readers are cache replays from another fixture format, which want a parsed `Alloc` anyway. Tradeoff: - Cache replays now pay the `ijson` parse cost on insert rather than on first `.get()`. This is the same parse the live path performs lazily; doing it eagerly at cache-set is fine because we know the caller has just finished using the result, so amortizing the parse here avoids a later surprise during replay. - The cached entry retains the parsed `Alloc` in Python heap rather than the `alloc.json` on disk. For a typical chained benchmark this is a strict improvement: one parsed `Alloc` is smaller than the equivalent JSON text plus the `TemporaryDirectory` overhead, and the peak-RSS savings of the original streaming PR are preserved during the live run (the materialization happens after the producing call has already released its working buffers). - The streaming benefit during the first run is fully preserved; only the cached-replay path materializes. A move-the-keepalive-to-the-consumer alternative was considered and rejected: the consumer block currently sees only the predecessor's `Path`, not the `LazyAllocFile` instance, so threading explicit cleanup back to the predecessor would be invasive and tangled with the `TransitionToolData` flow. Releasing at cache-insertion is the lowest-blast-radius point: it's the moment we know the file isn't needed for chained handoff anymore, and it's localized to `OutputCache.set` rather than spread across the two `_evaluate_*` paths. * fix(test-client-clis): reject non-object top-level JSON in `LazyAllocFile.validate` `ijson.kvitems(f, "")` only yields key-value pairs when the top-level JSON value is an object: for `null`, `[]`, scalars, or other valid-but-non-object inputs, the iterator silently yields zero pairs. With the streaming alloc parser landed in this branch, that means `Alloc.model_validate({})` quietly succeeds and the t8n caller receives an empty post-state instead of an error. The pre-streaming path (`LazyAllocStr.validate`, which calls `Alloc.model_validate_json`) raised on those same inputs, so the streaming PR is a regression in error fidelity even though success-path behavior is unchanged: the t8n binaries we drive (geth, evmone, execution-specs) all produce object-shaped `alloc.json` by contract, so this failure mode does not fire under normal operation. The risk is the failure shape: a t8n that crashes after redirecting stdout, an output path that gets overwritten with an error JSON, or any future divergence from the contract would silently zero the post-state, and the test would only fail downstream with a misleading consensus mismatch rather than a clean "alloc.json is malformed" at the point of corruption. Silent corruption that surfaces far from its source is the costly kind of debugging. Probe the first parse event from `ijson.parse` and raise `ValueError` if it is not `start_map`, then seek back to zero and let `ijson.kvitems` consume the stream as before. Tradeoffs: - One extra parse event per call. `ijson.parse` is event-driven; pulling a single event then re-seeking is effectively free relative to the streamed body parse, and we keep the `kvitems`-based hot path so the entry-by-entry validation pattern is unchanged. - `ValueError` rather than reusing `ijson.IncompleteJSONError`: the input here is well-formed JSON (just the wrong shape), so reporting it as an incomplete-stream error would itself be misleading. The existing malformed-JSON tests continue to surface as `IncompleteJSONError` from inside `ijson.parse` because those inputs raise before we ever read a complete first event: the new guard only takes effect for valid JSON of the wrong type. - The legitimately empty alloc (`{}`) is preserved: the guard accepts `start_map` and the rest of the function returns an empty `Alloc` exactly as before. New regression test covers this. Three new parametrized cases (`null`, `[]`, `42`) cover the silent-zero scenarios, and a positive test for `{}` pins the empty-object behavior so future tightening cannot accidentally reject it. --------- Co-authored-by: danceratopz --- packages/testing/pyproject.toml | 1 + .../client_clis/cli_types.py | 154 +++++++-- .../client_clis/file_utils.py | 56 ++-- .../client_clis/tests/test_transition_tool.py | 310 +++++++++++++++++- .../client_clis/transition_tool.py | 128 ++++++-- uv.lock | 82 +++++ 6 files changed, 644 insertions(+), 87 deletions(-) diff --git a/packages/testing/pyproject.toml b/packages/testing/pyproject.toml index 46f5f717649..12afa968097 100644 --- a/packages/testing/pyproject.toml +++ b/packages/testing/pyproject.toml @@ -52,6 +52,7 @@ dependencies = [ "ckzg>=2.1.3,<3", "tenacity>=9.0.0,<10", "Jinja2>=3,<4", + "ijson>=3.3,<4", ] [project.urls] diff --git a/packages/testing/src/execution_testing/client_clis/cli_types.py b/packages/testing/src/execution_testing/client_clis/cli_types.py index 41b74c73198..8fec397ebc2 100644 --- a/packages/testing/src/execution_testing/client_clis/cli_types.py +++ b/packages/testing/src/execution_testing/client_clis/cli_types.py @@ -1,7 +1,9 @@ """Types used in the transition tool interactions.""" import json -from dataclasses import dataclass +import shutil +import tempfile +from dataclasses import dataclass, field from pathlib import Path from typing import ( Annotated, @@ -10,13 +12,16 @@ Generic, List, NamedTuple, + Optional, Self, TypeVar, ) +import ijson # type: ignore[import-untyped] from pydantic import Field, PlainSerializer, PlainValidator from execution_testing.base_types import ( + Account, Bloom, Bytes, CamelModel, @@ -458,6 +463,55 @@ def validate(self) -> Alloc: return Alloc.model_validate_json(self.raw) +@dataclass(kw_only=True) +class LazyAllocFile(LazyAlloc[Path]): + """ + Lazy allocation backed by a filesystem path. + + Parses `{address: account_or_null}` entries from the file incrementally + via `ijson.kvitems` and validates each `Account` one at a time through + `Account.model_validate`. The full mapping of validated accounts is still + accumulated before `Alloc.model_validate` is called, so peak memory + scales with the size of the alloc — but the raw JSON string is never + held in Python memory, and there is no re-serialize / re-parse round + trip, which is where `LazyAllocStr` incurs its multi-GB peak. + + The optional ``_keepalive`` field holds the producing t8n call's + ``TemporaryDirectory`` so the on-disk alloc.json survives until this + LazyAllocFile is dropped. That lets a chained next-block t8n call + consume the alloc directly from disk (via ``--input.alloc=`` for + geth, or ``shutil.copyfile`` for filesystem t8ns) without round-tripping + through ``Alloc.get().model_dump_json()`` in Python. + """ + + _keepalive: Optional[tempfile.TemporaryDirectory] = field(default=None) + + def validate(self) -> Alloc: + """Validate the alloc by streaming entries from the backing file.""" + accumulated: Dict[str, Account | None] = {} + with open(self.raw, "rb") as f: + # `ijson.kvitems(f, "")` silently yields nothing for non-object + # top-level JSON (`null`, `[]`, scalars), which would turn a + # corrupted alloc.json into an empty post-state. Probe the first + # parse event so the streaming path matches the fail-loud + # behavior of `LazyAllocStr.validate` / + # `Alloc.model_validate_json`. + first = next(ijson.parse(f), None) + if first is None or first[1] != "start_map": + raise ValueError( + f"Expected JSON object at top level of {self.raw}" + ) + f.seek(0) + for address_str, account_data in ijson.kvitems(f, ""): + if account_data is None: + accumulated[address_str] = None + else: + accumulated[address_str] = Account.model_validate( + account_data + ) + return Alloc.model_validate(accumulated) + + @dataclass class TransitionToolInput: """Transition tool input.""" @@ -473,13 +527,20 @@ def to_files( """ Prepare the input in a directory path in the file system for consumption by the t8n tool. + + For ``LazyAllocFile`` inputs whose backing file is still on disk + (chained-block handoff: previous t8n call's temp dir is pinned via + the keepalive field), the alloc is copied byte-for-byte rather than + round-tripped through ``Alloc.get().model_dump_json()``. """ - if isinstance(self.alloc, Alloc): - alloc_contents = self.alloc.model_dump_json(**model_dump_config) - elif isinstance(self.alloc, LazyAllocStr): - alloc_contents = self.alloc.raw + alloc_path = directory_path / "alloc.json" + if ( + isinstance(self.alloc, LazyAllocFile) + and Path(self.alloc.raw).exists() + ): + shutil.copyfile(self.alloc.raw, alloc_path) else: - raise Exception(f"Invalid alloc type: {type(self.alloc)}") + alloc_path.write_text(self._serialize_alloc(**model_dump_config)) env_contents = self.env.model_dump_json(**model_dump_config) txs_contents = ( @@ -489,33 +550,41 @@ def to_files( ) + "]" ) - input_contents: Dict[str, str] = { - "alloc": alloc_contents, - "env": env_contents, - "txs": txs_contents, - } - if self.blob_params is not None: - input_contents["blobParams"] = self.blob_params.model_dump_json( - **model_dump_config - ) - input_paths: Dict[str, str] = {} - for content_type, contents in input_contents.items(): - file_path = directory_path / f"{content_type}.json" + input_paths: Dict[str, str] = {"alloc": str(alloc_path)} + for name, contents in (("env", env_contents), ("txs", txs_contents)): + file_path = directory_path / f"{name}.json" file_path.write_text(contents) - input_paths[content_type] = str(file_path) + input_paths[name] = str(file_path) + if self.blob_params is not None: + blob_path = directory_path / "blobParams.json" + blob_path.write_text( + self.blob_params.model_dump_json(**model_dump_config) + ) + input_paths["blobParams"] = str(blob_path) return input_paths - def model_dump_json(self, **model_dump_config: Any) -> str: - """Dump the model in string JSON format.""" + def _serialize_alloc(self, **model_dump_config: Any) -> str: + """Serialize ``self.alloc`` to a JSON string.""" if isinstance(self.alloc, Alloc): - alloc_contents = self.alloc.model_dump_json(**model_dump_config) - elif isinstance(self.alloc, LazyAllocStr): - alloc_contents = self.alloc.raw - else: - raise Exception(f"Invalid alloc type: {type(self.alloc)}") + return self.alloc.model_dump_json(**model_dump_config) + if isinstance(self.alloc, LazyAllocStr): + return self.alloc.raw + if isinstance(self.alloc, LazyAllocFile): + return self.alloc.get().model_dump_json(**model_dump_config) + raise Exception(f"Invalid alloc type: {type(self.alloc)}") + + def model_dump_json( + self, *, exclude_alloc: bool = False, **model_dump_config: Any + ) -> str: + """ + Dump the model in string JSON format. + Pass ``exclude_alloc=True`` when the t8n is reading the alloc from a + file path instead of the stdin bundle, to avoid building a multi-GB + JSON string in Python memory for chained-block handoffs. + """ env_contents = self.env.model_dump_json(**model_dump_config) txs_contents = ( "[" @@ -524,18 +593,21 @@ def model_dump_json(self, **model_dump_config: Any) -> str: ) + "]" ) - input_contents: Dict[str, str] = { - "alloc": alloc_contents, - "env": env_contents, - "txs": txs_contents, - } + input_contents: Dict[str, str] = {} + if not exclude_alloc: + input_contents["alloc"] = self._serialize_alloc( + **model_dump_config + ) + input_contents["env"] = env_contents + input_contents["txs"] = txs_contents if self.blob_params is not None: input_contents["blobParams"] = self.blob_params.model_dump_json( **model_dump_config ) - contents: List[str] = [] - for content_type, type_contents in input_contents.items(): - contents.append(f'"{content_type}": {type_contents}') + contents: List[str] = [ + f'"{content_type}": {type_contents}' + for content_type, type_contents in input_contents.items() + ] return "{" + ",".join(contents) + "}" def model_dump(self, mode: str, **model_dump_config: Any) -> Any: @@ -547,6 +619,10 @@ def model_dump(self, mode: str, **model_dump_config: Any) -> Any: ) elif isinstance(self.alloc, LazyAllocJson): alloc_contents = self.alloc.raw + elif isinstance(self.alloc, LazyAllocFile): + alloc_contents = self.alloc.get().model_dump( + mode=mode, **model_dump_config + ) else: raise Exception(f"Invalid alloc type: {type(self.alloc)}") @@ -582,13 +658,19 @@ def model_validate_files( """ Validate the model from the file system where each key is a different JSON file. + + `alloc.json` is referenced by path and parsed incrementally on + `.get()` via `LazyAllocFile`, so the full file is never held in + memory alongside the validated `Alloc`. """ - alloc_data = (directory_path / "alloc.json").read_text() result_data = (directory_path / "result.json").read_text() result = Result.model_validate_json( json_data=result_data, context=context ) - alloc = LazyAllocStr(raw=alloc_data, _state_root=result.state_root) + alloc = LazyAllocFile( + raw=directory_path / "alloc.json", + _state_root=result.state_root, + ) output = cls(result=result, alloc=alloc) return output diff --git a/packages/testing/src/execution_testing/client_clis/file_utils.py b/packages/testing/src/execution_testing/client_clis/file_utils.py index 5b2047a6e7b..47c1232dfbc 100644 --- a/packages/testing/src/execution_testing/client_clis/file_utils.py +++ b/packages/testing/src/execution_testing/client_clis/file_utils.py @@ -1,6 +1,7 @@ """Methods to work with the filesystem and json.""" import os +import shutil import stat from json import dump from pathlib import Path @@ -9,6 +10,7 @@ from pydantic import BaseModel, RootModel from execution_testing.client_clis.cli_types import ( + LazyAllocFile, LazyAllocJson, LazyAllocStr, TransitionToolInput, @@ -28,27 +30,41 @@ def dump_files_to_directory(output_path: Path, files: Dict[str, Any]) -> None: if rel_path: os.makedirs(output_path / rel_path, exist_ok=True) file_path = output_path / file_rel_path - with open(file_path, "w") as f: - if isinstance(file_contents, (LazyAllocStr, LazyAllocJson)): - if isinstance(file_contents, LazyAllocJson): - dump(file_contents.raw, f, ensure_ascii=True, indent=4) - else: - f.write(file_contents.raw) - - elif isinstance( - file_contents, (BaseModel, RootModel, TransitionToolInput) - ): - f.write( - file_contents.model_dump_json( - indent=4, - exclude_none=True, - by_alias=True, - ) + if ( + isinstance(file_contents, LazyAllocFile) + and Path(file_contents.raw).exists() + ): + shutil.copyfile(file_contents.raw, file_path) + elif isinstance(file_contents, LazyAllocFile): + # Backing temp dir was cleaned up after a previous `.get()` + # (e.g. chained-block t8n on the next block); fall back to + # the cached Alloc so debug dumps still capture the input. + file_path.write_text( + file_contents.get().model_dump_json( + indent=4, exclude_none=True, by_alias=True ) - elif isinstance(file_contents, str): - f.write(file_contents) - else: - dump(file_contents, f, ensure_ascii=True, indent=4) + ) + else: + with open(file_path, "w") as f: + if isinstance(file_contents, (LazyAllocStr, LazyAllocJson)): + if isinstance(file_contents, LazyAllocJson): + dump(file_contents.raw, f, ensure_ascii=True, indent=4) + else: + f.write(file_contents.raw) + elif isinstance( + file_contents, (BaseModel, RootModel, TransitionToolInput) + ): + f.write( + file_contents.model_dump_json( + indent=4, + exclude_none=True, + by_alias=True, + ) + ) + elif isinstance(file_contents, str): + f.write(file_contents) + else: + dump(file_contents, f, ensure_ascii=True, indent=4) if flags: file_mode = os.stat(file_path).st_mode if "x" in flags: diff --git a/packages/testing/src/execution_testing/client_clis/tests/test_transition_tool.py b/packages/testing/src/execution_testing/client_clis/tests/test_transition_tool.py index 5a77e809122..fa919bdbf42 100644 --- a/packages/testing/src/execution_testing/client_clis/tests/test_transition_tool.py +++ b/packages/testing/src/execution_testing/client_clis/tests/test_transition_tool.py @@ -1,10 +1,12 @@ """Test the transition tool and subclasses.""" +import json import shutil import subprocess from pathlib import Path from typing import Any, Type +import ijson # type: ignore[import-untyped] import pytest from execution_testing.client_clis import ( @@ -17,10 +19,14 @@ ) from execution_testing.client_clis.cli_types import ( LazyAlloc, + LazyAllocFile, LazyAllocJson, LazyAllocStr, + Result, + TransitionToolInput, + TransitionToolOutput, ) -from execution_testing.test_types import Alloc +from execution_testing.test_types import Alloc, Environment def test_default_tool() -> None: @@ -128,3 +134,305 @@ def test_lazy_alloc(ty: Type[LazyAlloc], raw: Any) -> None: lazy_instance = ty(raw=raw, _state_root=TEST_ALLOC_STATE_ROOT) assert lazy_instance.get() == TEST_ALLOC assert lazy_instance.state_root() == TEST_ALLOC_STATE_ROOT + + +def test_lazy_alloc_file(tmp_path: Path) -> None: + """LazyAllocFile streams the alloc from disk and yields the same Alloc.""" + alloc_path = tmp_path / "alloc.json" + alloc_path.write_text(TEST_ALLOC.model_dump_json()) + lazy_instance = LazyAllocFile( + raw=alloc_path, _state_root=TEST_ALLOC_STATE_ROOT + ) + assert lazy_instance.get() == TEST_ALLOC + assert lazy_instance.state_root() == TEST_ALLOC_STATE_ROOT + + +def test_lazy_alloc_file_handles_mixed_entries(tmp_path: Path) -> None: + """ + LazyAllocFile correctly reconstructs an Alloc containing None entries, + non-empty storage, long code, and multiple accounts. + """ + alloc = Alloc.model_validate( + { + 0xA: { + "balance": 1, + "nonce": 2, + "code": "0x" + "ab" * 128, + "storage": {"0x01": "0x02", "0x03": "0x04"}, + }, + 0xB: None, + 0xC: {"balance": "0xff", "nonce": 0, "code": "0x"}, + } + ) + state_root = alloc.state_root() + alloc_path = tmp_path / "alloc.json" + alloc_path.write_text(alloc.model_dump_json()) + lazy_instance = LazyAllocFile(raw=alloc_path, _state_root=state_root) + assert lazy_instance.get() == alloc + assert lazy_instance.state_root() == state_root + + +def _write_minimal_result(path: Path, state_root: Any) -> None: + """Write a minimal valid Result JSON to `path` using `state_root`.""" + result = Result.model_validate( + { + "stateRoot": state_root, + "txRoot": bytes(32), + "receiptsRoot": bytes(32), + "logsHash": bytes(32), + "logsBloom": bytes(256), + "receipts": [], + "gasUsed": 0, + } + ) + path.write_text(result.model_dump_json(by_alias=True, exclude_none=True)) + + +def test_model_validate_files_uses_lazy_alloc_file(tmp_path: Path) -> None: + """ + model_validate_files backs the alloc with the on-disk file, not a + multi-GB string in Python memory. + """ + alloc_path = tmp_path / "alloc.json" + alloc_path.write_text(TEST_ALLOC.model_dump_json()) + _write_minimal_result(tmp_path / "result.json", TEST_ALLOC_STATE_ROOT) + + output = TransitionToolOutput.model_validate_files(tmp_path) + + assert isinstance(output.alloc, LazyAllocFile) + assert output.alloc.raw == alloc_path + assert output.alloc.get() == TEST_ALLOC + + +def test_transition_tool_input_serializes_lazy_alloc_file( + tmp_path: Path, +) -> None: + """ + A `TransitionToolInput` carrying a `LazyAllocFile` (as happens when + one t8n invocation's output is chained into the next's input) can be + serialized via both `to_files` and `model_dump_json` without pulling + the alloc file into memory at `TransitionToolInput` construction. + """ + source_alloc = tmp_path / "source_alloc.json" + source_alloc.write_text(TEST_ALLOC.model_dump_json()) + lazy_alloc = LazyAllocFile( + raw=source_alloc, _state_root=TEST_ALLOC_STATE_ROOT + ) + + input_data = TransitionToolInput( + alloc=lazy_alloc, txs=[], env=Environment() + ) + + out_dir = tmp_path / "out" + out_dir.mkdir() + paths = input_data.to_files(out_dir, by_alias=True, exclude_none=True) + written_alloc = Alloc.model_validate_json(Path(paths["alloc"]).read_text()) + assert written_alloc == TEST_ALLOC + + dumped = input_data.model_dump_json(by_alias=True, exclude_none=True) + parsed = json.loads(dumped) + assert Alloc.model_validate(parsed["alloc"]) == TEST_ALLOC + + +def test_to_files_copies_chained_lazy_alloc_file_without_serialize( + tmp_path: Path, +) -> None: + """ + Chained-block handoff: `to_files` should copy the backing alloc file + byte-for-byte rather than round-tripping through + `LazyAllocFile.get().model_dump_json()`. Verified by populating the + file with bytes that don't match what pydantic would re-emit and + asserting those exact bytes survive the dump. + """ + source = tmp_path / "source_alloc.json" + # Indented form is not what `Alloc.model_dump_json()` emits — if to_files + # re-serialized through pydantic, the indentation would be lost. + source_bytes = json.dumps( + TEST_ALLOC.model_dump(mode="json"), indent=4 + ).encode() + source.write_bytes(source_bytes) + + lazy = LazyAllocFile(raw=source, _state_root=TEST_ALLOC_STATE_ROOT) + input_data = TransitionToolInput(alloc=lazy, txs=[], env=Environment()) + + out_dir = tmp_path / "out" + out_dir.mkdir() + paths = input_data.to_files(out_dir, by_alias=True, exclude_none=True) + assert Path(paths["alloc"]).read_bytes() == source_bytes + + +def test_model_dump_json_exclude_alloc_omits_alloc_field( + tmp_path: Path, +) -> None: + """ + `model_dump_json(exclude_alloc=True)` skips the alloc — used when the + t8n is reading alloc from `--input.alloc=` instead of the stdin + bundle, so Python never builds the multi-GB alloc JSON string. + """ + source = tmp_path / "alloc.json" + source.write_text(TEST_ALLOC.model_dump_json()) + lazy = LazyAllocFile(raw=source, _state_root=TEST_ALLOC_STATE_ROOT) + input_data = TransitionToolInput(alloc=lazy, txs=[], env=Environment()) + + full = json.loads( + input_data.model_dump_json(by_alias=True, exclude_none=True) + ) + assert set(full.keys()) == {"alloc", "env", "txs"} + + slim = json.loads( + input_data.model_dump_json( + exclude_alloc=True, by_alias=True, exclude_none=True + ) + ) + assert "alloc" not in slim + assert set(slim.keys()) == {"env", "txs"} + + +def test_lazy_alloc_file_keepalive_pins_temp_dir() -> None: + """ + `LazyAllocFile._keepalive` holds a `TemporaryDirectory` reference so + the on-disk alloc.json survives past the producing t8n call's logical + cleanup point — the next chained block can then consume the file + directly. Dropping the LazyAllocFile releases the keepalive and the + temp dir is cleaned up. + """ + import gc + import tempfile + + keep = tempfile.TemporaryDirectory() + keep_path = Path(keep.name) + alloc_path = keep_path / "alloc.json" + alloc_path.write_text(TEST_ALLOC.model_dump_json()) + + lazy = LazyAllocFile( + raw=alloc_path, + _state_root=TEST_ALLOC_STATE_ROOT, + _keepalive=keep, + ) + # Releasing our handle leaves the file alive via the keepalive on lazy. + del keep + assert alloc_path.exists() + assert lazy.get() == TEST_ALLOC + + # Dropping the LazyAllocFile drops the keepalive; TemporaryDirectory's + # finalizer wipes the directory. PyPy doesn't refcount, so trigger GC + # explicitly to run the finalizer deterministically. + del lazy + gc.collect() + assert not keep_path.exists() + + +def test_dump_files_to_directory_copies_lazy_alloc_file( + tmp_path: Path, +) -> None: + """ + `dump_files_to_directory` copies the backing file when given a + `LazyAllocFile`, preserving exact bytes without round-tripping the + alloc through Python memory. + """ + from execution_testing.client_clis.file_utils import ( + dump_files_to_directory, + ) + + source = tmp_path / "source_alloc.json" + source_text = TEST_ALLOC.model_dump_json() + source.write_text(source_text) + lazy = LazyAllocFile(raw=source, _state_root=TEST_ALLOC_STATE_ROOT) + + dump_dir = tmp_path / "dump" + dump_files_to_directory(dump_dir, {"output/alloc.json": lazy}) + + assert (dump_dir / "output" / "alloc.json").read_text() == source_text + + +def test_dump_files_to_directory_lazy_alloc_file_after_backing_removed( + tmp_path: Path, +) -> None: + """ + On chained blocks, the previous block's t8n temp dir is cleaned up after + its alloc is materialized via ``.get()``. The resulting ``LazyAllocFile`` + still carries a now-stale ``.raw`` path. Debug dumps must fall back to + re-serializing the cached ``Alloc`` instead of attempting to copy the + missing backing file. + """ + from execution_testing.client_clis.file_utils import ( + dump_files_to_directory, + ) + + source = tmp_path / "source_alloc.json" + source.write_text(TEST_ALLOC.model_dump_json()) + lazy = LazyAllocFile(raw=source, _state_root=TEST_ALLOC_STATE_ROOT) + lazy.get() + source.unlink() + + dump_dir = tmp_path / "dump" + dump_files_to_directory(dump_dir, {"input/alloc.json": lazy}) + + written = (dump_dir / "input" / "alloc.json").read_text() + assert Alloc.model_validate_json(written) == TEST_ALLOC + + +@pytest.mark.parametrize( + "contents", + [ + pytest.param(b"", id="empty_file"), + pytest.param(b"not json at all", id="garbage"), + pytest.param( + b'{"0x01": {"balance": 1, "nonce"', + id="truncated_mid_entry", + ), + pytest.param(b'{"0x01": {"balance": }}', id="invalid_value"), + ], +) +def test_lazy_alloc_file_malformed_json_raises( + tmp_path: Path, contents: bytes +) -> None: + """ + A malformed `alloc.json` surfaces as `ijson.IncompleteJSONError` when + `LazyAllocFile.validate()` streams it — no partial `Alloc` is returned. + """ + alloc_path = tmp_path / "alloc.json" + alloc_path.write_bytes(contents) + lazy = LazyAllocFile(raw=alloc_path, _state_root=TEST_ALLOC_STATE_ROOT) + + with pytest.raises(ijson.common.IncompleteJSONError): + lazy.get() + + +@pytest.mark.parametrize( + "contents", + [ + pytest.param(b"null", id="null"), + pytest.param(b"[]", id="array"), + pytest.param(b"42", id="scalar"), + ], +) +def test_lazy_alloc_file_non_object_top_level_raises( + tmp_path: Path, contents: bytes +) -> None: + """ + Valid JSON whose top-level value is not an object must raise rather + than silently producing an empty `Alloc`. `ijson.kvitems` would yield + nothing for these inputs, so without the explicit guard a corrupted + `alloc.json` would silently downgrade to a zero-account post-state. + """ + alloc_path = tmp_path / "alloc.json" + alloc_path.write_bytes(contents) + lazy = LazyAllocFile(raw=alloc_path, _state_root=TEST_ALLOC_STATE_ROOT) + + with pytest.raises(ValueError, match="Expected JSON object"): + lazy.get() + + +def test_lazy_alloc_file_empty_object_yields_empty_alloc( + tmp_path: Path, +) -> None: + """ + A legitimately empty alloc (`{}`) parses to an empty `Alloc` without + raising; the non-object guard must not reject this case. + """ + alloc_path = tmp_path / "alloc.json" + alloc_path.write_bytes(b"{}") + lazy = LazyAllocFile(raw=alloc_path, _state_root=TEST_ALLOC_STATE_ROOT) + + assert lazy.get() == Alloc.model_validate({}) diff --git a/packages/testing/src/execution_testing/client_clis/transition_tool.py b/packages/testing/src/execution_testing/client_clis/transition_tool.py index aad9f89a921..93d1d7e17d5 100644 --- a/packages/testing/src/execution_testing/client_clis/transition_tool.py +++ b/packages/testing/src/execution_testing/client_clis/transition_tool.py @@ -45,6 +45,7 @@ from .cli_types import ( LazyAlloc, + LazyAllocFile, OpcodeCount, Traces, TransactionReceipt, @@ -161,6 +162,15 @@ def get(self, subkey: int) -> TransitionToolOutput | None: def set(self, subkey: int, value: TransitionToolOutput) -> None: """Set a value in the cache for the current key.""" + alloc = getattr(value, "alloc", None) + if isinstance(alloc, LazyAllocFile): + # Materialize the streamed alloc before caching so the producing + # `TemporaryDirectory` (pinned via `_keepalive`) can be released. + # Without this, every cached subcall would retain its own + # `output/alloc.json` on disk for the test's lifetime - O(N) for + # an N-block chained test. + alloc.get() + alloc._keepalive = None self._cache[subkey] = value def clear(self) -> None: @@ -520,7 +530,12 @@ def _evaluate_filesystem( output.result.receipts, temp_dir, debug_output_path ) - temp_dir.cleanup() + # Pin temp_dir to the output alloc so the on-disk alloc.json + # survives until the next chained-block t8n call (or this + # LazyAllocFile is dropped) — lets the next call read the alloc + # via copyfile rather than re-serializing through Python. + if isinstance(output.alloc, LazyAllocFile): + output.alloc._keepalive = temp_dir return output @@ -668,15 +683,41 @@ def _evaluate_stream( profiler: Profiler, ) -> TransitionToolOutput: """ - Execute a transition tool using stdin and stdout for its inputs and + Execute a transition tool using stdin for inputs and files for outputs. + + The t8n writes `alloc.json`/`result.json`/`txs.rlp` into an + `output/` subdirectory of a temp dir; Python then parses `result.json` + eagerly and references `alloc.json` via `LazyAllocFile`, which + streams the file on demand. Avoids holding the full alloc JSON + (multi-GB for large benchmarks) in the stdout buffer alongside the + validated `Alloc` object graph. """ temp_dir = tempfile.TemporaryDirectory() - args = self.construct_args_stream(t8n_data, temp_dir) + output_dir = Path(temp_dir.name) / "output" + output_dir.mkdir() + + # Chained-block handoff: when the input alloc is a `LazyAllocFile` + # whose backing file is still on disk (pinned via the producing + # call's keepalive), point the t8n at it directly via + # `--input.alloc=` and omit alloc from the stdin bundle, so + # Python never builds a multi-GB JSON string for the next call. + alloc_path: Path | None = None + if ( + isinstance(t8n_data.alloc, LazyAllocFile) + and Path(t8n_data.alloc.raw).exists() + ): + alloc_path = Path(t8n_data.alloc.raw) + + args = self.construct_args_stream( + t8n_data, temp_dir, alloc_path=alloc_path + ) stdin = t8n_data.to_input() - process_input = stdin.model_dump_json(**model_dump_config) + process_input = stdin.model_dump_json( + exclude_alloc=alloc_path is not None, **model_dump_config + ) encoded_process_input = process_input.encode() result = subprocess.run( @@ -696,22 +737,20 @@ def _evaluate_stream( raise Exception("failed to evaluate: " + result.stderr.decode()) output: TransitionToolOutput = ( - TransitionToolOutput.model_validate_json( - result.stdout, + TransitionToolOutput.model_validate_files( + output_dir, context={"exception_mapper": self.exception_mapper}, ) ) if debug_output_path: with profiler.pause(): - dump_files_to_directory( - debug_output_path, - { - "output/alloc.json": output.alloc.raw, - "output/result.json": output.result, - "output/txs.rlp": str(output.body), - }, - ) + debug_output_dir = Path(debug_output_path) / "output" + debug_output_dir.mkdir(parents=True, exist_ok=True) + for name in ("alloc.json", "result.json", "txs.rlp"): + src = output_dir / name + if src.exists(): + shutil.copyfile(src, debug_output_dir / name) if self.supports_opcode_count: opcode_count_file_path = Path(temp_dir.name) / "opcodes.json" @@ -735,7 +774,14 @@ def _evaluate_stream( output.result.receipts, temp_dir, debug_output_path ) - temp_dir.cleanup() + # Pin temp_dir to the output alloc so the on-disk alloc.json + # survives until the next chained-block t8n call (or this + # LazyAllocFile is dropped) — lets the next call read the alloc + # via copyfile / `--input.alloc=` rather than re-serializing + # through Python. + if isinstance(output.alloc, LazyAllocFile): + output.alloc._keepalive = temp_dir + return output def safe_t8n_args( @@ -743,9 +789,16 @@ def safe_t8n_args( fork_name: str, chain_id: int, reward: int, - temp_dir: tempfile.TemporaryDirectory | None = None, + temp_dir: tempfile.TemporaryDirectory, + *, + alloc_path: Optional[Path] = None, ) -> List[str]: - """Safely construct t8n arguments with validated inputs.""" + """ + Safely construct t8n arguments with validated inputs. + + When ``alloc_path`` is provided (chained-block handoff), the alloc is + read from that file rather than from the stdin bundle. + """ # Validate fork name against actual transition tool names from all # available forks valid_forks = get_valid_transition_tool_names() @@ -760,13 +813,25 @@ def safe_t8n_args( if not isinstance(reward, int) or reward < 0: raise ValueError(f"Invalid reward: {reward}") - # Use literal strings for command flags - input_alloc: LiteralString = "--input.alloc=stdin" + if temp_dir is None: + raise ValueError( + "safe_t8n_args requires a temp_dir for file-based outputs" + ) + + # env/txs still come through stdin; alloc is either bundled on stdin + # (initial block) or streamed from a path (chained-block handoff). + # Outputs always go to files in the existing temp dir so Python can + # stream-read the post-state alloc rather than buffering stdout. + input_alloc = ( + f"--input.alloc={alloc_path}" + if alloc_path is not None + else "--input.alloc=stdin" + ) input_txs: LiteralString = "--input.txs=stdin" input_env: LiteralString = "--input.env=stdin" - output_result: LiteralString = "--output.result=stdout" - output_alloc: LiteralString = "--output.alloc=stdout" - output_body: LiteralString = "--output.body=stdout" + output_result: LiteralString = "--output.result=output/result.json" + output_alloc: LiteralString = "--output.alloc=output/alloc.json" + output_body: LiteralString = "--output.body=output/txs.rlp" trace_flag: LiteralString = "--trace" args = [ @@ -779,13 +844,12 @@ def safe_t8n_args( f"--state.fork={fork_name}", f"--state.chainid={chain_id}", f"--state.reward={reward}", + f"--output.basedir={temp_dir.name}", ] - if temp_dir and (self.trace or self.supports_opcode_count): - args.append(f"--output.basedir={temp_dir.name}") if self.trace: args.append(trace_flag) - if self.supports_opcode_count and temp_dir: + if self.supports_opcode_count: args.extend(["--opcode.count", "opcodes.json"]) return args @@ -794,6 +858,8 @@ def construct_args_stream( self, t8n_data: TransitionToolData, temp_dir: tempfile.TemporaryDirectory, + *, + alloc_path: Optional[Path] = None, ) -> List[str]: """Construct arguments for t8n interaction via streams.""" command: list[str] = [str(self.binary)] @@ -801,7 +867,11 @@ def construct_args_stream( command.append(self.subcommand) safe_args = self.safe_t8n_args( - t8n_data.fork_name, t8n_data.chain_id, t8n_data.reward, temp_dir + t8n_data.fork_name, + t8n_data.chain_id, + t8n_data.reward, + temp_dir, + alloc_path=alloc_path, ) return command + safe_args @@ -818,16 +888,14 @@ def dump_debug_stream( """ t8n_call = " ".join(args) t8n_output_base_dir = os.path.join(debug_output_path, "t8n.sh.out") - if self.trace: - t8n_call = t8n_call.replace(temp_dir.name, t8n_output_base_dir) + t8n_call = t8n_call.replace(temp_dir.name, t8n_output_base_dir) t8n_script = textwrap.dedent( f"""\ #!/bin/bash # hard-coded to avoid surprises rm -rf {debug_output_path}/t8n.sh.out - # unused if tracing is not enabled - mkdir {debug_output_path}/t8n.sh.out + mkdir -p {debug_output_path}/t8n.sh.out/output {t8n_call} < {debug_output_path}/stdin.txt """ ) diff --git a/uv.lock b/uv.lock index 056dedb4e0a..24d5828490a 100644 --- a/uv.lock +++ b/uv.lock @@ -1062,6 +1062,7 @@ dependencies = [ { name = "ethereum-types" }, { name = "filelock" }, { name = "gitpython" }, + { name = "ijson" }, { name = "jinja2" }, { name = "joblib" }, { name = "platformdirs" }, @@ -1115,6 +1116,7 @@ requires-dist = [ { name = "ethereum-types", specifier = ">=0.3.0,<0.4" }, { name = "filelock", specifier = ">=3.15.1,<4" }, { name = "gitpython", specifier = ">=3.1.31,<4" }, + { name = "ijson", specifier = ">=3.3,<4" }, { name = "jinja2", specifier = ">=3,<4" }, { name = "joblib", specifier = ">=1.4.2" }, { name = "platformdirs", specifier = ">=4.2,<5" }, @@ -1296,6 +1298,86 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] +[[package]] +name = "ijson" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/57/60d1a6a512f2f0508d0bc8b4f1cc5616fd3196619b66bd6a01f9155a1292/ijson-3.5.0.tar.gz", hash = "sha256:94688760720e3f5212731b3cb8d30267f9a045fb38fb3870254e7b9504246f31", size = 68658, upload-time = "2026-02-24T03:58:30.974Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/da/644343198abca5e0f6e2486063f8d8f3c443ca0ef5e5c890e51ef6032e33/ijson-3.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5616311404b858d32740b7ad8b9a799c62165f5ecb85d0a8ed16c21665a90533", size = 88964, upload-time = "2026-02-24T03:56:53.099Z" }, + { url = "https://files.pythonhosted.org/packages/5b/63/8621190aa2baf96156dfd4c632b6aa9f1464411e50b98750c09acc0505ea/ijson-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9733f94029dd41702d573ef64752e2556e72aea14623d6dbb7a44ca1ccf30fd", size = 60582, upload-time = "2026-02-24T03:56:54.261Z" }, + { url = "https://files.pythonhosted.org/packages/20/31/6a3f041fdd17dacff33b7d7d3ba3df6dca48740108340c6042f974b2ad20/ijson-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db8398c6721b98412a4f618da8022550c8b9c5d9214040646071b5deb4d4a393", size = 60632, upload-time = "2026-02-24T03:56:55.159Z" }, + { url = "https://files.pythonhosted.org/packages/e4/68/474541998abbdecfd46a744536878335de89aceb9f085bff1aaf35575ceb/ijson-3.5.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c061314845c08163b1784b6076ea5f075372461a32e6916f4e5f211fd4130b64", size = 131988, upload-time = "2026-02-24T03:56:56.35Z" }, + { url = "https://files.pythonhosted.org/packages/cd/32/e05ff8b72a44fe9d192f41c5dcbc35cfa87efc280cdbfe539ffaf4a7535e/ijson-3.5.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1111a1c5ac79119c5d6e836f900c1a53844b50a18af38311baa6bb61e2645aca", size = 138669, upload-time = "2026-02-24T03:56:57.555Z" }, + { url = "https://files.pythonhosted.org/packages/49/b5/955a83b031102c7a602e2c06d03aff0a0e584212f09edb94ccc754d203ac/ijson-3.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e74aff8c681c24002b61b1822f9511d4c384f324f7dbc08c78538e01fdc9fcb", size = 135093, upload-time = "2026-02-24T03:56:59.267Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f2/30250cfcb4d2766669b31f6732689aab2bb91de426a15a3ebe482df7ee48/ijson-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:739a7229b1b0cc5f7e2785a6e7a5fc915e850d3fed9588d0e89a09f88a417253", size = 138715, upload-time = "2026-02-24T03:57:00.491Z" }, + { url = "https://files.pythonhosted.org/packages/a2/05/785a145d7e75e04e04480d59b6323cd4b1d9013a6cd8643fa635fbc93490/ijson-3.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ef88712160360cab3ca6471a4e5418243f8b267cf1fe1620879d1b5558babc71", size = 133194, upload-time = "2026-02-24T03:57:01.759Z" }, + { url = "https://files.pythonhosted.org/packages/14/eb/80d6f8a748dead4034cea0939494a67d10ccf88d6413bf6e860393139676/ijson-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6ca0d1b6b5f8166a6248f4309497585fb8553b04bc8179a0260fad636cfdb798", size = 135588, upload-time = "2026-02-24T03:57:03.131Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a8/bbc21f9400ebdbca48fab272593e0d1f875691be1e927d264d90d48b8c47/ijson-3.5.0-cp311-cp311-win32.whl", hash = "sha256:966039cf9047c7967febf7b9a52ec6f38f5464a4c7fbb5565e0224b7376fefff", size = 52721, upload-time = "2026-02-24T03:57:04.365Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2e/4e8c0208b8f920ee80c88c956f93e78318f2cfb646455353b182738b490c/ijson-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:6bad6a1634cb7c9f3f4c7e52325283b35b565f5b6cc27d42660c6912ce883422", size = 55121, upload-time = "2026-02-24T03:57:05.498Z" }, + { url = "https://files.pythonhosted.org/packages/aa/17/9c63c7688025f3a8c47ea717b8306649c8c7244e49e20a2be4e3515dc75c/ijson-3.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ebefbe149a6106cc848a3eaf536af51a9b5ccc9082de801389f152dba6ab755", size = 88536, upload-time = "2026-02-24T03:57:06.809Z" }, + { url = "https://files.pythonhosted.org/packages/6f/dd/e15c2400244c117b06585452ebc63ae254f5a6964f712306afd1422daae0/ijson-3.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:19e30d9f00f82e64de689c0b8651b9cfed879c184b139d7e1ea5030cec401c21", size = 60499, upload-time = "2026-02-24T03:57:09.155Z" }, + { url = "https://files.pythonhosted.org/packages/77/a9/bf4fe3538a0c965f16b406f180a06105b875da83f0743e36246be64ef550/ijson-3.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a04a33ee78a6f27b9b8528c1ca3c207b1df3b8b867a4cf2fcc4109986f35c227", size = 60330, upload-time = "2026-02-24T03:57:10.574Z" }, + { url = "https://files.pythonhosted.org/packages/31/76/6f91bdb019dd978fce1bc5ea1cd620cfc096d258126c91db2c03a20a7f34/ijson-3.5.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7d48dc2984af02eb3c56edfb3f13b3f62f2f3e4fe36f058c8cfc75d93adf4fed", size = 138977, upload-time = "2026-02-24T03:57:11.932Z" }, + { url = "https://files.pythonhosted.org/packages/11/be/bbc983059e48a54b0121ee60042979faed7674490bbe7b2c41560db3f436/ijson-3.5.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1e73a44844d9adbca9cf2c4132cd875933e83f3d4b23881fcaf82be83644c7d", size = 149785, upload-time = "2026-02-24T03:57:13.255Z" }, + { url = "https://files.pythonhosted.org/packages/6d/81/2fee58f9024a3449aee83edfa7167fb5ccd7e1af2557300e28531bb68e16/ijson-3.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7389a56b8562a19948bdf1d7bae3a2edc8c7f86fb59834dcb1c4c722818e645a", size = 149729, upload-time = "2026-02-24T03:57:14.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/56/f1706761fcc096c9d414b3dcd000b1e6e5c24364c21cfba429837f98ee8d/ijson-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3176f23f8ebec83f374ed0c3b4e5a0c4db7ede54c005864efebbed46da123608", size = 150697, upload-time = "2026-02-24T03:57:15.855Z" }, + { url = "https://files.pythonhosted.org/packages/d9/6e/ee0d9c875a0193b632b3e9ccd1b22a50685fb510256ad57ba483b6529f77/ijson-3.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6babd88e508630c6ef86c9bebaaf13bb2fb8ec1d8f8868773a03c20253f599bc", size = 142873, upload-time = "2026-02-24T03:57:16.831Z" }, + { url = "https://files.pythonhosted.org/packages/d2/bf/f9d4399d0e6e3fd615035290a71e97c843f17f329b43638c0a01cf112d73/ijson-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dc1b3836b174b6db2fa8319f1926fb5445abd195dc963368092103f8579cb8ed", size = 151583, upload-time = "2026-02-24T03:57:17.757Z" }, + { url = "https://files.pythonhosted.org/packages/b2/71/a7254a065933c0e2ffd3586f46187d84830d3d7b6f41cfa5901820a4f87d/ijson-3.5.0-cp312-cp312-win32.whl", hash = "sha256:6673de9395fb9893c1c79a43becd8c8fbee0a250be6ea324bfd1487bb5e9ee4c", size = 53079, upload-time = "2026-02-24T03:57:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/8f/7b/2edca79b359fc9f95d774616867a03ecccdf333797baf5b3eea79733918c/ijson-3.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f4f7fabd653459dcb004175235f310435959b1bb5dfa8878578391c6cc9ad944", size = 55500, upload-time = "2026-02-24T03:57:20.428Z" }, + { url = "https://files.pythonhosted.org/packages/a2/71/d67e764a712c3590627480643a3b51efcc3afa4ef3cb54ee4c989073c97e/ijson-3.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e9cedc10e40dd6023c351ed8bfc7dcfce58204f15c321c3c1546b9c7b12562a4", size = 88544, upload-time = "2026-02-24T03:57:21.293Z" }, + { url = "https://files.pythonhosted.org/packages/1a/39/f1c299371686153fa3cf5c0736b96247a87a1bee1b7145e6d21f359c505a/ijson-3.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3647649f782ee06c97490b43680371186651f3f69bebe64c6083ee7615d185e5", size = 60495, upload-time = "2026-02-24T03:57:22.501Z" }, + { url = "https://files.pythonhosted.org/packages/16/94/b1438e204d75e01541bebe3e668fe3e68612d210e9931ae1611062dd0a56/ijson-3.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90e74be1dce05fce73451c62d1118671f78f47c9f6be3991c82b91063bf01fc9", size = 60325, upload-time = "2026-02-24T03:57:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/30/e2/4aa9c116fa86cc8b0f574f3c3a47409edc1cd4face05d0e589a5a176b05d/ijson-3.5.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:78e9ad73e7be2dd80627504bd5cbf512348c55ce2c06e362ed7683b5220e8568", size = 138774, upload-time = "2026-02-24T03:57:24.683Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d2/738b88752a70c3be1505faa4dcd7110668c2712e582a6a36488ed1e295d4/ijson-3.5.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9577449313cc94be89a4fe4b3e716c65f09cc19636d5a6b2861c4e80dddebd58", size = 149820, upload-time = "2026-02-24T03:57:26.062Z" }, + { url = "https://files.pythonhosted.org/packages/ed/df/0b3ab9f393ca8f72ea03bc896ba9fdc987e90ae08cdb51c32a4ee0c14d5e/ijson-3.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e4c1178fb50aff5f5701a30a5152ead82a14e189ce0f6102fa1b5f10b2f54ff", size = 149747, upload-time = "2026-02-24T03:57:27.308Z" }, + { url = "https://files.pythonhosted.org/packages/cc/a3/b0037119f75131b78cb00acc2657b1a9d0435475f1f2c5f8f5a170b66b9c/ijson-3.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0eb402ab026ffb37a918d75af2b7260fe6cfbce13232cc83728a714dd30bd81d", size = 151027, upload-time = "2026-02-24T03:57:28.522Z" }, + { url = "https://files.pythonhosted.org/packages/22/a0/cb344de1862bf09d8f769c9d25c944078c87dd59a1b496feec5ad96309a4/ijson-3.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5b08ee08355f9f729612a8eb9bf69cc14f9310c3b2a487c6f1c3c65d85216ec4", size = 142996, upload-time = "2026-02-24T03:57:29.774Z" }, + { url = "https://files.pythonhosted.org/packages/ca/32/a8ffd67182e02ea61f70f62daf43ded4fa8a830a2520a851d2782460aba8/ijson-3.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bda62b6d48442903e7bf56152108afb7f0f1293c2b9bef2f2c369defea76ab18", size = 152068, upload-time = "2026-02-24T03:57:30.969Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d1/3578df8e75d446aab0ae92e27f641341f586b85e1988536adebc65300cb4/ijson-3.5.0-cp313-cp313-win32.whl", hash = "sha256:8d073d9b13574cfa11083cc7267c238b7a6ed563c2661e79192da4a25f09c82c", size = 53065, upload-time = "2026-02-24T03:57:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a2/f7cdaf5896710da3e69e982e44f015a83d168aa0f3a89b6f074b5426779d/ijson-3.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:2419f9e32e0968a876b04d8f26aeac042abd16f582810b576936bbc4c6015069", size = 55499, upload-time = "2026-02-24T03:57:32.773Z" }, + { url = "https://files.pythonhosted.org/packages/42/65/13e2492d17e19a2084523e18716dc2809159f2287fd2700c735f311e76c4/ijson-3.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4d4b0cd676b8c842f7648c1a783448fac5cd3b98289abd83711b3e275e143524", size = 93019, upload-time = "2026-02-24T03:57:33.976Z" }, + { url = "https://files.pythonhosted.org/packages/33/92/483fc97ece0c3f1cecabf48f6a7a36e89d19369eec462faaeaa34c788992/ijson-3.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:252dec3680a48bb82d475e36b4ae1b3a9d7eb690b951bb98a76c5fe519e30188", size = 62714, upload-time = "2026-02-24T03:57:34.819Z" }, + { url = "https://files.pythonhosted.org/packages/4b/88/793fe020a0fe9d9eed4c285cf4a5cfdb0a935708b3bde0d72f35c794b513/ijson-3.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:aa1b5dca97d323931fde2501172337384c958914d81a9dac7f00f0d4bfc76bc7", size = 62460, upload-time = "2026-02-24T03:57:35.874Z" }, + { url = "https://files.pythonhosted.org/packages/51/69/f1a2690aa8d4df1f4e262b385e65a933ffdc250b091531bac9a449c19e16/ijson-3.5.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7a5ec7fd86d606094bba6f6f8f87494897102fa4584ef653f3005c51a784c320", size = 199273, upload-time = "2026-02-24T03:57:37.07Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a2/f1346d5299e79b988ab472dc773d5381ec2d57c23cb2f1af3ede4a810e62/ijson-3.5.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:009f41443e1521847701c6d87fa3923c0b1961be3c7e7de90947c8cb92ea7c44", size = 216884, upload-time = "2026-02-24T03:57:38.346Z" }, + { url = "https://files.pythonhosted.org/packages/28/3c/8b637e869be87799e6c2c3c275a30a546f086b1aed77e2b7f11512168c5a/ijson-3.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e4c3651d1f9fe2839a93fdf8fd1d5ca3a54975349894249f3b1b572bcc4bd577", size = 207306, upload-time = "2026-02-24T03:57:39.718Z" }, + { url = "https://files.pythonhosted.org/packages/7f/7c/18b1c1df6951ca056782d7580ec40cea4ff9a27a0947d92640d1cc8c4ae3/ijson-3.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:945b7abcfcfeae2cde17d8d900870f03536494245dda7ad4f8d056faa303256c", size = 211364, upload-time = "2026-02-24T03:57:40.953Z" }, + { url = "https://files.pythonhosted.org/packages/f3/55/e795812e82851574a9dba8a53fde045378f531ef14110c6fb55dbd23b443/ijson-3.5.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0574b0a841ff97495c13e9d7260fbf3d85358b061f540c52a123db9dbbaa2ed6", size = 200608, upload-time = "2026-02-24T03:57:42.272Z" }, + { url = "https://files.pythonhosted.org/packages/5c/cd/013c85b4749b57a4cb4c2670014d1b32b8db4ab1a7be92ea7aeb5d7fe7b5/ijson-3.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f969ffb2b89c5cdf686652d7fb66252bc72126fa54d416317411497276056a18", size = 205127, upload-time = "2026-02-24T03:57:43.286Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7c/faf643733e3ab677f180018f6a855c4ef70b7c46540987424c563c959e42/ijson-3.5.0-cp313-cp313t-win32.whl", hash = "sha256:59d3f9f46deed1332ad669518b8099920512a78bda64c1f021fcd2aff2b36693", size = 55282, upload-time = "2026-02-24T03:57:44.353Z" }, + { url = "https://files.pythonhosted.org/packages/69/22/94ddb47c24b491377aca06cd8fc9202cad6ab50619842457d2beefde21ea/ijson-3.5.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c2839fa233746d8aad3b8cd2354e441613f5df66d721d59da4a09394bd1db2b", size = 58016, upload-time = "2026-02-24T03:57:45.237Z" }, + { url = "https://files.pythonhosted.org/packages/7a/93/0868efe753dc1df80cc405cf0c1f2527a6991643607c741bff8dcb899b3b/ijson-3.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:25a5a6b2045c90bb83061df27cfa43572afa43ba9408611d7bfe237c20a731a9", size = 89094, upload-time = "2026-02-24T03:57:46.115Z" }, + { url = "https://files.pythonhosted.org/packages/24/94/fd5a832a0df52ef5e4e740f14ac8640725d61034a1b0c561e8b5fb424706/ijson-3.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:8976c54c0b864bc82b951bae06567566ac77ef63b90a773a69cd73aab47f4f4f", size = 60715, upload-time = "2026-02-24T03:57:47.552Z" }, + { url = "https://files.pythonhosted.org/packages/70/79/1b9a90af5732491f9eec751ee211b86b11011e1158c555c06576d52c3919/ijson-3.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:859eb2038f7f1b0664df4241957694cc35e6295992d71c98659b22c69b3cbc10", size = 60638, upload-time = "2026-02-24T03:57:48.428Z" }, + { url = "https://files.pythonhosted.org/packages/23/6f/2c551ea980fe56f68710a8d5389cfbd015fc45aaafd17c3c52c346db6aa1/ijson-3.5.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c911aa02991c7c0d3639b6619b93a93210ff1e7f58bf7225d613abea10adc78e", size = 140667, upload-time = "2026-02-24T03:57:49.314Z" }, + { url = "https://files.pythonhosted.org/packages/25/0e/27b887879ba6a5bc29766e3c5af4942638c952220fd63e1e442674f7883a/ijson-3.5.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:903cbdc350173605220edc19796fbea9b2203c8b3951fb7335abfa8ed37afda8", size = 149850, upload-time = "2026-02-24T03:57:50.329Z" }, + { url = "https://files.pythonhosted.org/packages/da/1e/23e10e1bc04bf31193b21e2960dce14b17dbd5d0c62204e8401c59d62c08/ijson-3.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4549d96ded5b8efa71639b2160235415f6bdb8c83367615e2dbabcb72755c33", size = 149206, upload-time = "2026-02-24T03:57:51.261Z" }, + { url = "https://files.pythonhosted.org/packages/8e/90/e552f6495063b235cf7fa2c592f6597c057077195e517b842a0374fd470c/ijson-3.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6b2dcf6349e6042d83f3f8c39ce84823cf7577eba25bac5aae5e39bbbbbe9c1c", size = 150438, upload-time = "2026-02-24T03:57:52.198Z" }, + { url = "https://files.pythonhosted.org/packages/5c/18/45bf8f297c41b42a1c231d261141097babd953d2c28a07be57ae4c3a1a02/ijson-3.5.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e44af39e6f8a17e5627dcd89715d8279bf3474153ff99aae031a936e5c5572e5", size = 144369, upload-time = "2026-02-24T03:57:53.22Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3a/deb9772bb2c0cead7ad64f00c3598eec9072bdf511818e70e2c512eeabbe/ijson-3.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9260332304b7e7828db56d43f08fc970a3ab741bf84ff10189361ea1b60c395b", size = 151352, upload-time = "2026-02-24T03:57:54.375Z" }, + { url = "https://files.pythonhosted.org/packages/e4/51/67f4d80cd58ad7eab0cd1af5fe28b961886338956b2f88c0979e21914346/ijson-3.5.0-cp314-cp314-win32.whl", hash = "sha256:63bc8121bb422f6969ced270173a3fa692c29d4ae30c860a2309941abd81012a", size = 53610, upload-time = "2026-02-24T03:57:55.655Z" }, + { url = "https://files.pythonhosted.org/packages/70/d3/263672ea22983ba3940f1534316dbc9200952c1c2a2332d7a664e4eaa7ae/ijson-3.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:01b6dad72b7b7df225ef970d334556dfad46c696a2c6767fb5d9ed8889728bca", size = 56301, upload-time = "2026-02-24T03:57:56.584Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d9/86f7fac35e0835faa188085ae0579e813493d5261ce056484015ad533445/ijson-3.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:2ea4b676ec98e374c1df400a47929859e4fa1239274339024df4716e802aa7e4", size = 93069, upload-time = "2026-02-24T03:57:57.849Z" }, + { url = "https://files.pythonhosted.org/packages/33/d2/e7366ed9c6e60228d35baf4404bac01a126e7775ea8ce57f560125ed190a/ijson-3.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:014586eec043e23c80be9a923c56c3a0920a0f1f7d17478ce7bc20ba443968ef", size = 62767, upload-time = "2026-02-24T03:57:58.758Z" }, + { url = "https://files.pythonhosted.org/packages/35/8b/3e703e8cc4b3ada79f13b28070b51d9550c578f76d1968657905857b2ddd/ijson-3.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5b8b886b0248652d437f66e7c5ac318bbdcb2c7137a7e5327a68ca00b286f5f", size = 62467, upload-time = "2026-02-24T03:58:00.261Z" }, + { url = "https://files.pythonhosted.org/packages/21/42/0c91af32c1ee8a957fdac2e051b5780756d05fd34e4b60d94a08d51bac1d/ijson-3.5.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:498fd46ae2349297e43acf97cdc421e711dbd7198418677259393d2acdc62d78", size = 200447, upload-time = "2026-02-24T03:58:01.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/80/796ea0e391b7e2d45c5b1b451734bba03f81c2984cf955ea5eaa6c4920ad/ijson-3.5.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22a51b4f9b81f12793731cf226266d1de2112c3c04ba4a04117ad4e466897e05", size = 217820, upload-time = "2026-02-24T03:58:02.598Z" }, + { url = "https://files.pythonhosted.org/packages/38/14/52b6613fdda4078c62eb5b4fe3efc724ddc55a4ad524c93de51830107aa3/ijson-3.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9636c710dc4ac4a281baa266a64f323b4cc165cec26836af702c44328b59a515", size = 208310, upload-time = "2026-02-24T03:58:04.759Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ad/8b3105a78774fd4a65e534a21d975ef3a77e189489fe3029ebcaeba5e243/ijson-3.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f7168a39e8211107666d71b25693fd1b2bac0b33735ef744114c403c6cac21e1", size = 211843, upload-time = "2026-02-24T03:58:05.836Z" }, + { url = "https://files.pythonhosted.org/packages/36/ab/a2739f6072d6e1160581bc3ed32da614c8cced023dcd519d9c5fa66e0425/ijson-3.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8696454245415bc617ab03b0dc3ae4c86987df5dc6a90bad378fe72c5409d89e", size = 200906, upload-time = "2026-02-24T03:58:07.788Z" }, + { url = "https://files.pythonhosted.org/packages/6d/5e/e06c2de3c3d4a9cfb655c1ad08a68fb72838d271072cdd3196576ac4431a/ijson-3.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c21bfb61f71f191565885bf1bc29e0a186292d866b4880637b833848360bdc1b", size = 205495, upload-time = "2026-02-24T03:58:09.163Z" }, + { url = "https://files.pythonhosted.org/packages/7c/11/778201eb2e202ddd76b36b0fb29bf3d8e3c167389d8aa883c62524e49f47/ijson-3.5.0-cp314-cp314t-win32.whl", hash = "sha256:a2619460d6795b70d0155e5bf016200ac8a63ab5397aa33588bb02b6c21759e6", size = 56280, upload-time = "2026-02-24T03:58:10.116Z" }, + { url = "https://files.pythonhosted.org/packages/23/28/96711503245339084c8086b892c47415895eba49782d6cc52d9f4ee50301/ijson-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4f24b78d4ef028d17eb57ad1b16c0aed4a17bdd9badbf232dc5d9305b7e13854", size = 58965, upload-time = "2026-02-24T03:58:11.278Z" }, + { url = "https://files.pythonhosted.org/packages/d9/3b/d31ecfa63a218978617446159f3d77aab2417a5bd2885c425b176353ff78/ijson-3.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d64c624da0e9d692d6eb0ff63a79656b59d76bf80773a17c5b0f835e4e8ef627", size = 57715, upload-time = "2026-02-24T03:58:24.545Z" }, + { url = "https://files.pythonhosted.org/packages/30/51/b170e646d378e8cccf9637c05edb5419b00c2c4df64b0258c3af5355608e/ijson-3.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:876f7df73b7e0d6474f9caa729b9cdbfc8e76de9075a4887dfd689e29e85c4ca", size = 57205, upload-time = "2026-02-24T03:58:25.681Z" }, + { url = "https://files.pythonhosted.org/packages/ef/83/44dbd0231b0a8c6c14d27473d10c4e27dfbce7d5d9a833c79e3e6c33eb40/ijson-3.5.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e7dbff2c8d9027809b0cde663df44f3210da10ea377121d42896fb6ee405dd31", size = 71229, upload-time = "2026-02-24T03:58:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/cf84048b7c6cec888826e696a31f45bee7ebcac15e532b6be1fc4c2c9608/ijson-3.5.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4217a1edc278660679e1197c83a1a2a2d367792bfbb2a3279577f4b59b93730d", size = 71217, upload-time = "2026-02-24T03:58:28.021Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0a/e34c729a87ff67dc6540f6bcc896626158e691d433ab57db0086d73decd2/ijson-3.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04f0fc740311388ee745ba55a12292b722d6f52000b11acbb913982ba5fbdf87", size = 68618, upload-time = "2026-02-24T03:58:28.918Z" }, + { url = "https://files.pythonhosted.org/packages/c1/0f/e849d072f2e0afe49627de3995fc9dae54b4c804c70c0840f928d95c10e1/ijson-3.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fdeee6957f92e0c114f65c55cf8fe7eabb80cfacab64eea6864060913173f66d", size = 55369, upload-time = "2026-02-24T03:58:29.839Z" }, +] + [[package]] name = "importlib-resources" version = "6.5.2" From 78fe5d2cdf5481ae4fbd2c69305eff10599f884f Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 28 Apr 2026 05:51:33 -0400 Subject: [PATCH 049/186] feat(doc): sort fork directory listings chronologically (#2756) Co-authored-by: danceratopz --- Justfile | 6 ++- pyproject.toml | 5 +- src/ethereum_spec_tools/docc.py | 94 +++++++++++++++++++++++++++++---- uv.lock | 10 ++-- vulture_whitelist.py | 2 + 5 files changed, 98 insertions(+), 19 deletions(-) diff --git a/Justfile b/Justfile index 2e53741f3d2..acd86151406 100644 --- a/Justfile +++ b/Justfile @@ -274,10 +274,14 @@ export DYLD_FALLBACK_LIBRARY_PATH := if os() == "macos" { "/opt/homebrew/lib" } # Generate documentation for EELS using docc [group('docs')] -docs-spec: +docs-spec $DOCC_SKIP_DIFFS="": uv run docc --output "{{ output_dir }}/docs-spec" uv run python -c 'import pathlib; print("documentation available under file://{0}".format(pathlib.Path(r"{{ output_dir }}") / "docs-spec" / "index.html"))' +# Generate documentation for EELS using docc, skipping the slow per-fork diff render +[group('docs')] +docs-spec-fast: (docs-spec "1") + # Build HTML site documentation with mkdocs [group('docs')] docs *args: diff --git a/pyproject.toml b/pyproject.toml index 061bf8fd466..f3754331c36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -225,7 +225,7 @@ actionlint = [ "shellcheck-py>=0.10", ] doc = [ - "docc>=0.5.0,<0.6.0", + "docc>=0.5.1,<0.6.0", "fladrif>=0.2.0,<0.3.0", "mistletoe>=1.5.0,<2", ] @@ -271,6 +271,7 @@ ethereum-spec-evm = "ethereum_spec_tools.evm_tools:main" whitelist = "ethereum_spec_tools.whitelist:main" [project.entry-points."docc.plugins"] +"ethereum_spec_tools.docc.listing" = "ethereum_spec_tools.docc:EthereumListingDiscover" "ethereum_spec_tools.docc.discover" = "ethereum_spec_tools.docc:EthereumDiscover" "ethereum_spec_tools.docc.build" = "ethereum_spec_tools.docc:EthereumBuilder" "ethereum_spec_tools.docc.fix-indexes" = "ethereum_spec_tools.docc:FixIndexTransform" @@ -312,7 +313,7 @@ discovery = [ "docc.html.discover", "docc.python.discover", "ethereum_spec_tools.docc.discover", - "docc.listing.discover", + "ethereum_spec_tools.docc.listing", "docc.files.discover", ] build = [ diff --git a/src/ethereum_spec_tools/docc.py b/src/ethereum_spec_tools/docc.py index 9b10cd90b51..d0dbc586fdd 100644 --- a/src/ethereum_spec_tools/docc.py +++ b/src/ethereum_spec_tools/docc.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Ethereum Foundation +# Copyright (C) 2022-2023,2026 Ethereum Foundation # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -45,7 +45,12 @@ from docc.discover import Discover, T from docc.document import BlankNode, Document, ListNode, Node, Visit, Visitor from docc.plugins import html, mistletoe, python, verbatim -from docc.plugins.listing import Listable, ListingNode +from docc.plugins.listing import ( + Listable, + ListingDiscover, + ListingNode, + ListingSource, +) from docc.plugins.python import PythonBuilder from docc.plugins.references import Definition, Reference from docc.settings import PluginSettings @@ -71,6 +76,80 @@ def pairwise(iterable: Iterable[G]) -> Iterable[Tuple[G, G]]: return zip(a, b, strict=False) +class _EthereumListingSource(ListingSource): + _sort: Final[int] + + def __init__( + self, + relative_path: PurePath, + output_path: PurePath, + sources: Set[Source], + sort: int, + ) -> None: + super().__init__(relative_path, output_path, sources) + self._sort = sort + + @override + def listing_order_key( + self, + ) -> Tuple[bool, Tuple[int, PurePath], None]: + return (self.is_leaf, (self._sort, self.output_path), None) + + +def _find_forks(config: PluginSettings) -> List[Hardfork]: + forks = config.resolve_path(PurePath("src") / "ethereum" / "forks") + return Hardfork.discover([str(forks)]) + + +def _diff_path(before: Hardfork, after: Hardfork) -> PurePath: + return PurePath("diffs") / before.short_name / after.short_name + + +class EthereumListingDiscover(ListingDiscover): + """ + Changes the sort order of directory listings so they render in hard fork + chronological order. + """ + + fork_order: List[PurePath] + diff_order: List[PurePath] + + def __init__(self, config: PluginSettings) -> None: + super().__init__(config) + forks = _find_forks(config) + self.fork_order = [ + config.unresolve_path(PurePath(f.path)) + for f in forks + if f.path is not None + ] + self.diff_order = [_diff_path(b, a).parent for b, a in pairwise(forks)] + + def _fork_index(self, parent: PurePath) -> Optional[int]: + for idx, fork in enumerate(self.fork_order): + if parent.is_relative_to(fork): + return idx + + for idx, diff in enumerate(self.diff_order): + if parent.is_relative_to(diff): + return idx + + return None + + @override + def _listing_source( + self, source: Source, parent: PurePath + ) -> ListingSource: + index = self._fork_index(parent) + if index is None: + return super()._listing_source(source, parent) + return _EthereumListingSource( + parent, + parent / "index", + set(), + -index, # Reverse chronological order + ) + + class EthereumDiscover(Discover): """ Creates sources that represent the diff between two other sources, one per @@ -82,9 +161,7 @@ class EthereumDiscover(Discover): def __init__(self, config: PluginSettings) -> None: self.settings = config - base = config.resolve_path(PurePath("src") / "ethereum") - forks = base / "forks" - self.forks = Hardfork.discover([str(forks)]) + self.forks = _find_forks(config) def discover(self, known: FrozenSet[T]) -> Iterator[Source]: """ @@ -137,12 +214,7 @@ def discover(self, known: FrozenSet[T]) -> Iterator[Source]: assert before_source or after_source - output_path = ( - PurePath("diffs") - / before.short_name - / after.short_name - / path - ) + output_path = _diff_path(before, after) / path yield DiffSource( before.name, diff --git a/uv.lock b/uv.lock index 24d5828490a..007bb56fca5 100644 --- a/uv.lock +++ b/uv.lock @@ -737,7 +737,7 @@ wheels = [ [[package]] name = "docc" -version = "0.5.0" +version = "0.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-resources" }, @@ -749,9 +749,9 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a4/c0/16c29211d1681769235d1eae52646e4dd967cda77d9643935f1c30c6f0a1/docc-0.5.0.tar.gz", hash = "sha256:e49bd0fd9df6bbbd8857c9feea44dc29b3343ae8e044e8d5e0a23a4bd5c2ecb8", size = 71806, upload-time = "2026-04-15T19:01:16.554Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/cd/2843f0f6cb0a3bc2d4cf070477aab8779fdde7a07c83d91b7827a67d45bb/docc-0.5.1.tar.gz", hash = "sha256:b58f7cf8fb4010afb3828b034393244be899820b1bbf7661d7982f697ec78bdb", size = 71959, upload-time = "2026-04-25T01:07:01.706Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/85/2c3d246676f6cb8acb4a50c4cdf130137d7f089f7ffe220ff776b4e6960e/docc-0.5.0-py3-none-any.whl", hash = "sha256:90fcf22e49ada1aaf802ead8e209bcf03316806c6799f6a2606fb927afaf7f1b", size = 98611, upload-time = "2026-04-15T19:01:15.526Z" }, + { url = "https://files.pythonhosted.org/packages/00/82/8c21566c89fd1b76b4ee18e0ef86ded549a3aa7cb63d77c4aaccd00d64e1/docc-0.5.1-py3-none-any.whl", hash = "sha256:5d82e7b0c654ee7de6e6988ee677ff4ac93b427f19d82546941eda96d2f546c7", size = 98650, upload-time = "2026-04-25T01:07:00.454Z" }, ] [[package]] @@ -965,7 +965,7 @@ dev = [ { name = "cairosvg", specifier = ">=2.7.0,<3" }, { name = "codespell", specifier = "==2.4.1" }, { name = "codespell", specifier = ">=2.4.1,<3" }, - { name = "docc", specifier = ">=0.5.0,<0.6.0" }, + { name = "docc", specifier = ">=0.5.1,<0.6.0" }, { name = "ethereum-execution", extras = ["optimized"] }, { name = "ethereum-execution-testing", editable = "packages/testing" }, { name = "filelock", specifier = ">=3.15.1,<4" }, @@ -1003,7 +1003,7 @@ dev = [ { name = "vulture", specifier = "==2.14.0" }, ] doc = [ - { name = "docc", specifier = ">=0.5.0,<0.6.0" }, + { name = "docc", specifier = ">=0.5.1,<0.6.0" }, { name = "fladrif", specifier = ">=0.2.0,<0.3.0" }, { name = "mistletoe", specifier = ">=1.5.0,<2" }, ] diff --git a/vulture_whitelist.py b/vulture_whitelist.py index 5a44d33da7c..94bccfdbafb 100644 --- a/vulture_whitelist.py +++ b/vulture_whitelist.py @@ -56,6 +56,7 @@ # src/ethereum_spec_tools/docc.py docc.EthereumDiscover docc.EthereumBuilder +docc.EthereumListingDiscover docc.DiffSource.show_in_listing docc.FixIndexTransform docc.FixIndexTransform.transform @@ -71,6 +72,7 @@ docc._MinimizeDiffsVisitor.enter docc.render_diff docc.render_before_after +docc._EthereumListingSource.listing_order_key # src/ethereum_spec_tools/evm_tools/daemon.py _EvmToolHandler.do_POST From 6333758e404889469abfed22a3028fa0eb459520 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 28 Apr 2026 13:55:21 +0200 Subject: [PATCH 050/186] fix(ci): install build deps in hive-consume dev mode (#2773) Add the `setup-env` step to the `dev` matrix entry in `hive-consume.yaml` so that `pkg-config`, `libsecp256k1-dev`, and `build-essential` are available when `uv sync --all-extras` has to compile `coincurve` from source. `coincurve` 20.0.0 has no `cp313` wheel on PyPI, so it builds from source whenever the uv cache misses; without these system packages the build fails with `Could NOT find PkgConfig`. --- .github/workflows/hive-consume.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index d57778086f4..b3f439789cf 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -140,6 +140,10 @@ jobs: with: cache-dependency-glob: "execution-specs/uv.lock" + - name: Setup environment + if: matrix.mode == 'dev' + uses: ./execution-specs/.github/actions/setup-env + - name: Load cached Docker images uses: ./execution-specs/.github/actions/load-docker-images From bf9dbb4dfe86298d54b07816fc1bd36ec062b004 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 30 Apr 2026 01:59:28 +0200 Subject: [PATCH 051/186] chore(ci): generate-all-formats for mainnet fixture releases (#2781) --- .github/configs/feature.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/configs/feature.yaml b/.github/configs/feature.yaml index ab8aa27da2c..cf6a92748d9 100644 --- a/.github/configs/feature.yaml +++ b/.github/configs/feature.yaml @@ -1,7 +1,7 @@ # Unless filling for special features, all features should fill for previous forks (starting from Frontier) too mainnet: evm-type: eels - fill-params: --until=BPO2 + fill-params: --until=BPO2 --generate-all-formats benchmark: evm-type: benchmark From 8a052aa9d2034eb936c7da87062680a8af1ed061 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:26:39 -0400 Subject: [PATCH 052/186] feat(doc): replace index with __init__.py (#2779) --- pyproject.toml | 7 +- src/ethereum_spec_tools/docc.py | 139 +++++++++++++++++++++++++++----- uv.lock | 10 +-- vulture_whitelist.py | 1 + 4 files changed, 128 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f3754331c36..b89580d7ac0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -225,7 +225,7 @@ actionlint = [ "shellcheck-py>=0.10", ] doc = [ - "docc>=0.5.1,<0.6.0", + "docc>=0.6.0,<0.7.0", "fladrif>=0.2.0,<0.3.0", "mistletoe>=1.5.0,<2", ] @@ -273,6 +273,7 @@ whitelist = "ethereum_spec_tools.whitelist:main" [project.entry-points."docc.plugins"] "ethereum_spec_tools.docc.listing" = "ethereum_spec_tools.docc:EthereumListingDiscover" "ethereum_spec_tools.docc.discover" = "ethereum_spec_tools.docc:EthereumDiscover" +"ethereum_spec_tools.docc.python" = "ethereum_spec_tools.docc:EthereumPythonDiscover" "ethereum_spec_tools.docc.build" = "ethereum_spec_tools.docc:EthereumBuilder" "ethereum_spec_tools.docc.fix-indexes" = "ethereum_spec_tools.docc:FixIndexTransform" "ethereum_spec_tools.docc.minimize-diffs" = "ethereum_spec_tools.docc:MinimizeDiffsTransform" @@ -311,7 +312,7 @@ context = [ discovery = [ "docc.search.discover", "docc.html.discover", - "docc.python.discover", + "ethereum_spec_tools.docc.python", "ethereum_spec_tools.docc.discover", "ethereum_spec_tools.docc.listing", "docc.files.discover", @@ -341,7 +342,7 @@ excluded_references = [ "ethereum_spec_tools.lint.lints", # This is a namespace package. ] -[tool.docc.plugins."docc.python.discover"] +[tool.docc.plugins."ethereum_spec_tools.docc.python"] paths = [ "src", ] diff --git a/src/ethereum_spec_tools/docc.py b/src/ethereum_spec_tools/docc.py index d0dbc586fdd..c93a943eeb1 100644 --- a/src/ethereum_spec_tools/docc.py +++ b/src/ethereum_spec_tools/docc.py @@ -21,6 +21,7 @@ import logging import os from collections import defaultdict +from functools import total_ordering from itertools import tee, zip_longest from pathlib import PurePath from typing import ( @@ -51,7 +52,8 @@ ListingNode, ListingSource, ) -from docc.plugins.python import PythonBuilder +from docc.plugins.python import PythonBuilder, PythonDiscover +from docc.plugins.python.cst import PythonSource from docc.plugins.references import Definition, Reference from docc.settings import PluginSettings from docc.source import Source @@ -76,6 +78,44 @@ def pairwise(iterable: Iterable[G]) -> Iterable[Tuple[G, G]]: return zip(a, b, strict=False) +@total_ordering +@dataclasses.dataclass(frozen=True) +class _EthereumSortKey: + sort: int + path: PurePath + + def __lt__(self, other: object) -> bool: + if isinstance(other, _EthereumSortKey): + return (self.sort, self.path) < (other.sort, other.path) + elif isinstance(other, PurePath): + return self.path < other + return NotImplemented + + +class _EthereumPythonSource(PythonSource): + _sort: Final[int] + + def __init__( + self, + root_path: PurePath, + relative_path: PurePath, + absolute_path: PurePath, + sort: int, + ) -> None: + super().__init__(root_path, relative_path, absolute_path) + self._sort = sort + + @override + def listing_order_key( + self, + ) -> Tuple[bool, _EthereumSortKey, None]: + return ( + self.index_dir is None, + _EthereumSortKey(self._sort, self.output_path), + None, + ) + + class _EthereumListingSource(ListingSource): _sort: Final[int] @@ -83,17 +123,20 @@ def __init__( self, relative_path: PurePath, output_path: PurePath, - sources: Set[Source], sort: int, ) -> None: - super().__init__(relative_path, output_path, sources) + super().__init__(relative_path, output_path) self._sort = sort @override def listing_order_key( self, - ) -> Tuple[bool, Tuple[int, PurePath], None]: - return (self.is_leaf, (self._sort, self.output_path), None) + ) -> Tuple[bool, _EthereumSortKey, None]: + return ( + self.index_dir is None, + _EthereumSortKey(self._sort, self.output_path), + None, + ) def _find_forks(config: PluginSettings) -> List[Hardfork]: @@ -105,47 +148,85 @@ def _diff_path(before: Hardfork, after: Hardfork) -> PurePath: return PurePath("diffs") / before.short_name / after.short_name -class EthereumListingDiscover(ListingDiscover): - """ - Changes the sort order of directory listings so they render in hard fork - chronological order. - """ - - fork_order: List[PurePath] - diff_order: List[PurePath] +class _ForkOrder: + forks: List[PurePath] + diffs: List[PurePath] def __init__(self, config: PluginSettings) -> None: - super().__init__(config) forks = _find_forks(config) - self.fork_order = [ + self.forks = [ config.unresolve_path(PurePath(f.path)) for f in forks if f.path is not None ] - self.diff_order = [_diff_path(b, a).parent for b, a in pairwise(forks)] + self.diffs = [_diff_path(b, a).parent for b, a in pairwise(forks)] - def _fork_index(self, parent: PurePath) -> Optional[int]: - for idx, fork in enumerate(self.fork_order): + def index(self, parent: PurePath) -> Optional[int]: + for idx, fork in enumerate(self.forks): if parent.is_relative_to(fork): return idx - for idx, diff in enumerate(self.diff_order): + for idx, diff in enumerate(self.diffs): if parent.is_relative_to(diff): return idx return None + +class EthereumListingDiscover(ListingDiscover): + """ + Changes the sort order of directory listings so they render in hard fork + chronological order. + """ + + _fork_order: _ForkOrder + + def __init__(self, config: PluginSettings) -> None: + super().__init__(config) + self._fork_order = _ForkOrder(config) + @override def _listing_source( self, source: Source, parent: PurePath ) -> ListingSource: - index = self._fork_index(parent) + index = self._fork_order.index(parent) if index is None: return super()._listing_source(source, parent) return _EthereumListingSource( parent, parent / "index", - set(), + -index, # Reverse chronological order + ) + + +class EthereumPythonDiscover(PythonDiscover): + """ + Changes the sort order of python files so they render in hard fork + chronological order. + """ + + _fork_order: _ForkOrder + + def __init__(self, config: PluginSettings) -> None: + super().__init__(config) + self._fork_order = _ForkOrder(config) + + @override + def _python_source( + self, + root_path: PurePath, + relative_path: PurePath, + absolute_path: PurePath, + ) -> PythonSource: + index = self._fork_order.index(relative_path) + if index is None: + return super()._python_source( + root_path, relative_path, absolute_path + ) + return _EthereumPythonSource( + root_path, + relative_path, + absolute_path, -index, # Reverse chronological order ) @@ -214,6 +295,9 @@ def discover(self, known: FrozenSet[T]) -> Iterator[Source]: assert before_source or after_source + if path.name == "__init__.py": + path = path.with_name("index") + output_path = _diff_path(before, after) / path yield DiffSource( @@ -282,6 +366,19 @@ def output_path(self) -> PurePath: """ return self._output_path + @property + def index_dir(self) -> Optional[PurePath]: + """ + For index sources, the directory the source indexes. For other sources, + `None`. + + For example, for an output path of `./foo/index`, this should return + `./foo`. + """ + if self.output_path.name == "index": + return self.output_path.parent + return None + class AfterNode(Node): """ diff --git a/uv.lock b/uv.lock index 007bb56fca5..9c6ba50bf78 100644 --- a/uv.lock +++ b/uv.lock @@ -737,7 +737,7 @@ wheels = [ [[package]] name = "docc" -version = "0.5.1" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-resources" }, @@ -749,9 +749,9 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6f/cd/2843f0f6cb0a3bc2d4cf070477aab8779fdde7a07c83d91b7827a67d45bb/docc-0.5.1.tar.gz", hash = "sha256:b58f7cf8fb4010afb3828b034393244be899820b1bbf7661d7982f697ec78bdb", size = 71959, upload-time = "2026-04-25T01:07:01.706Z" } +sdist = { url = "https://files.pythonhosted.org/packages/be/37/cd2e718c92e26da0e1129700467f62efd8bd1f53dc1dae59b3e0e0402574/docc-0.6.0.tar.gz", hash = "sha256:d335be8f509884fefb507e75a184a3c9824e50e511dd5464be9089d1ad744912", size = 72398, upload-time = "2026-04-29T02:02:30.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/82/8c21566c89fd1b76b4ee18e0ef86ded549a3aa7cb63d77c4aaccd00d64e1/docc-0.5.1-py3-none-any.whl", hash = "sha256:5d82e7b0c654ee7de6e6988ee677ff4ac93b427f19d82546941eda96d2f546c7", size = 98650, upload-time = "2026-04-25T01:07:00.454Z" }, + { url = "https://files.pythonhosted.org/packages/6a/66/b81c58e0514531a26201f3d6b437b24375b996db5a8105d3e21420ccfc08/docc-0.6.0-py3-none-any.whl", hash = "sha256:bb4ed18f23926f1cea649a407c67d6794a92361826593e6ba374e80892fe98d1", size = 99176, upload-time = "2026-04-29T02:02:28.829Z" }, ] [[package]] @@ -965,7 +965,7 @@ dev = [ { name = "cairosvg", specifier = ">=2.7.0,<3" }, { name = "codespell", specifier = "==2.4.1" }, { name = "codespell", specifier = ">=2.4.1,<3" }, - { name = "docc", specifier = ">=0.5.1,<0.6.0" }, + { name = "docc", specifier = ">=0.6.0,<0.7.0" }, { name = "ethereum-execution", extras = ["optimized"] }, { name = "ethereum-execution-testing", editable = "packages/testing" }, { name = "filelock", specifier = ">=3.15.1,<4" }, @@ -1003,7 +1003,7 @@ dev = [ { name = "vulture", specifier = "==2.14.0" }, ] doc = [ - { name = "docc", specifier = ">=0.5.1,<0.6.0" }, + { name = "docc", specifier = ">=0.6.0,<0.7.0" }, { name = "fladrif", specifier = ">=0.2.0,<0.3.0" }, { name = "mistletoe", specifier = ">=1.5.0,<2" }, ] diff --git a/vulture_whitelist.py b/vulture_whitelist.py index 94bccfdbafb..f550b98e4df 100644 --- a/vulture_whitelist.py +++ b/vulture_whitelist.py @@ -56,6 +56,7 @@ # src/ethereum_spec_tools/docc.py docc.EthereumDiscover docc.EthereumBuilder +docc.EthereumPythonDiscover docc.EthereumListingDiscover docc.DiffSource.show_in_listing docc.FixIndexTransform From e4c43d6d02be6222af45edb06326203eacc9f032 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 30 Apr 2026 20:40:53 +0200 Subject: [PATCH 053/186] fix(tests) fix ported quadratic complexity tests (#2784) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(tests): correct stQuadraticComplexityTest post-state expectations Three of these tests embed the runtime caller address directly in their target contract's bytecode. The expected post hashed in a literal hex string of the bytecode that hardcoded the pre-dynamic EOA address (e.g. \`0xd9b97c712eb…\`), so once \`pre.fund_eoa()\` started picking addresses dynamically the deployed code no longer matched the expected hex. Hoist the bytecode into a \`target_code\` variable used both at deploy time and as the expected \`code\`, so the address baked in via \`Op.CALL(address=addr, …)\` is whatever \`addr\` resolves to at fill time: - \`test_call50000\` - \`test_callcode50000\` - \`test_call20_kbytes_contract50_2\` \`test_quadratic_complexity_solidity_call_data_copy\` had a different drift: its post asserted empty storage on \`contract_0\`, but the success path (\`g=1\`, 250M gas) commits \`SSTORE(0, 50000)\` before entering the loop. Make the expected storage \`g\`-conditional so \`g=0\` (OOG) keeps an empty \`storage\` and \`g=1\` records slot 0. * chore(tests): remove unrequired `# noqa: F841` * chore(ported_static): mark stQuadraticComplexityTest fixes as @manually-enhanced The four post-state corrections cherry-picked from PR #2784 should not be overwritten the next time `tests/ported_static/` is regenerated by `scripts/filler_to_python`. Add the `@manually-enhanced` marker to each docstring so the regenerator skips them. --------- Co-authored-by: Leo Lara --- .../test_call20_kbytes_contract50_2.py | 18 +++++++++------ .../test_call50000.py | 22 ++++++++++--------- .../test_callcode50000.py | 22 ++++++++++--------- ...atic_complexity_solidity_call_data_copy.py | 10 ++++++++- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py index e064cb3e94e..00f12488c0a 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call20_kbytes_contract50_2.py @@ -3,6 +3,9 @@ Ported from: state_tests/stQuadraticComplexityTest/Call20KbytesContract50_2Filler.json + +@manually-enhanced: Do not overwrite. Post-state expectations corrected +manually (see PR #2784). """ import pytest @@ -74,7 +77,7 @@ def test_call20_kbytes_contract50_2( # Source: raw # 0x60015b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b600101600055 # noqa: E501 - addr = pre.deploy_contract( # noqa: F841 + addr = pre.deploy_contract( code=Op.PUSH1[0x1] + Op.JUMPDEST * 22237 + Op.PUSH1[0x1] @@ -84,8 +87,8 @@ def test_call20_kbytes_contract50_2( ) # Source: lll # { (def 'i 0x80) (for {} (< @i 50) [i](+ @i 1) [[ 0 ]] (CALL 88250000000 0 0 0 0 0) ) [[ 1 ]] @i } # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST + target_code = ( + Op.JUMPDEST + Op.JUMPI( pc=0x40, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0x32)) ) @@ -105,7 +108,10 @@ def test_call20_kbytes_contract50_2( + Op.JUMP(pc=0x0) + Op.JUMPDEST + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x80)) - + Op.STOP, + + Op.STOP + ) + target = pre.deploy_contract( + code=target_code, balance=0xFFFFFFFFFFFFF, nonce=0, ) @@ -128,9 +134,7 @@ def test_call20_kbytes_contract50_2( addr: Account(storage={}, nonce=0), target: Account( storage={}, - code=bytes.fromhex( - "5b603260805110156040576000600060006000600073e7ebafa0fea97a99a72b7f0996c07477e54df0c264148c1c2280f16000556001608051016080526000565b60805160015500" # noqa: E501 - ), + code=bytes(target_code), nonce=0, ), }, diff --git a/tests/ported_static/stQuadraticComplexityTest/test_call50000.py b/tests/ported_static/stQuadraticComplexityTest/test_call50000.py index 09054e27c25..b250e191052 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_call50000.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_call50000.py @@ -3,6 +3,9 @@ Ported from: state_tests/stQuadraticComplexityTest/Call50000Filler.json + +@manually-enhanced: Do not overwrite. Post-state expectations corrected +manually (see PR #2784). """ import pytest @@ -70,11 +73,11 @@ def test_call50000( gas_limit=860000000, ) - addr = pre.fund_eoa(amount=7000) # noqa: F841 + addr = pre.fund_eoa(amount=7000) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALL 1600 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST + target_code = ( + Op.JUMPDEST + Op.JUMPI( pc=0x3F, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) @@ -94,7 +97,10 @@ def test_call50000( + Op.JUMP(pc=0x0) + Op.JUMPDEST + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x80)) - + Op.STOP, + + Op.STOP + ) + target = pre.deploy_contract( + code=target_code, balance=0xFFFFFFFFFFFFF, nonce=0, ) @@ -108,9 +114,7 @@ def test_call50000( addr: Account(storage={}, code=b"", nonce=0), target: Account( storage={}, - code=bytes.fromhex( - "5b61c3506080511015603f576000600061c3506000600173d9b97c712ebce43f3c19179bbef44b550f9e8bc0610640f16000556001608051016080526000565b60805160015500" # noqa: E501 - ), + code=bytes(target_code), nonce=0, ), }, @@ -123,9 +127,7 @@ def test_call50000( addr: Account(storage={}, code=b"", nonce=0), target: Account( storage={}, - code=bytes.fromhex( - "5b61c3506080511015603f576000600061c3506000600173d9b97c712ebce43f3c19179bbef44b550f9e8bc0610640f16000556001608051016080526000565b60805160015500" # noqa: E501 - ), + code=bytes(target_code), nonce=0, ), }, diff --git a/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py b/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py index 6d2ec3e0d83..ad6b43a3b19 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_callcode50000.py @@ -3,6 +3,9 @@ Ported from: state_tests/stQuadraticComplexityTest/Callcode50000Filler.json + +@manually-enhanced: Do not overwrite. Post-state expectations corrected +manually (see PR #2784). """ import pytest @@ -70,11 +73,11 @@ def test_callcode50000( gas_limit=8600000000, ) - addr = pre.fund_eoa(amount=7000) # noqa: F841 + addr = pre.fund_eoa(amount=7000) # Source: lll # { (def 'i 0x80) (for {} (< @i 50000) [i](+ @i 1) [[ 0 ]] (CALLCODE 1600 1 0 50000 0 0) ) [[ 1 ]] @i} # noqa: E501 - target = pre.deploy_contract( # noqa: F841 - code=Op.JUMPDEST + target_code = ( + Op.JUMPDEST + Op.JUMPI( pc=0x3F, condition=Op.ISZERO(Op.LT(Op.MLOAD(offset=0x80), 0xC350)) ) @@ -94,7 +97,10 @@ def test_callcode50000( + Op.JUMP(pc=0x0) + Op.JUMPDEST + Op.SSTORE(key=0x1, value=Op.MLOAD(offset=0x80)) - + Op.STOP, + + Op.STOP + ) + target = pre.deploy_contract( + code=target_code, balance=0xFFFFFFFFFFFFF, nonce=0, ) @@ -108,9 +114,7 @@ def test_callcode50000( addr: Account(storage={}, code=b"", nonce=0), target: Account( storage={}, - code=bytes.fromhex( - "5b61c3506080511015603f576000600061c3506000600173d9b97c712ebce43f3c19179bbef44b550f9e8bc0610640f26000556001608051016080526000565b60805160015500" # noqa: E501 - ), + code=bytes(target_code), nonce=0, ), }, @@ -123,9 +127,7 @@ def test_callcode50000( addr: Account(storage={}, code=b"", nonce=0), target: Account( storage={}, - code=bytes.fromhex( - "5b61c3506080511015603f576000600061c3506000600173d9b97c712ebce43f3c19179bbef44b550f9e8bc0610640f26000556001608051016080526000565b60805160015500" # noqa: E501 - ), + code=bytes(target_code), nonce=0, ), }, diff --git a/tests/ported_static/stQuadraticComplexityTest/test_quadratic_complexity_solidity_call_data_copy.py b/tests/ported_static/stQuadraticComplexityTest/test_quadratic_complexity_solidity_call_data_copy.py index c79f7f2d2cf..d9145437597 100644 --- a/tests/ported_static/stQuadraticComplexityTest/test_quadratic_complexity_solidity_call_data_copy.py +++ b/tests/ported_static/stQuadraticComplexityTest/test_quadratic_complexity_solidity_call_data_copy.py @@ -3,6 +3,9 @@ Ported from: state_tests/stQuadraticComplexityTest/QuadraticComplexitySolidity_CallDataCopyFiller.json + +@manually-enhanced: Do not overwrite. Post-state expectations corrected +manually (see PR #2784). """ import pytest @@ -152,9 +155,14 @@ def test_quadratic_complexity_solidity_call_data_copy( value=tx_value[v], ) + # With `g=1` the tx completes the inner CALL loop and the + # leading `SSTORE(0, 50000)` (the loop-counter snapshot taken + # before entering the loop body) commits. With `g=0` the tx + # OOGs and rolls everything back, leaving storage empty. + contract_0_storage = {0: 0xC350} if g == 1 else {} post = { contract_0: Account( - storage={}, + storage=contract_0_storage, code=bytes.fromhex( "60003560e060020a9004806361a4770614601557005b601e6004356024565b60006000f35b60008160008190555073b94f5374fce5edbc8e2a8697c15331677e6ebf0b90505b600082131560bf5780600160a060020a03166000600060007f6a7573740000000000000000000000000000000000000000000000000000000081526004017f63616c6c000000000000000000000000000000000000000000000000000000008152602001600060008560155a03f150506001820391506045565b505056" # noqa: E501 ), From 9d18733602f7a4ed41001c16525943ca0836af4c Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 30 Apr 2026 20:57:24 +0200 Subject: [PATCH 054/186] fix(test-forks): treat transition fork variants as equal to canonical (#2782) * test(test-forks): add failing test for transition fork variant equality Cover the case where `with_env_gas_limit` variants of a transition fork compare unequal to their canonical class and to each other, breaking pre-alloc group reuse during fill. * fix(test-forks): treat transition fork variants as equal to canonical `TransitionBaseClass.with_env_gas_limit` produced new class objects that compared unequal via the default `type.__eq__`, breaking pre-alloc group reuse during fill (assertion in `add_test_pre`). Mirror `BaseForkMeta` by adding `__eq__`/`__hash__` on `TransitionBaseMetaClass` keyed on the canonical identity, and set `_base_fork` on the variant inside `with_env_gas_limit`. Widen `_identity`/`_maybe_transitioned` signatures to `type` so the metaclass can reuse them. --- .../src/execution_testing/forks/base_fork.py | 14 ++++----- .../forks/tests/test_forks.py | 29 +++++++++++++++++++ .../forks/transition_base_fork.py | 19 ++++++++++-- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index a36f55ae1c1..afdc3ccfbc0 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -184,7 +184,7 @@ def __repr__(cls) -> str: return cls.name() @staticmethod - def _maybe_transitioned(fork_cls: "BaseForkMeta") -> "BaseForkMeta": + def _maybe_transitioned(fork_cls: type) -> type: """ Return the transitioned fork, if a transition fork, otherwise return `fork_cls`. @@ -203,14 +203,14 @@ def _is_subclass_of(a: "BaseForkMeta", b: "BaseForkMeta") -> bool: """ # Resolve variants to canonical identity so comparisons between # a variant and a canonical descendant fork work as expected. - a = BaseForkMeta._identity(a) - b = BaseForkMeta._identity(b) - a = BaseForkMeta._maybe_transitioned(a) - b = BaseForkMeta._maybe_transitioned(b) - return issubclass(a, b) + a_id: type = BaseForkMeta._identity(a) + b_id: type = BaseForkMeta._identity(b) + a_id = BaseForkMeta._maybe_transitioned(a_id) + b_id = BaseForkMeta._maybe_transitioned(b_id) + return issubclass(a_id, b_id) @staticmethod - def _identity(fork_cls: "BaseForkMeta") -> "BaseForkMeta": + def _identity(fork_cls: type) -> type: """Return the canonical fork class, resolving variants.""" base = getattr(fork_cls, "_base_fork", None) return base if base is not None else fork_cls diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index a1a2d3d8e28..d82d31e5c4a 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -754,3 +754,32 @@ def test_fork_variant_ordering() -> None: assert not (variant < London) assert variant >= London assert variant <= London + + +def test_transition_fork_variant_equality() -> None: + """ + Variants of a transition fork created via `with_env_gas_limit` must + compare equal to their canonical parent and to each other, even when + different gas limits are used. Distinct canonical transition forks + must remain unequal. + """ + canonical = CancunToPragueAtTime15k + variant_a = canonical.with_env_gas_limit(30_000_000) + variant_b = canonical.with_env_gas_limit(45_000_000) + variant_c = canonical.with_env_gas_limit(30_000_000) + + assert variant_a is not canonical + assert variant_a is not variant_b + assert variant_a is not variant_c + + assert variant_a == canonical + assert variant_b == canonical + assert variant_a == variant_b + assert variant_a == variant_c + + assert hash(variant_a) == hash(canonical) + assert hash(variant_b) == hash(canonical) + assert hash(variant_c) == hash(canonical) + + assert canonical != PragueToOsakaAtTime15k + assert variant_a != PragueToOsakaAtTime15k diff --git a/packages/testing/src/execution_testing/forks/transition_base_fork.py b/packages/testing/src/execution_testing/forks/transition_base_fork.py index 8f5c45aa0a0..482b3c877ff 100644 --- a/packages/testing/src/execution_testing/forks/transition_base_fork.py +++ b/packages/testing/src/execution_testing/forks/transition_base_fork.py @@ -1,8 +1,8 @@ """Base objects used to define transition forks.""" -from typing import Any, Callable, ClassVar, Dict, Type +from typing import Any, Callable, ClassVar, Dict, Optional, Type -from .base_fork import BaseFork +from .base_fork import BaseFork, BaseForkMeta class TransitionBaseMetaClass(type): @@ -15,6 +15,19 @@ def name(cls) -> str: """ raise Exception("Not implemented") + def __eq__(cls, other: object) -> bool: + """ + Compare transition fork identity, treating variants created by + `with_env_gas_limit` as equal to their canonical parent. + """ + if not isinstance(other, type): + return NotImplemented + return BaseForkMeta._identity(cls) is BaseForkMeta._identity(other) + + def __hash__(cls) -> int: + """Hash by canonical transition fork identity.""" + return id(BaseForkMeta._identity(cls)) + def transitions_to(cls) -> Type[BaseFork]: """ Return fork where the transition ends. @@ -76,6 +89,7 @@ class TransitionBaseClass(metaclass=TransitionBaseMetaClass): at_timestamp: ClassVar[int] = 0 _ignore: ClassVar[bool] = False _env_gas_limit: ClassVar[int] = 0 + _base_fork: ClassVar[Optional[Type["TransitionBaseClass"]]] = None @classmethod def fork_at( @@ -117,6 +131,7 @@ def with_env_gas_limit( """ new_cls = type(cls.__name__, (cls,), {}) new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] + new_cls._base_fork = cls._base_fork or cls # type: ignore[attr-defined] return new_cls From 8fa9a0572578af805b5acd53f8319f53d9eb3b9a Mon Sep 17 00:00:00 2001 From: Ben {chmark} Adams Date: Mon, 4 May 2026 16:28:23 +0200 Subject: [PATCH 055/186] Update Nethermind exception mappings (#2794) --- .../client_clis/clis/nethermind.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py index 918dd535939..a833759b36b 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py +++ b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py @@ -405,7 +405,14 @@ class NethermindExceptionMapper(ExceptionMapper): TransactionException.INSUFFICIENT_ACCOUNT_FUNDS: ( r"insufficient sender balance|" r"insufficient MaxFeePerGas for sender balance" + r"|insufficient funds for gas \* price \+ value" + r"|insufficient funds for transfer|insufficient funds for gas" ), + TransactionException.INSUFFICIENT_MAX_FEE_PER_GAS: ( + r"max fee per gas less than block base fee" + ), + TransactionException.NONCE_MISMATCH_TOO_LOW: (r"nonce too low"), + TransactionException.NONCE_MISMATCH_TOO_HIGH: (r"nonce too high"), TransactionException.TYPE_3_TX_WITH_FULL_BLOBS: ( r"Transaction \d+ is not valid" ), @@ -418,7 +425,7 @@ class NethermindExceptionMapper(ExceptionMapper): r"exceeded MaxBlobGas per transaction=\d+" ), TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM: ( - r"TxGasLimitCapExceeded: Gas limit \d+ \w+ cap of \d+\.?" + r"TxGasLimitCapExceeded:" ), BlockException.INCORRECT_EXCESS_BLOB_GAS: ( r"HeaderExcessBlobGasMismatch: Excess blob gas in header " @@ -442,14 +449,18 @@ class NethermindExceptionMapper(ExceptionMapper): BlockException.INVALID_BLOCK_ACCESS_LIST: ( r"InvalidBlockLevelAccessListHash:" r"|InvalidBlockLevelAccessList:" + r"|BlockLevelAccessListIndexOutOfRange:" r"|could not be parsed as a block: " r"Error decoding block access list:" + r"|Error decoding block access list:" ), BlockException.INCORRECT_BLOCK_FORMAT: ( r"could not be parsed as a block: " r"Error decoding block access list:" + r"|Error decoding block access list:" ), TransactionException.GAS_ALLOWANCE_EXCEEDED: ( r"TxGasLimitCapExceeded:" + r"|BlockAccessListGasLimitExceeded:" ), } From 1f41b21a40f9dad2e880705a778a2fe637360798 Mon Sep 17 00:00:00 2001 From: Gottfried Herold Date: Tue, 5 May 2026 15:29:13 +0200 Subject: [PATCH 056/186] benchmarks/compute/precompile/test_sha256.py: Add 64 byte test cases. (#2801) benchmarks/compute/precompile/test_ripemd160.py: Add 64 byte test cases. Due to how, internally, padding+splitting into blocks (of 64bytes) in the actual hash functions works, even multiples of 32bytes behave slightly differently wrt. gas pricing. So we need to add a 64byte test case here. --- tests/benchmark/compute/precompile/test_ripemd160.py | 4 ++-- tests/benchmark/compute/precompile/test_sha256.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/benchmark/compute/precompile/test_ripemd160.py b/tests/benchmark/compute/precompile/test_ripemd160.py index 219ec7876d3..bd433921301 100644 --- a/tests/benchmark/compute/precompile/test_ripemd160.py +++ b/tests/benchmark/compute/precompile/test_ripemd160.py @@ -53,7 +53,7 @@ def test_ripemd160( @pytest.mark.repricing -@pytest.mark.parametrize("size", [0, 32, 256, 1024]) +@pytest.mark.parametrize("size", [0, 32, 64, 256, 1024]) def test_ripemd160_fixed_size( benchmark_test: BenchmarkTestFiller, size: int ) -> None: @@ -71,7 +71,7 @@ def test_ripemd160_fixed_size( @pytest.mark.repricing -@pytest.mark.parametrize("size", [32, 256, 1024]) +@pytest.mark.parametrize("size", [32, 64, 256, 1024]) def test_ripemd160_uncachable( benchmark_test: BenchmarkTestFiller, pre: Alloc, diff --git a/tests/benchmark/compute/precompile/test_sha256.py b/tests/benchmark/compute/precompile/test_sha256.py index 6397ffbc8fd..967bb4f2218 100644 --- a/tests/benchmark/compute/precompile/test_sha256.py +++ b/tests/benchmark/compute/precompile/test_sha256.py @@ -53,7 +53,7 @@ def test_sha256( @pytest.mark.repricing -@pytest.mark.parametrize("size", [0, 32, 256, 1024]) +@pytest.mark.parametrize("size", [0, 32, 64, 256, 1024]) def test_sha256_fixed_size( benchmark_test: BenchmarkTestFiller, size: int ) -> None: @@ -71,7 +71,7 @@ def test_sha256_fixed_size( @pytest.mark.repricing -@pytest.mark.parametrize("size", [32, 256, 1024]) +@pytest.mark.parametrize("size", [32, 64, 256, 1024]) def test_sha256_uncachable( benchmark_test: BenchmarkTestFiller, pre: Alloc, From 63b589ec776c30eafc500c02f7a4489202959fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Wed, 6 May 2026 06:26:35 +0200 Subject: [PATCH 057/186] feat(test-benchmark): storage initialization helper with 7702 authorization (#2672) --- .../stateful/bloatnet/test_single_opcode.py | 187 +---------- .../helpers.py | 80 ++++- ...t_block_access_lists_compute_then_sload.py | 12 +- .../test_block_access_lists_max_accounts.py | 11 +- .../test_block_access_lists_max_sloads.py | 15 +- .../test_block_access_lists_pointer_chase.py | 12 +- tests/benchmark/stateful/helpers.py | 316 ++++++++++++++++++ 7 files changed, 422 insertions(+), 211 deletions(-) diff --git a/tests/benchmark/stateful/bloatnet/test_single_opcode.py b/tests/benchmark/stateful/bloatnet/test_single_opcode.py index 3e67019d9c3..6f97d3ff8ec 100644 --- a/tests/benchmark/stateful/bloatnet/test_single_opcode.py +++ b/tests/benchmark/stateful/bloatnet/test_single_opcode.py @@ -9,7 +9,7 @@ from enum import Enum, auto from functools import partial -from typing import Callable, Generator, List +from typing import Generator, List import pytest from execution_testing import ( @@ -45,6 +45,9 @@ BALANCEOF_SELECTOR, CacheStrategy, build_cache_strategy_blocks, + build_delegated_storage_setup, + create_sstore_initializer, + initializer_calldata_generator, ) REFERENCE_SPEC_GIT_PATH = "DUMMY/bloatnet.md" @@ -83,9 +86,9 @@ def _sender_generator( benchmarks so the BAL builder can group nonce changes by sender uniformly regardless of mode. """ - sender = pre.fund_eoa() + shared_sender = pre.fund_eoa() if not distinct_senders else None while True: - yield sender if not distinct_senders else pre.fund_eoa() + yield pre.fund_eoa() if shared_sender is None else shared_sender def delegate_with_calldata( @@ -883,50 +886,6 @@ def test_sstore_erc20_generic( ) -def create_sstore_initializer(init_val: int) -> IteratingBytecode: - """ - Create a contract that initializes storage slots from calldata parameters. - - - CALLDATA[0..32] start slot (index) - - CALLDATA[32..64] slot count (num) - - storage[i] = init_val for i in [index, index + num). - - Returns: IteratingBytecode representing the storage initializer. - """ - # Setup: [index, index + num] - prefix = ( - Op.CALLDATALOAD(0) # [index] - + Op.DUP1 # [index, index] - + Op.CALLDATALOAD(32) # [index, index, num] - + Op.ADD # [index, index + num] - ) - - # Loop: decrement counter and store at current position - # Stack after subtraction: [index, current] - # where current goes from index+num-1 down to index - loop = ( - Op.JUMPDEST - + Op.PUSH1(1) # [index, current, 1] - + Op.SWAP1 # [index, 1, current] - + Op.SUB # [index, current - 1] - + Op.SSTORE( # STORAGE[current-1] = initial_value - Op.DUP2, - init_val, - key_warm=False, - # gas accounting - original_value=0, - current_value=0, - new_value=init_val, - ) - # After SSTORE: [index, current - 1] - # Continue while current - 1 > index - + Op.JUMPI(len(prefix), Op.GT(Op.DUP2, Op.DUP2)) - ) - - return IteratingBytecode(setup=prefix, iterating=loop) - - def create_sstore_executor( sloads_before_sstore: bool, key_warm: bool, @@ -1088,140 +1047,6 @@ def executor_calldata_generator( return result -def initializer_calldata_generator( - iteration_count: int, start_iteration: int -) -> bytes: - """Calldata generator for the storage: Hash(start) + Hash(count).""" - return Hash(start_iteration) + Hash(iteration_count) - - -def pack_transactions_into_blocks( - transactions: List[Transaction], - gas_limit: int, -) -> List[Block]: - """ - Pack transactions into blocks without exceeding gas_limit per block. - - Greedily adds transactions to the current block until adding another - would exceed the gas limit, then starts a new block. - """ - if not transactions: - return [] - - blocks: List[Block] = [] - current_txs: List[Transaction] = [] - current_gas = 0 - - for tx in transactions: - if current_gas + tx.gas_limit > gas_limit and current_txs: - blocks.append(Block(txs=current_txs)) - current_txs = [] - current_gas = 0 - - current_txs.append(tx) - current_gas += tx.gas_limit - - if current_txs: - blocks.append(Block(txs=current_txs)) - - return blocks - - -def build_delegated_storage_setup( - *, - pre: Alloc, - fork: Fork, - tx_gas_limit: int, - needs_init: bool, - num_target_slots: int, - initializer_code: IteratingBytecode, - initializer_addr: Address, - executor_addr: Address, - authority: EOA, - authority_nonce: int, - delegation_sender: EOA, - initializer_calldata_generator: Callable[[int, int], bytes], -) -> List[Block]: - """ - Build setup blocks for delegated storage benchmarks. - - Returns: - List of blocks for the setup phase. - - """ - blocks: List[Block] = [] - - if needs_init: - # Block 1: Authorize to initializer - blocks.append( - Block( - txs=[ - Transaction( - to=delegation_sender, - gas_limit=tx_gas_limit, - sender=delegation_sender, - authorization_list=[ - AuthorizationTuple( - address=initializer_addr, - nonce=authority_nonce, - signer=authority, - ), - ], - ) - ] - ) - ) - authority_nonce += 1 - - # Calculate max slots per transaction based on gas cost - iteration_cost = initializer_code.tx_gas_limit_by_iteration_count( - fork=fork, - iteration_count=1, - start_iteration=1, - calldata=initializer_calldata_generator, - ) - iteration_count = max(1, tx_gas_limit // iteration_cost) - - init_txs: List[Transaction] = [] - for start in range(1, num_target_slots + 1, iteration_count): - chunk_size = min(iteration_count, num_target_slots - start + 1) - init_txs.extend( - initializer_code.transactions_by_total_iteration_count( - fork=fork, - total_iterations=chunk_size, - sender=pre.fund_eoa(), - to=authority, - start_iteration=start, - calldata=initializer_calldata_generator, - ) - ) - - # Pack init transactions into blocks - blocks.extend(pack_transactions_into_blocks(init_txs, tx_gas_limit)) - - # Final block: Authorize to executor - blocks.append( - Block( - txs=[ - Transaction( - to=delegation_sender, - gas_limit=tx_gas_limit, - sender=delegation_sender, - authorization_list=[ - AuthorizationTuple( - address=executor_addr, - nonce=authority_nonce, - signer=authority, - ), - ], - ) - ] - ) - ) - - return blocks - - @pytest.mark.parametrize("access_warm", [True, False]) @pytest.mark.parametrize("sloads_before_sstore", [True, False]) @pytest.mark.parametrize( diff --git a/tests/benchmark/stateful/eip7928_block_level_access_lists/helpers.py b/tests/benchmark/stateful/eip7928_block_level_access_lists/helpers.py index 2df7350c857..5efcb83a71b 100644 --- a/tests/benchmark/stateful/eip7928_block_level_access_lists/helpers.py +++ b/tests/benchmark/stateful/eip7928_block_level_access_lists/helpers.py @@ -12,9 +12,11 @@ from dataclasses import dataclass from execution_testing import ( + EOA, Account, Address, Alloc, + AuthorizationTuple, BalAccountExpectation, BalNonceChange, BalStorageSlot, @@ -24,10 +26,15 @@ Bytecode, Fork, Op, - Storage, TestPhaseManager, Transaction, ) +from execution_testing.base_types.base_types import Number + +from tests.benchmark.stateful.helpers import ( + StorageInitRange, + build_sequential_storage_init, +) CURSOR_SLOT = 0 CURSOR_INIT = 1 @@ -207,38 +214,83 @@ def _iters(tx_gas: int) -> int: def run_bal_benchmark( pre: Alloc, + fork: Fork, benchmark_test: BenchmarkTestFiller, contract_code: Bytecode, - contract_storage: Storage, plan: BenchmarkPlan, + tx_gas_limit: int, + authority: EOA, + storage_init_ranges: list[StorageInitRange] | None = None, data_slot_reads: list[int] | None = None, extra_expectations: (dict[Address, BalAccountExpectation] | None) = None, ) -> None: - """Deploy contract, create txs, BAL expectations, and run.""" - contract = pre.deploy_contract( - code=contract_code, storage=contract_storage - ) + """ + Run a BAL benchmark using EIP-7702 delegated storage initialization. + + Deploy the executor contract, optionally initialize the + *authority*'s storage via delegation, then delegate to the + executor and run the benchmark transactions. The authority's + nonce is incremented in-place. + """ + executor_addr = pre.deploy_contract(code=contract_code) + + blocks: list[Block] = [] + + with TestPhaseManager.setup(): + if storage_init_ranges: + blocks.extend( + build_sequential_storage_init( + pre=pre, + fork=fork, + tx_gas_limit=tx_gas_limit, + authority=authority, + storage_init_ranges=storage_init_ranges, + ) + ) + # Delegate authority to executor + delegation_sender = pre.fund_eoa() + blocks.append( + Block( + txs=[ + Transaction( + to=delegation_sender, + gas_limit=tx_gas_limit, + sender=delegation_sender, + authorization_list=[ + AuthorizationTuple( + address=executor_addr, + nonce=authority.nonce, + signer=authority, + ), + ], + ) + ] + ) + ) + authority.nonce = Number(authority.nonce + 1) + + # Execution phase num_txs = len(plan.gas_limits) with TestPhaseManager.execution(): sender = pre.fund_eoa() transactions = [ Transaction( sender=sender, - to=contract, + to=authority, gas_limit=plan.gas_limits[i], data=b"", ) for i in range(num_txs) ] - # BAL expectations: contract slots + sender nonces. + # BAL expectations: authority slots + sender nonces. # Use validate_any_change for cursor — exact values depend # on gas dynamics and are verified by consensus test suites. # All txs share a single sender to prevent trivial per-sender # optimizations in BAL implementations. expectations: dict[Address, BalAccountExpectation] = { - contract: BalAccountExpectation( + authority: BalAccountExpectation( storage_reads=sorted(set(data_slot_reads or [])), storage_changes=[ BalStorageSlot( @@ -260,13 +312,15 @@ def run_bal_benchmark( if extra_expectations: expectations.update(extra_expectations) - block = Block( + exec_block = Block( txs=transactions, expected_block_access_list=BlockAccessListExpectation( account_expectations=expectations ), ) + blocks.append(exec_block) + # Post-state: only check sender nonce (sanity). # Exact storage values depend on gas dynamics and may be # slightly off; consensus correctness is verified elsewhere. @@ -275,5 +329,9 @@ def run_bal_benchmark( } benchmark_test( - pre=pre, post=post, blocks=[block], skip_gas_used_validation=True + pre=pre, + post=post, + blocks=blocks, + skip_gas_used_validation=True, + expected_receipt_status=1, ) diff --git a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_compute_then_sload.py b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_compute_then_sload.py index 05b23b3d156..f499c571049 100644 --- a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_compute_then_sload.py +++ b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_compute_then_sload.py @@ -14,10 +14,10 @@ Bytecode, Fork, Op, - Storage, ) from .helpers import ( + StorageInitRange, cursor_read, gas_check_loop_contract, plan_benchmark, @@ -72,6 +72,7 @@ def test_bal_compute_then_sload( benchmark_test: BenchmarkTestFiller, fork: Fork, gas_benchmark_value: int, + tx_gas_limit: int, compute_percent: int, ) -> None: """Test BAL with mixed computation and SLOAD per iteration.""" @@ -84,18 +85,19 @@ def test_bal_compute_then_sload( gas_benchmark_value=gas_benchmark_value, ) total = plan.total_iterations - storage = Storage( - {i: i + 1 for i in range(total + 1)} # type: ignore - ) + authority = pre.fund_eoa(amount=0) run_bal_benchmark( pre=pre, + fork=fork, benchmark_test=benchmark_test, contract_code=gas_check_loop_contract( setup=cursor_read(), body=body, gas_threshold=plan.gas_threshold, ), - contract_storage=storage, plan=plan, + tx_gas_limit=tx_gas_limit, + authority=authority, + storage_init_ranges=[StorageInitRange(0, total + 1, 1)], data_slot_reads=list(range(1, total + 1)), ) diff --git a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_accounts.py b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_accounts.py index 6e2a9427c5e..9b20ce8ed40 100644 --- a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_accounts.py +++ b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_accounts.py @@ -16,13 +16,11 @@ Bytecode, Fork, Op, - Storage, ) -from execution_testing.base_types.base_types import HashInt from .helpers import ( CURSOR_INIT, - CURSOR_SLOT, + StorageInitRange, cursor_read, cursor_write, gas_check_loop_contract, @@ -87,6 +85,7 @@ def test_bal_max_account_access( benchmark_test: BenchmarkTestFiller, fork: Fork, gas_benchmark_value: int, + tx_gas_limit: int, ) -> None: """Test BAL with maximum unique account accesses via BALANCE.""" setup = cursor_read() + Op.PUSH3(BASE_ADDR) + Op.ADD @@ -103,11 +102,15 @@ def test_bal_max_account_access( Address(BASE_ADDR + i): BalAccountExpectation.empty() for i in range(CURSOR_INIT, total + CURSOR_INIT) } + authority = pre.fund_eoa(amount=0) run_bal_benchmark( pre=pre, + fork=fork, benchmark_test=benchmark_test, contract_code=create_balance_loop_contract(plan.gas_threshold), - contract_storage=Storage({HashInt(CURSOR_SLOT): HashInt(CURSOR_INIT)}), plan=plan, + tx_gas_limit=tx_gas_limit, + authority=authority, + storage_init_ranges=[StorageInitRange(0, 1, CURSOR_INIT)], extra_expectations=extra, ) diff --git a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_sloads.py b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_sloads.py index be0b8dbb85d..9010c85404f 100644 --- a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_sloads.py +++ b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_max_sloads.py @@ -17,10 +17,10 @@ BenchmarkTestFiller, Bytecode, Fork, - Storage, ) from .helpers import ( + StorageInitRange, cursor_read, gas_check_loop_contract, plan_benchmark, @@ -66,6 +66,7 @@ def test_bal_max_sloads( benchmark_test: BenchmarkTestFiller, fork: Fork, gas_benchmark_value: int, + tx_gas_limit: int, reverse: bool, ) -> None: """Test BAL with maximum sequential SLOADs via cursor.""" @@ -81,16 +82,20 @@ def test_bal_max_sloads( # Cursor starts at slot 0; forward reads slots 1..total, # reverse reads slots total..1. cursor_start = total if reverse else 1 - storage = Storage( - {0: cursor_start} | {i: i for i in range(1, total + 1)} # type: ignore - ) + authority = pre.fund_eoa(amount=0) run_bal_benchmark( pre=pre, + fork=fork, benchmark_test=benchmark_test, contract_code=create_sload_loop_contract( plan.gas_threshold, reverse=reverse ), - contract_storage=storage, plan=plan, + tx_gas_limit=tx_gas_limit, + authority=authority, + storage_init_ranges=[ + StorageInitRange(1, total, 0), + StorageInitRange(0, 1, cursor_start), + ], data_slot_reads=list(range(1, total + 1)), ) diff --git a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_pointer_chase.py b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_pointer_chase.py index e40683db452..ab2e86f55bb 100644 --- a/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_pointer_chase.py +++ b/tests/benchmark/stateful/eip7928_block_level_access_lists/test_block_access_lists_pointer_chase.py @@ -15,10 +15,10 @@ Bytecode, Fork, Op, - Storage, ) from .helpers import ( + StorageInitRange, cursor_read, gas_check_loop_contract, plan_benchmark, @@ -64,6 +64,7 @@ def test_bal_max_pointer_chase( benchmark_test: BenchmarkTestFiller, fork: Fork, gas_benchmark_value: int, + tx_gas_limit: int, ) -> None: """Test BAL with maximum dependent pointer-chasing SLOADs.""" body_gas = _chase_body().gas_cost(fork) @@ -74,14 +75,15 @@ def test_bal_max_pointer_chase( gas_benchmark_value=gas_benchmark_value, ) total = plan.total_iterations - storage = Storage( - {i: i + 1 for i in range(total + 1)} # type: ignore - ) + authority = pre.fund_eoa(amount=0) run_bal_benchmark( pre=pre, + fork=fork, benchmark_test=benchmark_test, contract_code=create_pointer_chase_contract(plan.gas_threshold), - contract_storage=storage, plan=plan, + tx_gas_limit=tx_gas_limit, + authority=authority, + storage_init_ranges=[StorageInitRange(0, total + 1, 1)], data_slot_reads=list(range(1, total + 1)), ) diff --git a/tests/benchmark/stateful/helpers.py b/tests/benchmark/stateful/helpers.py index 70be990bb43..c746038a7d2 100644 --- a/tests/benchmark/stateful/helpers.py +++ b/tests/benchmark/stateful/helpers.py @@ -1,18 +1,24 @@ """Shared constants and helpers for stateful benchmark tests.""" from collections.abc import Callable +from dataclasses import dataclass from enum import Enum +from functools import partial from execution_testing import ( + EOA, AccessList, Address, Alloc, + AuthorizationTuple, Block, Fork, Hash, + IteratingBytecode, Op, Transaction, ) +from execution_testing.base_types.base_types import Number # ERC20 function selectors BALANCEOF_SELECTOR = 0x70A08231 # balanceOf(address) @@ -132,3 +138,313 @@ def build_cache_strategy_blocks( if cache_strategy != CacheStrategy.CACHE_PREVIOUS_BLOCK: return [Block(txs=txs)] return [Block(txs=cache_txs), Block(txs=txs)] + + +def pack_transactions_into_blocks( + transactions: list[Transaction], + gas_limit: int, +) -> list[Block]: + """ + Pack transactions into blocks without exceeding gas_limit per block. + + Greedily add transactions to the current block until adding another + would exceed the gas limit, then start a new block. + """ + if not transactions: + return [] + + blocks: list[Block] = [] + current_txs: list[Transaction] = [] + current_gas = 0 + + for tx in transactions: + if current_gas + tx.gas_limit > gas_limit and current_txs: + blocks.append(Block(txs=current_txs)) + current_txs = [] + current_gas = 0 + + current_txs.append(tx) + current_gas += tx.gas_limit + + if current_txs: + blocks.append(Block(txs=current_txs)) + + return blocks + + +def build_delegated_storage_setup( + *, + pre: Alloc, + fork: Fork, + tx_gas_limit: int, + needs_init: bool, + num_target_slots: int, + initializer_code: IteratingBytecode, + initializer_addr: Address, + executor_addr: Address, + authority: EOA, + authority_nonce: int, + delegation_sender: EOA, + initializer_calldata_generator: Callable[[int, int], bytes], +) -> list[Block]: + """ + Build setup blocks for delegated storage benchmarks. + + Use EIP-7702 authorization to delegate an authority EOA first to + a storage-initializer contract (if *needs_init*), then to the + benchmark executor contract. Return the list of setup blocks. + """ + blocks: list[Block] = [] + + if needs_init: + # Block 1: Authorize to initializer + blocks.append( + Block( + txs=[ + Transaction( + to=delegation_sender, + gas_limit=tx_gas_limit, + sender=delegation_sender, + authorization_list=[ + AuthorizationTuple( + address=initializer_addr, + nonce=authority_nonce, + signer=authority, + ), + ], + ) + ] + ) + ) + authority_nonce += 1 + + # Calculate max slots per transaction based on gas cost + iteration_cost = initializer_code.tx_gas_limit_by_iteration_count( + fork=fork, + iteration_count=1, + start_iteration=1, + calldata=initializer_calldata_generator, + ) + iteration_count = max(1, tx_gas_limit // iteration_cost) + + init_txs: list[Transaction] = [] + for start in range(1, num_target_slots + 1, iteration_count): + chunk_size = min(iteration_count, num_target_slots - start + 1) + init_txs.extend( + initializer_code.transactions_by_total_iteration_count( + fork=fork, + total_iterations=chunk_size, + sender=pre.fund_eoa(), + to=authority, + start_iteration=start, + calldata=initializer_calldata_generator, + ) + ) + + # Pack init transactions into blocks + blocks.extend(pack_transactions_into_blocks(init_txs, tx_gas_limit)) + + # Final block: Authorize to executor + blocks.append( + Block( + txs=[ + Transaction( + to=delegation_sender, + gas_limit=tx_gas_limit, + sender=delegation_sender, + authorization_list=[ + AuthorizationTuple( + address=executor_addr, + nonce=authority_nonce, + signer=authority, + ), + ], + ) + ] + ) + ) + + return blocks + + +def create_sstore_initializer(init_val: int) -> IteratingBytecode: + """ + Create a contract that initializes storage slots from calldata. + + - CALLDATA[0..32] start slot (index) + - CALLDATA[32..64] slot count (num) + + storage[i] = init_val for i in [index, index + num). + """ + # Setup: [index, index + num] + prefix = ( + Op.CALLDATALOAD(0) # [index] + + Op.DUP1 # [index, index] + + Op.CALLDATALOAD(32) # [index, index, num] + + Op.ADD # [index, index + num] + ) + + # Loop: decrement counter and store at current position + # Stack after subtraction: [index, current] + # where current goes from index+num-1 down to index + loop = ( + Op.JUMPDEST + + Op.PUSH1(1) # [index, current, 1] + + Op.SWAP1 # [index, 1, current] + + Op.SUB # [index, current - 1] + + Op.SSTORE( # STORAGE[current-1] = initial_value + Op.DUP2, + init_val, + key_warm=False, + # gas accounting + original_value=0, + current_value=0, + new_value=init_val, + ) + # After SSTORE: [index, current - 1] + # Continue while current - 1 > index + + Op.JUMPI(len(prefix), Op.GT(Op.DUP2, Op.DUP2)) + ) + + return IteratingBytecode(setup=prefix, iterating=loop) + + +def initializer_calldata_generator( + iteration_count: int, start_iteration: int +) -> bytes: + """Generate calldata for the storage initializer.""" + return Hash(start_iteration) + Hash(iteration_count) + + +def create_sequential_sstore_initializer() -> IteratingBytecode: + """ + Create a contract that initializes storage with slot-dependent values. + + - CALLDATA[0..32] start slot (index) + - CALLDATA[32..64] slot count (num) + - CALLDATA[64..96] value offset + + storage[i] = i + offset for i in [index, index + num). + """ + # Setup: [offset, index, index + num] + prefix = ( + Op.CALLDATALOAD(64) # [offset] + + Op.CALLDATALOAD(0) # [index, offset] + + Op.DUP1 # [index, index, offset] + + Op.CALLDATALOAD(32) # [num, index, index, offset] + + Op.ADD # [num + index, index, offset] + ) + + # Loop: decrement current and store slot-dependent value + # Stack: [current, index, offset] + # current goes from index+num down; stores at current-1 + loop = ( + Op.JUMPDEST + + Op.PUSH1(1) # [1, current, index, offset] + + Op.SWAP1 # [current, 1, index, offset] + + Op.SUB # [current-1, index, offset] + + Op.DUP1 # [current-1, current-1, index, offset] + + Op.DUP1 # [current-1, current-1, current-1, index, offset] + + Op.DUP5 # [offset, current-1, current-1, current-1, index, offset] + + Op.ADD # [current-1 + offset, current-1, current-1, index, offset] + + Op.SWAP1 # [current-1, current-1 + offset, current-1, index, offset] + + Op.SSTORE( # SSTORE(current-1, current-1 + offset) + key_warm=False, + original_value=0, + current_value=0, + new_value=1, + ) + # Stack: [current-1, index, offset] + # Continue while current-1 > index + + Op.JUMPI(len(prefix), Op.GT(Op.DUP2, Op.DUP2)) + ) + + return IteratingBytecode(setup=prefix, iterating=loop) + + +def sequential_initializer_calldata_generator( + iteration_count: int, + start_iteration: int, + *, + offset: int = 0, +) -> bytes: + """Generate calldata for the sequential storage initializer.""" + return Hash(start_iteration) + Hash(iteration_count) + Hash(offset) + + +@dataclass(frozen=True) +class StorageInitRange: + """One contiguous range of storage to initialize.""" + + start_slot: int + num_slots: int + offset: int + + +def build_sequential_storage_init( + *, + pre: Alloc, + fork: Fork, + tx_gas_limit: int, + authority: EOA, + storage_init_ranges: list[StorageInitRange], +) -> list[Block]: + """ + Build blocks that initialize storage with slot-dependent values. + + Deploy a sequential-SSTORE initializer, delegate *authority* to it, + and emit transactions that write + ``storage[i] = i + range.offset`` for every range. The authority's + nonce is incremented in-place. + """ + initializer_code = create_sequential_sstore_initializer() + initializer_addr = pre.deploy_contract(code=initializer_code) + + delegation_sender = pre.fund_eoa() + auth_tx = Transaction( + to=delegation_sender, + gas_limit=tx_gas_limit, + sender=delegation_sender, + authorization_list=[ + AuthorizationTuple( + address=initializer_addr, + nonce=authority.nonce, + signer=authority, + ), + ], + ) + authority.nonce = Number(authority.nonce + 1) + + init_txs: list[Transaction] = [] + for r in storage_init_ranges: + if r.num_slots == 0: + continue + calldata_gen = partial( + sequential_initializer_calldata_generator, + offset=r.offset, + ) + iteration_cost = initializer_code.tx_gas_limit_by_iteration_count( + fork=fork, + iteration_count=1, + start_iteration=max(1, r.start_slot), + calldata=calldata_gen, + ) + iteration_count = max(1, tx_gas_limit // iteration_cost) + + end_slot = r.start_slot + r.num_slots + for start in range(r.start_slot, end_slot, iteration_count): + chunk = min(iteration_count, end_slot - start) + init_txs.extend( + initializer_code.transactions_by_total_iteration_count( + fork=fork, + total_iterations=chunk, + sender=pre.fund_eoa(), + to=authority, + start_iteration=start, + calldata=calldata_gen, + ) + ) + + blocks: list[Block] = [Block(txs=[auth_tx])] + blocks.extend(pack_transactions_into_blocks(init_txs, tx_gas_limit)) + return blocks From 2e71a202c7b8f483672fef004809ace22a1225e4 Mon Sep 17 00:00:00 2001 From: Chen Can Date: Wed, 6 May 2026 13:17:03 +0800 Subject: [PATCH 058/186] feat(tools): use Hardfork for fork module loading (#2778) * feat(tools): use Hardfork for fork module loading * refactor: drop Hardfork|str union and move helper tests Remove the Hardfork | str union type from optimized monkey-patching functions, accepting only Hardfork directly per reviewer feedback. Move test_forks.py into tests/json_loader/ so fill/docs collection does not pick it up. --- src/ethereum_optimized/__init__.py | 20 +++++------- src/ethereum_optimized/fork.py | 6 ++-- src/ethereum_optimized/state_db.py | 10 +++--- .../evm_tools/loaders/fixture_loader.py | 6 +--- .../evm_tools/loaders/fork_loader.py | 26 ++++++++++++++++ .../evm_tools/t8n/__init__.py | 20 +++--------- .../evm_tools/t8n/t8n_types.py | 7 +---- src/ethereum_spec_tools/forks.py | 11 +++++++ tests/json_loader/helpers/load_vm_tests.py | 4 +-- tests/json_loader/test_forks.py | 31 +++++++++++++++++++ tests/json_loader/test_optimized_state.py | 6 ++-- 11 files changed, 94 insertions(+), 53 deletions(-) create mode 100644 tests/json_loader/test_forks.py diff --git a/src/ethereum_optimized/__init__.py b/src/ethereum_optimized/__init__.py index b1f8598188f..e51f1e4f7f9 100644 --- a/src/ethereum_optimized/__init__.py +++ b/src/ethereum_optimized/__init__.py @@ -15,7 +15,6 @@ function. This must be done before those modules are imported anywhere. """ -from importlib import import_module from typing import Any, Optional, cast from ethereum_spec_tools.forks import Hardfork @@ -25,7 +24,7 @@ def monkey_patch_optimized_state_db( - fork_name: str, state_path: Optional[str] + fork: Hardfork, state_path: Optional[str] ) -> None: """ Replace the state interface with one that supports high performance @@ -34,12 +33,9 @@ def monkey_patch_optimized_state_db( This function must be called before the state interface is imported anywhere. """ - slow_state = cast( - Any, - import_module("ethereum.forks." + fork_name + ".state"), - ) + slow_state = cast(Any, fork.module("state")) - optimized_state_db_patches = get_optimized_state_patches(fork_name) + optimized_state_db_patches = get_optimized_state_patches(fork) for name, value in optimized_state_db_patches.items(): setattr(slow_state, name, value) @@ -48,7 +44,7 @@ def monkey_patch_optimized_state_db( slow_state.State.default_path = state_path -def monkey_patch_optimized_spec(fork_name: str) -> None: +def monkey_patch_optimized_spec(fork: Hardfork) -> None: """ Replace the ethash implementation with one that supports higher performance. @@ -56,9 +52,9 @@ def monkey_patch_optimized_spec(fork_name: str) -> None: This function must be called before the spec interface is imported anywhere. """ - slow_spec = import_module("ethereum.forks." + fork_name + ".fork") + slow_spec = fork.module("fork") - optimized_pow_patches = get_optimized_pow_patches(fork_name) + optimized_pow_patches = get_optimized_pow_patches(fork) for name, value in optimized_pow_patches.items(): setattr(slow_spec, name, value) @@ -71,8 +67,8 @@ def monkey_patch(state_path: Optional[str]) -> None: forks = Hardfork.discover() for fork in forks: - monkey_patch_optimized_state_db(fork.short_name, state_path) + monkey_patch_optimized_state_db(fork, state_path) # Only patch the POW code on POW forks if fork.consensus.is_pow(): - monkey_patch_optimized_spec(fork.short_name) + monkey_patch_optimized_spec(fork) diff --git a/src/ethereum_optimized/fork.py b/src/ethereum_optimized/fork.py index 21c02fc19ea..f4820a31b03 100644 --- a/src/ethereum_optimized/fork.py +++ b/src/ethereum_optimized/fork.py @@ -12,13 +12,13 @@ the `fork` module of a fork. """ -from importlib import import_module from typing import Any, Dict, cast from ethereum_types.numeric import U256, Uint from ethereum.ethash import epoch from ethereum.exceptions import InvalidBlock +from ethereum_spec_tools.forks import Hardfork from .utils import add_item @@ -34,14 +34,14 @@ Header_ = Any -def get_optimized_pow_patches(_fork_name: str) -> Dict[str, Any]: +def get_optimized_pow_patches(fork: Hardfork) -> Dict[str, Any]: """ Get a dictionary of patches to be patched into the fork to make it optimized. """ patches: Dict[str, Any] = {} - mod = cast(Any, import_module("ethereum.forks." + _fork_name + ".fork")) + mod = cast(Any, fork.module("fork")) if not hasattr(mod, "validate_proof_of_work"): raise Exception( diff --git a/src/ethereum_optimized/state_db.py b/src/ethereum_optimized/state_db.py index aa2e3defb65..785099b7a71 100644 --- a/src/ethereum_optimized/state_db.py +++ b/src/ethereum_optimized/state_db.py @@ -15,7 +15,6 @@ import logging from collections import defaultdict from dataclasses import dataclass -from importlib import import_module from types import SimpleNamespace from typing import Any, ClassVar, Dict, List, Optional, Set, cast @@ -33,6 +32,7 @@ from ethereum.crypto.hash import Hash32, keccak256 from ethereum.state import EMPTY_CODE_HASH +from ethereum_spec_tools.forks import Hardfork from .utils import add_item @@ -52,17 +52,15 @@ class UnmodifiedType: Unmodified = UnmodifiedType() -def get_optimized_state_patches(fork: str) -> Dict[str, Any]: +def get_optimized_state_patches(fork: Hardfork) -> Dict[str, Any]: """ Get a dictionary of functions/objects to be monkey patched into the state to make it optimized. """ patches: Dict[str, Any] = {} - types_mod = cast( - Any, import_module("ethereum.forks." + fork + ".fork_types") - ) - state_mod = cast(Any, import_module("ethereum.forks." + fork + ".state")) + types_mod = cast(Any, fork.module("fork_types")) + state_mod = cast(Any, fork.module("state")) Account = types_mod.Account # noqa N806 has_transient_storage = hasattr(state_mod, "TransientStorage") diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py index 8caf5679c8e..eebb994a187 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py @@ -55,11 +55,7 @@ def __init__(self, fork_module: str | Hardfork): if isinstance(fork_module, Hardfork): self.fork = ForkLoad(fork_module) else: - for fork in Hardfork.discover(): - if fork.short_name == fork_module: - self.fork = ForkLoad(fork) - return - raise Exception(f"fork `{fork_module}` not found") + self.fork = ForkLoad(Hardfork.by_short_name(fork_module)) def json_to_state(self, raw: Any) -> Any: """Converts json state data to a state object.""" diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py index c88eec7d9bd..327bf0096d6 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py @@ -144,11 +144,27 @@ def build_block_access_list(self) -> Any: """build_block_access_list function of the fork.""" return self._module("block_access_lists").build_block_access_list + @property + def BlockAccessIndex(self) -> Any: + """BlockAccessIndex class of the fork.""" + return self._module("block_access_lists").BlockAccessIndex + + @property + def BlockAccessListBuilder(self) -> Any: + """BlockAccessListBuilder class of the fork.""" + return self._module("block_access_lists").BlockAccessListBuilder + @property def hash_block_access_list(self) -> Any: """hash_block_access_list function of the fork.""" return self._module("block_access_lists").hash_block_access_list + @property + def validate_block_access_list_gas_limit(self) -> Any: + """validate_block_access_list_gas_limit function of the fork.""" + block_access_lists = self._module("block_access_lists") + return block_access_lists.validate_block_access_list_gas_limit + @property def has_hash_block_access_list(self) -> bool: """Check if the fork has a `hash_block_access_list` function.""" @@ -304,6 +320,16 @@ def has_block_state(self) -> bool: return False return hasattr(module, "BlockState") + @property + def BlockState(self) -> Any: + """BlockState class of the fork.""" + return self._module("state_tracker").BlockState + + @property + def extract_block_diff(self) -> Any: + """extract_block_diff function of the fork.""" + return self._module("state_tracker").extract_block_diff + @property def State(self) -> Any: """State class of the fork.""" diff --git a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py index 23781ad7b94..8175015e5b6 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py @@ -17,14 +17,6 @@ from ethereum import trace from ethereum.exceptions import EthereumException, InvalidBlock from ethereum.fork_criteria import ByBlockNumber, ByTimestamp, Unscheduled - -# TODO: Make this not amsterdam specific once the state tracker has -# been added to older forks. -from ethereum.forks.amsterdam.block_access_lists import ( - BlockAccessIndex, - BlockAccessListBuilder, - validate_block_access_list_gas_limit, -) from ethereum_spec_tools.forks import Hardfork, TemporaryHardfork from ..loaders.fixture_loader import Load @@ -384,11 +376,7 @@ def block_environment(self) -> Any: } if self.fork.has_block_state: - from ethereum.forks.amsterdam.state_tracker import ( - BlockState, - ) - - block_state = BlockState(pre_state=self.alloc.state) + block_state = self.fork.BlockState(pre_state=self.alloc.state) kw_arguments["state"] = block_state self._block_state = block_state else: @@ -412,7 +400,7 @@ def block_environment(self) -> Any: if self.fork.has_hash_block_access_list: kw_arguments["block_access_list_builder"] = ( - BlockAccessListBuilder() + self.fork.BlockAccessListBuilder() ) return block_environment(**kw_arguments) @@ -523,7 +511,7 @@ def _run_blockchain_test(self, block_env: Any, block_output: Any) -> None: num_txs = len(self.txs.transactions) if self.fork.has_hash_block_access_list: block_env.block_access_list_builder.block_access_index = ( - BlockAccessIndex(Uint(num_txs) + Uint(1)) + self.fork.BlockAccessIndex(Uint(num_txs) + Uint(1)) ) if not self.fork.proof_of_stake: @@ -548,7 +536,7 @@ def _run_blockchain_test(self, block_env: Any, block_output: Any) -> None: ) # Validate block access list gas limit constraint (EIP-7928) - validate_block_access_list_gas_limit( + self.fork.validate_block_access_list_gas_limit( block_access_list=block_output.block_access_list, block_gas_limit=block_env.block_gas_limit, ) diff --git a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py index e2e953bd195..902b7e7c29b 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py @@ -313,14 +313,9 @@ def update(self, t8n: "T8N", block_env: Any, block_output: Any) -> None: self.bloom = t8n.fork.logs_bloom(block_output.block_logs) self.logs_hash = keccak256(rlp.encode(block_output.block_logs)) if t8n.fork.has_block_state: - # TODO: remove this once the state tracker is ported over - # to the older forks - from ethereum.forks.amsterdam.state_tracker import ( - extract_block_diff, - ) from ethereum.state import apply_changes_to_state - block_diff = extract_block_diff(t8n._block_state) + block_diff = t8n.fork.extract_block_diff(t8n._block_state) state_root_value, _ = ( t8n.alloc.state.compute_state_root_and_trie_changes( block_diff.account_changes, block_diff.storage_changes diff --git a/src/ethereum_spec_tools/forks.py b/src/ethereum_spec_tools/forks.py index 112da3ad592..cf29086b53b 100644 --- a/src/ethereum_spec_tools/forks.py +++ b/src/ethereum_spec_tools/forks.py @@ -141,6 +141,17 @@ def discover( return forks + @classmethod + def by_short_name(cls: Type[H], name: str) -> H: + """ + Return the hardfork matching the given short name. + """ + for fork in cls.discover(): + if fork.short_name == name: + return fork + + raise ValueError(f"unknown hardfork `{name}`") + @classmethod def load(cls: Type[H], config_dict: Dict["ForkCriteria", str]) -> List[H]: """ diff --git a/tests/json_loader/helpers/load_vm_tests.py b/tests/json_loader/helpers/load_vm_tests.py index b34a1dcc2f8..73660b42a05 100644 --- a/tests/json_loader/helpers/load_vm_tests.py +++ b/tests/json_loader/helpers/load_vm_tests.py @@ -1,6 +1,5 @@ """Helper class to load and run VM tests.""" -from importlib import import_module from pathlib import Path from typing import Any, Dict, Generator, List, Tuple @@ -49,6 +48,7 @@ class VmTestLoader: def __init__(self, network: str, fork_name: str): self.network = network self.fork_name = fork_name + self.hardfork = TestHardfork.by_short_name(fork_name) # Import relevant items from fork self.fork = self._module("fork") @@ -84,7 +84,7 @@ def __init__(self, network: str, fork_name: str): self.process_message_call = self.interpreter.process_message_call def _module(self, name: str) -> Any: - return import_module(f"ethereum.forks.{self.fork_name}.{name}") + return self.hardfork.module(name) def _state_module(self) -> Any: # TODO: remove this fallback once the state module is ported over diff --git a/tests/json_loader/test_forks.py b/tests/json_loader/test_forks.py new file mode 100644 index 00000000000..646b96f42dd --- /dev/null +++ b/tests/json_loader/test_forks.py @@ -0,0 +1,31 @@ +"""Tests for hardfork discovery helpers.""" + +import pytest + +from ethereum_spec_tools.forks import Hardfork + + +class CustomHardfork(Hardfork): + """Hardfork subclass used to test generic class methods.""" + + +def test_by_short_name_returns_matching_hardfork() -> None: + """Return the hardfork matching the requested short name.""" + fork = Hardfork.by_short_name("frontier") + + assert fork.short_name == "frontier" + assert fork.name == "ethereum.forks.frontier" + + +def test_by_short_name_preserves_subclass() -> None: + """Return the same hardfork subclass used for lookup.""" + fork = CustomHardfork.by_short_name("frontier") + + assert isinstance(fork, CustomHardfork) + assert fork.short_name == "frontier" + + +def test_by_short_name_rejects_unknown_fork() -> None: + """Raise an error when the hardfork short name is unknown.""" + with pytest.raises(ValueError, match="unknown hardfork `unknown_fork`"): + Hardfork.by_short_name("unknown_fork") diff --git a/tests/json_loader/test_optimized_state.py b/tests/json_loader/test_optimized_state.py index 8db41952ac6..418f00399a1 100644 --- a/tests/json_loader/test_optimized_state.py +++ b/tests/json_loader/test_optimized_state.py @@ -9,6 +9,7 @@ import ethereum.forks.frontier.state as state from ethereum.forks.frontier.fork_types import EMPTY_ACCOUNT from ethereum.forks.tangerine_whistle.utils.hexadecimal import hex_to_address +from ethereum_spec_tools.forks import Hardfork try: import ethereum_optimized.state_db as state_db @@ -20,9 +21,8 @@ class OptimizedState: optimized_state = cast(Any, OptimizedState()) - for name, value in state_db.get_optimized_state_patches( - "frontier" - ).items(): + frontier = Hardfork.by_short_name("frontier") + for name, value in state_db.get_optimized_state_patches(frontier).items(): setattr(optimized_state, name, value) except ImportError: From 5cdb055e069e246a877c8aa018079eb0b9093f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Wed, 6 May 2026 11:13:46 +0200 Subject: [PATCH 059/186] chore(test-benchmark): re-enable `blockhash` benchmark (#2809) --- tests/benchmark/compute/instruction/test_block_context.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/benchmark/compute/instruction/test_block_context.py b/tests/benchmark/compute/instruction/test_block_context.py index c2a1e6cbbc3..d31dba05c0a 100644 --- a/tests/benchmark/compute/instruction/test_block_context.py +++ b/tests/benchmark/compute/instruction/test_block_context.py @@ -48,7 +48,6 @@ def test_block_context_ops( ) -@pytest.mark.skip(reason="Temporarily disabled pending investigation") @pytest.mark.repricing @pytest.mark.parametrize( "index,chain_length", From 2e120a09b1461703cadbecec78fce815c6f2b9ca Mon Sep 17 00:00:00 2001 From: Ellie Date: Wed, 6 May 2026 19:11:45 +0400 Subject: [PATCH 060/186] =?UTF-8?q?feat(tests):=20add=20EIP-7928=20BALs=20?= =?UTF-8?q?missing=20test=20when=20multiple=20consecutive=E2=80=A6=20(#281?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(tests): add EIP-7928 BALs missing test when multiple consecutive SSTOREs change same slot in one tx issue #2812 * feat(test): increase coverage for same account SSTORE BAL test; add net zero test --------- Co-authored-by: fselmo --- .../testing/src/execution_testing/__init__.py | 2 + .../execution_testing/test_types/__init__.py | 2 + .../test_block_access_lists.py | 156 ++++++++++++++++++ .../test_cases.md | 2 + 4 files changed, 162 insertions(+) diff --git a/packages/testing/src/execution_testing/__init__.py b/packages/testing/src/execution_testing/__init__.py index d689bf9f28e..ae04d86a2e0 100644 --- a/packages/testing/src/execution_testing/__init__.py +++ b/packages/testing/src/execution_testing/__init__.py @@ -52,6 +52,7 @@ EOA, Alloc, AuthorizationTuple, + BalAccountAbsentValues, BalAccountChange, BalAccountExpectation, BalBalanceChange, @@ -125,6 +126,7 @@ "Address", "Alloc", "AuthorizationTuple", + "BalAccountAbsentValues", "BalAccountChange", "BalAccountExpectation", "BalBalanceChange", diff --git a/packages/testing/src/execution_testing/test_types/__init__.py b/packages/testing/src/execution_testing/test_types/__init__.py index 979a76d49ba..b9029ceb3ad 100644 --- a/packages/testing/src/execution_testing/test_types/__init__.py +++ b/packages/testing/src/execution_testing/test_types/__init__.py @@ -3,6 +3,7 @@ from .account_types import EOA, Alloc from .blob_types import Blob from .block_access_list import ( + BalAccountAbsentValues, BalAccountChange, BalAccountExpectation, BalBalanceChange, @@ -54,6 +55,7 @@ "DETERMINISTIC_FACTORY_ADDRESS", "Alloc", "AuthorizationTuple", + "BalAccountAbsentValues", "BalAccountChange", "BalAccountExpectation", "BalBalanceChange", diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index ba4fbd5f221..2226d9f78ff 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -9,6 +9,7 @@ Address, Alloc, AuthorizationTuple, + BalAccountAbsentValues, BalAccountExpectation, BalBalanceChange, BalCodeChange, @@ -2697,3 +2698,158 @@ def test_bal_gas_limit_boundary( post={}, genesis_environment=Environment(gas_limit=gas_limit), ) + + +@pytest.mark.parametrize( + "pre_value", + [ + pytest.param(0x00, id="slot_starts_empty"), + pytest.param(0x11, id="slot_starts_nonzero"), + pytest.param(0xBB, id="intermediate_equals_pre"), + ], +) +def test_bal_intra_tx_multiple_sstores_same_slot( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + pre_value: int, +) -> None: + """ + Test that consecutive SSTOREs to the same slot within one tx produce a + single storage change with the final post-value; intermediate writes + (0xAA, 0xBB) must not appear in the BAL. + """ + alice = pre.fund_eoa(amount=10**18) + + code = ( + Op.SSTORE(0x01, 0xAA) + Op.SSTORE(0x01, 0xBB) + Op.SSTORE(0x01, 0xCC) + ) + contract = pre.deploy_contract(code=code, storage={0x01: pre_value}) + + tx = Transaction( + sender=alice, + to=contract, + gas_limit=200_000, + ) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=1, post_nonce=1 + ), + ], + ), + contract: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=0x01, + slot_changes=[ + BalStorageChange( + block_access_index=1, + post_value=0xCC, + ), + ], + ), + ], + storage_reads=[], + balance_changes=[], + code_changes=[], + absent_values=BalAccountAbsentValues( + storage_changes=[ + BalStorageSlot( + slot=0x01, + slot_changes=[ + BalStorageChange( + block_access_index=1, + post_value=0xAA, + ), + BalStorageChange( + block_access_index=1, + post_value=0xBB, + ), + ], + ), + ], + ), + ), + } + ), + ) + ], + post={ + alice: Account(nonce=1), + contract: Account(storage={0x01: 0xCC}), + }, + ) + + +@pytest.mark.parametrize( + "pre_value,writes", + [ + pytest.param( + 0xCC, [0xAA, 0xBB, 0xCC], id="nonzero_pre_returns_to_pre" + ), + pytest.param( + 0x00, [0xAA, 0xBB, 0x00], id="empty_pre_ephemeral_writes" + ), + ], +) +def test_bal_intra_tx_sstores_same_slot_net_zero( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + pre_value: int, + writes: list[int], +) -> None: + """ + Test that consecutive SSTOREs to the same slot within one tx with a + net-zero result are filtered: the slot must appear in storage_reads + (it was accessed) but must not appear in storage_changes. + """ + alice = pre.fund_eoa(amount=10**18) + + code = Op.SSTORE(0x01, writes[0]) + for v in writes[1:]: + code += Op.SSTORE(0x01, v) + contract = pre.deploy_contract(code=code, storage={0x01: pre_value}) + + tx = Transaction( + sender=alice, + to=contract, + gas_limit=200_000, + ) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=1, post_nonce=1 + ), + ], + ), + contract: BalAccountExpectation( + storage_reads=[0x01], + storage_changes=[], + balance_changes=[], + code_changes=[], + ), + } + ), + ) + ], + post={ + alice: Account(nonce=1), + contract: Account(storage={0x01: pre_value}), + }, + ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index dd307611502..bd89ac5f66b 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -69,6 +69,8 @@ | `test_bal_multiple_storage_writes_same_slot` | Ensure BAL tracks multiple writes to same storage slot across transactions | Alice calls contract 3 times in same block. Contract increments slot 1 on each call: 0 → 1 → 2 → 3 | BAL **MUST** include contract with slot 1 having three `slot_changes`: txIndex=1 (value 1), txIndex=2 (value 2), txIndex=3 (value 3). Each transaction's write must be recorded separately. | ✅ Completed | | `test_bal_nested_delegatecall_storage_writes_net_zero` | Ensure BAL correctly filters net-zero storage changes across nested DELEGATECALL frames | Parametrized by nesting depth (1-3). Root contract has slot 0 = 1. Each frame writes a different intermediate value via DELEGATECALL chain, deepest frame writes back to original value (1). Example depth=2: 1 → 2 → 3 → 1 | BAL **MUST** include root contract with `storage_reads` for slot 0 but **MUST NOT** include `storage_changes` (net-zero). All delegate contracts **MUST** have empty changes. Tests that frame merging correctly removes parent's intermediate writes when child reverts to pre-tx value. | ✅ Completed | | `test_bal_cross_tx_storage_revert_to_zero` | Ensure BAL captures storage changes when tx2 reverts slot back to original value (blobhash regression test) | Alice sends tx1 writing slot 0=0xABCD (from 0x0), then tx2 writing slot 0=0x0 (back to original) | BAL **MUST** include contract with slot 0 having two `slot_changes`: txIndex=1 (0xABCD) and txIndex=2 (0x0). Cross-transaction net-zero **MUST NOT** be filtered. | ✅ Completed | +| `test_bal_intra_tx_multiple_sstores_same_slot` | Ensure BAL coalesces consecutive SSTOREs to the same slot within one tx into a single storage change with the final post-value | Contract executes `SSTORE(0x01, 0xAA) + SSTORE(0x01, 0xBB) + SSTORE(0x01, 0xCC)` in one tx. Parametrized by `pre_value`: `slot_starts_empty` (0x00), `slot_starts_nonzero` (0x11), `intermediate_equals_pre` (0xBB, where the second write transiently matches the pre-state). | BAL **MUST** include contract with slot `0x01` having exactly one `slot_changes` entry: `txIndex=1, post_value=0xCC`. Intermediate values `0xAA` and `0xBB` **MUST NOT** appear as separate entries (enforced via `absent_values`). | ✅ Completed | +| `test_bal_intra_tx_sstores_same_slot_net_zero` | Ensure BAL filters net-zero result when multiple SSTOREs to the same slot occur within one tx | Parametrized: `nonzero_pre_returns_to_pre` (pre=0xCC, writes 0xAA→0xBB→0xCC) and `empty_pre_ephemeral_writes` (pre=0x00, writes 0xAA→0xBB→0x00). Final value equals pre-state in both cases. | BAL **MUST** include contract with slot `0x01` in `storage_reads` (slot was accessed) and **MUST NOT** include slot `0x01` in `storage_changes` (net-zero). | ✅ Completed | | `test_bal_create_contract_init_revert` | Ensure BAL correctly handles CREATE when parent call reverts | Caller calls factory, factory executes CREATE (succeeds), then factory REVERTs rolling back the CREATE | BAL **MUST** include Alice with `nonce_changes`. Caller and factory with no changes (reverted). Created contract address appears in BAL but **MUST NOT** have `nonce_changes` or `code_changes` (CREATE was rolled back). Contract address **MUST NOT** exist in post-state. | ✅ Completed | | `test_bal_create_oog_code_deposit` | Ensure BAL correctly handles CREATE OOG during code deposit | Alice calls factory contract that executes CREATE with init code returning 10,000 bytes. Transaction has insufficient gas for code deposit. Factory nonce increments, CREATE returns 0 and stores in slot 1. | BAL **MUST** include Alice with `nonce_changes`. Factory with `nonce_changes` (incremented by CREATE) and `storage_changes` (slot 1 = 0). Contract address with empty changes (read during collision check). **MUST NOT** include nonce or code changes for contract address (rolled back on OOG). Contract address **MUST NOT** exist in post-state. | ✅ Completed | | `test_bal_create_early_failure` | Ensure BAL correctly handles CREATE that fails before accessing contract address | Factory (balance=50) attempts CREATE(value=100). CREATE fails due to insufficient endowment (100 > 50). Factory stores CREATE result (0) in slot 0. | BAL **MUST** include Alice with `nonce_changes`. Factory with `storage_changes` (slot 0 = 0) but **MUST NOT** have `nonce_changes` (CREATE failed before nonce increment). Contract address **MUST NOT** appear in BAL (never accessed - CREATE failed before `track_address`). This is distinct from collision/OOG failures where contract address IS in BAL. | ✅ Completed | From 1292bce491239e007c178620a63faf8123453d29 Mon Sep 17 00:00:00 2001 From: Gottfried Herold Date: Thu, 7 May 2026 05:10:32 +0200 Subject: [PATCH 061/186] test(test-benchmark): add `bn128_add` precompile special case benchmarks (#2811) --- .../compute/precompile/test_alt_bn128.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/benchmark/compute/precompile/test_alt_bn128.py b/tests/benchmark/compute/precompile/test_alt_bn128.py index dfb63a9aeab..d95345f5132 100644 --- a/tests/benchmark/compute/precompile/test_alt_bn128.py +++ b/tests/benchmark/compute/precompile/test_alt_bn128.py @@ -40,6 +40,35 @@ id="bn128_add", marks=pytest.mark.repricing, ), + pytest.param( + 0x06, + concatenate_parameters( + [ + "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", + "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", + "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", + "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", + ] + ), + Precompile.BN128_ADD, + id="bn128_double", + marks=pytest.mark.repricing, + ), + # Second point is the negative of the first one + pytest.param( + 0x06, + concatenate_parameters( + [ + "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", + "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", + "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", + "2A27BDD69A111C1D033CF8FC8BE1B1142229D40FD218F75E401363953F898AE1", + ] + ), + Precompile.BN128_ADD, + id="bn128_add_negative", + marks=pytest.mark.repricing, + ), # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L326 pytest.param( From 8671966fe5133c35dcc142c3be6725008f26ed99 Mon Sep 17 00:00:00 2001 From: pdobacz <5735525+pdobacz@users.noreply.github.com> Date: Thu, 7 May 2026 05:14:36 +0200 Subject: [PATCH 062/186] fix(tests): EIP-3860 & 1153 - parametrize max_code_size (#2780) --- .../eip1153_tstore/test_tstorage_create_contexts.py | 8 ++++++-- tests/shanghai/eip3860_initcode/test_initcode.py | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py b/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py index 1dc82ea1ed4..6ee241be0fc 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py @@ -18,6 +18,7 @@ compute_create_address, ) from execution_testing import Macros as Om +from execution_testing.forks.helpers import Fork from . import CreateOpcodeParams, PytestParameterEnum from .spec import ref_spec_1153 @@ -271,6 +272,7 @@ def test_tstore_rollback_on_failed_create( state_test: StateTestFiller, pre: Alloc, create_opcode: Op, + fork: Fork, ) -> None: """ Test TSTORE is rolled back after failed CREATE/CREATE2 initcode. @@ -296,11 +298,13 @@ def test_tstore_rollback_on_failed_create( # # TLOAD(1)==0: return_size = 0x600a > max code size -> fail # TLOAD(1)==0x6000: return_size = 0x0a <= max code size -> succeed + max_code_size = fork.max_code_size() + initcode = ( Op.TLOAD(1) - + Op.PUSH2(0x600A) + + Op.PUSH4(max_code_size + 0x0A) + Op.SUB - + Op.TSTORE(1, 0x6000) + + Op.TSTORE(1, max_code_size) + Op.PUSH1(0) + Op.RETURN ) diff --git a/tests/shanghai/eip3860_initcode/test_initcode.py b/tests/shanghai/eip3860_initcode/test_initcode.py index 08e56b48c48..f76bca44c2a 100644 --- a/tests/shanghai/eip3860_initcode/test_initcode.py +++ b/tests/shanghai/eip3860_initcode/test_initcode.py @@ -605,6 +605,7 @@ def test_create2_oversized_initcode_with_insufficient_balance( pre: Alloc, initcode_oversize: bool, expected_storage_1: int, + fork: Fork, ) -> None: """ Test CREATE2 with oversized initcode and insufficient balance. @@ -621,7 +622,9 @@ def test_create2_oversized_initcode_with_insufficient_balance( - Initcode within limit: insufficient balance pushes 0, execution continues, SSTORE(1, 1) executes, so storage slot 1 becomes 1. """ - initcode_size = 0x20000 if initcode_oversize else 0x100 + initcode_size = ( + fork.max_initcode_size() * 2 if initcode_oversize else 0x100 + ) caller_code = ( Op.CREATE2(1123123123, 0, initcode_size, 0) + Op.POP + Op.SSTORE(1, 1) ) From 0c25df6c8959483852bf6876e0db96015c2fbe7f Mon Sep 17 00:00:00 2001 From: pdobacz <5735525+pdobacz@users.noreply.github.com> Date: Thu, 7 May 2026 10:13:45 +0200 Subject: [PATCH 063/186] refactor(tests): `tx_gas` and `cold_gas` for `gas_test` generator (#2083) --- .../tools/utility/generators.py | 29 ++++++++++--------- tests/frontier/opcodes/test_all_opcodes.py | 4 +-- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/testing/src/execution_testing/tools/utility/generators.py b/packages/testing/src/execution_testing/tools/utility/generators.py index 78a9f172c51..ca28a5b9fe1 100644 --- a/packages/testing/src/execution_testing/tools/utility/generators.py +++ b/packages/testing/src/execution_testing/tools/utility/generators.py @@ -483,9 +483,9 @@ def gas_test( if cold_gas is None: cold_gas = subject_code.gas_cost(fork) - if cold_gas <= 0: + if cold_gas < 0: raise ValueError( - f"Target gas allocations (cold_gas) must be > 0, got {cold_gas}" + f"Target gas allocations (cold_gas) must be >= 0, got {cold_gas}" ) if warm_gas is None: if subject_code_warm is not None: @@ -503,18 +503,12 @@ def gas_test( balance=subject_balance, address=subject_address, ) - # 2 times GAS, POP, CALL, 6 times PUSH1 - instructions charged for at every - # gas run - gas_costs = fork.gas_costs() - opcode_gas_cost = gas_costs.BASE - opcode_pop_cost = gas_costs.BASE - opcode_push_cost = gas_costs.VERY_LOW + + # Auxiliary instructions charged for at every gas run gas_single_gas_run = ( - 2 * opcode_gas_cost - + opcode_pop_cost - + gas_costs.WARM_ACCESS - + 6 * opcode_push_cost - ) + Op.GAS + Op.CALL(gas=Op.GAS, address_warm=True) + Op.POP + ).gas_cost(fork=fork) + address_legacy_harness = pre.deploy_contract( code=( # warm subject and baseline without executing @@ -624,8 +618,15 @@ def gas_test( LEGACY_CALL_SUCCESS ) + gas_sstore = Op.SSTORE(1, 1).gas_cost(fork=fork) if tx_gas is None: - tx_gas = gas_single_gas_run + cold_gas + 500_000 + tx_gas = ( + 5 * gas_single_gas_run + + cold_gas + + 4 * warm_gas + + 5 * gas_sstore + + 500_000 + ) tx = Transaction( to=address_legacy_harness, gas_limit=tx_gas, sender=sender ) diff --git a/tests/frontier/opcodes/test_all_opcodes.py b/tests/frontier/opcodes/test_all_opcodes.py index 35c8be2953f..774df19e4af 100644 --- a/tests/frontier/opcodes/test_all_opcodes.py +++ b/tests/frontier/opcodes/test_all_opcodes.py @@ -223,9 +223,6 @@ def constant_gas_opcodes(fork: Fork) -> Generator[ParameterSet, None, None]: # delta used by gas_test. Excluded to keep the test meaningful. if fork.is_eip_enabled(8037) and opcode in (Op.CREATE, Op.CREATE2): continue - if opcode.gas_cost(fork) == 0: - # zero constant gas opcodes - untestable - continue yield pytest.param( opcode, id=f"{opcode}", @@ -267,4 +264,5 @@ def test_constant_gas( subject_code=opcode, subject_code_warm=warm_opcode, tear_down_code=prepare_suffix(opcode), + out_of_gas_testing=opcode.gas_cost(fork) > 0, ) From c9d8be0101c6649e060950317e14fb4f515f70e9 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Thu, 7 May 2026 10:46:30 +0200 Subject: [PATCH 064/186] chore(doc): remove unmaintained `docs/CHANGELOG` (#2810) The `docs/CHANGELOG.md` file is a leftover from the `ethereum/execution-spec-tests` repository and has not been properly maintained since the merge into `ethereum/execution-specs`. Its contents do not match any of the new changelog formats proposed in issue #2036 and only receive sporadic updates, so the file in its current shape is more confusing than useful. Remove the changelog along with all references to it: the `just changelog` recipe, its `tox` migration shim, the CI workflow job, the `validate_changelog` entry point and helper function, the `Changelog` project URL, the section template, and the docs developer instructions. The file history remains in git should it need to be restored. Refs: https://github.com/ethereum/execution-specs/issues/2036 --- .github/workflows/docs-build.yaml | 11 +- Justfile | 5 - docs/CHANGELOG.md | 1130 ----------------- docs/changelog_section_template.md | 19 - docs/dev/docs.md | 1 - packages/testing/pyproject.toml | 2 - .../src/execution_testing/cli/ci_helpers.py | 52 +- tox.ini | 5 - 8 files changed, 2 insertions(+), 1223 deletions(-) delete mode 100644 docs/CHANGELOG.md delete mode 100644 docs/changelog_section_template.md diff --git a/.github/workflows/docs-build.yaml b/.github/workflows/docs-build.yaml index a9617549142..477d159119b 100644 --- a/.github/workflows/docs-build.yaml +++ b/.github/workflows/docs-build.yaml @@ -71,19 +71,10 @@ jobs: docs/**/*.md *.md - changelog: - name: "Validate Changelog Entries" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: ./.github/actions/setup-uv - - name: Run changelog validation - run: just changelog - check-should-publish: name: "Check Should Publish" runs-on: ubuntu-latest - needs: [lint-md, changelog] + needs: [lint-md] outputs: should_publish: ${{ steps.check.outputs.should_publish }} branch: ${{ steps.check.outputs.branch }} diff --git a/Justfile b/Justfile index acd86151406..39041974066 100644 --- a/Justfile +++ b/Justfile @@ -302,11 +302,6 @@ docs-serve *args: docs-serve-fast *args: FAST_DOCS=True uv run mkdocs serve "$@" -# Validate docs/CHANGELOG.md entries -[group('docs')] -changelog: - uv run validate_changelog - # Lint markdown files (markdownlint) [group('docs')] lint-md: diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md deleted file mode 100644 index 4286cf29063..00000000000 --- a/docs/CHANGELOG.md +++ /dev/null @@ -1,1130 +0,0 @@ -# Changelog - -Test fixtures for use by clients are available for each release on the [Github releases page](https://github.com/ethereum/execution-spec-tests/releases). - -**Key:** ✨ = New, 🐞 = Fixed, 🔀 = Changed. 💥 = Breaking - -## 🔜 [Unreleased] - -### 💥 Breaking Change - -### 🛠️ Framework - -- 🐞 Remove `Op.CLZ` from `UndefinedOpcodes` list ([#1970](https://github.com/ethereum/execution-specs/pull/1970)). -- 🐞 Make `TransactionTraces` `CamelModel` less lestrictive ([#2081](https://github.com/ethereum/execution-specs/pull/2081)). - -#### `fill` - -- ✨ Allow command to customize `--chain-id` used for filling ([#2016](https://github.com/ethereum/execution-specs/pull/2016)). - -#### `consume` - -- ✨ Add Besu `evmtool` support for `consume direct` via `state-test` and `block-test` subcommands ([#2219](https://github.com/ethereum/execution-specs/pull/2219)). - -#### `execute` - -- ✨ Add transaction batching to avoid RPC overload when executing tests with many transactions. Transactions are now sent in configurable batches (default: 750) with progress logging. Use `--max-tx-per-batch` to configure the batch size ([#1907](https://github.com/ethereum/execution-specs/pull/1907)). -- ✨ `execute hive` and `execute remote` now defer funding of accounts until the minimum amount required to send the test transactions is calculated, in order to optimize the amount of Eth used to execute the tests ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). -- ✨ Dynamically fetch gas prices from the network and update all transactions to use 1.5x the current values ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). -- ✨ New `--dry-run` flag to calculate the amount of Eth that will be spent executing a test given the current network gas prices ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). -- 🔀 Load balancing mode of `execute` for xdist was updated from `loadscope` to `load` ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). -- 💥 `--eoa-fund-amount-default` has been deprecated since the command now automatically calculates the funding amount ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). -- 💥 `--sender-key-initial-balance` flag of `execute hive` has been renamed to `--seed-key-initial-balance` ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). -- 🔀 Flags --default-gas-price, --default-max-fee-per-gas and --default-max-priority-fee-per-gas now default to None and ideally should be omitted because, when unset, the command now defaults to fetch the value from the network, which is a more reliable behavior ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). - -### 📋 Misc - -- ✨ Implement EIP-7928 Block-Level Access Lists ([#1719](https://github.com/ethereum/execution-specs/pull/1719)). - -### 🧪 Test Cases - -- ✨ Add missing fuzzy-compute benchmark configurations for `KECCAK256`, `CODECOPY`, `CALLDATACOPY`, `RETURNDATACOPY`, `MLOAD`, `MSTORE`, `MSTORE8`, `MCOPY`, `LOG*`, `CALLDATASIZE`, `CALLDATALOAD`, and `RETURNDATASIZE` opcodes ([#1956](https://github.com/ethereum/execution-specs/pull/1956)). -- ✨ Add precompile benchmark configurations for `ecPairing`, `blake2f`, `BLS12_G1_MSM`, `BLS12_G2_MSM` and `BLS12_PAIRING` to unblock repricing analysis ([#2003](https://github.com/ethereum/execution-specs/pull/2003)). -- 🔀 Relabel `@pytest.mark.repricing` markers in benchmark tests to reflect configurations requested for gas repricing analysis ([#1971](https://github.com/ethereum/execution-specs/pull/1971)). -- ✨ New EIP-7702 test cases added ([#1974](https://github.com/ethereum/execution-specs/pull/1974)). -- ✨ Add missing benchmark configurations / opcode to benchmark tests for repricing analysis([#2006](https://github.com/ethereum/execution-specs/pull/2006)). -- ✨ Port STATICCALL to CALL tests with zero and non-zero value transfer from `tests/static`, extending coverage with `pytest.mark.with_all_precompiles` ([#1960](https://github.com/ethereum/execution-specs/pull/1960)). -- ✨ Add BAL tests that dequeue EIP-7251 consolidation requests. ([#2076](https://github.com/ethereum/execution-specs/pull/2076)). -- ✨ Add BAL tests for handling 7702 delegation reset and delegated create. ([#2097](https://github.com/ethereum/execution-specs/pull/2097)). -- ✨ Add benchmark scenarios for ether transfers to precompiles, warm access list transfers, and max-size contract creation transactions ([#2171](https://github.com/ethereum/execution-specs/pull/2171)). - -## [v5.4.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.4.0) - 2025-12-07 - -### 🛠️ Framework - -#### General - -- 🔀 Updated default block gas limit from 45M to 60M to align with [EIP-7935](https://eips.ethereum.org/EIPS/eip-7935) for the Osaka fork. - -#### `fill` - -- 🐞 Allow `evmone` to fill Prague and Osaka blockchain tests (mainly modified deposit contract tests) ([#1689](https://github.com/ethereum/execution-specs/pull/1689)). -- 🐞 Turn off Block-Level Access List related checks when filling tests for Amsterdam ([#1737](https://github.com/ethereum/execution-specs/pull/1737)). - -#### `consume` - -- 🐞 Fix a bug with `consume sync` tests where some clients don't have JSON-RPC immediately available after syncing and can't yet serve the synced block ([#1670](https://github.com/ethereum/execution-specs/pull/1670)). - -### 📋 Misc - -- 🐞 WELDed the EEST tox environments relevant to producing documentation into EELS, and added a tool to cleanly add codespell whitelist entries. ([#1695](https://github.com/ethereum/execution-specs/pull/1659)). -- 🐞 Fix duplicate storage write issues for block access lists EIP-7928 implementation ([#1743](https://github.com/ethereum/execution-specs/pull/1743)). - -### 🧪 Test Cases - -- 🐞 Fix BALs opcode OOG test vectors by updating the Amsterdam commit hash in specs and validating appropriately on the testing side ([#2293](https://github.com/ethereum/execution-spec-tests/pull/2293)). -- ✨ Fix test vector for BALs SSTORE with OOG by pointing to updated specs; add new boundary conditions cases for SSTORE w/ OOG ([#2297](https://github.com/ethereum/execution-spec-tests/pull/2297)). -- ✨ Expand EIP-6110 modified contract tests, where the extra event log has no topics at all ([#1693](https://github.com/ethereum/execution-specs/pull/1693)). -- ✨ Add a CREATE/2 test cases for when it runs OOG on code deposit ([#1705](https://github.com/ethereum/execution-specs/pull/1705)). -- ✨ Expand cases to test *CALL opcodes causing OOG ([#1703](https://github.com/ethereum/execution-specs/pull/1703)). -- ✨ Add a test case for base fee in block check after London ([#1702](https://github.com/ethereum/execution-specs/pull/1702)). -- ✨ Add tests for `modexp` and `ripemd` precompiled contracts ([#1691](https://github.com/ethereum/execution-specs/pull/1691), [#1781](https://github.com/ethereum/execution-specs/pull/1781)). -- ✨ Add `ecrecover` precompile tests originating form `evmone` unittests ([#1685](https://github.com/ethereum/execution-specs/pull/1685)). -- ✨ Add test to validate withdarawls root ([#1746](https://github.com/ethereum/execution-specs/pull/1746)). -- ✨ Add test for old behavior of zero gasprice txs ([#1736](https://github.com/ethereum/execution-specs/pull/1736)). -- ✨ Add stack overflow tests and expand `BLOCKHASH` tests ([#1728](https://github.com/ethereum/execution-specs/pull/1728)). -- ✨ Ported tests for `ripemd` precompile going OOG for all forks ([#1732](https://github.com/ethereum/execution-specs/pull/1732)). -- ✨ Add tests for ecadd/ecmul/ecpairing constant gas repricing ([#1738](https://github.com/ethereum/execution-specs/pull/1738)). -- ✨ Add tests that EIP-1559 and EIP-2930 typed txs are invalid and void before their fork ([#1754](https://github.com/ethereum/execution-specs/pull/1754)). -- ✨ Add tests for an old validation rule for gas limit above 5000 ([#1731](https://github.com/ethereum/execution-specs/pull/1731)). -- ✨ Add tests for OOG in EXP, LOG and others ([#1686](https://github.com/ethereum/execution-specs/pull/1686)). -- ✨ Make EIP-7934 tests more dynamic and able to handle new header fields added in future forks ([#2022](https://github.com/ethereum/execution-specs/pull/2022)). - -## [v5.3.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.3.0) - 2025-10-09 - -## 🇯🇵 Summary - -EEST v5.3.0 is a follow-up from our main v5.0.0 [release](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.0.0), with updated BPO1 and BPO2 values aligning with the testnet parameters. - -This release additionally includes fixes for tests in hive, as well as new test cases for EIP-7883, EIP-7934 and critical cases for EIP-7951 (added to EEST by @chfast following a coverage review of the test suite). - -## 🔑 Key Changes - -### 🛠️ Framework - -- ✨ Add benchmark-specific test wrapper (`benchmark_test`) that supports **EIP-7825** and create a benchmark code generator for common test pattern ([#1945](https://github.com/ethereum/execution-spec-tests/pull/1945)). - -#### `fill` - -- ✨ Added `--optimize-gas`, `--optimize-gas-output` and `--optimize-gas-post-processing` flags that allow to binary search the minimum gas limit value for a transaction in a test that still yields the same test result ([#1979](https://github.com/ethereum/execution-spec-tests/pull/1979)). -- ✨ Added `--watch` flag that monitors test files for changes and automatically re-runs the fill command when developing tests ([#2173](https://github.com/ethereum/execution-spec-tests/pull/2173)). -- 🔀 Upgraded ckzg version to 2.1.3 or newer for correct handling of points at infinity ([#2171](https://github.com/ethereum/execution-spec-tests/pull/2171)). -- 🔀 Move pytest marker registration for `fill` and `execute-*` from their respective ini files to the shared `pytest_plugins.shared.execute_fill` pytest plugin ([#2110](https://github.com/ethereum/execution-spec-tests/pull/2110)). -- ✨ Added an `--input.blobParams` CLI argument to the transition tool (`t8n`) invocation ([#2264](https://github.com/ethereum/execution-spec-tests/pull/2264)). - -#### `consume` - -- ✨ Add retry logic to RPC requests to fix flaky connection issues in Hive ([#2205](https://github.com/ethereum/execution-spec-tests/pull/2205)). -- 🛠️ Mark `consume sync` tests as `flaky` with 3 retires due to client sync inconsistencies ([#2252](https://github.com/ethereum/execution-spec-tests/pull/2252)). -- ✨ Add `consume direct` using `evmone-statetest` and `evmone-blockchaintest` ([#2243](https://github.com/ethereum/execution-spec-tests/pull/2243)). - -### 📋 Misc - -- ✨ Add tighter validation for EIP-7928 model coming from t8n when filling ([#2138](https://github.com/ethereum/execution-spec-tests/pull/2138)). -- ✨ Add flexible API for absence checks for EIP-7928 (BAL) tests ([#2124](https://github.com/ethereum/execution-spec-tests/pull/2124)). -- 🐞 Use `engine_newPayloadV5` for `>=Amsterdam` forks in `consume engine` ([#2170](https://github.com/ethereum/execution-spec-tests/pull/2170)). -- 🔀 Refactor EIP-7928 (BAL) absence checks into a friendlier class-based DevEx ([#2175](https://github.com/ethereum/execution-spec-tests/pull/2175)). -- 🐞 Tighten up validation for empty lists on Block-Level Access List tests ([#2118](https://github.com/ethereum/execution-spec-tests/pull/2118)). -- ✨ Added the `MemoryVariable` EVM abstraction to generate more readable bytecode when there's heavy use of variables that are stored in memory ([#1609](https://github.com/ethereum/execution-spec-tests/pull/1609)). -- 🐞 Fix an issue with `test_bal_block_rewards` where the block base fee was wrongfully overridden ([#2262](https://github.com/ethereum/execution-spec-tests/pull/2262)). -- ✨ Complete EIP checklist for EIP-7934 and update the checklist template to include block-level constraint checks ([#2282](https://github.com/ethereum/execution-spec-tests/pull/2282)). - -### 🧪 Test Cases - -- ✨ Add safe EIP-6110 workaround to allow Geth/Reth to pass invalid deposit request tests even thought they are out of spec ([#2177](https://github.com/ethereum/execution-spec-tests/pull/2177), [#2233](https://github.com/ethereum/execution-spec-tests/pull/2233)). -- ✨ Add an EIP-7928 test case targeting the `SELFDESTRUCT` opcode. ([#2159](https://github.com/ethereum/execution-spec-tests/pull/2159)). -- ✨ Add essential tests for coverage gaps in EIP-7951 (`p256verify` precompile) ([#2179](https://github.com/ethereum/execution-spec-tests/pull/2159), [#2203](https://github.com/ethereum/execution-spec-tests/pull/2203), [#2215](https://github.com/ethereum/execution-spec-tests/pull/2215), [#2216](https://github.com/ethereum/execution-spec-tests/pull/2216), [#2217](https://github.com/ethereum/execution-spec-tests/pull/2217), [#2218](https://github.com/ethereum/execution-spec-tests/pull/2218), [#2221](https://github.com/ethereum/execution-spec-tests/pull/2221), [#2229](https://github.com/ethereum/execution-spec-tests/pull/2229), [#2230](https://github.com/ethereum/execution-spec-tests/pull/2230), [#2237](https://github.com/ethereum/execution-spec-tests/pull/2237), [#2238](https://github.com/ethereum/execution-spec-tests/pull/2238)). -- ✨ Add EIP-7928 successful and OOG single-opcode tests ([#2118](https://github.com/ethereum/execution-spec-tests/pull/2118)). -- ✨ Add EIP-7928 tests for EIP-2930 interactions ([#2167](https://github.com/ethereum/execution-spec-tests/pull/2167)). -- ✨ Add EIP-7928 tests for NOOP operations ([#2178](https://github.com/ethereum/execution-spec-tests/pull/2178)). -- ✨ Add EIP-7928 tests for net-zero balance transfers ([#2280](https://github.com/ethereum/execution-spec-tests/pull/2280)). -- ✨ Add fork transition test cases for EIP-7934 ([#2282](https://github.com/ethereum/execution-spec-tests/pull/2282)). - -## [v5.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.0.0) - 2025-09-05 - -## 🇯🇵 Summary - -EEST Fujisan is our first full release for Osaka, the first full release since Pectra! - -In addition to the latest Osaka specific test cases, it includes re-filled `GeneralStateTests` from `ethereum/tests` (now fully maintained within EEST under `tests/static`) for Osaka adhering to the transaction gas limit cap from [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825). Further framework changes include new simulators, test formats and test types. - -## ⚔️ Future Weld with EELS - -EEST will merge with [EELS](https://github.com/ethereum/execution-specs) during **Q4 2025**, after which EEST becomes read-only for external contributors. - -**What this means?** - -- All EEST code moves to the EELS repository. -- New EEST framework location: `execution-specs/src/ethereum_spec_tests/`. -- New EEST tests location: `execution-specs/tests/eest/`. -- Future PRs go to EELS instead of EEST. - -**Important Notes:** - -- All PRs for tests and framework changes should still be directed at EEST until further notice. -- There will be a brief freeze on EEST contributions during Q4 "The Switch", after which contributors can continue as before, but in EELS. -- Test releases will continue from EEST as normal before, during, and after this transition. - -More information will be communicated accordingly through the normal communication channels. - -## ❗Current Status Quo - -### Test Fixtures Overview - -- `fixtures_static.tar.gz` has been deprecated. -- `fixtures_stable.tar.gz` & `fixtures_develop.tar.gz` now both contain re-filled static tests, `GeneralStateTests` from `ethereum/tests`, filled **from Cancun**. -- `fixtures_stable.tar.gz` contains tests filled for forks until Prague. -- `fixtures_develop.tar.gz` contains tests filled for forks until Osaka. -- `fixtures_benchmark.tar.gz` contains benchmark tests filled for only Prague. - -### EL Client Test Requirements - -**Prague Coverage (Mainnet):** - -- Run all `state_test`'s & `blockchain_test`'s from `fixtures_stable.tar.gz`. -- Run only `BlockchainTests` from the latest `ethereum/tests` [release](https://github.com/ethereum/tests/releases/tag/v17.2), filled **until Prague**. - -**Fusaka Coverage (Including Mainnet):** - -- Run all `state_test`'s & `blockchain_test`'s from `fixtures_develop.tar.gz`. -- Run only `BlockchainTests` from the latest `ethereum/tests` [release](https://github.com/ethereum/tests/releases/tag/v17.2), filled **until Prague**. - -**Note**: If you require `GeneralStateTests` from `ethereum/tests` **filled for forks before Cancun** then you must get these from the latest `ethereum/tests` [release](https://github.com/ethereum/tests/releases/tag/v17.2). - -### Benchmark Tests - -For the most up-to-date benchmark tests, use `fixtures_benchmark.tar.gz`. - -> **Note**: Benchmark tests for Osaka (compliant with EIP-7825 transaction gas limit cap) will be added in a future feature release. - -### Test Fixture Formats - -This release includes 2 new test formats designed primarily for [Hive](https://github.com/ethereum/hive) simulators: - -- [**`blockchain_tests_engine_x`**](https://eest.ethereum.org/v5.0.0/running_tests/test_formats/blockchain_test_engine_x/?h=#blockchain-engine-x-tests): An optimized version of `blockchain_tests_engine` where multiple tests share the same genesis state, allowing multiple tests to run on a single client instantiation within Hive's `consume-engine`. The standard format requires a fresh client startup for each test. Due its combined genesis state, this is additionally the primary format used by the Nethermind team for benchmarking. - -- [**`blockchain_tests_sync`**](https://eest.ethereum.org/main/running_tests/test_formats/blockchain_test_sync/?h=sync#blockchain-engine-sync-tests): A new format adjacent to the existing `blockchain_tests_engine` format. Used specifically for the upcoming `consume-sync` simulator, which delivers engine payloads from test fixtures to the client under test, then sync's a separate client to it. This test fixture is only marked to be filled for the [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934) block RLP limit tests in Osaka. - -### Tooling & Simulators - -Improved tooling and new Hive simulators are additionally included in this release: - -- [**`execute remote`**](https://eest.ethereum.org/main/running_tests/execute/remote/#running-test-on-a-live-remote-network): this command now supports optional [Engine RPC endpoints](https://eest.ethereum.org/main/running_tests/execute/remote/#engine-rpc-endpoint-optional) (`--engine-endpoint`) with JWT authentication #2070. - - This allows manual control over block creation and transaction inclusion for more deterministic test execution on live networks. Previously, `execute remote` could only submit transactions and rely on the network's automatic block production, but now it can actively drive chain progression by creating blocks on-demand via the Engine API. -- [**`consume sync`**](https://eest.ethereum.org/main/running_tests/running/#sync): Adjacent to `consume-engine`, designed to work with the `blockchain_tests_sync` format for testing client sync scenarios. -- [**`execute blobs`**](https://eest.ethereum.org/main/running_tests/execute/hive/#the-eestexecute-blobs-simulator): A new Hive specific simulator that uses the EEST execute pytest plugin. Sends blob transactions to the client under test and verifies its `engine_getBlobsVX` endpoint. Requires tests to be written with a new python test format `blob_transaction_test`. Primarily used to test PeerDAS from the EL perspective. -- [**`execute eth config`**](https://eest.ethereum.org/main/running_tests/execute/eth_config/): A command used to test the `eth_config` endpoint from [EIP-7910](https://eips.ethereum.org/EIPS/eip-7910). Can be ran [remotely](https://github.com/ethereum/execution-spec-tests/issues/2049) or within Hive. - -### Filling For Stateless Clients - -A `witness-filler` extension is included in this release, allowing for tests to be filled that include an `executionWitness` for each fixture #2066. This essentially calls an external executable written in rust, and hence must be installed for usage within `fill` using the `--witness` flag. The current approach is below: - -```sh -cargo install --git https://github.com/kevaundray/reth.git --branch jsign-witness-filler witness-filler -uv run fill ... --output=fixtures-witness --witness --clean -``` - -> **Note**: The `witness-filler` executable is not maintained by EEST so we cannot help with any issues. - -## 💥 Breaking Changes - -### Important changes for EEST superusers - -- EEST now requires `uv>=0.7.0` ([#1904](https://github.com/ethereum/execution-spec-tests/pull/1904)). If your version of `uv` is too old. -- When filling fixtures transition forks are included within there respective "to" fork, where `--fork Osaka` will now include `PragueToOsakaAtTime15k`. Previously transitions fork would only be included when filling with `--from Prague --until Osaka` flags. -- Python 3.10 support was removed in this release ([#1808](https://github.com/ethereum/execution-spec-tests/pull/1808)). -- EEST no longer allows usage of Yul code in Python tests. From now on, please make use of our opcode wrapper. Yul code is now only allowed in the "static tests" located in `./tests/static/` (these are test cases defined by JSON and YAML files instead of Python test functions that were originally maintained in [ethereum/tests](https://github.com/ethereum/tests)). -- In order to fill the static tests (which is not the case by default), please ensure that `solc` is located in your `PATH`. -- The output behavior of `fill` has changed ([#1608](https://github.com/ethereum/execution-spec-tests/pull/1608)): - - Before: `fill` wrote fixtures into the directory specified by the `--output` flag (default: `fixtures`). This could have many unintended consequences, including unexpected errors if old or invalid fixtures existed in the directory (for details see [#1030](https://github.com/ethereum/execution-spec-tests/issues/1030)). - - Now: `fill` will exit without filling any tests if the specified directory exists and is not-empty. This may be overridden by adding the `--clean` flag, which will first remove the specified directory. -- Writing debugging information to the EVM "dump directory" by default has been disabled. To obtain debug output, the `--evm-dump-dir` flag must now be explicitly set. As a consequence, the now redundant `--skip-evm-dump` option was removed ([#1874](https://github.com/ethereum/execution-spec-tests/pull/1874)). This undoes functionality originally introduced in [#999](https://github.com/ethereum/execution-spec-tests/pull/999) and [#1150](https://github.com/ethereum/execution-spec-tests/pull/1150). - -### Feature `zkevm` updated to `benchmark` - -Due to the crossover between `zkevm` and `benchmark` tests, all instances of the former have been replaced with the latter nomenclature. Repository PR labels and titles are additionally updated to reflect this change. - -This update renames the `zkevm` feature release to `benchmark` and further expands the latter for 1M, 10M, 30M, 45M, 60M, 90M, and 120M block gas limits in `fixtures_benchmark.tar.gz`. - -To select a test for a given gas limit, the IDs of the tests have been expanded to contain `benchmark-gas-value_XM`, where `X` can be any of the aforementioned values. - -The benchmark release also now includes BlockchainEngineX format that combines most of the tests into a minimal amount of genesis files. For more info see [Blockchain Engine X Tests](https://eest.ethereum.org/main/running_tests/test_formats/blockchain_test_engine_x/) in the EEST documentation. - -Users can select any of the artifacts depending on their benchmarking or testing needs for their provers. - -## 🔑 Other Key Changes - -### 🛠️ Framework - -#### 🔀 Refactoring - -- 🔀 Move `TransactionType` enum from test file to proper module location in `ethereum_test_types.transaction_types` for better code organization and reusability. -- ✨ Opcode classes now validate keyword arguments and raise `ValueError` with clear error messages. -- 🔀 This PR removes the `solc` requirement to fill Python test cases. Regular test contributors no longer need to concern themselves with `solc` and, as such, the `solc-select` dependency has been removed. The remaining tests that used Yul have been ported to the EEST opcode wrapper mini-lang and the use of Yul in Python tests is no longer supported. Maintainers only: To fill the "static" JSON and YAML tests (`./tests/static/`) locally, `solc` (ideally v0.8.24) must be available in your PATH. -- 🔀 Updated default block gas limit from 36M to 45M to match mainnet environment. -- 🔀 Refactor fork logic to include transition forks within there "to" fork ([#2051](https://github.com/ethereum/execution-spec-tests/pull/2051)). - -#### `fill` - -- ✨ Add the `ported_from` test marker to track Python test cases that were converted from static fillers in [ethereum/tests](https://github.com/ethereum/tests) repository ([#1590](https://github.com/ethereum/execution-spec-tests/pull/1590)). -- ✨ Add a new pytest plugin, `ported_tests`, that lists the static fillers and PRs from `ported_from` markers for use in the coverage Github Workflow ([#1634](https://github.com/ethereum/execution-spec-tests/pull/1634)). -- ✨ Enable two-phase filling of fixtures with pre-allocation groups and add a `BlockchainEngineXFixture` format ([#1706](https://github.com/ethereum/execution-spec-tests/pull/1706), [#1760](https://github.com/ethereum/execution-spec-tests/pull/1760)). -- ✨ Add `--generate-all-formats` flag to enable generation of all fixture formats including `BlockchainEngineXFixture` in a single command; enable `--generate-all-formats` automatically for tarball output, `--output=fixtures.tar.gz`, [#1855](https://github.com/ethereum/execution-spec-tests/pull/1855). -- 🔀 Refactor: Encapsulate `fill`'s fixture output options (`--output`, `--flat-output`, `--single-fixture-per-file`) into a `FixtureOutput` class ([#1471](https://github.com/ethereum/execution-spec-tests/pull/1471),[#1612](https://github.com/ethereum/execution-spec-tests/pull/1612)). -- ✨ Don't warn about a "high Transaction gas_limit" for `zkevm` tests ([#1598](https://github.com/ethereum/execution-spec-tests/pull/1598)). -- 🐞 `fill` no longer writes generated fixtures into an existing, non-empty output directory; it must now be empty or `--clean` must be used to delete it first ([#1608](https://github.com/ethereum/execution-spec-tests/pull/1608)). -- 🐞 `zkevm` marked tests have been removed from `tests-deployed` tox environment into its own separate workflow `tests-deployed-zkevm` and are filled by `evmone-t8n` ([#1617](https://github.com/ethereum/execution-spec-tests/pull/1617)). -- ✨ Field `postStateHash` is now added to all `blockchain_test` and `blockchain_test_engine` tests that use `exclude_full_post_state_in_output` in place of `postState`. Fixes `evmone-blockchaintest` test consumption and indirectly fixes coverage runs for these tests ([#1667](https://github.com/ethereum/execution-spec-tests/pull/1667)). -- 🔀 Changed INVALID_DEPOSIT_EVENT_LAYOUT to a BlockException instead of a TransactionException ([#1773](https://github.com/ethereum/execution-spec-tests/pull/1773)). -- 🔀 Disabled writing debugging information to the EVM "dump directory" to improve performance. To obtain debug output, the `--evm-dump-dir` flag must now be explicitly set. As a consequence, the now redundant `--skip-evm-dump` option was removed ([#1874](https://github.com/ethereum/execution-spec-tests/pull/1874)). -- ✨ Generate unique addresses with Python for compatible static tests, instead of using hard-coded addresses from legacy static test fillers ([#1781](https://github.com/ethereum/execution-spec-tests/pull/1781)). -- ✨ Added support for the `--benchmark-gas-values` flag in the `fill` command, allowing a single genesis file to be used across different gas limit settings when generating fixtures. ([#1895](https://github.com/ethereum/execution-spec-tests/pull/1895)). -- ✨ Static tests can now specify a maximum fork where they should be filled for ([#1977](https://github.com/ethereum/execution-spec-tests/pull/1977)). -- ✨ Static tests can now be filled in every format using `--generate-all-formats` ([#2006](https://github.com/ethereum/execution-spec-tests/pull/2006)). -- 💥 Flag `--flat-output` has been removed due to having been unneeded for an extended period of time ([#2018](https://github.com/ethereum/execution-spec-tests/pull/2018)). -- ✨ Add support for `BlockchainEngineSyncFixture` format for tests marked with `pytest.mark.verify_sync` to enable client synchronization testing via `consume sync` command ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)). -- ✨ Framework is updated to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) fork markers to enable the filling of BPO tests ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)). -- ✨ Generate and include execution witness data in blockchain fixtures if `--witness` is specified ([#2066](https://github.com/ethereum/execution-spec-tests/pull/2066)). - -#### `consume` - -- ✨ Add `--extract-to` parameter to `consume cache` command for direct fixture extraction to specified directory, replacing the need for separate download scripts. ([#1861](https://github.com/ethereum/execution-spec-tests/pull/1861)). -- 🐞 Fix `consume cache --cache-folder` parameter being ignored, now properly caches fixtures in the specified directory instead of always using the default system cache location. -- 🐞 Fix the `consume_direct.sh` script generated by `consume` in the `--evm-dump` dir by quoting test IDs [#1987](https://github.com/ethereum/execution-spec-tests/pull/1987). -- 🔀 `consume` now automatically avoids GitHub API calls when using direct release URLs (better for CI environments), while release specifiers like `stable@latest` continue to use the API for version resolution ([#1788](https://github.com/ethereum/execution-spec-tests/pull/1788)). -- 🔀 Refactor consume simulator architecture to use explicit pytest plugin structure with forward-looking architecture ([#1801](https://github.com/ethereum/execution-spec-tests/pull/1801)). -- 🔀 Add exponential retry logic to initial fcu within consume engine ([#1815](https://github.com/ethereum/execution-spec-tests/pull/1815)). -- ✨ Add `consume sync` command to test client synchronization capabilities by having one client sync from another via Engine API and P2P networking ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)). -- 💥 Removed the `consume hive` command, this was a convenience command that ran `consume rlp` and `consume engine` in one pytest session; the individual commands should now be used instead ([#2008](https://github.com/ethereum/execution-spec-tests/pull/2008)). -- ✨ Update the hive ruleset to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) forks ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)). - -#### `execute` - -- ✨ Added new `Blob` class which can use the ckzg library to generate valid blobs at runtime ([#1614](https://github.com/ethereum/execution-spec-tests/pull/1614)). -- ✨ Added `blob_transaction_test` execute test spec, which allows tests that send blob transactions to a running client and verifying its `engine_getBlobsVX` endpoint behavior ([#1644](https://github.com/ethereum/execution-spec-tests/pull/1644)). -- ✨ Added `execute eth-config` command to test the `eth_config` RPC endpoint of a client, and includes configurations by default for Mainnet, Sepolia, Holesky, and Hoodi ([#1863](https://github.com/ethereum/execution-spec-tests/pull/1863)). -- ✨ Command `execute remote` now allows specification of an Engine API endpoint to drive the chain via `--engine-endpoint` and either `--engine-jwt-secret` or `--engine-jwt-secret-file`. This mode is useful when there's no consensus client connected to the execution client so `execute` will automatically request blocks via the Engine API when it sends transactions ([#2070](https://github.com/ethereum/execution-spec-tests/pull/2070)). -- ✨ Added `--address-stubs` flag to the `execute` command which allows to specify a JSON-formatted string, JSON file or YAML file which contains label-to-address of specific pre-deployed contracts already existing in the network where the tests are executed ([#2073](https://github.com/ethereum/execution-spec-tests/pull/2073)). - -### 📋 Misc - -- ✨ Add pypy3.11 support ([#1854](https://github.com/ethereum/execution-spec-tests/pull/1854)). -- 🔀 Use only relative imports in `tests/` directory ([#1848](https://github.com/ethereum/execution-spec-tests/pull/1848)). -- 🔀 Convert absolute imports to relative imports in `src/` directory for better code maintainability ([#1907](https://github.com/ethereum/execution-spec-tests/pull/1907)). -- 🔀 Misc. doc updates, including a navigation footer ([#1846](https://github.com/ethereum/execution-spec-tests/pull/1846)). -- 🔀 Remove Python 3.10 support ([#1808](https://github.com/ethereum/execution-spec-tests/pull/1808)). -- 🔀 Modernize codebase with Python 3.11 language features ([#1812](https://github.com/ethereum/execution-spec-tests/pull/1812)). -- ✨ Add changelog formatting validation to CI to ensure consistent punctuation in bullet points [#1691](https://github.com/ethereum/execution-spec-tests/pull/1691). -- ✨ Added the [EIP checklist template](https://eest.ethereum.org/main/writing_tests/checklist_templates/eip_testing_checklist_template/) that serves as a reference to achieve better coverage when implementing tests for new EIPs ([#1327](https://github.com/ethereum/execution-spec-tests/pull/1327)). -- ✨ Added [Post-Mortems of Missed Test Scenarios](https://eest.ethereum.org/main/writing_tests/post_mortems/) to the documentation that serves as a reference list of all cases that were missed during the test implementation phase of a new EIP, and includes the steps taken in order to prevent similar test cases to be missed in the future ([#1327](https://github.com/ethereum/execution-spec-tests/pull/1327)). -- ✨ Add documentation "Running Tests" that explains the different methods available to run EEST tests and reference guides for running `consume` and `hive`: ([#1172](https://github.com/ethereum/execution-spec-tests/pull/1172)). -- ✨ Added a new `eest` sub-command, `eest info`, to easily print a cloned EEST repository's version and the versions of relevant tools, e.g., `python`, `uv` ([#1621](https://github.com/ethereum/execution-spec-tests/pull/1621)). -- ✨ Add `CONTRIBUTING.md` for execution-spec-tests and improve coding standards documentation ([#1604](https://github.com/ethereum/execution-spec-tests/pull/1604)). -- ✨ Add `CLAUDE.md` to help working in @ethereum/execution-spec-tests with [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) ([#1749](https://github.com/ethereum/execution-spec-tests/pull/1749)). -- ✨ Use `codespell` instead of `pyspelling` to spell-check python and markdown sources ([#1715](https://github.com/ethereum/execution-spec-tests/pull/1715)). -- 🔀 Updated from pytest 7 to [pytest 8](https://docs.pytest.org/en/stable/changelog.html#features-and-improvements), benefits include improved type hinting and hook typing, stricter mark handling, and clearer error messages for plugin and metadata development ([#1433](https://github.com/ethereum/execution-spec-tests/pull/1433)). -- 🐞 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 `extract_config` command to extract genesis files used to launch clients in hive ([#1740](https://github.com/ethereum/execution-spec-tests/pull/1740)). -- ✨ 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)). -- 🔀 Add macOS hive development mode workaround to the docs [#1786](https://github.com/ethereum/execution-spec-tests/pull/1786). -- 🔀 Refactor and clean up of exceptions including EOF exceptions within client specific mappers [#1803](https://github.com/ethereum/execution-spec-tests/pull/1803). -- 🔀 Rename `tests/zkevm/` to `tests/benchmark/` and replace the `zkevm` pytest mark with `benchmark` [#1804](https://github.com/ethereum/execution-spec-tests/pull/1804). -- 🔀 Add fixture comparison check to optimize coverage workflow in CI ([#1833](https://github.com/ethereum/execution-spec-tests/pull/1833)). -- 🔀 Move `TransactionType` enum from test file to proper module location in `ethereum_test_types.transaction_types` for better code organization and reusability ([#1763](https://github.com/ethereum/execution-spec-tests/pull/1673)). -- ✨ Opcode classes now validate keyword arguments and raise `ValueError` with clear error messages ([#1739](https://github.com/ethereum/execution-spec-tests/pull/1739), [#1856](https://github.com/ethereum/execution-spec-tests/pull/1856)). -- ✨ All commands (`fill`, `consume`, `execute`) now work without having to clone the repository, e.g. `uv run --with git+https://github.com/ethereum/execution-spec-tests.git consume` now works from any folder ([#1863](https://github.com/ethereum/execution-spec-tests/pull/1863)). -- 🔀 Move Prague to stable and Osaka to develop ([#1573](https://github.com/ethereum/execution-spec-tests/pull/1573)). -- ✨ Add a `pytest.mark.with_all_typed_transactions` marker that creates default typed transactions for each `tx_type` supported by the current `fork` ([#1890](https://github.com/ethereum/execution-spec-tests/pull/1890)). -- ✨ Add basic support for ``Amsterdam`` fork in order to begin testing Glamsterdam ([#2069](https://github.com/ethereum/execution-spec-tests/pull/2069)). -- ✨ [EIP-7928](https://eips.ethereum.org/EIPS/eip-7928): Add initial framework support for `Block Level Access Lists (BAL)` testing for Amsterdam ([#2067](https://github.com/ethereum/execution-spec-tests/pull/2067)). - -### 🧪 Test Cases - -- ✨ [BloatNet](https://bloatnet.info)/Multidimensional Metering: Add benchmarks to be used as part of the BloatNet project and also for Multidimensional Metering. -- ✨ [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): Add additional test cases for modular comparison. -- 🔀 Refactored `BLOBHASH` opcode context tests to use the `pre_alloc` plugin in order to avoid contract and EOA address collisions ([#1637](https://github.com/ethereum/execution-spec-tests/pull/1637)). -- 🔀 Refactored `SELFDESTRUCT` opcode collision tests to use the `pre_alloc` plugin in order to avoid contract and EOA address collisions ([#1643](https://github.com/ethereum/execution-spec-tests/pull/1643)). -- ✨ EIP-7594: Sanity test cases to send blob transactions and verify `engine_getBlobsVX` using the `execute` command ([#1644](https://github.com/ethereum/execution-spec-tests/pull/1644),[#1884](https://github.com/ethereum/execution-spec-tests/pull/1884)). -- 🔀 Refactored EIP-145 static tests into python ([#1683](https://github.com/ethereum/execution-spec-tests/pull/1683)). -- ✨ EIP-7823, EIP-7883: Add test cases for ModExp precompile gas-cost updates and input limits on Osaka ([#1579](https://github.com/ethereum/execution-spec-tests/pull/1579), [#1729](https://github.com/ethereum/execution-spec-tests/pull/1729), [#1881](https://github.com/ethereum/execution-spec-tests/pull/1881)). -- ✨ [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825): Add test cases for the transaction gas limit of 2^24 gas ([#1711](https://github.com/ethereum/execution-spec-tests/pull/1711), [#1882](https://github.com/ethereum/execution-spec-tests/pull/1882)). -- ✨ [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): add test cases for `P256VERIFY` precompile to support secp256r1 curve [#1670](https://github.com/ethereum/execution-spec-tests/pull/1670). -- ✨ Introduce blockchain tests for benchmark to cover the scenario of pure ether transfers [#1742](https://github.com/ethereum/execution-spec-tests/pull/1742). -- ✨ [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934): Add test cases for the block RLP max limit of 10MiB ([#1730](https://github.com/ethereum/execution-spec-tests/pull/1730)). -- ✨ [EIP-7939](https://eips.ethereum.org/EIPS/eip-7939): Add count leading zeros (CLZ) opcode tests for Osaka ([#1733](https://github.com/ethereum/execution-spec-tests/pull/1733)). -- ✨ [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934): Add additional test cases for block RLP max limit with all typed transactions and for a log-creating transactions ([#1890](https://github.com/ethereum/execution-spec-tests/pull/1890)). -- ✨ [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825): Pre-Osaka tests have been updated to either (1) dynamically adapt to the transaction gas limit cap, or (2) reduce overall gas consumption to fit the new limit ([#1924](https://github.com/ethereum/EIPs/pull/1924), [#1928](https://github.com/ethereum/EIPs/pull/1928), [#1980](https://github.com/ethereum/EIPs/pull/1980)). -- ✨ [EIP-7918](https://eips.ethereum.org/EIPS/eip-7918): Blob base fee bounded by execution cost test cases (initial), includes some adjustments to [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) tests ([#1685](https://github.com/ethereum/execution-spec-tests/pull/1685)). -- 🔀 Adds the max blob transaction limit to the tests including updates to [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) for Osaka ([#1884](https://github.com/ethereum/execution-spec-tests/pull/1884)). -- 🐞 Fix issues when filling block rlp size limit tests with ``--generate-pre-alloc-groups`` ([#1989](https://github.com/ethereum/execution-spec-tests/pull/1989)). -- ✨ [EIP-7928](https://eips.ethereum.org/EIPS/eip-7928): Add test cases for `Block Level Access Lists (BAL)` to Amsterdam ([#2067](https://github.com/ethereum/execution-spec-tests/pull/2067)). -- 🐞 Fix issues with `Block Level Access Lists (BAL)` tests for Amsterdam ([#2121](https://github.com/ethereum/execution-spec-tests/pull/2121)). - -## [v4.5.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.5.0) - 2025-05-14 - -### 💥 Breaking Change - -#### EOF removed from Osaka - -Following ["Interop Testing Call 34"](https://github.com/ethereum/pm/issues/1499) and the procedural EIPs [PR](https://github.com/ethereum/EIPs/pull/9703) the decision to remove EOF from Osaka was made. - -To accommodate EOF testing for the interim within EEST, its tests have migrated to a new `tests/unscheduled` folder. This folder will now contain tests for features that are not yet CFI'd in any fork. When EOF is CFI'd for a fork in the future, all tests will be moved from unscheduled to the respective future fork folder. - -A new fork `EOFv1` has additionally been created to fill and consume EOF related fixtures. Client tests fillers such as `evmone` (and client consumers) will now need to use this fork name. - -### 🛠️ Framework - -- ✨ Add an empty account function for usage within fill and execute ([#1482](https://github.com/ethereum/execution-spec-tests/pull/1482)). -- ✨ Added `TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST` exception to specifically catch the case where the intrinsic gas cost is insufficient due to the data floor gas cost ([#1582](https://github.com/ethereum/execution-spec-tests/pull/1582)). - -### 📋 Misc - -- ✨ Engine API updates for Osaka, add `get_blobs` rpc method ([#1510](https://github.com/ethereum/execution-spec-tests/pull/1510)). -- ✨ The EIP Version checker has been moved from `fill` and `execute` to it's own command-line tool `check_eip_versions` that gets ran daily as a Github Action ([#1537](https://github.com/ethereum/execution-spec-tests/pull/1537)). -- 🔀 Add new `tests/unscheduled` folder, move EOF from Osaka to unscheduled, add `EOFv1` fork name for EOF tests ([#1507](https://github.com/ethereum/execution-spec-tests/pull/1507)). -- ✨ CI features now contain an optional field to skip them from EEST full releases, `benchmark` and EOF features are now feature only ([#1596](https://github.com/ethereum/execution-spec-tests/pull/1596)). -- 🐞 Don't attempt to install `solc` via `solc-select` on ARM (official Linux ARM builds of `solc` are not available at the time of writing, cf [ethereum/solidity#11351](https://github.com/ethereum/solidity/issues/11351)) and add a version sanity check ([#1556](https://github.com/ethereum/execution-spec-tests/pull/1556)). - -### 🧪 Test Cases - -- 🔀 Automatically apply the `benchmark` marker to all tests under `./tests/benchmark/` and `./tests/prague/eip2537_bls_12_381_precompiles/` via conftest configuration ([#1534](https://github.com/ethereum/execution-spec-tests/pull/1534)). -- ✨ Port [calldataload](https://github.com/ethereum/tests/blob/ae4791077e8fcf716136e70fe8392f1a1f1495fb/src/GeneralStateTestsFiller/VMTests/vmTests/calldatacopyFiller.yml) and [calldatasize](https://github.com/ethereum/tests/blob/81862e4848585a438d64f911a19b3825f0f4cd95/src/GeneralStateTestsFiller/VMTests/vmTests/calldatasizeFiller.yml) tests ([#1236](https://github.com/ethereum/execution-spec-tests/pull/1236)). - -## [v4.4.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.4.0) - 2025-04-29 - -### 💥 Breaking Change - -#### `fixtures_static` - -A new fixture tarball has been included in this release: `fixtures_static.tar.gz`. - -This tarball contains all tests inside of [`./tests/static`](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static), which at this point only contains all tests copied from [`GeneralStateTests` in `ethereum/tests@7dc757ec132e372b6178a016b91f4c639f366c02`](https://github.com/ethereum/tests/tree/7dc757ec132e372b6178a016b91f4c639f366c02/src/GeneralStateTestsFiller). - -The tests have been filled using the new static test filler introduced in [#1336](https://github.com/ethereum/execution-spec-tests/pull/1336), and enhanced in [#1362](https://github.com/ethereum/execution-spec-tests/pull/1362) and [#1439](https://github.com/ethereum/execution-spec-tests/pull/1439). - -Users can expect that all tests currently living in [ethereum/tests](https://github.com/ethereum/tests/tree/develop/src) should eventually make its way into [`./tests/static`](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static) and can rely that these tests, filled for new forks even, will be included in `fixtures_static.tar.gz`. - -#### `fixtures_benchmark` - -Another new fixture tarball has been included in this release: `fixtures_benchmark.tar.gz`. - -Includes tests that are tailored specifically to test the execution layer proof generators. - -### 🛠️ Framework - -#### `fill` - -- 🐞 Fix the reported fixture source URLs for the case of auto-generated tests ([#1488](https://github.com/ethereum/execution-spec-tests/pull/1488)). - -#### `consume` - -- 🐞 Fix the Hive commands used to reproduce test executions that are displayed in test descriptions in the Hive UI ([#1494](https://github.com/ethereum/execution-spec-tests/pull/1494)). -- 🐞 Fix consume direct fails for geth blockchain tests ([#1502](https://github.com/ethereum/execution-spec-tests/pull/1502)). - -### 📋 Misc - -### 🧪 Test Cases - -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Test that DELEGATECALL to a 7702 target works as intended ([#1485](https://github.com/ethereum/execution-spec-tests/pull/1485)). -- ✨ [EIP-2573](https://eips.ethereum.org/EIPS/eip-2537): Includes a BLS12 point generator, alongside additional coverage many of the precompiles ([#1350](https://github.com/ethereum/execution-spec-tests/pull/1350)), ([#1505](https://github.com/ethereum/execution-spec-tests/pull/1505)). -- ✨ Add all [`GeneralStateTests` from `ethereum/tests`](https://github.com/ethereum/tests/tree/7dc757ec132e372b6178a016b91f4c639f366c02/src/GeneralStateTestsFiller) to `execution-spec-tests` located now at [tests/static/state_tests](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static/state_tests) ([#1442](https://github.com/ethereum/execution-spec-tests/pull/1442)). -- ✨ [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929): Test that precompile addresses are cold/warm depending on the fork they are activated ([#1495](https://github.com/ethereum/execution-spec-tests/pull/1495)). - -## [v4.3.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.3.0) - 2025-04-18 - -### 💥 Breaking Change - -#### Consume engine strict exception checking - -`consume engine` now checks exceptions returned by the execution clients in their Engine API responses, specifically in the `validationError`field of the `engine_newPayloadVX` method. - -While not strictly a breaking change since tests will continue to run normally, failures are expected if a client modifies their exception messages. - -This feature can be disabled by using `--disable-strict-exception-matching` for specific clients or forks. - -### 🛠️ Framework - -#### `fill` - -- ✨ The `static_filler` plug-in now has support for static state tests (from [GeneralStateTests](https://github.com/ethereum/tests/tree/develop/src/GeneralStateTestsFiller)) ([#1362](https://github.com/ethereum/execution-spec-tests/pull/1362)). -- ✨ Introduce `pytest.mark.exception_test` to mark tests that contain an invalid transaction or block ([#1436](https://github.com/ethereum/execution-spec-tests/pull/1436)). -- 🐞 Fix `DeprecationWarning: Pickle, copy, and deepcopy support will be removed from itertools in Python 3.14.` by avoiding use `itertools` object in the spec `BaseTest` pydantic model ([#1414](https://github.com/ethereum/execution-spec-tests/pull/1414)). -- ✨ An optional configuration flag to override the maximum gas limit in the environment for filling or executing tests is now available. The `--block-gas-limit` flag overrides the default block gas limit during filling. The `--transaction-gas-limit` flag overrides the maximum for transactions during execution. ([#1470](https://github.com/ethereum/execution-spec-tests/pull/1470)). - -#### `consume` - -- 🐞 Fix fixture tarball downloading with regular, non-Github release URLS and with numerical versions in regular release specs, e.g., `stable@v4.2.0` ([#1437](https://github.com/ethereum/execution-spec-tests/pull/1437)). -- ✨ `consume engine` now has strict exception mapping enabled by default ([#1416](https://github.com/ethereum/execution-spec-tests/pull/1416)). - -#### Tools - -- 🔀 `generate_system_contract_deploy_test` test generator has been updated to handle system contracts that are not allowed to be absent when the fork happens ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). -- ✨ Add `generate_system_contract_error_test` to generate tests on system contracts that invalidate a block in case of error ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). - -#### Exceptions - -- ✨ `BlockException.SYSTEM_CONTRACT_EMPTY`: Raised when a required system contract was not found in the state by the time it was due to execution with a system transaction call ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). -- ✨ `BlockException.SYSTEM_CONTRACT_CALL_FAILED`: Raised when a system contract call made by a system transaction fails ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). -- ✨ `BlockException.INVALID_BLOCK_HASH`: Raised when the calculated block hash does not match the expectation (Currently only during Engine API calls) ([#1416](https://github.com/ethereum/execution-spec-tests/pull/1416)). -- ✨ `BlockException.INVALID_VERSIONED_HASHES`: Raised when a discrepancy is found between versioned hashes in the payload and the ones found in the transactions ([#1416](https://github.com/ethereum/execution-spec-tests/pull/1416)). - -### 🧪 Test Cases - -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Test precompile case in same transaction as delegation without extra gas in case of precompile code execution; parametrize all call opcodes in existing precompile test ([#1431](https://github.com/ethereum/execution-spec-tests/pull/1431)). -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Add invalid nonce authorizations tests for the case of multiple signers when the sender's nonce gets increased ([#1441](https://github.com/ethereum/execution-spec-tests/pull/1441)). -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Add a test that verifies that set code transactions are correctly rejected before Prague activation ([#1463](https://github.com/ethereum/execution-spec-tests/pull/1463)). -- ✨ [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623): Additionally parametrize transaction validity tests with the `to` set to an EOA account (previously only contracts) ([#1422](https://github.com/ethereum/execution-spec-tests/pull/1422)). -- ✨ [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Add EIP-7251 test cases for modified consolidations contract that allows more consolidations ([#1465](https://github.com/ethereum/execution-spec-tests/pull/1465)). -- ✨ [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Add extra deposit request edge cases, sending eth to the deposit contract while sending a deposit request ([#1467](https://github.com/ethereum/execution-spec-tests/pull/1467)). -- ✨ [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Add cases for deposit log layout and other topics (ERC-20) transfer ([#1371](https://github.com/ethereum/execution-spec-tests/pull/1371)). -- ✨ [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Remove pytest skips for consolidation request cases ([#1449](https://github.com/ethereum/execution-spec-tests/pull/1449)). -- ✨ [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Add cases to verify behavior of contracts missing at fork ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). -- ✨ [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Add cases to verify behavior of system contract errors invalidating a block ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). -- 🔀 Remove [EIP-7698](https://eips.ethereum.org/EIPS/eip-7698): EIP has been removed and the tests related to it have also been removed, while preserving a subset of the tests to verify that functionality is removed in clients ([#1451](https://github.com/ethereum/execution-spec-tests/pull/1451)). - -### 📋 Misc - -- 🐞 Configure `markdownlint` to expect an indent of 4 with unordered lists (otherwise HTML documentation is rendered incorrectly, [#1460](https://github.com/ethereum/execution-spec-tests/pull/1460)). -- 🔀 Update `eels_resolutions.json` to point to temporary commit `bb0eb750d643ced0ebf5dec732cdd23558d0b7f2`, which is based on `forks/prague` branch, commit `d9a7ee24db359aacecd636349b4f3ac95a4a6e71`, with PRs , and merged ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). - -## [v4.2.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.2.0) - 2025-04-08 - -**Note**: Although not a breaking change, `consume` users should delete the cache directory (typically located at `~/.cache/ethereum-execution-spec-tests`) used to store downloaded fixture release tarballs. This release adds support for [ethereum/tests](https://github.com/ethereum/tests) and [ethereum/legacytests](https://github.com/ethereum/legacytests) fixture release downloads and the structure of the cache directory has been updated to accommodate this change. - -To try this feature: - -```shell -consume direct --input=https://github.com/ethereum/tests/releases/download/v17.0/fixtures_blockchain_tests.tgz -``` - -To determine the cache directory location, see the `--cache-folder` entry from the command: - -```shell -consume cache --help -``` - -### 💥 Breaking Change - -### 🛠️ Framework - -#### `consume` - -- ✨ Add support for [ethereum/tests](https://github.com/ethereum/tests) and [ethereum/legacytests](https://github.com/ethereum/legacytests) release tarball download via URL to the `--input` flag of `consume` commands ([#1306](https://github.com/ethereum/execution-spec-tests/pull/1306)). -- ✨ Add support for Nethermind's `nethtest` command to `consume direct` ([#1250](https://github.com/ethereum/execution-spec-tests/pull/1250)). -- ✨ Allow filtering of test cases by fork via pytest marks (e.g., `-m "Cancun or Prague"`) ([#1304](https://github.com/ethereum/execution-spec-tests/pull/1304), [#1318](https://github.com/ethereum/execution-spec-tests/pull/1318)). -- ✨ Allow filtering of test cases by fixture format via pytest marks (e.g., `-m blockchain_test`) ([#1314](https://github.com/ethereum/execution-spec-tests/pull/1314)). -- ✨ Add top-level entries `forks` and `fixture_formats` to the index file that list all the forks and fixture formats used in the indexed fixtures ([#1318](https://github.com/ethereum/execution-spec-tests/pull/1318)). -- ✨ Enable logging from `consume` commands ([#1361](https://github.com/ethereum/execution-spec-tests/pull/1361)). -- ✨ Propagate stdout and stderr (including logs) captured during test execution to the Hive test result ([#1361](https://github.com/ethereum/execution-spec-tests/pull/1361)). -- 🐞 Don't parametrize tests for unsupported fixture formats; improve `consume` test collection ([#1315](https://github.com/ethereum/execution-spec-tests/pull/1315)). -- 🐞 Fix the the hive command printed in test reports to reproduce tests in isolation by prefixing the `--sim.limit` flag value with `id:` ([#1333](https://github.com/ethereum/execution-spec-tests/pull/1333)). -- 🐞 Improve index generation of [ethereum/tests](https://github.com/ethereum/tests) fixtures: Allow generation at any directory level and include `generatedTestHash` in the index file for the `fixture_hash` ([#1303](https://github.com/ethereum/execution-spec-tests/pull/1303)). -- 🐞 Fix loading of [ethereum/tests](https://github.com/ethereum/tests) and [ethereum/legacytests](https://github.com/ethereum/legacytests) fixtures for the case of mixed `0x0` and `0x1` transaction types in multi-index (`data`, `gas`, `value`) state test fixtures ([#1330](https://github.com/ethereum/execution-spec-tests/pull/1330)). -- ✨ Add Osaka to the hive ruleset, includes a small ruleset refactor ([#1355](https://github.com/ethereum/execution-spec-tests/pull/1355)). - -#### `fill` - -- 🐞 Fix `--fork/from/until` for transition forks when using `fill` [#1311](https://github.com/ethereum/execution-spec-tests/pull/1311). -- 🐞 Fix the node id for state tests marked by transition forks ([#1313](https://github.com/ethereum/execution-spec-tests/pull/1313)). -- ✨ Add `static_filler` plug-in which allows to fill static YAML and JSON tests (from [ethereum/tests](https://github.com/ethereum/tests)) by adding flag `--fill-static-tests` to `uv run fill` ([#1336](https://github.com/ethereum/execution-spec-tests/pull/1336)). - -#### `execute` - -- 🔀 Test IDs have changed to include the name of the test spec where the test came from (e.g. `state_test`, `blockchain_test`, etc) ([#1367](https://github.com/ethereum/execution-spec-tests/pull/1367)). -- ✨ Markers can now be used to execute only tests from a specific test spec type (e.g. `-m state_test`, `-m blockchain_test`, etc) ([#1367](https://github.com/ethereum/execution-spec-tests/pull/1367)). - -### 📋 Misc - -- 🔀 Bump the version of `execution-specs` used by the framework to the package [`ethereum-execution==1.17.0rc6.dev1`](https://pypi.org/project/ethereum-execution/1.17.0rc6.dev1/); bump the version used for test fixture generation for forks < Prague to current `execution-specs` master, [fa847a0](https://github.com/ethereum/execution-specs/commit/fa847a0e48309debee8edc510ceddb2fd5db2f2e) ([#1310](https://github.com/ethereum/execution-spec-tests/pull/1310)). -- 🐞 Init `TransitionTool` in `GethTransitionTool` ([#1276](https://github.com/ethereum/execution-spec-tests/pull/1276)). -- 🔀 Refactored RLP encoding of test objects to allow automatic generation of tests ([#1359](https://github.com/ethereum/execution-spec-tests/pull/1359)). -- ✨ Document how to manage `execution-spec-tests` package dependencies ([#1388](https://github.com/ethereum/execution-spec-tests/pull/1388)). - -#### Packaging - -- 🐞 Fix `eest make test` when `ethereum-execution-spec-tests` is installed as a package ([#1342](https://github.com/ethereum/execution-spec-tests/pull/1342)). -- 🔀 Pin `setuptools` and `wheel` in `[build-system]`, bump `trie>=3.1` and remove `setuptools` from package dependencies ([#1345](https://github.com/ethereum/execution-spec-tests/pull/1345), [#1351](https://github.com/ethereum/execution-spec-tests/pull/1351)). - -### 🧪 Test Cases - -- ✨ Add additional test coverage for EIP-152 Blake2 precompiles ([#1244](https://github.com/ethereum/execution-spec-tests/pull/1244)). Refactor to add variables for spec constants and common fixture code. ([#1395](https://github.com/ethereum/execution-spec-tests/pull/1395)), ([#1405](https://github.com/ethereum/execution-spec-tests/pull/1405)). -- ✨ Add EIP-7702 incorrect-rlp-encoding tests ([#1347](https://github.com/ethereum/execution-spec-tests/pull/1347)). -- ✨ Add EIP-2935 tests for all call opcodes ([#1379](https://github.com/ethereum/execution-spec-tests/pull/1379)). -- ✨ Add more tests for EIP-7702: max-fee-per-gas verification, delegation-designation as initcode tests ([#1372](https://github.com/ethereum/execution-spec-tests/pull/1372)). -- ✨ Add converted Identity precompile tests ([#1344](https://github.com/ethereum/execution-spec-tests/pull/1344)). - -## [v4.1.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.1.0) - 2025-03-11 - -### 💥 Breaking Changes - -The following changes may be potentially breaking (all clients were tested with these changes with the state test format, but not the blockchain test format): - -- 💥 Add a `yParity` field (that duplicates `v`) to transaction authorization tuples in fixture formats to have fields that conform to EIP-7702 spec, resolves [erigontech/erigon#14073](https://github.com/erigontech/erigon/issues/14073) ([#1286](https://github.com/ethereum/execution-spec-tests/pull/1286)). -- 💥 Rename the recently introduced `_info` field `fixture_format` to `fixture-format` for consistency [#1295](https://github.com/ethereum/execution-spec-tests/pull/1295). - -### 🛠️ Framework - -- 🔀 Make `BaseFixture` able to parse any fixture format such as `BlockchainFixture` ([#1210](https://github.com/ethereum/execution-spec-tests/pull/1210)). -- ✨ Blockchain and Blockchain-Engine tests now have a marker to specify that they were generated from a state test, which can be used with `-m blockchain_test_from_state_test` and `-m blockchain_test_engine_from_state_test` respectively ([#1220](https://github.com/ethereum/execution-spec-tests/pull/1220)). -- ✨ Blockchain and Blockchain-Engine tests that were generated from a state test now have `blockchain_test_from_state_test` or `blockchain_test_engine_from_state_test` as part of their test IDs ([#1220](https://github.com/ethereum/execution-spec-tests/pull/1220)). -- 🔀 Refactor `ethereum_test_fixtures` and `ethereum_clis` to create `FixtureConsumer` and `FixtureConsumerTool` classes which abstract away the consumption process used by `consume direct` ([#935](https://github.com/ethereum/execution-spec-tests/pull/935)). -- ✨ Allow `consume direct --collect-only` without specifying a fixture consumer binary on the command-line ([#1237](https://github.com/ethereum/execution-spec-tests/pull/1237)). -- ✨ Allow `fill --collect-only` without the need for existence of the folder `./fixtures`. -- ✨ Report the (resolved) fixture tarball URL and local fixture cache directory when `consume`'s `--input` flag is a release spec or URL ([#1239](https://github.com/ethereum/execution-spec-tests/pull/1239)). -- ✨ EOF Container validation tests (`eof_test`) now generate container deployment state tests, by wrapping the EOF container in an init-container and sending a deploy transaction ([#783](https://github.com/ethereum/execution-spec-tests/pull/783), [#1233](https://github.com/ethereum/execution-spec-tests/pull/1233)). -- ✨ Use regexes for Hive's `--sim.limit` argument and don't use xdist if `--sim.parallelism==1` in the `eest/consume-rlp` and `eest/consume-rlp` simulators ([#1220](https://github.com/ethereum/execution-spec-tests/pull/1220)). -- 🐞 Register generated test markers, e.g., `blockchain_test_from_state_test`, to prevent test session warnings ([#1238](https://github.com/ethereum/execution-spec-tests/pull/1238), [#1245](https://github.com/ethereum/execution-spec-tests/pull/1245)). -- 🐞 Zero-pad `Environment` fields passed to `t8n` tools as required by `evmone-t8n` ([#1268](https://github.com/ethereum/execution-spec-tests/pull/1268)). - -### 📋 Misc - -- ✨ Add a guide to the docs for porting tests from `ethereum/tests` to EEST ([#1165](https://github.com/ethereum/execution-spec-tests/pull/1165)). -- ✨ Improve the `uv run eest make test` interactive CLI to enable creation of new test modules within existing test sub-folders ([#1241](https://github.com/ethereum/execution-spec-tests/pull/1241)). -- ✨ Update `mypy` to latest release `>=1.15.0,<1.16` ([#1209](https://github.com/ethereum/execution-spec-tests/pull/1209)). -- 🐞 Bug fix for filling with EELS for certain Python versions due to an issue with CPython ([#1231](https://github.com/ethereum/execution-spec-tests/pull/1231)). -- 🐞 Fix HTML site deployment due to the site's index file exceeding Github's max file size limit ([#1292](https://github.com/ethereum/execution-spec-tests/pull/1292)). -- ✨ Update the build fixtures workflow to use multiple self-hosted runners, remove `pectra-devnet-6` feature build ([#1296](https://github.com/ethereum/execution-spec-tests/pull/1296)). - -### 🧪 Test Cases - -- ✨ Add gas cost of delegation access in CALL opcode ([#1208](https://github.com/ethereum/execution-spec-tests/pull/1208)). -- ✨ Add EIP-7698 failed nonce and short data tests ([#1211](https://github.com/ethereum/execution-spec-tests/pull/1211)). -- ✨ Add EIP-2537 additional pairing precompile tests cases, and then update all BLS12 test vectors ([#1275](https://github.com/ethereum/execution-spec-tests/pull/1275), [#1289](https://github.com/ethereum/execution-spec-tests/pull/1289)). -- ✨ Add EIP-7685 and EIP-7002 test cases for additional request type combinations and modified withdrawal contract that allows more withdrawals ([#1340](https://github.com/ethereum/execution-spec-tests/pull/1340)). -- ✨ Add test cases for EIP-152 Blake2 and Identity precompiles ([#1244](https://github.com/ethereum/execution-spec-tests/pull/1244)). - -## [v4.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.0.0) - 2025-02-14 - 💕 - -### 📁 Fixture Releases - -- 🔀 Initially we moved old fork configured tests within stable and develop fixture releases to a separate legacy release ([#788](https://github.com/ethereum/execution-spec-tests/pull/788)). -- 🔀 This was later reverted after some client teams preferred to keep them in all in the same releases ([#1053](https://github.com/ethereum/execution-spec-tests/pull/1053)). - -### 💥 Breaking Change - -- ✨ Use uv for package management replacing pip ([#777](https://github.com/ethereum/execution-spec-tests/pull/777)). -- ✨ Ruff now replaces Flake8, Isort and Black resulting in significant changes to the entire code base including its usage ([#922](https://github.com/ethereum/execution-spec-tests/pull/922)). -- 🔀 Fill test fixtures using EELS by default. EEST now uses the [`ethereum-specs-evm-resolver`](https://github.com/petertdavies/ethereum-spec-evm-resolver) with the EELS daemon ([#792](https://github.com/ethereum/execution-spec-tests/pull/792)). -- 🔀 The EOF fixture format contained in `eof_tests` may now contain multiple exceptions in the `"exception"` field in the form of a pipe (`|`) separated string ([#759](https://github.com/ethereum/execution-spec-tests/pull/759)). -- 🔀 `state_test`, `blockchain_test` and `blockchain_test_engine` fixtures now contain a `config` field, which contains an object that contains a `blobSchedule` field. On the `blockchain_test` and `blockchain_test_engine` fixtures, the object also contains a duplicate of the `network` root field. The root's `network` field will be eventually deprecated ([#1040](https://github.com/ethereum/execution-spec-tests/pull/1040)). -- 🔀 `latest-stable-release` and `latest-develop-release` keywords for the `--input` flag in consume commands have been replaced with `stable@latest` and `develop@latest` respectively ([#1044](https://github.com/ethereum/execution-spec-tests/pull/1044)). - -### 🛠️ Framework - -- ✨ Execute command added to run existing tests in live networks ([#](https://github.com/ethereum/execution-spec-tests/pull/1157)). -- 🐞 Fixed consume hive commands from spawning different hive test suites during the same test execution when using xdist ([#712](https://github.com/ethereum/execution-spec-tests/pull/712)). -- ✨ `consume hive` command is now available to run all types of hive tests ([#712](https://github.com/ethereum/execution-spec-tests/pull/712)). -- ✨ Generated fixtures now contain the test index `index.json` by default ([#716](https://github.com/ethereum/execution-spec-tests/pull/716)). -- ✨ A metadata folder `.meta/` now stores all fixture metadata files by default ([#721](https://github.com/ethereum/execution-spec-tests/pull/721)). -- 🐞 Fixed `fill` command index generation issue due to concurrency ([#725](https://github.com/ethereum/execution-spec-tests/pull/725)). -- ✨ Added `with_all_evm_code_types`, `with_all_call_opcodes` and `with_all_create_opcodes` markers, which allow automatic parametrization of tests to EOF ([#610](https://github.com/ethereum/execution-spec-tests/pull/610), [#739](https://github.com/ethereum/execution-spec-tests/pull/739)). -- ✨ Added `with_all_system_contracts` marker, which helps parametrize tests with all contracts that affect the chain on a system level ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). -- ✨ Code generators `Conditional` and `Switch` now support EOF by adding parameter `evm_code_type` ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). -- ✨ `fill` command now supports parameter `--evm-code-type` that can be (currently) set to `legacy` or `eof_v1` to force all test smart contracts to deployed in normal or in EOF containers ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). -- 🐞 Fixed fixture index generation on EOF tests ([#728](https://github.com/ethereum/execution-spec-tests/pull/728)). -- 🐞 Fixes consume genesis mismatch exception for hive based simulators ([#734](https://github.com/ethereum/execution-spec-tests/pull/734)). -- ✨ Adds reproducible consume commands to hiveview ([#717](https://github.com/ethereum/execution-spec-tests/pull/717)). -- 💥 Added multiple exceptions to the EOF fixture format ([#759](https://github.com/ethereum/execution-spec-tests/pull/759)). -- ✨ Added optional parameter to all `with_all_*` markers to specify a lambda function that filters the parametrized values ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). -- ✨ Added [`extend_with_defaults` utility function](https://eest.ethereum.org/main/writing_tests/writing_a_new_test/#ethereum_test_tools.utility.pytest.extend_with_defaults), which helps extend test case parameter sets with default values. `@pytest.mark.parametrize` ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). -- ✨ Added `Container.Init` to `ethereum_test_types.EOF.V1` package, which allows generation of an EOF init container more easily ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). -- ✨ Introduce method valid_opcodes() to the fork class ([#748](https://github.com/ethereum/execution-spec-tests/pull/748)). -- 🐞 Fixed `consume` exit code return values, ensuring that pytest's return value is correctly propagated to the shell. This allows the shell to accurately reflect the test results (e.g., failures) based on the pytest exit code ([#765](https://github.com/ethereum/execution-spec-tests/pull/765)). -- ✨ Added a new flag `--solc-version` to the `fill` command, which allows the user to specify the version of the Solidity compiler to use when compiling Yul source code; this version will now be automatically downloaded by `fill` via [`solc-select`](https://github.com/crytic/solc-select) ([#772](https://github.com/ethereum/execution-spec-tests/pull/772)). -- 🐞 Fix usage of multiple `@pytest.mark.with_all*` markers which shared parameters, such as `with_all_call_opcodes` and `with_all_create_opcodes` which shared `evm_code_type`, and now only parametrize compatible values ([#762](https://github.com/ethereum/execution-spec-tests/pull/762)). -- ✨ Added `selector` and `marks` fields to all `@pytest.mark.with_all*` markers, which allows passing lambda functions to select or mark specific parametrized values (see [documentation](https://eest.ethereum.org/main/writing_tests/test_markers/#covariant-marker-keyword-arguments) for more information) ([#762](https://github.com/ethereum/execution-spec-tests/pull/762)). -- ✨ Improves consume input flags for develop and stable fixture releases, fixes `--help` flag for consume ([#745](https://github.com/ethereum/execution-spec-tests/pull/745)). -- 🔀 Return exit-code from `consume` commands ([#766](https://github.com/ethereum/execution-spec-tests/pull/766)). -- 🔀 Remove duplicate EOF container tests, automatically check for duplicates ([#800](https://github.com/ethereum/execution-spec-tests/pull/800)). -- 🔀 Fix DATALOAD `pushed_stack_items` calculation ([#784](https://github.com/ethereum/execution-spec-tests/pull/784)). -- ✨ Add `evm_bytes` rename and print asm ([#844](https://github.com/ethereum/execution-spec-tests/pull/844)). -- 🔀 Use the `session_temp_folder` introduced in #824 ([#845](https://github.com/ethereum/execution-spec-tests/pull/845)). -- 🐞 Don't treat eels resolutions as a fixture ([#878](https://github.com/ethereum/execution-spec-tests/pull/878)). -- ✨ Emphasize that no tests were executed during a fill pytest session ([#887](https://github.com/ethereum/execution-spec-tests/pull/887)). -- 🔀 Move generic code from TransitionTool to a new generic base class EthereumCLI ([#894](https://github.com/ethereum/execution-spec-tests/pull/894)). -- 🐞 Fix erroneous fork mes- 🔀 Fix max stack height calculation ([#810](https://github.com/ethereum/execution-spec-tests/pull/810)). -- ✨ Add storage key hint in Storage class ([#917](https://github.com/ethereum/execution-spec-tests/pull/917)). -- ✨ Add system to verify exception strings ([#795](https://github.com/ethereum/execution-spec-tests/pull/795)). -- 🔀 Fix `FixedBytes` assignment rules ([#1010](https://github.com/ethereum/execution-spec-tests/pull/1010)). -- 🔀 Fix `Address` padding options ([#1113](https://github.com/ethereum/execution-spec-tests/pull/1113)). -- 🔀 Add `Container.expected_bytecode` optional parameter ([#737](https://github.com/ethereum/execution-spec-tests/pull/737)). -- ✨ Add support for `initcode_prefix` on EOF `Container.Init` ([#819](https://github.com/ethereum/execution-spec-tests/pull/819)).sage in pytest session header with development forks ([#806](https://github.com/ethereum/execution-spec-tests/pull/806)). -- 🐞 Fix `Conditional` code generator in EOF mode ([#821](https://github.com/ethereum/execution-spec-tests/pull/821)). -- 🔀 Ensure that `Block` objects keep track of their `fork`, for example, when the block's `rlp_modifier` is not `None` ([#854](https://github.com/ethereum/execution-spec-tests/pull/854)). -- 🔀 `ethereum_test_rpc` library has been created with what was previously `ethereum_test_tools.rpc` ([#822](https://github.com/ethereum/execution-spec-tests/pull/822)). -- ✨ Add `Wei` type to `ethereum_test_base_types` which allows parsing wei amounts from strings like "1 ether", "1000 wei", "10**2 gwei", etc ([#825](https://github.com/ethereum/execution-spec-tests/pull/825)). -- ✨ Pin EELS versions in `eels_resolutions.json` and include this file in fixture releases ([#872](https://github.com/ethereum/execution-spec-tests/pull/872)). -- 🔀 Replace `ethereum.base_types` with `ethereum-types` ([#850](https://github.com/ethereum/execution-spec-tests/pull/850)). -- 💥 Rename the `PragueEIP7692` fork to `Osaka` ([#869](https://github.com/ethereum/execution-spec-tests/pull/869)). -- ✨ Improve `fill` terminal output to emphasize that filling tests is not actually testing a client ([#807](https://github.com/ethereum/execution-spec-tests/pull/887)). -- ✨ Add the `BlockchainTestEngine` test spec type that only generates a fixture in the `EngineFixture` (`blockchain_test_engine`) format ([#888](https://github.com/ethereum/execution-spec-tests/pull/888)). -- 🔀 Move the `evm_transition_tool` package to `ethereum_clis` and derive the transition tool CL interfaces from a shared `EthereumCLI` class that can be reused for other sub-commands ([#894](https://github.com/ethereum/execution-spec-tests/pull/894)). -- ✨ Pass `state_test` property to T8N tools that support it (Only EELS at the time of merge) ([#943](https://github.com/ethereum/execution-spec-tests/pull/943)). -- ✨ Add the `eofwrap` cli used to wrap tests from `ethereum/tests` in an EOF container ([#896](https://github.com/ethereum/execution-spec-tests/pull/896)). -- 🔀 Improve gentest architecture with `EthereumTestBaseModel` and `EthereumTestRootModel` ([#901](https://github.com/ethereum/execution-spec-tests/pull/901)). -- 🔀 Migrate transaction test to `state_test` for `gentest` ([#903](https://github.com/ethereum/execution-spec-tests/pull/903)). -- 🔀 `ethereum_test_forks` forks now contain gas-calculating functions, which return the appropriate function to calculate the gas used by a transaction or memory function for the given fork ([#779](https://github.com/ethereum/execution-spec-tests/pull/779)). -- 🐞 Fix `Bytecode` class `__eq__` method ([#939](https://github.com/ethereum/execution-spec-tests/pull/939)). -- 🔀 Update `pydantic` from 2.8.2 to 2.9.2 ([#960](https://github.com/ethereum/execution-spec-tests/pull/960)). -- ✨ Add the `eest make test` command, an interactive CLI that helps users create a new test module and function ([#950](https://github.com/ethereum/execution-spec-tests/pull/950)). -- ✨ Add the `eest clean` command that helps delete generated files and directories from the repository ([#980](https://github.com/ethereum/execution-spec-tests/pull/980)). -- ✨ Add framework changes for EIP-7742, required for Prague devnet-5 ([#931](https://github.com/ethereum/execution-spec-tests/pull/931)). -- ✨ Add the `eest make env` command that generates a default env file (`env.yaml`)([#996](https://github.com/ethereum/execution-spec-tests/pull/996)). -- ✨ Generate Transaction Test type ([#933](https://github.com/ethereum/execution-spec-tests/pull/933)). -- ✨ Add a default location for evm logs (`--evm-dump-dir`) when filling tests ([#999](https://github.com/ethereum/execution-spec-tests/pull/999)). -- ✨ Slow tests now have greater timeout when making a request to the T8N server ([#1037](https://github.com/ethereum/execution-spec-tests/pull/1037)). -- ✨ Introduce [`pytest.mark.parametrize_by_fork`](https://eest.ethereum.org/main/writing_tests/test_markers/#pytestmarkfork_parametrize) helper marker ([#1019](https://github.com/ethereum/execution-spec-tests/pull/1019), [#1057](https://github.com/ethereum/execution-spec-tests/pull/1057)). -- 🐞 fix(consume): allow absolute paths with `--evm-bin` ([#1052](https://github.com/ethereum/execution-spec-tests/pull/1052)). -- ✨ Disable EIP-7742 framework changes for Prague ([#1023](https://github.com/ethereum/execution-spec-tests/pull/1023)). -- ✨ Allow verification of the transaction receipt on executed test transactions ([#1068](https://github.com/ethereum/execution-spec-tests/pull/1068)). -- ✨ Modify `valid_at_transition_to` marker to add keyword arguments `subsequent_transitions` and `until` to fill a test using multiple transition forks ([#1081](https://github.com/ethereum/execution-spec-tests/pull/1081)). -- 🐞 fix(consume): use `"HIVE_CHECK_LIVE_PORT"` to signal hive to wait for port 8551 (Engine API port) instead of the 8545 port when running `consume engine` ([#1095](https://github.com/ethereum/execution-spec-tests/pull/1095)). -- ✨ `state_test`, `blockchain_test` and `blockchain_test_engine` fixtures now contain the `blobSchedule` from [EIP-7840](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7840.md), only for tests filled for Cancun and Prague forks ([#1040](https://github.com/ethereum/execution-spec-tests/pull/1040)). -- 🔀 Change `--dist` flag to the default value, `load`, for better parallelism handling during test filling ([#1118](https://github.com/ethereum/execution-spec-tests/pull/1118)). -- 🔀 Refactor framework code to use the [`ethereum-rlp`](https://pypi.org/project/ethereum-rlp/) package instead of `ethereum.rlp`, previously available in ethereum/execution-specs ([#1180](https://github.com/ethereum/execution-spec-tests/pull/1180)). -- 🔀 Update EELS / execution-specs EEST dependency to [99238233](https://github.com/ethereum/execution-specs/commit/9923823367b5586228e590537d47aa9cc4c6a206) for EEST framework libraries and test case generation ([#1181](https://github.com/ethereum/execution-spec-tests/pull/1181)). -- ✨ Add the `consume cache` command to cache fixtures before running consume commands ([#1044](https://github.com/ethereum/execution-spec-tests/pull/1044)). -- ✨ The `--input` flag of the consume commands now supports parsing of tagged release names in the format `@` ([#1044](https://github.com/ethereum/execution-spec-tests/pull/1044)). -- 🐞 Fix stdout output when using the `fill` command ([#1188](https://github.com/ethereum/execution-spec-tests/pull/1188)). -- ✨ Add tests for blockchain intermediate state verification ([#1075](https://github.com/ethereum/execution-spec-tests/pull/1075)). -- ✨ Add Interactive CLI input functionality ([#947](https://github.com/ethereum/execution-spec-tests/pull/947)). -- 🔀 Rename `EOFTest.data` to `EOFTest.container` with rebase of `EOFStateTest` ([#1145](https://github.com/ethereum/execution-spec-tests/pull/1145)). -- ✨ Turn on `--traces` for EELS + `ethereum-specs-evm-resolver` ([#1174](https://github.com/ethereum/execution-spec-tests/pull/1174)). - -### 📋 Misc - -- ✨ Feature releases can now include multiple types of fixture tarball files from different releases that start with the same prefix ([#736](https://github.com/ethereum/execution-spec-tests/pull/736)). -- ✨ Releases for feature eip7692 now include both Cancun and Prague based tests in the same release, in files `fixtures_eip7692.tar.gz` and `fixtures_eip7692-prague.tar.gz` respectively ([#743](https://github.com/ethereum/execution-spec-tests/pull/743)). -✨ Re-write the test case reference doc flow as a pytest plugin and add pages for test functions with a table providing an overview of their parametrized test cases ([#801](https://github.com/ethereum/execution-spec-tests/pull/801), [#842](https://github.com/ethereum/execution-spec-tests/pull/842)). -- 🔀 Simplify Python project configuration and consolidate it into `pyproject.toml` ([#764](https://github.com/ethereum/execution-spec-tests/pull/764)). -- ✨ Add dev docs to help using nectos/act ([#776](https://github.com/ethereum/execution-spec-tests/pull/776)). -- 🔀 Update `uv.lock` for updated solc deps ([#782](https://github.com/ethereum/execution-spec-tests/pull/782)). -- ✨ Enable coverage on any test change ([#790](https://github.com/ethereum/execution-spec-tests/pull/790)). -- 🔀 Created `pytest_plugins.concurrency` plugin to sync multiple `xdist` processes without using a command flag to specify the temporary working folder ([#824](https://github.com/ethereum/execution-spec-tests/pull/824)). -- 🔀 Move pytest plugin `pytest_plugins.filler.solc` to `pytest_plugins.solc.solc` ([#823](https://github.com/ethereum/execution-spec-tests/pull/823)). -- 🔀 Remove `formats.py`, embed properties as class vars ([#826](https://github.com/ethereum/execution-spec-tests/pull/826)). -- ✨ Add `build-evm-base` to docs deploy workflows ([#829](https://github.com/ethereum/execution-spec-tests/pull/829)). -- 🔀 Add links to the online test case docs in the EOF tracker ([#838](https://github.com/ethereum/execution-spec-tests/pull/838)). -- 🔀 Fix miscellaneous improvements to troubleshooting, navigation, styling ([#840](https://github.com/ethereum/execution-spec-tests/pull/840)). -- ✨ Include all parameters in test parameter datatables ([#842](https://github.com/ethereum/execution-spec-tests/pull/842)). -- ✨ Add info about ripemd160 & update running actions locally ([#847](https://github.com/ethereum/execution-spec-tests/pull/847)). -- ✨ Add `SECURITY.md` describing how to report vulnerabilities ([#848](https://github.com/ethereum/execution-spec-tests/pull/848)). -- 🔀 Change image from ubuntu-24.04 to ubuntu-latest in CI ([#855](https://github.com/ethereum/execution-spec-tests/pull/855)). -- 🐞 Asserts that the deploy docs tags workflow is only triggered for full releases ([#857](https://github.com/ethereum/execution-spec-tests/pull/857)). -- 🐞 Fix deploy docs tags workflow trigger ([#858](https://github.com/ethereum/execution-spec-tests/pull/858)). -- ✨ A new application-wide configuration manager provides access to environment and application configurations. ([#892](https://github.com/ethereum/execution-spec-tests/pull/892)). -- 🔀 Update the developer docs navigation ([#898](https://github.com/ethereum/execution-spec-tests/pull/898)). -- 🔀 Use jinja2 templating in `gentest` ([#900](https://github.com/ethereum/execution-spec-tests/pull/900)). -- ✨ Fix/add test github actions locally page ([#909](https://github.com/ethereum/execution-spec-tests/pull/909)). -- 🐞 Fix print fill output in coverage workflow on errors ([#919](https://github.com/ethereum/execution-spec-tests/pull/919)). -- 🐞 Use a local version of ethereum/execution-specs (EELS) when running the framework tests in CI ([#997](https://github.com/ethereum/execution-spec-tests/pull/997)). -- ✨ Use self-hosted runners for fixture building in CI ([#1051](https://github.com/ethereum/execution-spec-tests/pull/1051)). -- ✨ Release tarballs now contain fixtures filled for all forks, not only the fork under active development and the fork currently deployed on mainnet ([#1053](https://github.com/ethereum/execution-spec-tests/pull/1053)). -- ✨ `StateTest` fixture format now contains `state` field in each network post result, containing the decoded post allocation that results from the transaction execution ([#1064](https://github.com/ethereum/execution-spec-tests/pull/1064)). -- ✨ Include EELS fork resolution information in filled json test fixtures ([#1123](https://github.com/ethereum/execution-spec-tests/pull/1123)). -- 🔀 Updates ruff from version 0.8.2 to 0.9.4 ([#1168](https://github.com/ethereum/execution-spec-tests/pull/1168)). -- 🔀 Update `uv.lock` to be compatible with `uv>=0.5.22` ([#1178](https://github.com/ethereum/execution-spec-tests/pull/1178)). -- 🔀 Update `mypy` from version `0.991` to `1.15` ([#1209](https://github.com/ethereum/execution-spec-tests/pull/1209)). - -### 🧪 Test Cases - -- ✨ Migrate validation tests `EIP3540/validInvalidFiller.yml` ([#598](https://github.com/ethereum/execution-spec-tests/pull/598)). -- ✨ EIP-4844 test `tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py` includes an EOF test case ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). -- ✨ Example test `tests/frontier/opcodes/test_dup.py` now includes EOF parametrization ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). -- ✨ Add EOFv1 function test - Call simple contract test ([#695](https://github.com/ethereum/execution-spec-tests/pull/695)). -- ✨ Add section size validation tests ([#705](https://github.com/ethereum/execution-spec-tests/pull/705)). -- ✨ Add deep and wide EOF subcontainers tests ([#718](https://github.com/ethereum/execution-spec-tests/pull/718)). -- ✨ Update [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) tests for Devnet-3 ([#733](https://github.com/ethereum/execution-spec-tests/pull/733)). -- ✨ Migrate "valid" EOFCREATE validation ([#738](https://github.com/ethereum/execution-spec-tests/pull/738)). -- ✨ Migrate tests for truncated sections ([#740](https://github.com/ethereum/execution-spec-tests/pull/740)). -- ✨ Add out of order container section test ([#741](https://github.com/ethereum/execution-spec-tests/pull/741)). -- ✨ Convert all opcodes validation test `tests/frontier/opcodes/test_all_opcodes.py` ([#748](https://github.com/ethereum/execution-spec-tests/pull/748)). -- 🔀 Add Test types with 128 inputs ([#749](https://github.com/ethereum/execution-spec-tests/pull/749)). -- 🔀 Use new marker to EOF-ize MCOPY test ([#754](https://github.com/ethereum/execution-spec-tests/pull/754)). -- ✨ Add EOF Tests from Fuzzing ([#756](https://github.com/ethereum/execution-spec-tests/pull/756)). -- ✨ Add embedded container tests ([#763](https://github.com/ethereum/execution-spec-tests/pull/763)). -- ✨ Validate EOF only opcodes are invalid in legacy ([#768](https://github.com/ethereum/execution-spec-tests/pull/768)). -- ✨ Update EOF tracker, add unimplemented tests ([#773](https://github.com/ethereum/execution-spec-tests/pull/773)). -- ✨ Add EIP-7620 EOFCREATE gas tests ([#785](https://github.com/ethereum/execution-spec-tests/pull/785)). -- ✨ Add more fuzzing discovered EOF tests ([#789](https://github.com/ethereum/execution-spec-tests/pull/789)). -- ✨ Add EOF tests for invalid non-returning sections ([#794](https://github.com/ethereum/execution-spec-tests/pull/794)). -- ✨ Test to ensure transient storage is cleared after transactions ([#798](https://github.com/ethereum/execution-spec-tests/pull/798)). -- ✨ Test that transient storage stays at correct address ([#799](https://github.com/ethereum/execution-spec-tests/pull/799)). -- ✨ Add EOFCREATE referencing the same subcontainer twice test ([#809](https://github.com/ethereum/execution-spec-tests/pull/809)). -- ✨ Add dangling data in subcontainer test ([#812](https://github.com/ethereum/execution-spec-tests/pull/812)). -- 🐞 Fix [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)+EOF tests due to incorrect test expectations and faulty `Conditional` test generator in EOF mode ([#821](https://github.com/ethereum/execution-spec-tests/pull/821)). -- 🐞 Fix TSTORE EOF variant test ([#831](https://github.com/ethereum/execution-spec-tests/pull/831)). -- 🔀 Unify EOF return code constants ([#834](https://github.com/ethereum/execution-spec-tests/pull/834)). -- ✨ Add RJUMP* vs CALLF tests ([#833](https://github.com/ethereum/execution-spec-tests/pull/833)). -- ✨ Add tests to clarify "non-returning instruction" ([#837](https://github.com/ethereum/execution-spec-tests/pull/837)). -- ✨ Add double RJUMPI stack validation tests ([#851](https://github.com/ethereum/execution-spec-tests/pull/851)). -- ✨ Add unreachable code sections tests ([#856](https://github.com/ethereum/execution-spec-tests/pull/856)). -- 💥 `PragueEIP7692` fork in tests has been updated to `Osaka` ([#869](https://github.com/ethereum/execution-spec-tests/pull/869)). -- ✨ Update [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110), [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251), [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685), and [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) tests for Devnet-4 ([#832](https://github.com/ethereum/execution-spec-tests/pull/832)). -- ✨ Add EIP-7069 and EIP-7620 failures and context vars tests ([#836](https://github.com/ethereum/execution-spec-tests/pull/836)). -- ✨ Add EOF EIP-4750 Stack validation in CALLF test ([#889](https://github.com/ethereum/execution-spec-tests/pull/889)). -- ✨ Add stack overflow by rule check to JUMPF tests ([#902](https://github.com/ethereum/execution-spec-tests/pull/902)). -- 🐞 Fix erroneous test with`CALLF` rule bug ([#907](https://github.com/ethereum/execution-spec-tests/pull/907)). -- ✨ Add test for EXTDELEGATECALL value cost ([#911](https://github.com/ethereum/execution-spec-tests/pull/911)). -- ✨ Add basic EOF execution tests ([#912](https://github.com/ethereum/execution-spec-tests/pull/912)). -- ✨ Add parametrized CALLF execution tests ([#913](https://github.com/ethereum/execution-spec-tests/pull/913)). -- ✨ Add CALLF execution tests ([#914](https://github.com/ethereum/execution-spec-tests/pull/914)). -- ✨ Add fibonacci and factorial CALLF tests ([#915](https://github.com/ethereum/execution-spec-tests/pull/915)). -- ✨ Add RJUMP* execution tests ([#916](https://github.com/ethereum/execution-spec-tests/pull/916)). -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) many delegations test ([#923](https://github.com/ethereum/execution-spec-tests/pull/923)). -- ✨ Add opcode validation tests ([#932](https://github.com/ethereum/execution-spec-tests/pull/932)). -- ✨ Add RJUMPI with JUMPF tests ([#928](https://github.com/ethereum/execution-spec-tests/pull/928)). -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) set code of non-empty-storage account test ([#948](https://github.com/ethereum/execution-spec-tests/pull/948)). -- ✨ Add PUSH* opcode tests ([#975](https://github.com/ethereum/execution-spec-tests/pull/975)). -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) implement 7702 test ideas ([#981](https://github.com/ethereum/execution-spec-tests/pull/981)). -- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Remove delegation behavior of EXTCODE* ([#984](https://github.com/ethereum/execution-spec-tests/pull/984)). -- ✨ Add EIP-7620 RETURNCONTRACT behavior verification test ([#1109](https://github.com/ethereum/execution-spec-tests/pull/1109)). -- ✨ Add EIP-7069 p256verify EOF calls tests ([#1021](https://github.com/ethereum/execution-spec-tests/pull/1021)). -- ✨ Add EIP-7480 DATACOPY edge cases tests ([#1020](https://github.com/ethereum/execution-spec-tests/pull/1020)). -- ✨ Add EIP-7069 EXTCALL creation gas charge tests ([#1025](https://github.com/ethereum/execution-spec-tests/pull/1025)). -- ✨ Add generic precompile-absence test ([#1036](https://github.com/ethereum/execution-spec-tests/pull/1036)). -- ✨ Add test for [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) which uses the full discount table of G2 MSM ([#1038](https://github.com/ethereum/execution-spec-tests/pull/1038)). -- ✨ [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691) Blob throughput increase tests by parametrization of existing EIP-4844 tests ([#1023](https://github.com/ethereum/execution-spec-tests/pull/1023), [#1082](https://github.com/ethereum/execution-spec-tests/pull/1082)). -- ✨ Port [calldatacopy test](https://github.com/ethereum/tests/blob/ae4791077e8fcf716136e70fe8392f1a1f1495fb/src/GeneralStateTestsFiller/VMTests/vmTests/calldatacopyFiller.yml) ([#1056](https://github.com/ethereum/execution-spec-tests/pull/1056)). -- ✨ [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) Increase calldata cost ([#1004](https://github.com/ethereum/execution-spec-tests/pull/1004), [#1071](https://github.com/ethereum/execution-spec-tests/pull/1071)). -- ✨ Add CALLF invalid section index tests ([#1111](https://github.com/ethereum/execution-spec-tests/pull/1111)). -- ✨ Add JUMPF invalid section index tests ([#1112](https://github.com/ethereum/execution-spec-tests/pull/1112)). -- ✨ Add CALLF truncated immediate bytes tests ([#1114](https://github.com/ethereum/execution-spec-tests/pull/1114)). -- ✨ [EIP-152](https://eips.ethereum.org/EIPS/eip-152) Add tests for Blake2 compression function `F` precompile ([#1067](https://github.com/ethereum/execution-spec-tests/pull/1067)). -- ✨ Add CALLF non-returning section tests ([#1126](https://github.com/ethereum/execution-spec-tests/pull/1126)). -- ✨ Add DATALOADN truncated immediate bytes tests ([#1127](https://github.com/ethereum/execution-spec-tests/pull/1127)). -- 🔀 Update EIP-7702 test expectations according to [spec updates](https://github.com/ethereum/EIPs/pull/9248) ([#1129](https://github.com/ethereum/execution-spec-tests/pull/1129)). -- ✨ Add tests for CALLF and non-returning ([#1140](https://github.com/ethereum/execution-spec-tests/pull/1140)). -- 🔀 Update EIP-7251 according to spec updates [#9127](https://github.com/ethereum/EIPs/pull/9127), [#9289](https://github.com/ethereum/EIPs/pull/9289) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024), [#1155](https://github.com/ethereum/execution-spec-tests/pull/1155)). -- 🔀 Update EIP-7002 according to spec updates [#9119](https://github.com/ethereum/EIPs/pull/9119), [#9288](https://github.com/ethereum/EIPs/pull/9288) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024), [#1155](https://github.com/ethereum/execution-spec-tests/pull/1155)). -- 🔀 Update EIP-2935 according to spec updates [#9144](https://github.com/ethereum/EIPs/pull/9144), [#9287](https://github.com/ethereum/EIPs/pull/9287) ([#1046](https://github.com/ethereum/execution-spec-tests/pull/1046), [#1155](https://github.com/ethereum/execution-spec-tests/pull/1155)). -- ✨ Add DATALOADN validation and execution tests ([#1162](https://github.com/ethereum/execution-spec-tests/pull/1162)). -- ✨ Add EOF prefix tests ([#1187](https://github.com/ethereum/execution-spec-tests/pull/1187)). -- ✨ Add tests for EOF code header missing ([#1193](https://github.com/ethereum/execution-spec-tests/pull/1193)). -- ✨ Add tests for empty EOF type section ([#1194](https://github.com/ethereum/execution-spec-tests/pull/1194)). -- ✨ Add tests for multiple EOF type sections ([#1195](https://github.com/ethereum/execution-spec-tests/pull/1195)). -- ✨ Add EIP-7698 legacy EOF creation prevention tests ([#1206](https://github.com/ethereum/execution-spec-tests/pull/1206)). - -## [v3.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v3.0.0) - 2024-07-22 - -### 🧪 Test Cases - -- ✨ Port create2 return data test ([#497](https://github.com/ethereum/execution-spec-tests/pull/497)). -- ✨ Add tests for eof container's section bytes position smart fuzzing ([#592](https://github.com/ethereum/execution-spec-tests/pull/592)). -- ✨ Add `test_create_selfdestruct_same_tx_increased_nonce` which tests self-destructing a contract with a nonce > 1 ([#478](https://github.com/ethereum/execution-spec-tests/pull/478)). -- ✨ Add `test_double_kill` and `test_recreate` which test resurrection of accounts killed with `SELFDESTRUCT` ([#488](https://github.com/ethereum/execution-spec-tests/pull/488)). -- ✨ Add eof example valid invalid tests from ori, fetch EOF Container implementation ([#535](https://github.com/ethereum/execution-spec-tests/pull/535)). -- ✨ Add tests for [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) ([#499](https://github.com/ethereum/execution-spec-tests/pull/499)). -- ✨ [EIP-663](https://eips.ethereum.org/EIPS/eip-663): Add `test_dupn.py` and `test_swapn.py` ([#502](https://github.com/ethereum/execution-spec-tests/pull/502)). -- ✨ Add tests for [EIP-6110: Supply validator deposits on chain](https://eips.ethereum.org/EIPS/eip-6110) ([#530](https://github.com/ethereum/execution-spec-tests/pull/530)). -- ✨ Add tests for [EIP-7002: Execution layer triggerable withdrawals](https://eips.ethereum.org/EIPS/eip-7002) ([#530](https://github.com/ethereum/execution-spec-tests/pull/530)). -- ✨ Add tests for [EIP-7685: General purpose execution layer requests](https://eips.ethereum.org/EIPS/eip-7685) ([#530](https://github.com/ethereum/execution-spec-tests/pull/530)). -- ✨ Add tests for [EIP-2935: Serve historical block hashes from state](https://eips.ethereum.org/EIPS/eip-2935) ([#564](https://github.com/ethereum/execution-spec-tests/pull/564), [#585](https://github.com/ethereum/execution-spec-tests/pull/585)). -- ✨ Add tests for [EIP-4200: EOF - Static relative jumps](https://eips.ethereum.org/EIPS/eip-4200) ([#581](https://github.com/ethereum/execution-spec-tests/pull/581), [#666](https://github.com/ethereum/execution-spec-tests/pull/666)). -- ✨ Add tests for [EIP-7069: EOF - Revamped CALL instructions](https://eips.ethereum.org/EIPS/eip-7069) ([#595](https://github.com/ethereum/execution-spec-tests/pull/595)). -- 🐞 Fix typos in self-destruct collision test from erroneous pytest parametrization ([#608](https://github.com/ethereum/execution-spec-tests/pull/608)). -- ✨ Add tests for [EIP-3540: EOF - EVM Object Format v1](https://eips.ethereum.org/EIPS/eip-3540) ([#634](https://github.com/ethereum/execution-spec-tests/pull/634), [#668](https://github.com/ethereum/execution-spec-tests/pull/668)). -- 🔀 Update EIP-7002 tests to match spec changes in [ethereum/execution-apis#549](https://github.com/ethereum/execution-apis/pull/549) ([#600](https://github.com/ethereum/execution-spec-tests/pull/600)). -- ✨ Convert a few eip1153 tests from ethereum/tests repo into .py ([#440](https://github.com/ethereum/execution-spec-tests/pull/440)). -- ✨ Add tests for [EIP-7480: EOF - Data section access instructions](https://eips.ethereum.org/EIPS/eip-7480) ([#518](https://github.com/ethereum/execution-spec-tests/pull/518), [#664](https://github.com/ethereum/execution-spec-tests/pull/664)). -- ✨ Add tests for subcontainer kind validation from [EIP-7620: EOF Contract Creation](https://eips.ethereum.org/EIPS/eip-7620) for the cases with deeply nested containers and non-first code sections ([#676](https://github.com/ethereum/execution-spec-tests/pull/676)). -- ✨ Add tests for runtime stack overflow at CALLF instruction from [EIP-4750: EOF - Functions](https://eips.ethereum.org/EIPS/eip-4750) ([#678](https://github.com/ethereum/execution-spec-tests/pull/678)). -- ✨ Add tests for runtime stack overflow at JUMPF instruction from [EIP-6206: EOF - JUMPF and non-returning functions](https://eips.ethereum.org/EIPS/eip-6206) ([#690](https://github.com/ethereum/execution-spec-tests/pull/690)). -- ✨ Add tests for Devnet-1 version of [EIP-7702: Set EOA account code](https://eips.ethereum.org/EIPS/eip-7702) ([#621](https://github.com/ethereum/execution-spec-tests/pull/621)). - -### 🛠️ Framework - -- 🐞 Fix incorrect `!=` operator for `FixedSizeBytes` ([#477](https://github.com/ethereum/execution-spec-tests/pull/477)). -- ✨ Add Macro enum that represents byte sequence of Op instructions ([#457](https://github.com/ethereum/execution-spec-tests/pull/457)). -- ✨ Number of parameters used to call opcodes (to generate bytecode) is now checked ([#492](https://github.com/ethereum/execution-spec-tests/pull/492)). -- ✨ Libraries have been refactored to use `pydantic` for type checking in most test types ([#486](https://github.com/ethereum/execution-spec-tests/pull/486), [#501](https://github.com/ethereum/execution-spec-tests/pull/501), [#508](https://github.com/ethereum/execution-spec-tests/pull/508)). -- ✨ Opcodes are now subscriptable and it's used to define the data portion of the opcode: `Op.PUSH1(1) == Op.PUSH1[1] == b"\x60\x01"` ([#513](https://github.com/ethereum/execution-spec-tests/pull/513)). -- ✨ Added EOF fixture format ([#512](https://github.com/ethereum/execution-spec-tests/pull/512)). -- ✨ Verify filled EOF fixtures using `evmone-eofparse` during `fill` execution ([#519](https://github.com/ethereum/execution-spec-tests/pull/519)). -- ✨ Added `--traces` support when running with Hyperledger Besu ([#511](https://github.com/ethereum/execution-spec-tests/pull/511)). -- ✨ Use pytest's "short" traceback style (`--tb=short`) for failure summaries in the test report for more compact terminal output ([#542](https://github.com/ethereum/execution-spec-tests/pull/542)). -- ✨ The `fill` command now generates HTML test reports with links to the JSON fixtures and debug information ([#537](https://github.com/ethereum/execution-spec-tests/pull/537)). -- ✨ Add an Ethereum RPC client class for use with consume commands ([#556](https://github.com/ethereum/execution-spec-tests/pull/556)). -- ✨ Add a "slow" pytest marker, in order to be able to limit the filled tests until release ([#562](https://github.com/ethereum/execution-spec-tests/pull/562)). -- ✨ Add a CLI tool that generates blockchain tests as Python from a transaction hash ([#470](https://github.com/ethereum/execution-spec-tests/pull/470), [#576](https://github.com/ethereum/execution-spec-tests/pull/576)). -- ✨ Add more Transaction and Block exceptions from existing ethereum/tests repo ([#572](https://github.com/ethereum/execution-spec-tests/pull/572)). -- ✨ Add "description" and "url" fields containing test case documentation and a source code permalink to fixtures during `fill` and use them in `consume`-generated Hive test reports ([#579](https://github.com/ethereum/execution-spec-tests/pull/579)). -- ✨ Add git workflow evmone coverage script for any new lines mentioned in converted_ethereum_tests.txt ([#503](https://github.com/ethereum/execution-spec-tests/pull/503)). -- ✨ Add a new covariant marker `with_all_contract_creating_tx_types` that allows automatic parametrization of a test with all contract-creating transaction types at the current executing fork ([#602](https://github.com/ethereum/execution-spec-tests/pull/602)). -- ✨ Tests are now encouraged to declare a `pre: Alloc` parameter to get the pre-allocation object for the test, and use `pre.deploy_contract` and `pre.fund_eoa` to deploy contracts and fund accounts respectively, instead of declaring the `pre` as a dictionary or modifying its contents directly (see the [state test tutorial](https://eest.ethereum.org/v4.1.0/writing_tests/tutorials/state_transition/) for an updated example) ([#584](https://github.com/ethereum/execution-spec-tests/pull/584)). -- ✨ Enable loading of [ethereum/tests/BlockchainTests](https://github.com/ethereum/tests/tree/develop/BlockchainTests) ([#596](https://github.com/ethereum/execution-spec-tests/pull/596)). -- 🔀 Refactor `gentest` to use `ethereum_test_tools.rpc.rpc` by adding to `get_transaction_by_hash`, `debug_trace_call` to `EthRPC` ([#568](https://github.com/ethereum/execution-spec-tests/pull/568)). -- ✨ Write a properties file to the output directory and enable direct generation of a fixture tarball from `fill` via `--output=fixtures.tgz`([#627](https://github.com/ethereum/execution-spec-tests/pull/627)). -- 🔀 `ethereum_test_tools` library has been split into multiple libraries ([#645](https://github.com/ethereum/execution-spec-tests/pull/645)). -- ✨ Add the consume engine simulator and refactor the consume simulator suite ([#691](https://github.com/ethereum/execution-spec-tests/pull/691)). -- 🐞 Prevents forcing consume to use stdin as an input when running from hive ([#701](https://github.com/ethereum/execution-spec-tests/pull/701)). - -### 📋 Misc - -- 🐞 Fix CI by using Golang 1.21 in Github Actions to build geth ([#484](https://github.com/ethereum/execution-spec-tests/pull/484)). -- 💥 "Merge" has been renamed to "Paris" in the "network" field of the Blockchain tests, and in the "post" field of the State tests ([#480](https://github.com/ethereum/execution-spec-tests/pull/480)). -- ✨ Port entry point scripts to use [click](https://click.palletsprojects.com) and add tests ([#483](https://github.com/ethereum/execution-spec-tests/pull/483)). -- 💥 As part of the pydantic conversion, the fixtures have the following (possibly breaking) changes ([#486](https://github.com/ethereum/execution-spec-tests/pull/486)): - - State test field `transaction` now uses the proper zero-padded hex number format for fields `maxPriorityFeePerGas`, `maxFeePerGas`, and `maxFeePerBlobGas`. - - Fixtures' hashes (in the `_info` field) are now calculated by removing the "_info" field entirely instead of it being set to an empty dict. -- 🐞 Relax minor and patch dependency requirements to avoid conflicting package dependencies ([#510](https://github.com/ethereum/execution-spec-tests/pull/510)). -- 🔀 Update all CI actions to use their respective Node.js 20 versions, ahead of their Node.js 16 version deprecations ([#527](https://github.com/ethereum/execution-spec-tests/pull/527)). -- ✨ Releases now contain a `fixtures_eip7692.tar.gz` which contains all EOF fixtures ([#573](https://github.com/ethereum/execution-spec-tests/pull/573)). -- ✨ Use `solc-select` for tox when running locally and within CI ([#604](https://github.com/ethereum/execution-spec-tests/pull/604)). - -### 💥 Breaking Change - -- Cancun is now the latest deployed fork, and the development fork is now Prague ([#489](https://github.com/ethereum/execution-spec-tests/pull/489)). -- Stable fixtures artifact `fixtures.tar.gz` has been renamed to `fixtures_stable.tar.gz` ([#573](https://github.com/ethereum/execution-spec-tests/pull/573)). -- The "Blockchain Test Hive" fixture format has been renamed to "Blockchain Test Engine" and updated to more closely resemble the `engine_newPayload` format in the `execution-apis` specification () and now contains a single `"params"` field instead of multiple fields for each parameter ([#687](https://github.com/ethereum/execution-spec-tests/pull/687)). -- Output folder for fixtures has been renamed from "blockchain_tests_hive" to "blockchain_tests_engine" ([#687](https://github.com/ethereum/execution-spec-tests/pull/687)). - -## [v2.1.1](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.1.1) - 2024-03-09 - -### 🧪 Test Cases - -- 🐞 Dynamic create2 collision from different transactions same block ([#430](https://github.com/ethereum/execution-spec-tests/pull/430)). -- 🐞 Fix beacon root contract deployment tests so the account in the pre-alloc is not empty ([#425](https://github.com/ethereum/execution-spec-tests/pull/425)). -- 🔀 All beacon root contract tests are now contained in tests/cancun/eip4788_beacon_root/test_beacon_root_contract.py, and all state tests have been converted back to blockchain tests format ([#449](https://github.com/ethereum/execution-spec-tests/pull/449)). - -### 🛠️ Framework - -- ✨ Adds two `consume` commands [#339](https://github.com/ethereum/execution-spec-tests/pull/339): - - 1. `consume direct` - Execute a test fixture directly against a client using a `blocktest`-like command (currently only geth supported). - 2. `consume rlp` - Execute a test fixture in a hive simulator against a client that imports the test's genesis config and blocks as RLP upon startup. This is a re-write of the [ethereum/consensus](https://github.com/ethereum/hive/tree/master/simulators/ethereum/consensus) Golang simulator. - -- ✨ Add Prague to forks ([#419](https://github.com/ethereum/execution-spec-tests/pull/419)). -- ✨ Improve handling of the argument passed to `solc --evm-version` when compiling Yul code ([#418](https://github.com/ethereum/execution-spec-tests/pull/418)). -- 🐞 Fix `fill -m yul_test` which failed to filter tests that are (dynamically) marked as a yul test ([#418](https://github.com/ethereum/execution-spec-tests/pull/418)). -- 🔀 Helper methods `to_address`, `to_hash` and `to_hash_bytes` have been deprecated in favor of `Address` and `Hash`, which are automatically detected as opcode parameters and pushed to the stack in the resulting bytecode ([#422](https://github.com/ethereum/execution-spec-tests/pull/422)). -- ✨ `Opcodes` enum now contains docstrings with each opcode description, including parameters and return values, which show up in many development environments ([#424](https://github.com/ethereum/execution-spec-tests/pull/424)) @ThreeHrSleep. -- 🔀 Locally calculate state root for the genesis blocks in the blockchain tests instead of calling t8n ([#450](https://github.com/ethereum/execution-spec-tests/pull/450)). -- 🐞 Fix bug that causes an exception during test collection because the fork parameter contains `None` ([#452](https://github.com/ethereum/execution-spec-tests/pull/452)). -- ✨ The `_info` field in the test fixtures now contains a `hash` field, which is the hash of the test fixture, and a `hasher` script has been added which prints and performs calculations on top of the hashes of all fixtures (see `hasher -h`) ([#454](https://github.com/ethereum/execution-spec-tests/pull/454)). -- ✨ Adds an optional `verify_sync` field to hive blockchain tests (EngineAPI). When set to true a second client attempts to sync to the first client that executed the tests ([#431](https://github.com/ethereum/execution-spec-tests/pull/431)). -- 🐞 Fix manually setting the gas limit in the genesis test env for post genesis blocks in blockchain tests ([#472](https://github.com/ethereum/execution-spec-tests/pull/472)). - -### 📋 Misc - -- 🐞 Fix deprecation warnings due to outdated config in recommended VS Code project settings ([#420](https://github.com/ethereum/execution-spec-tests/pull/420)). -- 🐞 Fix typo in the selfdestruct revert tests module ([#421](https://github.com/ethereum/execution-spec-tests/pull/421)). - -## [v2.1.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.1.0) - 2024-01-29: 🐍🏖️ Cancun - -Release [v2.1.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.1.0) primarily fixes a small bug introduced within the previous release where transition forks are used within the new `StateTest` format. This was highlighted by @chfast within #405 (), where the fork name `ShanghaiToCancunAtTime15k` was found within state tests. - -### 🧪 Test Cases - -- ✨ [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Adds `test_blob_gas_subtraction_tx()` verifying the blob gas fee is subtracted from the sender before executing the blob tx ([#407](https://github.com/ethereum/execution-spec-tests/pull/407)). - -### 🛠️ Framework - -- 🐞 State tests generated with transition forks no longer use the transition fork name in the fixture output, instead they use the actual enabled fork according to the state test's block number and timestamp ([#406](https://github.com/ethereum/execution-spec-tests/pull/406)). - -### 📋 Misc - -- ✨ Use `run-parallel` and shared wheel packages for `tox` ([#408](https://github.com/ethereum/execution-spec-tests/pull/408)). - -## [v2.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.0.0) - 2024-01-25: 🐍🏖️ Cancun - -Release [v2.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.0.0) contains many important framework changes, including introduction of the `StateTest` format, and some additional Cancun and other test coverage. - -Due to changes in the framework, there is a breaking change in the directory structure in the release tarball, please see the dedicated "💥 Breaking Changes" section below for more information. - -### 🧪 Test Cases - -- ✨ [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Add `test_sufficient_balance_blob_tx()` and `test_sufficient_balance_blob_tx_pre_fund_tx()` ([#379](https://github.com/ethereum/execution-spec-tests/pull/379)). -- ✨ [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780): Add a reentrancy suicide revert test ([#372](https://github.com/ethereum/execution-spec-tests/pull/372)). -- ✨ [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153): Add `test_run_until_out_of_gas()` for transient storage opcodes ([#401](https://github.com/ethereum/execution-spec-tests/pull/401)). -- ✨ [EIP-198](https://eips.ethereum.org/EIPS/eip-198): Add tests for the MODEXP precompile ([#364](https://github.com/ethereum/execution-spec-tests/pull/364)). -- ✨ Tests for nested `CALL` and `CALLCODE` gas consumption with a positive value transfer (previously lacking coverage) ([#371](https://github.com/ethereum/execution-spec-tests/pull/371)). -- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fixed `test_invalid_tx_max_fee_per_blob_gas()` to account for extra gas required in the case where the account is incorrectly deduced the balance as if it had the correct block blob gas fee ([#370](https://github.com/ethereum/execution-spec-tests/pull/370)). -- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fixed `test_insufficient_balance_blob_tx()` to correctly calculate the minimum balance required for the accounts ([#379](https://github.com/ethereum/execution-spec-tests/pull/379)). -- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fix and enable `test_invalid_blob_tx_contract_creation` ([#379](https://github.com/ethereum/execution-spec-tests/pull/379)). -- 🔀 Convert all eligible `BlockchainTest`s to `StateTest`s (and additionally generate corresponding `BlockchainTest`s) ([#368](https://github.com/ethereum/execution-spec-tests/pull/368), [#370](https://github.com/ethereum/execution-spec-tests/pull/370)). - -### 🛠️ Framework - -- ✨ Add `StateTest` fixture format generation; `StateTests` now generate a `StateTest` and a corresponding `BlockchainTest` test fixture, previously only `BlockchainTest` fixtures were generated ([#368](https://github.com/ethereum/execution-spec-tests/pull/368)). -- ✨ Add `StateTestOnly` fixture format is now available and its only difference with `StateTest` is that it does not produce a `BlockchainTest` ([#368](https://github.com/ethereum/execution-spec-tests/pull/368)). -- ✨ Add `evm_bytes_to_python` command-line utility which converts EVM bytecode to Python Opcodes ([#357](https://github.com/ethereum/execution-spec-tests/pull/357)). -- ✨ Fork objects used to write tests can now be compared using the `>`, `>=`, `<`, `<=` operators, to check for a fork being newer than, newer than or equal, older than, older than or equal, respectively when compared against other fork ([#367](https://github.com/ethereum/execution-spec-tests/pull/367)). -- ✨ Add [solc 0.8.23](https://github.com/ethereum/solidity/releases/tag/v0.8.23) support ([#373](https://github.com/ethereum/execution-spec-tests/pull/373)). -- ✨ Add framework unit tests for post state exception verification ([#350](https://github.com/ethereum/execution-spec-tests/pull/350)). -- ✨ Add a helper class `ethereum_test_tools.TestParameterGroup` to define test parameters as dataclasses and auto-generate test IDs ([#364](https://github.com/ethereum/execution-spec-tests/pull/364)). -- ✨ Add a `--single-fixture-per-file` flag to generate one fixture JSON file per test case ([#331](https://github.com/ethereum/execution-spec-tests/pull/331)). -- 🐞 Storage type iterator is now fixed ([#369](https://github.com/ethereum/execution-spec-tests/pull/369)). -- 🐞 Fix type coercion in `FixtureHeader.join()` ([#398](https://github.com/ethereum/execution-spec-tests/pull/398)). -- 🔀 Locally calculate the transactions list's root instead of using the one returned by t8n when producing BlockchainTests ([#353](https://github.com/ethereum/execution-spec-tests/pull/353)). -- 🔀 Change custom exception classes to dataclasses to improve testability ([#386](https://github.com/ethereum/execution-spec-tests/pull/386)). -- 🔀 Update fork name from "Merge" to "Paris" used within the framework and tests ([#363](https://github.com/ethereum/execution-spec-tests/pull/363)). -- 💥 Replace `=` with `_` in pytest node ids and test fixture names ([#342](https://github.com/ethereum/execution-spec-tests/pull/342)). -- 💥 The `StateTest`, spec format used to write tests, is now limited to a single transaction per test ([#361](https://github.com/ethereum/execution-spec-tests/pull/361)). -- 💥 Tests must now use `BlockException` and `TransactionException` to define the expected exception of a given test, which can be used to test whether the client is hitting the proper exception when processing the block or transaction ([#384](https://github.com/ethereum/execution-spec-tests/pull/384)). -- 💥 `fill`: Remove the `--enable-hive` flag; now all test types are generated by default ([#358](https://github.com/ethereum/execution-spec-tests/pull/358)). -- 💥 Rename test fixtures names to match the corresponding pytest node ID as generated using `fill` ([#342](https://github.com/ethereum/execution-spec-tests/pull/342)). - -### 📋 Misc - -- ✨ Docs: Add a ["Consuming Tests"](https://eest.ethereum.org/main/consuming_tests/) section to the docs, where each test fixture format is described, along with the steps to consume them, and the description of the structures used in each format ([#375](https://github.com/ethereum/execution-spec-tests/pull/375)). -- 🔀 Docs: Update `t8n` tool branch to fill tests for development features in the [readme](https://github.com/ethereum/execution-spec-tests) ([#338](https://github.com/ethereum/execution-spec-tests/pull/338)). -- 🔀 Filling tool: Updated the default filling tool (`t8n`) to go-ethereum@master ([#368](https://github.com/ethereum/execution-spec-tests/pull/368)). -- 🐞 Docs: Fix error banner in online docs due to mermaid syntax error ([#398](https://github.com/ethereum/execution-spec-tests/pull/398)). -- 🐞 Docs: Fix incorrectly formatted nested lists in online doc ([#403](https://github.com/ethereum/execution-spec-tests/pull/403)). -- 🔀 CLI: `evm_bytes_to_python` is renamed to `evm_bytes` and now accepts flag `--assembly` to output the code in assembly format ([#844](https://github.com/ethereum/execution-spec-tests/pull/844)). - -### 💥 Breaking Changes - -A concrete example of the test name renaming and change in directory structure is provided below. - -1. Fixture output, including release tarballs, now contain subdirectories for different test types: - - 1. `blockchain_tests`: Contains `BlockchainTest` formatted tests - 2. `blockchain_tests_hive`: Contains `BlockchainTest` with Engine API call directives for use in hive - 3. `state_tests`: Contains `StateTest` formatted tests - -2. `StateTest`, spec format used to write tests, is now limited to a single transaction per test. -3. In this release the pytest node ID is now used for fixture names (previously only the test parameters were used), this should not be breaking. However, `=` in both node IDs (and therefore fixture names) have been replaced with `_`, which may break tooling that depends on the `=` character. -4. Produced `blockchain_tests` fixtures and their corresponding `blockchain_tests_hive` fixtures now contain the named exceptions `BlockException` and `TransactionException` as strings in the `expectException` and `validationError` fields, respectively. These exceptions can be used to test whether the client is hitting the proper exception when processing an invalid block. - - Blockchain test: - - ```json - "blocks": [ - { - ... - "expectException": "TransactionException.INSUFFICIENT_ACCOUNT_FUNDS", - ... - } - ... - ] - ``` - - Blockchain hive test: - - ```json - "engineNewPayloads": [ - { - ... - "validationError": "TransactionException.INSUFFICIENT_ACCOUNT_FUNDS", - ... - } - ... - ] - ``` - -#### Renaming and Release Tarball Directory Structure Change Example - -The fixture renaming provides a more consistent naming scheme between the pytest node ID and fixture name and allows the fixture name to be provided directly to pytest 5on the command line to execute individual tests in isolation, e.g. `pytest tests/frontier/opcodes/test_dup.py::test_dup[fork_Frontier]`. - -1. Pytest node ID example: - - 1. Previous node ID: `tests/frontier/opcodes/test_dup.py::test_dup[fork=Frontier]`. - 2. New node ID: `tests/frontier/opcodes/test_dup.py::test_dup[fork_Frontier]`. - -2. Fixture name example: - - 1. Previous fixture name: `000-fork=Frontier` - 2. New fixture name: `tests/frontier/opcodes/test_dup.py::test_dup[fork_Frontier]` (now the same as the pytest node ID). - -3. Fixture JSON file name example (within the release tarball): - - 1. Previous fixture file name: `fixtures/frontier/opcodes/dup/dup.json` (`BlockChainTest` format). - 2. New fixture file names (all present within the release tarball): - - - `fixtures/state_tests/frontier/opcodes/dup/dup.json` (`StateTest` format). - - `fixtures/blockchain_tests/frontier/opcodes/dup/dup.json` (`BlockChainTest` format). - - `fixtures/blockchain_tests_hive/frontier/opcodes/dup/dup.json` (a blockchain test in `HiveFixture` format). - -## [v1.0.6](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.6) - 2023-10-19: 🐍🏖️ Cancun Devnet 10 - -### 🧪 Test Cases - -- 🔀 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Update KZG point evaluation test vectors to use data from the official KZG setup and Mainnet Trusted Setup ([#336](https://github.com/ethereum/execution-spec-tests/pull/336)). - -### 🛠️ Framework - -- 🔀 Fixtures: Add a non-RLP format field (`rlp_decoded`) to invalid blocks ([#322](https://github.com/ethereum/execution-spec-tests/pull/322)). -- 🔀 Spec: Refactor state and blockchain spec ([#307](https://github.com/ethereum/execution-spec-tests/pull/307)). - -### 🔧 EVM Tools - -- ✨ Run geth's `evm blocktest` command to verify JSON fixtures after test case execution (`--verify-fixtures`) ([#325](https://github.com/ethereum/execution-spec-tests/pull/325)). -- ✨ Enable tracing support for `ethereum-spec-evm` ([#289](https://github.com/ethereum/execution-spec-tests/pull/289)). - -### 📋 Misc - -- ✨ Tooling: Add Python 3.12 support ([#309](https://github.com/ethereum/execution-spec-tests/pull/309)). -- ✨ Process: Added a Github pull request template ([#308](https://github.com/ethereum/execution-spec-tests/pull/308)). -- ✨ Docs: Changelog updated post release ([#321](https://github.com/ethereum/execution-spec-tests/pull/321)). -- ✨ Docs: Add [a section explaining execution-spec-tests release artifacts](https://eest.ethereum.org/v4.1.0/consuming_tests/) ([#334](https://github.com/ethereum/execution-spec-tests/pull/334)). -- 🔀 T8N Tool: Branch used to generate the tests for Cancun is now [lightclient/go-ethereum@devnet-10](https://github.com/lightclient/go-ethereum/tree/devnet-10) ([#336](https://github.com/ethereum/execution-spec-tests/pull/336)). - -### 💥 Breaking Change - -- Fixtures now use the Mainnet Trusted Setup merged on [consensus-specs#3521](https://github.com/ethereum/consensus-specs/pull/3521) ([#336](https://github.com/ethereum/execution-spec-tests/pull/336)). - -## [v1.0.5](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.5) - 2023-09-26: 🐍🏖️ Cancun Devnet 9 Release 3 - -This release mainly serves to update the EIP-4788 beacon roots address to `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`, as updated in [ethereum/EIPs/pull/7672](https://github.com/ethereum/EIPs/pull/7672). - -### 🧪 Test Cases - -- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fix invalid blob txs pre-Cancun engine response ([#306](https://github.com/ethereum/execution-spec-tests/pull/306)). -- ✨ [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788): Final update to the beacon root address ([#312](https://github.com/ethereum/execution-spec-tests/pull/312)). - -### 📋 Misc - -- ✨ Docs: Changelog added ([#305](https://github.com/ethereum/execution-spec-tests/pull/305)). -- ✨ CI/CD: Run development fork tests in Github Actions ([#302](https://github.com/ethereum/execution-spec-tests/pull/302)). -- ✨ CI/CD: Generate test JSON fixtures on push ([#303](https://github.com/ethereum/execution-spec-tests/pull/303)). - -### 💥 Breaking Change - -Please use development fixtures from now on when testing Cancun. These refer to changes that are currently under development within clients: - -- fixtures: All tests until the last stable fork (Shanghai). -- fixtures_develop: All tests until the last development fork (Cancun). -- fixtures_hive: All tests until the last stable fork (Shanghai) in hive format (Engine API directives instead of the usual BlockchainTest format). -- fixtures_develop_hive: All tests until the last development fork (Cancun) in hive format. - -## [v1.0.4](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.4) - 2023-09-21: 🐍 Cancun Devnet 9 Release 2 - -This release adds additional coverage to the current set of Cancun tests, up to the [Devnet-9 Cancun specification](https://notes.ethereum.org/@ethpandaops/dencun-devnet-9). - -**Note:** Additional EIP-4788 updates from [ethereum/EIPs/pull/7672](https://github.com/ethereum/EIPs/pull/7672) will be included in the next release. - -### 🧪 Test Cases - -- ✨ [EIP-7516: BLOBBASEFEE opcode](https://eips.ethereum.org/EIPS/eip-7516): Add first and comprehensive tests (@marioevz in [#294](https://github.com/ethereum/execution-spec-tests/pull/294)). -- ✨ [EIP-4788: Beacon block root in the EVM](https://eips.ethereum.org/EIPS/eip-4788): Increase coverage (@spencer-tb in [#297](https://github.com/ethereum/execution-spec-tests/pull/297)). -- 🐞 [EIP-1153: Transient storage opcodes](https://eips.ethereum.org/EIPS/eip-1153): Remove conftest '+1153' in network field (@spencer-tb in [#299](https://github.com/ethereum/execution-spec-tests/pull/299)). - -### 🛠️ Framework - -- 🔀 [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788): Beacon root contract is pre-deployed at `0xbEAC020008aFF7331c0A389CB2AAb67597567d7a` (@spencer-tb in [#297](https://github.com/ethereum/execution-spec-tests/pull/297)). -- ✨ Deprecate empty accounts within framework (@spencer-tb in [#300](https://github.com/ethereum/execution-spec-tests/pull/300)). -- ✨ Fixture generation split based on hive specificity (@spencer-tb in [#301](https://github.com/ethereum/execution-spec-tests/pull/301)). -- 💥 `fill`: `--disable-hive` flag removed; replaced by `--enable-hive` (@spencer-tb in [#301](https://github.com/ethereum/execution-spec-tests/pull/301)). -- ✨ Add engine API forkchoice updated information in fixtures (@spencer-tb in [#256](https://github.com/ethereum/execution-spec-tests/pull/256)). - -## [v1.0.3](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.3) - 2023-09-14: 🐍 Cancun Devnet 9 Release - -See [v1.0.3](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.3). - -## [v1.0.2](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.2) - 2023-08-11: 🐍 Cancun Devnet 8 + 4788 v2 Pre-Release - -See [v1.0.2](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.2). - -## [v1.0.1](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.1) - 2023-08-03: 🐍 Cancun Devnet-8 Pre-Release - -See [v1.0.1](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.1). - -## [v1.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.0) - 2023-06-27: 🧪 Welcome to the Pytest Era - -See [v1.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.0). - -Older releases can be found on [the releases page](https://github.com/ethereum/execution-spec-tests/releases). diff --git a/docs/changelog_section_template.md b/docs/changelog_section_template.md deleted file mode 100644 index dfa30a4ec83..00000000000 --- a/docs/changelog_section_template.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog Section Template - -The following can be copy-pasted into the `CHANGELOG.md` file for a new release. - -## 🔜 [Unreleased] - -### 💥 Breaking Change - -### 🛠️ Framework - -#### `fill` - -#### `consume` - -#### `execute` - -### 📋 Misc - -### 🧪 Test Cases diff --git a/docs/dev/docs.md b/docs/dev/docs.md index 96fe14f6044..3be9a658e6b 100644 --- a/docs/dev/docs.md +++ b/docs/dev/docs.md @@ -22,7 +22,6 @@ Run all docs related checks: just spellcheck just lint-md just docs -just changelog ``` ### Local Deployment and Test diff --git a/packages/testing/pyproject.toml b/packages/testing/pyproject.toml index 12afa968097..28a07929f12 100644 --- a/packages/testing/pyproject.toml +++ b/packages/testing/pyproject.toml @@ -60,7 +60,6 @@ Homepage = "https://github.com/ethereum/execution-specs" Documentation = "https://eest.ethereum.org" Repository = "https://github.com/ethereum/execution-specs" Issues = "https://github.com/ethereum/execution-specs/issues" -Changelog = "https://eest.ethereum.org/main/CHANGELOG/" [dependency-groups] test = [ @@ -99,7 +98,6 @@ groupstats = "execution_testing.cli.show_pre_alloc_group_stats:main" extract_config = "execution_testing.cli.extract_config:extract_config" compare_fixtures = "execution_testing.cli.compare_fixtures:main" modify_static_test_gas_limits = "execution_testing.cli.modify_static_test_gas_limits:main" -validate_changelog = "execution_testing.cli.ci_helpers:validate_changelog" benchmark_parser = "execution_testing.cli.benchmark_parser:main" [tool.setuptools.packages.find] diff --git a/packages/testing/src/execution_testing/cli/ci_helpers.py b/packages/testing/src/execution_testing/cli/ci_helpers.py index e24c569166e..e606252b4c0 100644 --- a/packages/testing/src/execution_testing/cli/ci_helpers.py +++ b/packages/testing/src/execution_testing/cli/ci_helpers.py @@ -1,7 +1,7 @@ """ CLI helper commands for CI static checks. -Contains wrappers to markdownlint-cli2 and changelog validation that fail +Contains a wrapper to markdownlint-cli2 validation which fails silently if external tools are not available, to avoid disruption to external contributors. """ @@ -96,53 +96,3 @@ def markdownlint(args: tuple[str, ...]) -> None: command = ["node", markdownlint] + args_list sys.exit(subprocess.run(command).returncode) - - -@click.command() -def validate_changelog() -> None: - """ - Validate changelog formatting to ensure bullet points end with proper - punctuation. - - Check that all bullet points (including nested ones) end with either: - - A period (.) for regular entries - - A colon (:) for section headers that introduce lists - """ - project_root = find_project_root() - changelog_path = Path(project_root / "docs/CHANGELOG.md") - - if not changelog_path.exists(): - click.echo(f"❌ Changelog file not found: {changelog_path}") - sys.exit(1) - - try: - with open(changelog_path, "r", encoding="utf-8") as f: - content = f.read() - except Exception as e: - click.echo(f"❌ Error reading changelog: {e}.") - sys.exit(1) - - # Find bullet points that don't end with period or colon - invalid_lines = [] - for line_num, line in enumerate(content.splitlines(), 1): - if re.match(r"^\s*-\s+", line) and re.search( - r"[^\.:]$", line.rstrip() - ): - invalid_lines.append((line_num, line.strip())) - - if invalid_lines: - click.echo( - f"❌ Found bullet points in {changelog_path} without proper " - "punctuation:" - ) - click.echo() - for line_num, line in invalid_lines: - click.echo(f"Line {line_num}: {line}") - click.echo() - click.echo("💡 All bullet points should end with:") - click.echo(" - A period (.) for regular entries.") - click.echo(" - A colon (:) for paragraphs that introduce lists.") - sys.exit(1) - else: - click.echo("✅ All bullet points have proper punctuation!") - sys.exit(0) diff --git a/tox.ini b/tox.ini index 98b485cbbd5..f390f3ada51 100644 --- a/tox.ini +++ b/tox.ini @@ -74,11 +74,6 @@ commands = printf '\n\033[1m execution-specs has migrated from tox to just.\033[0m\n Install just: https://just.systems/man/en/pre-built-binaries.html\n\n This tox env can be run using just via:\n \033[1mjust docs\033[0m\n\n' false -[testenv:changelog] -commands = - printf '\n\033[1m execution-specs has migrated from tox to just.\033[0m\n Install just: https://just.systems/man/en/pre-built-binaries.html\n\n This tox env can be run using just via:\n \033[1mjust changelog\033[0m\n\n' - false - [testenv:markdownlint] commands = printf '\n\033[1m execution-specs has migrated from tox to just.\033[0m\n Install just: https://just.systems/man/en/pre-built-binaries.html\n\n This tox env can be run using just via:\n \033[1mjust lint-md\033[0m\n\n' From 462ee80572c70821e384341e51b5d56b4479b126 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Fri, 8 May 2026 10:42:58 -0600 Subject: [PATCH 065/186] feat(test-forks): Revert gas-limit-aware `Fork`, fork-aware `Environment` (#2762) Revert "fix(test-forks): treat transition fork variants as equal to canonical (#2782)" This reverts commit 9d18733602f7a4ed41001c16525943ca0836af4c. This reverts commit c3462e030f7e2cebe93688d15d2423dcf16fc8cc. --- .../plugins/execute/execute.py | 7 +- .../pytest_commands/plugins/filler/filler.py | 8 +-- .../filler/gen_test_doc/gen_test_doc.py | 2 +- .../plugins/filler/static_filler.py | 2 +- .../pytest_commands/plugins/forks/forks.py | 16 ++--- .../tests/test_fork_parametrizer_types.py | 23 +++---- .../plugins/shared/benchmarking.py | 18 ++---- .../plugins/shared/execute_fill.py | 64 +------------------ .../src/execution_testing/forks/base_fork.py | 63 ++++-------------- .../forks/tests/test_forks.py | 52 --------------- .../forks/transition_base_fork.py | 45 ++----------- 11 files changed, 43 insertions(+), 257 deletions(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py index 9a15a9c3ecc..f5c567627bb 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py @@ -851,13 +851,10 @@ def pytest_collection_modifyitems( if isinstance(item, EIPSpecTestItem): continue params: Dict[str, Any] = item.callspec.params # type: ignore - if ( - "parametrized_fork" not in params - or params["parametrized_fork"] is None - ): + if "fork" not in params or params["fork"] is None: items_for_removal.append(i) continue - fork: Fork | TransitionFork = params["parametrized_fork"] + fork: Fork | TransitionFork = params["fork"] spec_type, execute_format = get_spec_format_for_item(params) assert issubclass(execute_format, BaseExecute) markers = list(item.iter_markers()) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py index 1b1bdb1d7b2..5a733c09ad5 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py @@ -1922,14 +1922,10 @@ def pytest_collection_modifyitems( params = item.callspec.params elif hasattr(item, "params"): params = item.params - if ( - not params - or "parametrized_fork" not in params - or params["parametrized_fork"] is None - ): + if not params or "fork" not in params or params["fork"] is None: items_for_removal.append(i) continue - fork: Fork | TransitionFork = params["parametrized_fork"] + fork: Fork | TransitionFork = params["fork"] spec_type, fixture_format = get_spec_format_for_item(params) if isinstance(fixture_format, NotSetType): items_for_removal.append(i) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py index 88a0e586066..f5eab27ac65 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py @@ -446,7 +446,7 @@ def create_function_page_props( ) for value in values ] - fork = item.callspec.params.get("parametrized_fork").name() # type: ignore + fork = item.callspec.params.get("fork").name() # type: ignore test_type = get_test_function_test_type(item) test_type_value = item.callspec.params.get(test_type) fixture_type = test_type_value.format_name # type: ignore diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py index c6d4ea6ecf5..08b2195410f 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py @@ -275,7 +275,7 @@ def collect(self: "FillerFile") -> Generator["FillerTestItem", None, None]: ps_id = fixture_format_parameter_set.id test_id = f"fork_{fork.name()}-{ps_id}" if "fork" in func_parameters: - params["parametrized_fork"] = fork + params["fork"] = fork if "pre" in func_parameters: fixturenames.append("pre") if "request" in func_parameters: diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py index 6f1bb468a18..2dc7336f6e8 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py @@ -118,7 +118,7 @@ def __init__( marks = [] self.fork_covariant_parameters = [ ForkCovariantParameter( - names=["parametrized_fork"], + names=["fork"], values=[ pytest.param( fork, @@ -671,7 +671,7 @@ def pytest_report_header(config: pytest.Config, start_path: Any) -> List[str]: @pytest.fixture(autouse=True) -def parametrized_fork(request: pytest.FixtureRequest) -> None: +def fork(request: pytest.FixtureRequest) -> None: """Parametrize test cases by fork.""" pass @@ -1234,9 +1234,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: ], ) ] - metafunc.parametrize( - "parametrized_fork", pytest_params, scope="function" - ) + metafunc.parametrize("fork", pytest_params, scope="function") return # Get the intersection between the test's validity marker and the current @@ -1245,7 +1243,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: test_fork_set & metafunc.config.selected_fork_set # type: ignore ) - if "parametrized_fork" not in metafunc.fixturenames: + if "fork" not in metafunc.fixturenames: return unsupported_forks: Set[Fork | TransitionFork] = ( @@ -1268,9 +1266,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: ], ) ] - metafunc.parametrize( - "parametrized_fork", pytest_params, scope="function" - ) + metafunc.parametrize("fork", pytest_params, scope="function") else: pytest_params = [] for fork in sorted(intersection_set): @@ -1574,7 +1570,7 @@ def pytest_collection_modifyitems( continue # --- validity markers --- - fork = params.get("parametrized_fork") + fork = params.get("fork") if fork is None: continue diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py index 381eb4712fd..cb1aa6da1f3 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py @@ -19,7 +19,7 @@ [ pytest.param( [ForkParametrizer(fork=Frontier)], - ["parametrized_fork"], + ["fork"], [pytest.param(Frontier)], id="only_fork", ), @@ -34,7 +34,7 @@ ], ) ], - ["parametrized_fork", "some_value"], + ["fork", "some_value"], [pytest.param(Frontier, 1)], id="fork_with_single_covariant_parameter", ), @@ -50,7 +50,7 @@ ], ) ], - ["parametrized_fork", "some_value"], + ["fork", "some_value"], [pytest.param(Frontier, 1), pytest.param(Frontier, 2)], id="fork_with_single_covariant_parameter_multiple_values", ), @@ -69,7 +69,7 @@ ], ) ], - ["parametrized_fork", "some_value"], + ["fork", "some_value"], [ pytest.param(Frontier, 1, marks=[pytest.mark.some_mark]), pytest.param(Frontier, 2), @@ -90,7 +90,7 @@ ], ) ], - ["parametrized_fork", "some_value", "another_value"], + ["fork", "some_value", "another_value"], [pytest.param(Frontier, 1, 2)], id="fork_with_multiple_covariant_parameters", ), @@ -109,7 +109,7 @@ ], ) ], - ["parametrized_fork", "some_value", "another_value"], + ["fork", "some_value", "another_value"], [pytest.param(Frontier, 1, 2), pytest.param(Frontier, 1, 3)], id="fork_with_multiple_covariant_parameters_multiple_values", ), @@ -128,7 +128,7 @@ ], ) ], - ["parametrized_fork", "some_value", "another_value"], + ["fork", "some_value", "another_value"], [pytest.param(Frontier, 1, "a"), pytest.param(Frontier, 2, "b")], id="fork_with_single_multi_value_covariant_parameter_multiple_values", ), @@ -155,7 +155,7 @@ ) ], [ - "parametrized_fork", + "fork", "some_value", "another_value", "yet_another_value", @@ -191,12 +191,7 @@ ], ) ], - [ - "parametrized_fork", - "shared_value", - "different_value_1", - "different_value_2", - ], + ["fork", "shared_value", "different_value_1", "different_value_2"], [ pytest.param(Frontier, 1, "a", "x"), pytest.param(Frontier, 2, "b", "y"), diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py index ed98551a10e..2a47ed80365 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py @@ -553,26 +553,16 @@ def _is_benchmark_test(request: pytest.FixtureRequest) -> bool: @pytest.fixture -def env_gas_limit(request: pytest.FixtureRequest) -> int: +def genesis_environment(request: pytest.FixtureRequest) -> Environment: """Return an Environment with appropriate gas limit.""" if _is_benchmark_test(request): - return BENCHMARKING_MAX_GAS - return EnvironmentDefaults.gas_limit - - -@pytest.fixture -def genesis_environment( - request: pytest.FixtureRequest, env_gas_limit: int -) -> Environment: - """Return an Environment with appropriate gas limit.""" - if _is_benchmark_test(request): - return Environment(gas_limit=env_gas_limit) + return Environment(gas_limit=BENCHMARKING_MAX_GAS) return Environment() @pytest.fixture -def env(request: pytest.FixtureRequest, env_gas_limit: int) -> Environment: +def env(request: pytest.FixtureRequest) -> Environment: """Return an Environment with appropriate gas limit.""" if _is_benchmark_test(request): - return Environment(gas_limit=env_gas_limit) + return Environment(gas_limit=BENCHMARKING_MAX_GAS) return Environment() diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py index 8b33474dfc4..d827d96927a 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py @@ -2,10 +2,8 @@ Shared pytest fixtures and hooks for EEST generation modes (fill and execute). """ -from __future__ import annotations - from pathlib import Path -from typing import TYPE_CHECKING, Dict, List, Tuple +from typing import Dict, List, Tuple import pytest from pytest import StashKey @@ -17,20 +15,11 @@ LabeledExecuteFormat, ) from execution_testing.fixtures import BaseFixture, LabeledFixtureFormat - -if TYPE_CHECKING: - from execution_testing.forks import Fork, TransitionFork -import sys - from execution_testing.logging import get_logger from execution_testing.rpc import EthRPC from execution_testing.specs import BaseTest from execution_testing.specs.base import OpMode -from execution_testing.test_types import ( - EOA, - Alloc, - ChainConfig, -) +from execution_testing.test_types import EOA, Alloc, ChainConfig from ..shared.address_stubs import AddressStubs, StubEOA from ..shared.helpers import get_rpc_endpoint @@ -321,58 +310,9 @@ def pytest_make_parametrize_id( readable test ids for the generated tests. """ del config - if argname == "parametrized_fork": - return f"fork_{val}" return f"{argname}_{val}" -@pytest.fixture(scope="function") -def fork( - parametrized_fork: Fork | TransitionFork, - monkeypatch: pytest.MonkeyPatch, - env_gas_limit: int, -) -> Fork | TransitionFork: - """ - Return a per-test fork variant whose ``_env_gas_limit`` tracks the - ``Environment.gas_limit`` used by the test. - """ - fork_variant = parametrized_fork.with_env_gas_limit(env_gas_limit) - - # Now we monkey-patch the `Environment` class with one that is aware of - # the fork that the test is using, and will update its `_env_gas_limit` - # automatically. - # TODO: This should not be necessary, we should treat the `env` object the - # same way we do `pre` and force it to be a singleton in the test's - # context. - from execution_testing.test_types.block_types import ( - Environment as OriginalEnvironment, - ) - - class _ForkAwareEnvironment(OriginalEnvironment): - """Transparently syncs ``gas_limit`` back to the fork variant.""" - - def model_post_init(self, __context: object) -> None: - super().model_post_init(__context) - fork_variant._env_gas_limit = int(self.gas_limit) - - def __setattr__(self, name: str, value: object) -> None: - super().__setattr__(name, value) - if name == "gas_limit": - fork_variant._env_gas_limit = int(self.gas_limit) - - # Replace Environment in every module that imported the original class - # so that both `Environment(...)` in test code and in conftest fixtures - # create _ForkAwareEnvironment instances. - for mod in list(sys.modules.values()): - try: - if getattr(mod, "Environment", None) is OriginalEnvironment: - monkeypatch.setattr(mod, "Environment", _ForkAwareEnvironment) - except Exception: - continue - - return fork_variant - - SPEC_TYPES_PARAMETERS: List[str] = list(BaseTest.spec_types.keys()) diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index afdc3ccfbc0..c074c3da840 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -184,7 +184,7 @@ def __repr__(cls) -> str: return cls.name() @staticmethod - def _maybe_transitioned(fork_cls: type) -> type: + def _maybe_transitioned(fork_cls: "BaseForkMeta") -> "BaseForkMeta": """ Return the transitioned fork, if a transition fork, otherwise return `fork_cls`. @@ -198,54 +198,35 @@ def _maybe_transitioned(fork_cls: type) -> type: @staticmethod def _is_subclass_of(a: "BaseForkMeta", b: "BaseForkMeta") -> bool: """ - Check if `a` is a subclass of `b`, taking fork transitions and - variants (created by `with_env_gas_limit`) into account. + Check if `a` is a subclass of `b`, taking fork transitions into + account. """ - # Resolve variants to canonical identity so comparisons between - # a variant and a canonical descendant fork work as expected. - a_id: type = BaseForkMeta._identity(a) - b_id: type = BaseForkMeta._identity(b) - a_id = BaseForkMeta._maybe_transitioned(a_id) - b_id = BaseForkMeta._maybe_transitioned(b_id) - return issubclass(a_id, b_id) - - @staticmethod - def _identity(fork_cls: type) -> type: - """Return the canonical fork class, resolving variants.""" - base = getattr(fork_cls, "_base_fork", None) - return base if base is not None else fork_cls - - def __eq__(cls, other: object) -> bool: - """Compare fork identity, treating variants as equal to parents.""" - if not isinstance(other, BaseForkMeta): - return NotImplemented - return BaseForkMeta._identity(cls) is BaseForkMeta._identity(other) - - def __hash__(cls) -> int: - """Hash by canonical fork identity.""" - return id(BaseForkMeta._identity(cls)) + a = BaseForkMeta._maybe_transitioned(a) + b = BaseForkMeta._maybe_transitioned(b) + return issubclass(a, b) def __gt__(cls, other: "BaseForkMeta") -> bool: """Compare if a fork is newer than some other fork (cls > other).""" - return cls != other and BaseForkMeta._is_subclass_of(cls, other) + return cls is not other and BaseForkMeta._is_subclass_of(cls, other) def __ge__(cls, other: "BaseForkMeta") -> bool: """ Compare if a fork is newer than or equal to some other fork (cls >= other). """ - return cls == other or BaseForkMeta._is_subclass_of(cls, other) + return cls is other or BaseForkMeta._is_subclass_of(cls, other) def __lt__(cls, other: "BaseForkMeta") -> bool: """Compare if a fork is older than some other fork (cls < other).""" - return cls != other and BaseForkMeta._is_subclass_of(other, cls) + # "Older" means other is a subclass of cls, but not the same. + return cls is not other and BaseForkMeta._is_subclass_of(other, cls) def __le__(cls, other: "BaseForkMeta") -> bool: """ Compare if a fork is older than or equal to some other fork (cls <= other). """ - return cls == other or BaseForkMeta._is_subclass_of(other, cls) + return cls is other or BaseForkMeta._is_subclass_of(other, cls) class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta): @@ -265,10 +246,6 @@ class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta): _ruleset_name: ClassVar[Optional[str]] = None _fork_by_timestamp: ClassVar[bool] = False _blob_constants: ClassVar[Dict[str, int]] = {} - - # Environment overrides (set on variants created by with_env_gas_limit) - _base_fork: ClassVar[Optional[Type["BaseFork"]]] = None - _env_gas_limit: ClassVar[int] = 0 _deployed: ClassVar[bool] = True _enabled_eips: ClassVar[Set[int]] = set() _enabling_forks: ClassVar[Set[Type["BaseFork"]]] = set() @@ -1132,24 +1109,6 @@ def children(cls) -> Set[Type["BaseFork"]]: """Return the children forks.""" return set(cls._children) - @classmethod - def with_env_gas_limit(cls, env_gas_limit: int) -> Type["BaseFork"]: - """Return a new fork class with the specified environment gas limit.""" - new_cls = type(cls.__name__, (cls,), {}) - # __init_subclass__ resets per-class overrides; restore from parent. - new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] - new_cls._base_fork = cls._base_fork or cls # type: ignore[attr-defined] - new_cls._transition_tool_name = ( # type: ignore[attr-defined] - cls._transition_tool_name - ) - new_cls._solc_name = cls._solc_name # type: ignore[attr-defined] - new_cls._ignore = cls._ignore # type: ignore[attr-defined] - new_cls._bpo_fork = cls._bpo_fork # type: ignore[attr-defined] - new_cls._ruleset_name = cls._ruleset_name # type: ignore[attr-defined] - # Prevent the variant from appearing in fork traversals. - cls._children.discard(new_cls) - return new_cls - @classmethod @abstractmethod def build_default_block_header( diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index d82d31e5c4a..8d9cec7882c 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -24,7 +24,6 @@ Paris, Prague, Shanghai, - SpuriousDragon, ) from ..forks.transition import ( BerlinToLondonAt5, @@ -732,54 +731,3 @@ def test_eips() -> None: # noqa: D103 assert not Paris.is_eip_enabled(3675, 3855) assert not Paris.is_eip_enabled(3855, 3675) assert Shanghai.is_eip_enabled(3855) - - -def test_fork_variant_ordering() -> None: - """ - Variants from `with_env_gas_limit` must compare consistently with - their canonical parent: equal to the parent, ordered identically - against other canonical forks. - """ - variant = London.with_env_gas_limit(30_000_000) - - assert variant == London - assert hash(variant) == hash(London) - - assert variant > SpuriousDragon - assert variant >= SpuriousDragon - assert variant < Cancun - assert variant <= Cancun - - assert not (variant > London) - assert not (variant < London) - assert variant >= London - assert variant <= London - - -def test_transition_fork_variant_equality() -> None: - """ - Variants of a transition fork created via `with_env_gas_limit` must - compare equal to their canonical parent and to each other, even when - different gas limits are used. Distinct canonical transition forks - must remain unequal. - """ - canonical = CancunToPragueAtTime15k - variant_a = canonical.with_env_gas_limit(30_000_000) - variant_b = canonical.with_env_gas_limit(45_000_000) - variant_c = canonical.with_env_gas_limit(30_000_000) - - assert variant_a is not canonical - assert variant_a is not variant_b - assert variant_a is not variant_c - - assert variant_a == canonical - assert variant_b == canonical - assert variant_a == variant_b - assert variant_a == variant_c - - assert hash(variant_a) == hash(canonical) - assert hash(variant_b) == hash(canonical) - assert hash(variant_c) == hash(canonical) - - assert canonical != PragueToOsakaAtTime15k - assert variant_a != PragueToOsakaAtTime15k diff --git a/packages/testing/src/execution_testing/forks/transition_base_fork.py b/packages/testing/src/execution_testing/forks/transition_base_fork.py index 482b3c877ff..3dca0cb1d31 100644 --- a/packages/testing/src/execution_testing/forks/transition_base_fork.py +++ b/packages/testing/src/execution_testing/forks/transition_base_fork.py @@ -1,8 +1,8 @@ """Base objects used to define transition forks.""" -from typing import Any, Callable, ClassVar, Dict, Optional, Type +from typing import Any, Callable, ClassVar, Dict, Type -from .base_fork import BaseFork, BaseForkMeta +from .base_fork import BaseFork class TransitionBaseMetaClass(type): @@ -15,19 +15,6 @@ def name(cls) -> str: """ raise Exception("Not implemented") - def __eq__(cls, other: object) -> bool: - """ - Compare transition fork identity, treating variants created by - `with_env_gas_limit` as equal to their canonical parent. - """ - if not isinstance(other, type): - return NotImplemented - return BaseForkMeta._identity(cls) is BaseForkMeta._identity(other) - - def __hash__(cls) -> int: - """Hash by canonical transition fork identity.""" - return id(BaseForkMeta._identity(cls)) - def transitions_to(cls) -> Type[BaseFork]: """ Return fork where the transition ends. @@ -88,8 +75,6 @@ class TransitionBaseClass(metaclass=TransitionBaseMetaClass): at_block: ClassVar[int] = 0 at_timestamp: ClassVar[int] = 0 _ignore: ClassVar[bool] = False - _env_gas_limit: ClassVar[int] = 0 - _base_fork: ClassVar[Optional[Type["TransitionBaseClass"]]] = None @classmethod def fork_at( @@ -121,19 +106,6 @@ def ruleset(cls) -> Dict[str, int]: """ raise Exception("Not implemented") - @classmethod - def with_env_gas_limit( - cls, env_gas_limit: int - ) -> Type["TransitionBaseClass"]: - """ - Return a new transition fork class with the specified environment - gas limit. - """ - new_cls = type(cls.__name__, (cls,), {}) - new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] - new_cls._base_fork = cls._base_fork or cls # type: ignore[attr-defined] - return new_cls - def transition_fork( to_fork: Type[BaseFork], @@ -162,30 +134,23 @@ class NewTransitionClass( ): _ignore = ignore - @classmethod - def _propagate_env(cls, fork: Type[BaseFork]) -> Type[BaseFork]: - if cls._env_gas_limit: - return fork.with_env_gas_limit(cls._env_gas_limit) - return fork - @classmethod def transitions_to(cls) -> Type[BaseFork]: - return cls._propagate_env(to_fork) + return to_fork @classmethod def transitions_from(cls) -> Type[BaseFork]: - return cls._propagate_env(from_fork) + return from_fork @classmethod def fork_at( cls, *, block_number: int = 0, timestamp: int = 0 ) -> Type[BaseFork]: - fork = ( + return ( to_fork if block_number >= at_block and timestamp >= at_timestamp else from_fork ) - return cls._propagate_env(fork) @classmethod def name(cls) -> str: From 2eb175eb315281dcc7e260b1c802b5adca8a3abf Mon Sep 17 00:00:00 2001 From: raxhvl <10168946+raxhvl@users.noreply.github.com> Date: Mon, 11 May 2026 15:18:23 +0000 Subject: [PATCH 066/186] =?UTF-8?q?=F0=9F=A7=AA=20feat(tests):=20=20EIP-79?= =?UTF-8?q?28=20BAL=20test=20for=207702=20account=20call=20with=20low=20ba?= =?UTF-8?q?lance=20(#2824)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🧪 test: BAL test for 7702 account call with low balance * 🧹 chore: Lint * feat(test): parametrize warm/cold on 7702 insufficient bal tests; add to test_cases.md * feat(test): parametrize insufficient fund BALtest with 7702, warm/cold, CALL & CALLCODE --------- Co-authored-by: raxhvl Co-authored-by: fselmo --- .../test_block_access_lists_opcodes.py | 158 +++++++++++------- .../test_cases.md | 2 +- 2 files changed, 98 insertions(+), 62 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index 67f5aeda8ff..5b40643303b 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -2385,88 +2385,124 @@ def test_bal_create_contract_init_revert( ) +@pytest.mark.parametrize( + "delegated,target_is_warm,delegation_is_warm", + [ + pytest.param(False, False, False, id="no_delegation-cold_target"), + pytest.param(False, True, False, id="no_delegation-warm_target"), + pytest.param( + True, False, False, id="delegated-cold_target-cold_delegation" + ), + pytest.param( + True, True, False, id="delegated-warm_target-cold_delegation" + ), + pytest.param( + True, False, True, id="delegated-cold_target-warm_delegation" + ), + pytest.param( + True, True, True, id="delegated-warm_target-warm_delegation" + ), + ], +) +@pytest.mark.with_all_call_opcodes( + selector=lambda call_opcode: call_opcode in (Op.CALL, Op.CALLCODE) +) def test_bal_call_revert_insufficient_funds( pre: Alloc, blockchain_test: BlockchainTestFiller, + call_opcode: Op, + delegated: bool, + target_is_warm: bool, + delegation_is_warm: bool, ) -> None: """ - Test BAL with CALL failure due to insufficient balance (not OOG). + Test BAL with CALL/CALLCODE failure due to insufficient balance + (not OOG), with and without 7702 delegation. - Contract (balance=100): SLOAD(0x01)→CALL(target, value=1000)→SSTORE(0x02). - CALL fails because 1000 > 100. Target is 0xDEAD. + Caller (balance=100): SLOAD(0x01) → call_opcode(target, value=1000) + → SSTORE(0x02, result). The call fails because 1000 > 100. The + failure happens after delegation resolution, so when the target is + a 7702-delegated EOA both target and delegation target appear in + the BAL — distinct from the OOG case (see + test_bal_call_7702_delegation_and_oog) where the static-check + optimization keeps the delegation target out of the BAL. - Expected BAL: - - Contract: storage_reads [0x01], storage_changes slot 0x02 (value=0) - - Target: appears in BAL (accessed before balance check fails) + Access-list warming does NOT add to BAL on its own — only EVM + access does — so the BAL is identical across warm/cold variants. """ alice = pre.fund_eoa() - contract_balance = 100 - transfer_amount = 1000 # More than contract has + caller_balance = 100 + transfer_amount = 1000 # > caller_balance, transfer must fail + target_balance = 1 # non-zero balance keeps non-delegated target non-empty - # Target address that should be warmed but not receive funds - # Give it a small balance so it's not considered "empty" and pruned - target_balance = 1 - target_address = pre.fund_eoa(amount=target_balance) + delegation_target: Address | None = None + if delegated: + delegation_target = pre.deploy_contract(code=Op.STOP) + target = pre.fund_eoa( + amount=target_balance, delegation=delegation_target + ) + else: + target = pre.fund_eoa(amount=target_balance) - # Contract that: - # 1. SLOAD slot 0x01 - # 2. CALL target with value=1000 (will fail - insufficient funds) - # 3. SSTORE slot 0x02 with CALL result (0 = failure) - contract_code = ( - Op.SLOAD(0x01) # Read from slot 0x01, push to stack - + Op.POP # Discard value - # CALL(gas, addr, value, argsOffset, argsSize, retOffset, retSize) - + Op.CALL(100_000, target_address, transfer_amount, 0, 0, 0, 0) - # CALL result is on stack (0 = failure, 1 = success) - # Stack: [result] - + Op.PUSH1(0x02) # Push slot number - # Stack: [0x02, result] - + Op.SSTORE # SSTORE pops slot (0x02), then value (result) + caller_code = ( + Op.SLOAD(0x01) + + Op.POP + + call_opcode(100_000, target, transfer_amount, 0, 0, 0, 0) + + Op.PUSH1(0x02) + + Op.SSTORE + Op.STOP ) - contract = pre.deploy_contract( - code=contract_code, - balance=contract_balance, - storage={ - 0x02: 0xDEAD - }, # Non-zero initial value so SSTORE(0) is a change + caller = pre.deploy_contract( + code=caller_code, + balance=caller_balance, + storage={0x02: 0xDEAD}, # non-zero so SSTORE(0) is a change ) + access_list: list[AccessList] = [] + if target_is_warm: + access_list.append(AccessList(address=target, storage_keys=[])) + if delegated and delegation_is_warm: + assert delegation_target is not None + access_list.append( + AccessList(address=delegation_target, storage_keys=[]) + ) + tx = Transaction( sender=alice, - to=contract, + to=caller, gas_limit=1_000_000, + access_list=access_list, ) + account_expectations: Dict[Address, BalAccountExpectation] = { + alice: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + ), + caller: BalAccountExpectation( + storage_reads=[0x01], + storage_changes=[ + BalStorageSlot( + slot=0x02, + slot_changes=[ + BalStorageChange(block_access_index=1, post_value=0) + ], + ) + ], + ), + # Target accessed before balance check fails. + target: BalAccountExpectation.empty(), + } + if delegated: + assert delegation_target is not None + # Delegation resolved before balance check fails. + account_expectations[delegation_target] = BalAccountExpectation.empty() + block = Block( txs=[tx], expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - alice: BalAccountExpectation( - nonce_changes=[ - BalNonceChange(block_access_index=1, post_nonce=1) - ], - ), - contract: BalAccountExpectation( - # Storage read for slot 0x01 - storage_reads=[0x01], - # Storage change for slot 0x02 (CALL result = 0) - storage_changes=[ - BalStorageSlot( - slot=0x02, - slot_changes=[ - BalStorageChange( - block_access_index=1, post_value=0 - ) - ], - ) - ], - ), - # Target appears in BAL - accessed before balance check fails - target_address: BalAccountExpectation.empty(), - } + account_expectations=account_expectations ), ) @@ -2475,11 +2511,11 @@ def test_bal_call_revert_insufficient_funds( blocks=[block], post={ alice: Account(nonce=1), - contract: Account( - balance=contract_balance, # Unchanged - transfer failed - storage={0x02: 0}, # CALL returned 0 (failure) + caller: Account( + balance=caller_balance, # unchanged - transfer failed + storage={0x02: 0}, # Failed call returned 0 ), - target_address: Account(balance=target_balance), # Unchanged + target: Account(balance=target_balance), # unchanged }, ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index bd89ac5f66b..6d990d5b3e2 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -111,7 +111,7 @@ | `test_bal_create2_collision` | Ensure BAL handles CREATE2 address collision correctly | Factory contract (nonce=1, storage slot 0=0xDEAD) executes `CREATE2(salt=0, initcode)` targeting address that already has `code=STOP, nonce=1`. Pre-deploy contract at calculated CREATE2 target address before factory deployment. | BAL **MUST** include: (1) Factory with `nonce_changes` (1→2, incremented even on failed CREATE2), `storage_changes` for slot 0 (0xDEAD→0, stores failure). (2) Collision address with empty changes (accessed during collision check, no state changes). CREATE2 returns 0. Collision address **MUST NOT** have `nonce_changes` or `code_changes`. | ✅ Completed | | `test_bal_create_selfdestruct_to_self_with_call` | Ensure BAL handles init code that calls external contract then selfdestructs to itself | Factory executes `CREATE2` with endowment=100. Init code (embedded in factory via CODECOPY): (1) `CALL(Oracle, 0)` - Oracle writes to its storage slot 0x01. (2) `SSTORE(0x01, 0x42)` - write to own storage. (3) `SELFDESTRUCT(SELF)` - selfdestruct to own address. Contract created and destroyed in same tx. | BAL **MUST** include: (1) Factory with `nonce_changes`, `balance_changes` (loses 100). (2) Oracle with `storage_changes` for slot 0x01 (external call succeeded). (3) Created address with `storage_reads` for slot 0x01 (aborted write becomes read) - **MUST NOT** have `nonce_changes`, `code_changes`, `storage_changes`, or `balance_changes` (ephemeral contract, balance burned via SELFDESTRUCT to self). | ✅ Completed | | `test_bal_selfdestruct_to_7702_delegation` | Ensure BAL correctly handles SELFDESTRUCT to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Tx2: Victim contract (balance=100) executes `SELFDESTRUCT(Alice)`. Two separate transactions in same block. Note: Alice starts with initial balance which accumulates with selfdestruct. | BAL **MUST** include: (1) Alice at block_access_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at block_access_index=2 with `balance_changes` (receives selfdestruct). (3) Victim at block_access_index=2 with `balance_changes` (100→0). **Oracle MUST NOT appear in tx2** - per EVM spec, SELFDESTRUCT transfers balance without executing recipient code, so delegation target is never accessed. | ✅ Completed | -| `test_bal_call_revert_insufficient_funds` | Ensure BAL handles CALL failure due to insufficient balance (not OOG) | Contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), CALL(target, value=1000), SSTORE(0x02, result)`. CALL fails because 1000 > 100. Target address 0xDEAD (pre-existing with non-zero balance to avoid pruning). Note: slot 0x02 must start non-zero so SSTORE(0) is a change. | BAL **MUST** include: (1) Contract with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, CALL returned failure). (2) Target (0xDEAD) **MUST** appear in BAL with empty changes - target is accessed before balance check fails. | ✅ Completed | +| `test_bal_call_revert_insufficient_funds` | Ensure BAL handles value-transferring call failure due to insufficient balance (not OOG), with and without 7702 delegation | Caller contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), call_opcode(target, value=1000), SSTORE(0x02, result)`. The call fails because 1000 > 100. Parametrized: (1) `call_opcode` over CALL and CALLCODE via `with_all_call_opcodes(selector=...)`, (2) `delegated` (target is plain EOA vs. 7702-delegated EOA pointing to `delegation_target`=STOP), (3) `target_is_warm` (cold/warm via EIP-2930 access list), (4) `delegation_is_warm` (only when delegated). | BAL **MUST** include: (1) Caller with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, call returned failure). (2) Target with empty changes - accessed before balance check fails. (3) When delegated: `delegation_target` with empty changes - delegation is loaded before balance check fails (unlike the OOG cases in `test_bal_call_7702_delegation_and_oog` where the static-check optimization avoids the delegation load). Access-list warming does NOT add to BAL on its own, so the BAL is identical across warm/cold variants. | ✅ Completed | | `test_bal_lexicographic_address_ordering` | Ensure BAL enforces strict lexicographic byte-wise ordering | Pre-fund three addresses with specific byte patterns: `addr_low = 0x0000...0001`, `addr_mid = 0x0000...0100`, `addr_high = 0x0100...0000`. Contract touches them in reverse order: `BALANCE(addr_high), BALANCE(addr_low), BALANCE(addr_mid)`. Additionally, include two endian-trap addresses that are byte-reversals of each other: `addr_endian_low = 0x0100000000000000000000000000000000000002`, `addr_endian_high = 0x0200000000000000000000000000000000000001`. Note: `reverse(addr_endian_low) = addr_endian_high`. Correct lexicographic order: `addr_endian_low < addr_endian_high` (0x01 < 0x02 at byte 0). If implementation incorrectly reverses bytes before comparing, it would get `addr_endian_low > addr_endian_high` (wrong). | BAL account list **MUST** be sorted lexicographically by address bytes: `addr_low` < `addr_mid` < `addr_high` < `addr_endian_low` < `addr_endian_high`, regardless of access order. The endian-trap addresses specifically catch byte-reversal bugs where addresses are compared with wrong byte order. Complements `test_bal_invalid_account_order` which tests rejection; this tests correct generation. | ✅ Completed | | `test_bal_gas_limit_boundary` | Ensure BAL max items gas limit boundary is enforced for empty blocks | Empty block with gas limit set to the exact boundary where `bal_items <= block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM`. Parameterized: (1) at_boundary (gas limit = exact minimum, passes), (2) below_boundary (gas limit = exact minimum - 1, fails). | At boundary: block **MUST** be accepted. Below boundary: block **MUST** be rejected with `BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED` exception. | ✅ Completed | | `test_bal_transient_storage_not_tracked` | Ensure BAL excludes EIP-1153 transient storage operations | Contract executes: `TSTORE(0x01, 0x42)` (transient write), `TLOAD(0x01)` (transient read), `SSTORE(0x02, result)` (persistent write using transient value). | BAL **MUST** include slot 0x02 in `storage_changes` (persistent storage was modified). BAL **MUST NOT** include slot 0x01 in `storage_reads` or `storage_changes` (transient storage is not persisted, not needed for stateless execution). This verifies TSTORE/TLOAD don't pollute BAL. | ✅ Completed | From f3557261908f5dea21bbcab2f49ca3bec13c7869 Mon Sep 17 00:00:00 2001 From: spencer Date: Mon, 11 May 2026 18:21:34 +0100 Subject: [PATCH 067/186] chore(tests): stop mutating parametrize values in EL request helpers (#2833) * chore(tests): stop mutating parametrize values in EL request helpers * fix(tests): Review comments --------- Co-authored-by: marioevz --- .../test_block_access_lists_eip7002.py | 20 ++++---- .../test_block_access_lists_eip7251.py | 4 +- .../test_tstorage_selfdestruct.py | 4 +- tests/prague/eip6110_deposits/conftest.py | 21 +++++---- tests/prague/eip6110_deposits/helpers.py | 47 ++++++++++++------- .../conftest.py | 31 +++++++----- .../helpers.py | 47 ++++++++++++------- .../test_modified_withdrawal_contract.py | 4 +- .../test_withdrawal_requests.py | 7 ++- .../prague/eip7251_consolidations/conftest.py | 27 ++++++----- .../prague/eip7251_consolidations/helpers.py | 47 ++++++++++++------- .../test_consolidations.py | 7 ++- .../test_modified_consolidation_contract.py | 4 +- .../conftest.py | 6 +-- 14 files changed, 160 insertions(+), 116 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7002.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7002.py index 6a23cd6bb24..907dc6ce099 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7002.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7002.py @@ -542,18 +542,18 @@ def test_bal_7002_request_from_contract( ) # Set up pre-state using helper - interaction.update_pre(pre) + prepared = interaction.update_pre(pre) - alice = interaction.sender_account - relay_contract = interaction.contract_address + alice = prepared.sender_account + relay_contract = prepared.contract_address # Build queue storage slots with contract as source queue_writes, queue_reads = _build_queue_storage_slots( - [relay_contract], interaction.requests + [relay_contract], prepared.requests ) block = Block( - txs=interaction.transactions(), + txs=prepared.transactions(), expected_block_access_list=BlockAccessListExpectation( account_expectations={ alice: BalAccountExpectation( @@ -766,9 +766,9 @@ def test_bal_7002_request_invalid( - No withdrawal request is queued """ # Use helper to set up pre-state and get transaction - interaction.update_pre(pre) - tx = interaction.transactions()[0] - alice = interaction.sender_account + prepared = interaction.update_pre(pre) + tx = prepared.transactions()[0] + alice = prepared.sender_account # Build account expectations account_expectations = { @@ -801,8 +801,8 @@ def test_bal_7002_request_invalid( } # Add relay contract to post-state for contract scenarios - if isinstance(interaction, WithdrawalRequestContract): - post[interaction.contract_address] = Account() + if isinstance(prepared, WithdrawalRequestContract): + post[prepared.contract_address] = Account() blockchain_test( pre=pre, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7251.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7251.py index c6be6cdecdd..35494f4207f 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7251.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7251.py @@ -102,8 +102,8 @@ def test_bal_system_dequeue_consolidations_eip7251( txs = [] for request in blocks_consolidation_requests: - request.update_pre(pre=pre) - txs += request.transactions() + prepared = request.update_pre(pre=pre) + txs += prepared.transactions() num = len(txs) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_selfdestruct.py b/tests/cancun/eip1153_tstore/test_tstorage_selfdestruct.py index b4fff4152d8..b1d9cd3d1cf 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_selfdestruct.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_selfdestruct.py @@ -276,9 +276,9 @@ def test_reentrant_selfdestructing_call( data=data, ) - expected_storage[0] = callee_address + post_storage = {**expected_storage, 0: callee_address} - post: Dict = {caller_address: Account(storage=expected_storage)} + post: Dict = {caller_address: Account(storage=post_storage)} if pre_existing_contract: post[callee_address] = Account(code=callee_bytecode) diff --git a/tests/prague/eip6110_deposits/conftest.py b/tests/prague/eip6110_deposits/conftest.py index 5d1ce9f296e..6e50c4f2e36 100644 --- a/tests/prague/eip6110_deposits/conftest.py +++ b/tests/prague/eip6110_deposits/conftest.py @@ -17,23 +17,24 @@ @pytest.fixture -def update_pre(pre: Alloc, requests: List[DepositInteractionBase]) -> None: +def prepared_requests( + pre: Alloc, requests: List[DepositInteractionBase] +) -> List[DepositInteractionBase]: """ - Init state of the accounts. Every deposit transaction defines their own - pre-state requirements, and this fixture aggregates them all. + Allocate accounts/contracts for each request in `pre` and return copies + with the allocated state populated. The parametrize value `requests` is + not mutated, so it stays pristine across fixture format runs. """ - for d in requests: - d.update_pre(pre) + return [r.update_pre(pre) for r in requests] @pytest.fixture def txs( - requests: List[DepositInteractionBase], - update_pre: None, # Fixture is used for its side effects + prepared_requests: List[DepositInteractionBase], ) -> List[Transaction]: """List of transactions to include in the block.""" txs = [] - for r in requests: + for r in prepared_requests: txs += r.transactions() return txs @@ -55,14 +56,14 @@ def exception() -> BlockException | None: @pytest.fixture def included_requests( - requests: List[DepositInteractionBase], + prepared_requests: List[DepositInteractionBase], ) -> List[DepositRequest]: """ Return the list of deposit requests that should be included in each block. """ valid_requests: List[DepositRequest] = [] - for d in requests: + for d in prepared_requests: valid_requests += d.valid_requests(10**18) return valid_requests diff --git a/tests/prague/eip6110_deposits/helpers.py b/tests/prague/eip6110_deposits/helpers.py index d898b031c93..e20b7b64966 100644 --- a/tests/prague/eip6110_deposits/helpers.py +++ b/tests/prague/eip6110_deposits/helpers.py @@ -1,9 +1,9 @@ """Helpers for the EIP-6110 deposit tests.""" -from dataclasses import dataclass, field +from dataclasses import dataclass, field, replace from functools import cached_property from hashlib import sha256 as sha256_hashlib -from typing import Callable, ClassVar, List +from typing import Callable, ClassVar, List, Self from execution_testing import ( EOA, @@ -214,7 +214,7 @@ def with_source_address(self, source_address: Address) -> "DepositRequest": return self.copy() -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class DepositInteractionBase: """Base class for all types of deposit transactions we want to test.""" @@ -229,8 +229,12 @@ def transactions(self) -> List[Transaction]: """Return a transaction for the deposit request.""" raise NotImplementedError - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" + def update_pre(self, pre: Alloc) -> Self: + """ + Allocate accounts/contracts in `pre` and return a new instance with + the allocated state populated. Does not mutate `self`, so the + parametrize value remains pristine across fixture format runs. + """ raise NotImplementedError def valid_requests(self, current_minimum_fee: int) -> List[DepositRequest]: @@ -241,7 +245,7 @@ def valid_requests(self, current_minimum_fee: int) -> List[DepositRequest]: raise NotImplementedError -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class DepositTransaction(DepositInteractionBase): """ Class used to describe a deposit originated from an externally owned @@ -265,9 +269,9 @@ def transactions(self) -> List[Transaction]: for request in self.requests ] - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" - self.sender_account = pre.fund_eoa(self.sender_balance) + def update_pre(self, pre: Alloc) -> Self: + """Return a copy of self with `sender_account` populated.""" + return replace(self, sender_account=pre.fund_eoa(self.sender_balance)) def valid_requests(self, current_minimum_fee: int) -> List[DepositRequest]: """ @@ -281,7 +285,7 @@ def valid_requests(self, current_minimum_fee: int) -> List[DepositRequest]: ] -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class DepositContract(DepositInteractionBase): """Class used to describe a deposit originated from a contract.""" @@ -347,26 +351,29 @@ def transactions(self) -> List[Transaction]: ) ] - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" + def update_pre(self, pre: Alloc) -> Self: + """ + Return a copy of self with the allocated sender/contract/entry + addresses populated. + """ required_balance = self.sender_balance if self.tx_value > 0: required_balance = max( required_balance, self.tx_value + self.tx_gas_limit * 7 ) - self.sender_account = pre.fund_eoa(required_balance) - self.contract_address = pre.deploy_contract( + sender_account = pre.fund_eoa(required_balance) + contract_address = pre.deploy_contract( code=self.contract_code, balance=self.contract_balance ) - self.entry_address = self.contract_address + entry_address = contract_address if self.call_depth > 2: for _ in range(1, self.call_depth - 1): - self.entry_address = pre.deploy_contract( + entry_address = pre.deploy_contract( code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + Op.POP( Op.CALL( Op.GAS, - self.entry_address, + entry_address, 0, 0, Op.CALLDATASIZE, @@ -375,6 +382,12 @@ def update_pre(self, pre: Alloc) -> None: ) ), ) + return replace( + self, + sender_account=sender_account, + contract_address=contract_address, + entry_address=entry_address, + ) def valid_requests(self, current_minimum_fee: int) -> List[DepositRequest]: """ diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/conftest.py b/tests/prague/eip7002_el_triggerable_withdrawals/conftest.py index c89022c96e0..de1eebb28f4 100644 --- a/tests/prague/eip7002_el_triggerable_withdrawals/conftest.py +++ b/tests/prague/eip7002_el_triggerable_withdrawals/conftest.py @@ -18,23 +18,27 @@ @pytest.fixture -def update_pre( +def prepared_blocks_withdrawal_requests( pre: Alloc, blocks_withdrawal_requests: List[List[WithdrawalRequestInteractionBase]], -) -> None: +) -> List[List[WithdrawalRequestInteractionBase]]: """ - Init state of the accounts. Every deposit transaction defines their own - pre-state requirements, and this fixture aggregates them all. + Allocate accounts/contracts for each interaction in `pre` and return + copies with the allocated state populated. The parametrize value + `blocks_withdrawal_requests` is not mutated, so it stays pristine across + fixture format runs. """ - for requests in blocks_withdrawal_requests: - for r in requests: - r.update_pre(pre) + return [ + [r.update_pre(pre) for r in block_requests] + for block_requests in blocks_withdrawal_requests + ] @pytest.fixture def included_requests( - update_pre: None, # Fixture is used for its side effects - blocks_withdrawal_requests: List[List[WithdrawalRequestInteractionBase]], + prepared_blocks_withdrawal_requests: List[ + List[WithdrawalRequestInteractionBase] + ], ) -> List[List[WithdrawalRequest]]: """ Return the list of withdrawal requests that should be included in each @@ -43,7 +47,7 @@ def included_requests( excess_withdrawal_requests = 0 carry_over_requests: List[WithdrawalRequest] = [] per_block_included_requests: List[List[WithdrawalRequest]] = [] - for block_withdrawal_requests in blocks_withdrawal_requests: + for block_withdrawal_requests in prepared_blocks_withdrawal_requests: # Get fee for the current block current_minimum_fee = Spec.get_fee(excess_withdrawal_requests) @@ -87,8 +91,9 @@ def timestamp() -> int: @pytest.fixture def blocks( fork: Fork | TransitionFork, - update_pre: None, # Fixture is used for its side effects - blocks_withdrawal_requests: List[List[WithdrawalRequestInteractionBase]], + prepared_blocks_withdrawal_requests: List[ + List[WithdrawalRequestInteractionBase] + ], included_requests: List[List[WithdrawalRequest]], timestamp: int, ) -> List[Block]: @@ -96,7 +101,7 @@ def blocks( blocks: List[Block] = [] for block_requests, block_included_requests in zip_longest( # type: ignore - blocks_withdrawal_requests, + prepared_blocks_withdrawal_requests, included_requests, fillvalue=[], ): diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/helpers.py b/tests/prague/eip7002_el_triggerable_withdrawals/helpers.py index feed63299f1..2c2e37b137e 100644 --- a/tests/prague/eip7002_el_triggerable_withdrawals/helpers.py +++ b/tests/prague/eip7002_el_triggerable_withdrawals/helpers.py @@ -1,9 +1,9 @@ """Helpers for the EIP-7002 withdrawal tests.""" -from dataclasses import dataclass, field +from dataclasses import dataclass, field, replace from functools import cached_property from itertools import count -from typing import Callable, ClassVar, List +from typing import Callable, ClassVar, List, Self from execution_testing import ( EOA, @@ -69,7 +69,7 @@ def with_source_address( return self.copy(source_address=source_address) -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class WithdrawalRequestInteractionBase: """Base class for all types of withdrawal transactions we want to test.""" @@ -84,8 +84,12 @@ def transactions(self) -> List[Transaction]: """Return a transaction for the withdrawal request.""" raise NotImplementedError - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" + def update_pre(self, pre: Alloc) -> Self: + """ + Allocate accounts/contracts in `pre` and return a new instance with + the allocated state populated. Does not mutate `self`, so the + parametrize value remains pristine across fixture format runs. + """ raise NotImplementedError def valid_requests( @@ -98,7 +102,7 @@ def valid_requests( raise NotImplementedError -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class WithdrawalRequestTransaction(WithdrawalRequestInteractionBase): """ Class used to describe a withdrawal request originated from an externally @@ -122,9 +126,9 @@ def transactions(self) -> List[Transaction]: for request in self.requests ] - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" - self.sender_account = pre.fund_eoa(self.sender_balance) + def update_pre(self, pre: Alloc) -> Self: + """Return a copy of self with `sender_account` populated.""" + return replace(self, sender_account=pre.fund_eoa(self.sender_balance)) def valid_requests( self, current_minimum_fee: int @@ -140,7 +144,7 @@ def valid_requests( ] -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class WithdrawalRequestContract(WithdrawalRequestInteractionBase): """Class used to describe a withdrawal originated from a contract.""" @@ -204,21 +208,24 @@ def transactions(self) -> List[Transaction]: ) ] - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" - self.sender_account = pre.fund_eoa(self.sender_balance) - self.contract_address = pre.deploy_contract( + def update_pre(self, pre: Alloc) -> Self: + """ + Return a copy of self with the allocated sender/contract/entry + addresses populated. + """ + sender_account = pre.fund_eoa(self.sender_balance) + contract_address = pre.deploy_contract( code=self.contract_code, balance=self.contract_balance ) - self.entry_address = self.contract_address + entry_address = contract_address if self.call_depth > 2: for _ in range(1, self.call_depth - 1): - self.entry_address = pre.deploy_contract( + entry_address = pre.deploy_contract( code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + Op.POP( Op.CALL( Op.GAS, - self.entry_address, + entry_address, 0, 0, Op.CALLDATASIZE, @@ -227,6 +234,12 @@ def update_pre(self, pre: Alloc) -> None: ) ) ) + return replace( + self, + sender_account=sender_account, + contract_address=contract_address, + entry_address=entry_address, + ) def valid_requests( self, current_minimum_fee: int diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/test_modified_withdrawal_contract.py b/tests/prague/eip7002_el_triggerable_withdrawals/test_modified_withdrawal_contract.py index 8e83c06fdbc..7a5aeb5cb11 100644 --- a/tests/prague/eip7002_el_triggerable_withdrawals/test_modified_withdrawal_contract.py +++ b/tests/prague/eip7002_el_triggerable_withdrawals/test_modified_withdrawal_contract.py @@ -124,9 +124,9 @@ def test_extra_withdrawals( requests=requests_list ) # prepare withdrawal senders - withdrawal_request_transaction.update_pre(pre=pre) + prepared = withdrawal_request_transaction.update_pre(pre=pre) # get transaction list - txs: List[Transaction] = withdrawal_request_transaction.transactions() + txs: List[Transaction] = prepared.transactions() blockchain_test( pre=pre, diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/test_withdrawal_requests.py b/tests/prague/eip7002_el_triggerable_withdrawals/test_withdrawal_requests.py index 6bdeaa5a1f7..54417965417 100644 --- a/tests/prague/eip7002_el_triggerable_withdrawals/test_withdrawal_requests.py +++ b/tests/prague/eip7002_el_triggerable_withdrawals/test_withdrawal_requests.py @@ -847,13 +847,12 @@ def test_withdrawal_requests_negative( Test blocks where the requests list and the actual withdrawal requests that happened in the block's transactions do not match. """ - for d in requests: - d.update_pre(pre) + prepared = [d.update_pre(pre) for d in requests] # No previous block so fee is the base fee = 1 current_block_requests = [] - for w in requests: + for w in prepared: current_block_requests += w.valid_requests(fee) included_requests = current_block_requests[ : Spec.MAX_WITHDRAWAL_REQUESTS_PER_BLOCK @@ -865,7 +864,7 @@ def test_withdrawal_requests_negative( post={}, blocks=[ Block( - txs=sum((r.transactions() for r in requests), []), + txs=sum((r.transactions() for r in prepared), []), header_verify=Header( requests_hash=Requests( *included_requests, diff --git a/tests/prague/eip7251_consolidations/conftest.py b/tests/prague/eip7251_consolidations/conftest.py index 27f7816aeb0..083047e0377 100644 --- a/tests/prague/eip7251_consolidations/conftest.py +++ b/tests/prague/eip7251_consolidations/conftest.py @@ -18,25 +18,27 @@ @pytest.fixture -def update_pre( +def prepared_blocks_consolidation_requests( pre: Alloc, blocks_consolidation_requests: List[ List[ConsolidationRequestInteractionBase] ], -) -> None: +) -> List[List[ConsolidationRequestInteractionBase]]: """ - Init state of the accounts. Every consolidation request defines its own - pre-state requirements, and this fixture aggregates them all. + Allocate accounts/contracts for each interaction in `pre` and return + copies with the allocated state populated. The parametrize value + `blocks_consolidation_requests` is not mutated, so it stays pristine + across fixture format runs. """ - for requests in blocks_consolidation_requests: - for r in requests: - r.update_pre(pre) + return [ + [r.update_pre(pre) for r in block_requests] + for block_requests in blocks_consolidation_requests + ] @pytest.fixture def included_requests( - update_pre: None, # Fixture is used for its side effects - blocks_consolidation_requests: List[ + prepared_blocks_consolidation_requests: List[ List[ConsolidationRequestInteractionBase] ], ) -> List[List[ConsolidationRequest]]: @@ -47,7 +49,7 @@ def included_requests( excess_consolidation_requests = 0 carry_over_requests: List[ConsolidationRequest] = [] per_block_included_requests: List[List[ConsolidationRequest]] = [] - for block_consolidation_requests in blocks_consolidation_requests: + for block_consolidation_requests in prepared_blocks_consolidation_requests: # Get fee for the current block current_minimum_fee = Spec.get_fee(excess_consolidation_requests) @@ -93,8 +95,7 @@ def timestamp() -> int: @pytest.fixture def blocks( fork: Fork | TransitionFork, - update_pre: None, # Fixture is used for its side effects - blocks_consolidation_requests: List[ + prepared_blocks_consolidation_requests: List[ List[ConsolidationRequestInteractionBase] ], included_requests: List[List[ConsolidationRequest]], @@ -104,7 +105,7 @@ def blocks( blocks: List[Block] = [] for block_requests, block_included_requests in zip_longest( # type: ignore - blocks_consolidation_requests, + prepared_blocks_consolidation_requests, included_requests, fillvalue=[], ): diff --git a/tests/prague/eip7251_consolidations/helpers.py b/tests/prague/eip7251_consolidations/helpers.py index dc55ee09347..f42d6934e42 100644 --- a/tests/prague/eip7251_consolidations/helpers.py +++ b/tests/prague/eip7251_consolidations/helpers.py @@ -1,9 +1,9 @@ """Helpers for the EIP-7251 consolidation tests.""" -from dataclasses import dataclass, field +from dataclasses import dataclass, field, replace from functools import cached_property from itertools import count -from typing import Callable, ClassVar, List +from typing import Callable, ClassVar, List, Self from execution_testing import ( EOA, @@ -62,7 +62,7 @@ def with_source_address( return self.copy(source_address=source_address) -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class ConsolidationRequestInteractionBase: """ Base class for all types of consolidation transactions we want to test. @@ -79,8 +79,12 @@ def transactions(self) -> List[Transaction]: """Return a transaction for the consolidation request.""" raise NotImplementedError - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" + def update_pre(self, pre: Alloc) -> Self: + """ + Allocate accounts/contracts in `pre` and return a new instance with + the allocated state populated. Does not mutate `self`, so the + parametrize value remains pristine across fixture format runs. + """ raise NotImplementedError def valid_requests( @@ -93,7 +97,7 @@ def valid_requests( raise NotImplementedError -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class ConsolidationRequestTransaction(ConsolidationRequestInteractionBase): """ Class to describe a consolidation request originated from an externally @@ -117,9 +121,9 @@ def transactions(self) -> List[Transaction]: for request in self.requests ] - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" - self.sender_account = pre.fund_eoa(self.sender_balance) + def update_pre(self, pre: Alloc) -> Self: + """Return a copy of self with `sender_account` populated.""" + return replace(self, sender_account=pre.fund_eoa(self.sender_balance)) def valid_requests( self, current_minimum_fee: int @@ -135,7 +139,7 @@ def valid_requests( ] -@dataclass(kw_only=True) +@dataclass(kw_only=True, frozen=True) class ConsolidationRequestContract(ConsolidationRequestInteractionBase): """Class used to describe a consolidation originated from a contract.""" @@ -199,21 +203,24 @@ def transactions(self) -> List[Transaction]: ) ] - def update_pre(self, pre: Alloc) -> None: - """Return the pre-state of the account.""" - self.sender_account = pre.fund_eoa(self.sender_balance) - self.contract_address = pre.deploy_contract( + def update_pre(self, pre: Alloc) -> Self: + """ + Return a copy of self with the allocated sender/contract/entry + addresses populated. + """ + sender_account = pre.fund_eoa(self.sender_balance) + contract_address = pre.deploy_contract( code=self.contract_code, balance=self.contract_balance ) - self.entry_address = self.contract_address + entry_address = contract_address if self.call_depth > 2: for _ in range(1, self.call_depth - 1): - self.entry_address = pre.deploy_contract( + entry_address = pre.deploy_contract( code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + Op.POP( Op.CALL( Op.GAS, - self.entry_address, + entry_address, 0, 0, Op.CALLDATASIZE, @@ -222,6 +229,12 @@ def update_pre(self, pre: Alloc) -> None: ) ) ) + return replace( + self, + sender_account=sender_account, + contract_address=contract_address, + entry_address=entry_address, + ) def valid_requests( self, current_minimum_fee: int diff --git a/tests/prague/eip7251_consolidations/test_consolidations.py b/tests/prague/eip7251_consolidations/test_consolidations.py index 52eb22c57ef..4e276039e87 100644 --- a/tests/prague/eip7251_consolidations/test_consolidations.py +++ b/tests/prague/eip7251_consolidations/test_consolidations.py @@ -884,13 +884,12 @@ def test_consolidation_requests_negative( Test blocks where the requests list and the actual consolidation requests that happened in the block's transactions do not match. """ - for d in requests: - d.update_pre(pre) + prepared = [d.update_pre(pre) for d in requests] # No previous block so fee is the base fee = 1 current_block_requests = [] - for w in requests: + for w in prepared: current_block_requests += w.valid_requests(fee) included_requests = current_block_requests[ : Spec.MAX_CONSOLIDATION_REQUESTS_PER_BLOCK @@ -902,7 +901,7 @@ def test_consolidation_requests_negative( post={}, blocks=[ Block( - txs=sum((r.transactions() for r in requests), []), + txs=sum((r.transactions() for r in prepared), []), header_verify=Header( requests_hash=Requests(*included_requests), ), diff --git a/tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py b/tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py index fce87399467..eb1fe9cfc28 100644 --- a/tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py +++ b/tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py @@ -125,9 +125,9 @@ def test_extra_consolidations( requests=requests_list ) # prepare consolidation senders - consolidation_request_transaction.update_pre(pre=pre) + prepared = consolidation_request_transaction.update_pre(pre=pre) # get transaction list - txs: List[Transaction] = consolidation_request_transaction.transactions() + txs: List[Transaction] = prepared.transactions() blockchain_test( pre=pre, diff --git a/tests/prague/eip7685_general_purpose_el_requests/conftest.py b/tests/prague/eip7685_general_purpose_el_requests/conftest.py index b832895cda3..79bef284f42 100644 --- a/tests/prague/eip7685_general_purpose_el_requests/conftest.py +++ b/tests/prague/eip7685_general_purpose_el_requests/conftest.py @@ -97,8 +97,8 @@ def blocks( # Single block therefore base fee withdrawal_request_fee = 1 consolidation_request_fee = 1 - for r in requests: - r.update_pre(pre) + prepared = [r.update_pre(pre) for r in requests] + for r in prepared: if isinstance(r, DepositInteractionBase): valid_requests_list += r.valid_requests(10**18) elif isinstance(r, WithdrawalRequestInteractionBase): @@ -115,7 +115,7 @@ def blocks( ) return [ Block( - txs=sum((r.transactions() for r in requests), []), + txs=sum((r.transactions() for r in prepared), []), header_verify=Header(requests_hash=valid_requests), requests=block_body_override_requests, exception=exception, From c29f8949da4041dd139405e328e94e637add1b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Mon, 11 May 2026 20:00:27 +0200 Subject: [PATCH 068/186] refactor(test-benchmark): precompile input parameter format (#2817) * refactor: precompile input parameter display * fix: linting issue * chore: remove redundant type conversion --- .../compute/precompile/test_alt_bn128.py | 635 ++++++++++-------- .../compute/precompile/test_bls12_381.py | 82 +-- .../compute/precompile/test_ecrecover.py | 22 +- .../compute/precompile/test_identity.py | 19 +- .../compute/precompile/test_modexp.py | 2 +- .../compute/precompile/test_p256verify.py | 76 ++- .../precompile/test_point_evaluation.py | 37 +- .../compute/precompile/test_ripemd160.py | 24 +- .../compute/precompile/test_sha256.py | 24 +- tests/cancun/eip4844_blobs/spec.py | 31 +- tests/frontier/identity_precompile/spec.py | 12 + tests/frontier/precompiles/spec.py | 34 + 12 files changed, 581 insertions(+), 417 deletions(-) create mode 100644 tests/frontier/identity_precompile/spec.py create mode 100644 tests/frontier/precompiles/spec.py diff --git a/tests/benchmark/compute/precompile/test_alt_bn128.py b/tests/benchmark/compute/precompile/test_alt_bn128.py index d95345f5132..9d2943b2e7f 100644 --- a/tests/benchmark/compute/precompile/test_alt_bn128.py +++ b/tests/benchmark/compute/precompile/test_alt_bn128.py @@ -19,36 +19,50 @@ WhileGas, ) from py_ecc.bn128 import G1, G2, multiply +from py_ecc.fields import bn128_FQ2 -from ..helpers import Precompile, concatenate_parameters +from tests.benchmark.compute.helpers import Precompile +from tests.byzantium.eip196_ec_add_mul.spec import ( + PointG1, + Scalar, +) +from tests.byzantium.eip196_ec_add_mul.spec import ( + Spec as EIP196Spec, +) +from tests.byzantium.eip197_ec_pairing.spec import ( + PointG2, +) +from tests.byzantium.eip197_ec_pairing.spec import ( + Spec as EIP197Spec, +) @pytest.mark.parametrize( "precompile_address,calldata,target", [ pytest.param( - 0x06, - concatenate_parameters( - [ - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - "07C2B7F58A84BD6145F00C9C2BC0BB1A187F20FF2C92963A88019E7C6A014EED", - "06614E20C147E940F2D70DA3F74C9A17DF361706A4485C742BD6788478FA17D7", - ] + EIP196Spec.ECADD, + PointG1( + x=0x18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9, + y=0x063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266, + ) + + PointG1( + x=0x07C2B7F58A84BD6145F00C9C2BC0BB1A187F20FF2C92963A88019E7C6A014EED, + y=0x06614E20C147E940F2D70DA3F74C9A17DF361706A4485C742BD6788478FA17D7, ), Precompile.BN128_ADD, id="bn128_add", marks=pytest.mark.repricing, ), pytest.param( - 0x06, - concatenate_parameters( - [ - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - ] + EIP196Spec.ECADD, + PointG1( + x=0x18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9, + y=0x063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266, + ) + + PointG1( + x=0x18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9, + y=0x063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266, ), Precompile.BN128_ADD, id="bn128_double", @@ -56,14 +70,14 @@ ), # Second point is the negative of the first one pytest.param( - 0x06, - concatenate_parameters( - [ - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "2A27BDD69A111C1D033CF8FC8BE1B1142229D40FD218F75E401363953F898AE1", - ] + EIP196Spec.ECADD, + PointG1( + x=0x18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9, + y=0x063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266, + ) + + PointG1( + x=0x18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9, + y=0x2A27BDD69A111C1D033CF8FC8BE1B1142229D40FD218F75E401363953F898AE1, ), Precompile.BN128_ADD, id="bn128_add_negative", @@ -72,15 +86,8 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L326 pytest.param( - 0x06, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - ] - ), + EIP196Spec.ECADD, + EIP196Spec.INF_G1 + EIP196Spec.INF_G1, Precompile.BN128_ADD, id="bn128_add_infinities", marks=pytest.mark.repricing, @@ -88,26 +95,19 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L329 pytest.param( - 0x06, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000001", - "0000000000000000000000000000000000000000000000000000000000000002", - "0000000000000000000000000000000000000000000000000000000000000001", - "0000000000000000000000000000000000000000000000000000000000000002", - ] - ), + EIP196Spec.ECADD, + EIP196Spec.G1 + EIP196Spec.G1, Precompile.BN128_ADD, id="bn128_add_1_2", ), pytest.param( - 0x07, - concatenate_parameters( - [ - "1A87B0584CE92F4593D161480614F2989035225609F08058CCFA3D0F940FEBE3", - "1A2F3C951F6DADCC7EE9007DFF81504B0FCD6D7CF59996EFDC33D92BF7F9F8F6", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - ] + EIP196Spec.ECMUL, + PointG1( + x=0x1A87B0584CE92F4593D161480614F2989035225609F08058CCFA3D0F940FEBE3, + y=0x1A2F3C951F6DADCC7EE9007DFF81504B0FCD6D7CF59996EFDC33D92BF7F9F8F6, + ) + + Scalar( + x=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ), Precompile.BN128_MUL, id="bn128_mul", @@ -115,27 +115,18 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L335 pytest.param( - 0x07, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000002", - ] - ), + EIP196Spec.ECMUL, + EIP196Spec.INF_G1 + Scalar(x=2), Precompile.BN128_MUL, id="bn128_mul_infinities_2_scalar", ), # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L338 pytest.param( - 0x07, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "25f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd585", - ] + EIP196Spec.ECMUL, + EIP196Spec.INF_G1 + + Scalar( + x=0x25F8C89EA3437F44F8FC8B6BFBB6312074DC6F983809A5E809FF4E1D076DD585 ), Precompile.BN128_MUL, id="bn128_mul_infinities_32_byte_scalar", @@ -144,27 +135,18 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L341 pytest.param( - 0x07, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000001", - "0000000000000000000000000000000000000000000000000000000000000002", - "0000000000000000000000000000000000000000000000000000000000000002", - ] - ), + EIP196Spec.ECMUL, + EIP196Spec.G1 + Scalar(x=2), Precompile.BN128_MUL, id="bn128_mul_1_2_2_scalar", ), # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L344 pytest.param( - 0x07, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000001", - "0000000000000000000000000000000000000000000000000000000000000002", - "25f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd585", - ] + EIP196Spec.ECMUL, + EIP196Spec.G1 + + Scalar( + x=0x25F8C89EA3437F44F8FC8B6BFBB6312074DC6F983809A5E809FF4E1D076DD585 ), Precompile.BN128_MUL, id="bn128_mul_1_2_32_byte_scalar", @@ -172,14 +154,12 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L347 pytest.param( - 0x07, - concatenate_parameters( - [ - "089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf", - "2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b36", - "0000000000000000000000000000000000000000000000000000000000000002", - ] - ), + EIP196Spec.ECMUL, + PointG1( + x=0x089142DEBB13C461F61523586A60732D8B69C5B38A3380A74DA7B2961D867DBF, + y=0x2D5FC7BBC013C16D7945F190B232EACC25DA675C0EB093FE6B9F1B4B4E107B36, + ) + + Scalar(x=2), Precompile.BN128_MUL, id="bn128_mul_32_byte_coord_and_2_scalar", marks=pytest.mark.repricing, @@ -187,53 +167,59 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L350 pytest.param( - 0x07, - concatenate_parameters( - [ - "089142debb13c461f61523586a60732d8b69c5b38a3380a74da7b2961d867dbf", - "2d5fc7bbc013c16d7945f190b232eacc25da675c0eb093fe6b9f1b4b4e107b36", - "25f8c89ea3437f44f8fc8b6bfbb6312074dc6f983809a5e809ff4e1d076dd585", - ] + EIP196Spec.ECMUL, + PointG1( + x=0x089142DEBB13C461F61523586A60732D8B69C5B38A3380A74DA7B2961D867DBF, + y=0x2D5FC7BBC013C16D7945F190B232EACC25DA675C0EB093FE6B9F1B4B4E107B36, + ) + + Scalar( + x=0x25F8C89EA3437F44F8FC8B6BFBB6312074DC6F983809A5E809FF4E1D076DD585 ), Precompile.BN128_MUL, id="bn128_mul_32_byte_coord_and_scalar", marks=pytest.mark.repricing, ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "1C76476F4DEF4BB94541D57EBBA1193381FFA7AA76ADA664DD31C16024C43F59", - "3034DD2920F673E204FEE2811C678745FC819B55D3E9D294E45C9B03A76AEF41", - "209DD15EBFF5D46C4BD888E51A93CF99A7329636C63514396B4A452003A35BF7", - "04BF11CA01483BFA8B34B43561848D28905960114C8AC04049AF4B6315A41678", - "2BB8324AF6CFC93537A2AD1A445CFD0CA2A71ACD7AC41FADBF933C2A51BE344D", - "120A2A4CF30C1BF9845F20C6FE39E07EA2CCE61F0C9BB048165FE5E4DE877550", - # Second pairing - "111E129F1CF1097710D41C4AC70FCDFA5BA2023C6FF1CBEAC322DE49D1B6DF7C", - "103188585E2364128FE25C70558F1560F4F9350BAF3959E603CC91486E110936", - "198E9393920D483A7260BFB731FB5D25F1AA493335A9E71297E485B7AEF312C2", - "1800DEEF121F1E76426A00665E5C4479674322D4F75EDADD46DEBD5CD992F6ED", - "090689D0585FF075EC9E99AD690C3395BC4B313370B38EF355ACDADCD122975B", - "12C85EA5DB8C6DEB4AAB71808DCB408FE3D1E7690C43D37B4CE6CC0166FA7DAA", - ] - ), + EIP197Spec.ECPAIRING, + # First pairing + PointG1( + x=0x1C76476F4DEF4BB94541D57EBBA1193381FFA7AA76ADA664DD31C16024C43F59, + y=0x3034DD2920F673E204FEE2811C678745FC819B55D3E9D294E45C9B03A76AEF41, + ) + + PointG2( + x=( + 0x209DD15EBFF5D46C4BD888E51A93CF99A7329636C63514396B4A452003A35BF7, + 0x04BF11CA01483BFA8B34B43561848D28905960114C8AC04049AF4B6315A41678, + ), + y=( + 0x2BB8324AF6CFC93537A2AD1A445CFD0CA2A71ACD7AC41FADBF933C2A51BE344D, + 0x120A2A4CF30C1BF9845F20C6FE39E07EA2CCE61F0C9BB048165FE5E4DE877550, + ), + ) + # Second pairing + + PointG1( + x=0x111E129F1CF1097710D41C4AC70FCDFA5BA2023C6FF1CBEAC322DE49D1B6DF7C, + y=0x103188585E2364128FE25C70558F1560F4F9350BAF3959E603CC91486E110936, + ) + + EIP197Spec.G2, Precompile.BN128_PAIRING, id="bn128_two_pairings", ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "1C76476F4DEF4BB94541D57EBBA1193381FFA7AA76ADA664DD31C16024C43F59", - "3034DD2920F673E204FEE2811C678745FC819B55D3E9D294E45C9B03A76AEF41", - "209DD15EBFF5D46C4BD888E51A93CF99A7329636C63514396B4A452003A35BF7", - "04BF11CA01483BFA8B34B43561848D28905960114C8AC04049AF4B6315A41678", - "2BB8324AF6CFC93537A2AD1A445CFD0CA2A71ACD7AC41FADBF933C2A51BE344D", - "120A2A4CF30C1BF9845F20C6FE39E07EA2CCE61F0C9BB048165FE5E4DE877550", - ] + EIP197Spec.ECPAIRING, + PointG1( + x=0x1C76476F4DEF4BB94541D57EBBA1193381FFA7AA76ADA664DD31C16024C43F59, + y=0x3034DD2920F673E204FEE2811C678745FC819B55D3E9D294E45C9B03A76AEF41, + ) + + PointG2( + x=( + 0x209DD15EBFF5D46C4BD888E51A93CF99A7329636C63514396B4A452003A35BF7, + 0x04BF11CA01483BFA8B34B43561848D28905960114C8AC04049AF4B6315A41678, + ), + y=( + 0x2BB8324AF6CFC93537A2AD1A445CFD0CA2A71ACD7AC41FADBF933C2A51BE344D, + 0x120A2A4CF30C1BF9845F20C6FE39E07EA2CCE61F0C9BB048165FE5E4DE877550, + ), ), Precompile.BN128_PAIRING, id="bn128_one_pairing", @@ -241,179 +227,244 @@ # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L353 pytest.param( - 0x08, + EIP197Spec.ECPAIRING, [], Precompile.BN128_PAIRING, id="ec_pairing_zero_input", ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "2cf44499d5d27bb186308b7af7af02ac5bc9eeb6a3d147c186b21fb1b76e18da", - "2c0f001f52110ccfe69108924926e45f0b0c868df0e7bde1fe16d3242dc715f6", - "1fb19bb476f6b9e44e2a32234da8212f61cd63919354bc06aef31e3cfaff3ebc", - "22606845ff186793914e03e21df544c34ffe2f2f3504de8a79d9159eca2d98d9", - "2bd368e28381e8eccb5fa81fc26cf3f048eea9abfdd85d7ed3ab3698d63e4f90", - "2fe02e47887507adf0ff1743cbac6ba291e66f59be6bd763950bb16041a0a85e", - # Second pairing - "0000000000000000000000000000000000000000000000000000000000000013", - "0644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451", - "971ff0471b09fa93caaf13cbf443c1aede09cc4328f5a62aad45f40ec133eb40", - "91058a3141822985733cbdddfed0fd8d6c104e9e9eff40bf5abfef9ab163bc72", - "a23af9a5ce2ba2796c1f4e453a370eb0af8c212d9dc9acd8fc02c2e907baea22", - "3a8eb0b0996252cb548a4487da97b02422ebc0e834613f954de6c7e0afdc1fc0", - ] + EIP197Spec.ECPAIRING, + # First pairing + PointG1( + x=0x2CF44499D5D27BB186308B7AF7AF02AC5BC9EEB6A3D147C186B21FB1B76E18DA, + y=0x2C0F001F52110CCFE69108924926E45F0B0C868DF0E7BDE1FE16D3242DC715F6, + ) + + PointG2( + x=( + 0x1FB19BB476F6B9E44E2A32234DA8212F61CD63919354BC06AEF31E3CFAFF3EBC, + 0x22606845FF186793914E03E21DF544C34FFE2F2F3504DE8A79D9159ECA2D98D9, + ), + y=( + 0x2BD368E28381E8ECCB5FA81FC26CF3F048EEA9ABFDD85D7ED3AB3698D63E4F90, + 0x2FE02E47887507ADF0FF1743CBAC6BA291E66F59BE6BD763950BB16041A0A85E, + ), + ) + # Second pairing + + PointG1( + x=0x0000000000000000000000000000000000000000000000000000000000000013, + y=0x0644E72E131A029B85045B68181585D97816A916871CA8D3C208C16D87CFD451, + ) + + PointG2( + x=( + 0x971FF0471B09FA93CAAF13CBF443C1AEDE09CC4328F5A62AAD45F40EC133EB40, + 0x91058A3141822985733CBDDDFED0FD8D6C104E9E9EFF40BF5ABFEF9AB163BC72, + ), + y=( + 0xA23AF9A5CE2BA2796C1F4E453A370EB0AF8C212D9DC9ACD8FC02C2E907BAEA22, + 0x3A8EB0B0996252CB548A4487DA97B02422EBC0E834613F954DE6C7E0AFDC1FC0, + ), ), Precompile.BN128_PAIRING, id="ec_pairing_2_sets", ), pytest.param( - 0x08, - concatenate_parameters([""]), + EIP197Spec.ECPAIRING, + b"", Precompile.BN128_PAIRING, id="ec_pairing_1_pair", ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "2371e7d92e9fc444d0e11526f0752b520318c80be68bf0131704b36b7976572e", - "2dca8f05ed5d58e0f2e13c49ae40480c0f99dfcd9268521eea6c81c6387b66c4", - "051a93d697db02afd3dcf8414ecb906a114a2bfdb6b06c95d41798d1801b3cbd", - "2e275fef7a0bdb0a2aea77d8ec5817e66e199b3d55bc0fa308dcdda74e85060b", - "1c7e33c2a72d6e12a31eababad3dbc388525135628102bb64742d9e325f43410", - "115dc41fa10b2dbf99036f252ad6f00e8876b22f02cb4738dc4413b22ea9b2df", - # Second pairing - "09a760ea8f9bd87dc258a949395a03f7d2500c6e72c61f570986328a096b610a", - "148027063c072345298117eb2cb980ad79601db31cc69bba6bcbe4937ada6720", - "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2", - "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed", - "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b", - "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", - ] - ), + EIP197Spec.ECPAIRING, + # First pairing + PointG1( + x=0x2371E7D92E9FC444D0E11526F0752B520318C80BE68BF0131704B36B7976572E, + y=0x2DCA8F05ED5D58E0F2E13C49AE40480C0F99DFCD9268521EEA6C81C6387B66C4, + ) + + PointG2( + x=( + 0x051A93D697DB02AFD3DCF8414ECB906A114A2BFDB6B06C95D41798D1801B3CBD, + 0x2E275FEF7A0BDB0A2AEA77D8EC5817E66E199B3D55BC0FA308DCDDA74E85060B, + ), + y=( + 0x1C7E33C2A72D6E12A31EABABAD3DBC388525135628102BB64742D9E325F43410, + 0x115DC41FA10B2DBF99036F252AD6F00E8876B22F02CB4738DC4413B22EA9B2DF, + ), + ) + # Second pairing: G2 generator + + PointG1( + x=0x09A760EA8F9BD87DC258A949395A03F7D2500C6E72C61F570986328A096B610A, + y=0x148027063C072345298117EB2CB980AD79601DB31CC69BBA6BCBE4937ADA6720, + ) + + EIP197Spec.G2, Precompile.BN128_PAIRING, id="ec_pairing_2_pair", ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0ef4aac9b7954d5fc6eafae7f4f4c2a732ab05b45f8d50d102cee4973f36eb2c", - "23db7d30c99e0a2a7f3bb5cd1f04635aaea58732b58887df93d9239c28230d28", - "2bd99d31a5054f2556d226f2e5ef0e075423d8604178b2e2c08006311caee54f", - "0f11afb0c6073d12d21b13f4f78210e8ca9a66729206d3fcc2c1b04824c425f2", - # Second pairing - "0000000000000000000000000000000000000000000000000000000000000000", - "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2", - "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed", - "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b", - "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", - # Third pairing - "0000000000000000000000000000000000000000000000000000000000000000", - "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2", - "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed", - "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b", - "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", - ] - ), + EIP197Spec.ECPAIRING, + # First pairing + PointG1(x=0, y=0) + + PointG2( + x=( + 0x0EF4AAC9B7954D5FC6EAFAE7F4F4C2A732AB05B45F8D50D102CEE4973F36EB2C, + 0x23DB7D30C99E0A2A7F3BB5CD1F04635AAEA58732B58887DF93D9239C28230D28, + ), + y=( + 0x2BD99D31A5054F2556D226F2E5EF0E075423D8604178B2E2C08006311CAEE54F, + 0x0F11AFB0C6073D12D21B13F4F78210E8CA9A66729206D3FCC2C1B04824C425F2, + ), + ) + # Second pairing (32 zero + G2 generator = 160 bytes) + + bytes(32) + + EIP197Spec.G2 + # Third pairing (same structure as second) + + bytes(32) + + EIP197Spec.G2, Precompile.BN128_PAIRING, id="ec_pairing_3_pair", ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "24ab69f46f3e3333027d67d51af71571141bd5652b9829157a3c5d1268461984", - "0f0e1495665bccf97d627b714e8a49e9c77c21e8d5b383ad7dde7e50040d0f62", - "2cab595b9d579f8b82e433249b83ae1d7b62d7073a4f67cb3aeb9b316988907f", - "1326d1905ffde0c77e8ebd98257aa239b05ae76c8ec7723ec19bbc8282b0debe", - "130502106676b537e01cc356765e91c005d6c4bd1a75f5f6d41d2556c73e56ac", - "2dc4cb08068b4aa5f14b7f1096ab35d5c13d78319ec7e66e9f67a1ff20cbbf03", - # Second pairing - "1459f4140b271cbc8746de9dfcb477d5b72d50ef95bec5fef4a68dd69ddfdb2e", - "2c589584551d16a9723b5d356d1ee2066d10381555cdc739e39efca2612fc544", - "229ab0abdb0a7d1a5f0d93fb36ce41e12a31ba52fd9e3c27bebce524ab6c4e9b", - "00f8756832b244377d06e2d00eeb95ec8096dcfd81f4e4931b50fea23c04a2fe", - "29605352ce973ec48d1ab2c8355643c999b70ff771946078b519c556058c3d56", - "059a65ae6e0189d4e04a966140aa40f781a1345824a90a91bb035e12ad29af1d", - # Third pairing - "1459f4140b271cbc8746de9dfcb477d5b72d50ef95bec5fef4a68dd69ddfdb2e", - "2c589584551d16a9723b5d356d1ee2066d10381555cdc739e39efca2612fc544", - "229ab0abdb0a7d1a5f0d93fb36ce41e12a31ba52fd9e3c27bebce524ab6c4e9b", - "00f8756832b244377d06e2d00eeb95ec8096dcfd81f4e4931b50fea23c04a2fe", - "29605352ce973ec48d1ab2c8355643c999b70ff771946078b519c556058c3d56", - "059a65ae6e0189d4e04a966140aa40f781a1345824a90a91bb035e12ad29af1d", - # Fourth pairing - "24ab69f46f3e3333027d67d51af71571141bd5652b9829157a3c5d1268461984", - "0f0e1495665bccf97d627b714e8a49e9c77c21e8d5b383ad7dde7e50040d0f62", - "2cab595b9d579f8b82e433249b83ae1d7b62d7073a4f67cb3aeb9b316988907f", - "1326d1905ffde0c77e8ebd98257aa239b05ae76c8ec7723ec19bbc8282b0debe", - "130502106676b537e01cc356765e91c005d6c4bd1a75f5f6d41d2556c73e56ac", - "2dc4cb08068b4aa5f14b7f1096ab35d5c13d78319ec7e66e9f67a1ff20cbbf03", - ] + EIP197Spec.ECPAIRING, + ( + PointG1( + x=0x24AB69F46F3E3333027D67D51AF71571141BD5652B9829157A3C5D1268461984, + y=0x0F0E1495665BCCF97D627B714E8A49E9C77C21E8D5B383AD7DDE7E50040D0F62, + ) + + PointG2( + x=( + 0x2CAB595B9D579F8B82E433249B83AE1D7B62D7073A4F67CB3AEB9B316988907F, + 0x1326D1905FFDE0C77E8EBD98257AA239B05AE76C8EC7723EC19BBC8282B0DEBE, + ), + y=( + 0x130502106676B537E01CC356765E91C005D6C4BD1A75F5F6D41D2556C73E56AC, + 0x2DC4CB08068B4AA5F14B7F1096AB35D5C13D78319EC7E66E9F67A1FF20CBBF03, + ), + ) + ) + + ( + PointG1( + x=0x1459F4140B271CBC8746DE9DFCB477D5B72D50EF95BEC5FEF4A68DD69DDFDB2E, + y=0x2C589584551D16A9723B5D356D1EE2066D10381555CDC739E39EFCA2612FC544, + ) + + PointG2( + x=( + 0x229AB0ABDB0A7D1A5F0D93FB36CE41E12A31BA52FD9E3C27BEBCE524AB6C4E9B, + 0x00F8756832B244377D06E2D00EEB95EC8096DCFD81F4E4931B50FEA23C04A2FE, + ), + y=( + 0x29605352CE973EC48D1AB2C8355643C999B70FF771946078B519C556058C3D56, + 0x059A65AE6E0189D4E04A966140AA40F781A1345824A90A91BB035E12AD29AF1D, + ), + ) + ) + + ( + PointG1( + x=0x1459F4140B271CBC8746DE9DFCB477D5B72D50EF95BEC5FEF4A68DD69DDFDB2E, + y=0x2C589584551D16A9723B5D356D1EE2066D10381555CDC739E39EFCA2612FC544, + ) + + PointG2( + x=( + 0x229AB0ABDB0A7D1A5F0D93FB36CE41E12A31BA52FD9E3C27BEBCE524AB6C4E9B, + 0x00F8756832B244377D06E2D00EEB95EC8096DCFD81F4E4931B50FEA23C04A2FE, + ), + y=( + 0x29605352CE973EC48D1AB2C8355643C999B70FF771946078B519C556058C3D56, + 0x059A65AE6E0189D4E04A966140AA40F781A1345824A90A91BB035E12AD29AF1D, + ), + ) + ) + + ( + PointG1( + x=0x24AB69F46F3E3333027D67D51AF71571141BD5652B9829157A3C5D1268461984, + y=0x0F0E1495665BCCF97D627B714E8A49E9C77C21E8D5B383AD7DDE7E50040D0F62, + ) + + PointG2( + x=( + 0x2CAB595B9D579F8B82E433249B83AE1D7B62D7073A4F67CB3AEB9B316988907F, + 0x1326D1905FFDE0C77E8EBD98257AA239B05AE76C8EC7723EC19BBC8282B0DEBE, + ), + y=( + 0x130502106676B537E01CC356765E91C005D6C4BD1A75F5F6D41D2556C73E56AC, + 0x2DC4CB08068B4AA5F14B7F1096AB35D5C13D78319EC7E66E9F67A1FF20CBBF03, + ), + ) ), Precompile.BN128_PAIRING, id="ec_pairing_4_pair", ), pytest.param( - 0x08, - concatenate_parameters( - [ - # First pairing - "1147057b17237df94a3186435acf66924e1d382b8c935fdd493ceb38c38def73", - "03cd046286139915160357ce5b29b9ea28bfb781b71734455d20ef1a64be76ca", - "0daa7cc4983cf74c94607519df747f61e317307c449bafb6923f6d6a65299a7e", - "1d48db8f275830859fd61370addbc5d5ef3f0ce7491d16918e065f7e3727439d", - "1ca8ac2f4a0f540e5505edbe1d15d13899a2a0dfccb012d068134ac66edec625", - "2162c315417d1d12c9d7028c5619015391003a9006d4d8979784c7af2c4537a3", - # Second pairing - "0d221a19ca86dafa8cb804daff78fd3d1bed30aa32e7d4029b1aa69afda2d750", - "018628c766a98de1d0cca887a6d90303e68a7729490f25f937b76b57624ba0be", - "14550ccf7139312da6fa9eb1259c6365b0bd688a27473ccb42bc5cd6f14c8abd", - "165f8721ee9f614382c8c7edb103c941d3a55c1849c9787f34317777d5d9365b", - "0d19da7439edb573a1b3e357faade63d5d68b6031771fd911459b7ab0bda9d3f", - "25a50a44d10c99c5f107e3b3874f717873cb2d4674699a468204df27c0c50a9a", - # Third pairing - "0d7136c59b907615e1b45cf730fbfd6cf38b7e126e85e52be804620a23ace4fb", - "03e80c29d24ed5cc407329ae093bb1be00f9e3c9332f532bc3658937110d7607", - "2129813bd7247065ac58eac42c81e874044e199f48c12aa749a9fe6bb6e4bddc", - "1b72b9ab4579283e62445555d5b2921424213d09a776152361c46988b82be8a7", - "111bc8198f932e379b8f9825f01af0f5e5cacbf8bfe274bf674f6eaa6e338e04", - "259f58d438fd6391e158c991e155966218e6a432703a84068a32543965749857", - # Fourth pairing - "1ba47a91d487cce77aa78390a295df54d9351637d67810c400415fb374278e3f", - "24318bbc05a4e4d779b9498075841c360c6973c1c51dea254281829bbc9aef33", - "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2", - "1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed", - "090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b", - "12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", - # Fifth pairing - "1e219772c16eee72450bbf43e9cadae7bf6b2e6ae6637cfeb1d1e8965287acfb", - "0347e7bf4245debd3d00b6f51d2d50fd718e6769352f4fe1db0efe492fed2fc3", - "24fdcc7d4ed0953e3dad500c7ef9836fc61ded44ba454ec76f0a6d0687f4c1b4", - "282b18f7e59c1db4852e622919b2ce9aa5980ca883eac312049c19a3deb79f6d", - "0c9d6ce303b7811dd7ea506c8fa124837405bd209b8731bda79a66eb7206277b", - "1ac5dac62d2332faa8069faca3b0d27fcdf95d8c8bafc9074ee72b5c1f33aa70", - ] + EIP197Spec.ECPAIRING, + # First pairing + PointG1( + x=0x1147057B17237DF94A3186435ACF66924E1D382B8C935FDD493CEB38C38DEF73, + y=0x03CD046286139915160357CE5B29B9EA28BFB781B71734455D20EF1A64BE76CA, + ) + + PointG2( + x=( + 0x0DAA7CC4983CF74C94607519DF747F61E317307C449BAFB6923F6D6A65299A7E, + 0x1D48DB8F275830859FD61370ADDBC5D5EF3F0CE7491D16918E065F7E3727439D, + ), + y=( + 0x1CA8AC2F4A0F540E5505EDBE1D15D13899A2A0DFCCB012D068134AC66EDEC625, + 0x2162C315417D1D12C9D7028C5619015391003A9006D4D8979784C7AF2C4537A3, + ), + ) + # Second pairing + + PointG1( + x=0x0D221A19CA86DAFA8CB804DAFF78FD3D1BED30AA32E7D4029B1AA69AFDA2D750, + y=0x018628C766A98DE1D0CCA887A6D90303E68A7729490F25F937B76B57624BA0BE, + ) + + PointG2( + x=( + 0x14550CCF7139312DA6FA9EB1259C6365B0BD688A27473CCB42BC5CD6F14C8ABD, + 0x165F8721EE9F614382C8C7EDB103C941D3A55C1849C9787F34317777D5D9365B, + ), + y=( + 0x0D19DA7439EDB573A1B3E357FAADE63D5D68B6031771FD911459B7AB0BDA9D3F, + 0x25A50A44D10C99C5F107E3B3874F717873CB2D4674699A468204DF27C0C50A9A, + ), + ) + # Third pairing + + PointG1( + x=0x0D7136C59B907615E1B45CF730FBFD6CF38B7E126E85E52BE804620A23ACE4FB, + y=0x03E80C29D24ED5CC407329AE093BB1BE00F9E3C9332F532BC3658937110D7607, + ) + + PointG2( + x=( + 0x2129813BD7247065AC58EAC42C81E874044E199F48C12AA749A9FE6BB6E4BDDC, + 0x1B72B9AB4579283E62445555D5B2921424213D09A776152361C46988B82BE8A7, + ), + y=( + 0x111BC8198F932E379B8F9825F01AF0F5E5CACBF8BFE274BF674F6EAA6E338E04, + 0x259F58D438FD6391E158C991E155966218E6A432703A84068A32543965749857, + ), + ) + # Fourth pairing: G2 generator + + PointG1( + x=0x1BA47A91D487CCE77AA78390A295DF54D9351637D67810C400415FB374278E3F, + y=0x24318BBC05A4E4D779B9498075841C360C6973C1C51DEA254281829BBC9AEF33, + ) + + EIP197Spec.G2 + # Fifth pairing + + PointG1( + x=0x1E219772C16EEE72450BBF43E9CADAE7BF6B2E6AE6637CFEB1D1E8965287ACFB, + y=0x0347E7BF4245DEBD3D00B6F51D2D50FD718E6769352F4FE1DB0EFE492FED2FC3, + ) + + PointG2( + x=( + 0x24FDCC7D4ED0953E3DAD500C7EF9836FC61DED44BA454EC76F0A6D0687F4C1B4, + 0x282B18F7E59C1DB4852E622919B2CE9AA5980CA883EAC312049C19A3DEB79F6D, + ), + y=( + 0x0C9D6CE303B7811DD7EA506C8FA124837405BD209B8731BDA79A66EB7206277B, + 0x1AC5DAC62D2332FAA8069FACA3B0D27FCDF95D8C8BAFC9074EE72B5C1F33AA70, + ), ), Precompile.BN128_PAIRING, id="ec_pairing_5_pair", ), pytest.param( - 0x08, - concatenate_parameters( - [ - "0000000000000000000000000000000000000000000000000000000000000000", - ] - ), + EIP197Spec.ECPAIRING, + bytes(32), Precompile.BN128_PAIRING, id="ec_pairing_1_pair_empty", ), @@ -459,21 +510,25 @@ def _generate_bn128_pairs(n: int, seed: int = 0) -> Bytes: assert point_y_affine is not None, ( "G2 multiplication resulted in point at infinity" ) + assert isinstance(point_y_affine[0], bn128_FQ2) + assert isinstance(point_y_affine[1], bn128_FQ2) - g1_x_bytes = point_x_affine[0].n.to_bytes(32, "big") - g1_y_bytes = point_x_affine[1].n.to_bytes(32, "big") - g1_serialized = g1_x_bytes + g1_y_bytes - - g2_x_c1_bytes = point_y_affine[0].coeffs[1].n.to_bytes(32, "big") # type: ignore - g2_x_c0_bytes = point_y_affine[0].coeffs[0].n.to_bytes(32, "big") # type: ignore - g2_y_c1_bytes = point_y_affine[1].coeffs[1].n.to_bytes(32, "big") # type: ignore - g2_y_c0_bytes = point_y_affine[1].coeffs[0].n.to_bytes(32, "big") # type: ignore - g2_serialized = ( - g2_x_c1_bytes + g2_x_c0_bytes + g2_y_c1_bytes + g2_y_c0_bytes + g1 = PointG1( + x=point_x_affine[0].n, + y=point_x_affine[1].n, + ) + g2 = PointG2( + x=( + int(point_y_affine[0].coeffs[1]), + int(point_y_affine[0].coeffs[0]), + ), + y=( + int(point_y_affine[1].coeffs[1]), + int(point_y_affine[1].coeffs[0]), + ), ) - pair_calldata = g1_serialized + g2_serialized - calldata = Bytes(calldata + pair_calldata) + calldata = Bytes(calldata + g1 + g2) return calldata @@ -545,7 +600,7 @@ def test_bn128_pairings_amortized( setup = Op.CALLDATACOPY(size=Op.CALLDATASIZE) attack_block = Op.POP( - Op.STATICCALL(Op.GAS, 0x08, 0, Op.CALLDATASIZE, 0, 0) + Op.STATICCALL(Op.GAS, EIP197Spec.ECPAIRING, 0, Op.CALLDATASIZE, 0, 0) ) benchmark_test( @@ -572,7 +627,11 @@ def test_alt_bn128_benchmark( calldata = _generate_bn128_pairs(num_pairs, seed=42) attack_block = Op.POP( - Op.STATICCALL(gas=Op.GAS, address=0x08, args_size=Op.CALLDATASIZE), + Op.STATICCALL( + gas=Op.GAS, + address=EIP197Spec.ECPAIRING, + args_size=Op.CALLDATASIZE, + ), ) benchmark_test( @@ -611,7 +670,7 @@ def test_ec_pairing( attack_block = Op.POP( Op.STATICCALL( gas=Op.GAS, - address=0x08, + address=EIP197Spec.ECPAIRING, args_offset=Op.MLOAD(Op.CALLDATASIZE), args_size=pair_size, # gas accounting @@ -709,24 +768,24 @@ def _generate_g1_point(seed: int) -> Bytes: priv_key = rng.randint(1, 2**32 - 1) point = multiply(G1, priv_key) assert point is not None - return Bytes( - point[0].n.to_bytes(32, "big") + point[1].n.to_bytes(32, "big") - ) + return Bytes(PointG1(x=point[0].n, y=point[1].n)) @pytest.mark.repricing @pytest.mark.parametrize( "precompile_address,scalar,target", [ - pytest.param(0x06, None, Precompile.BN128_ADD, id="ec_add"), pytest.param( - 0x07, + EIP196Spec.ECADD, None, Precompile.BN128_ADD, id="ec_add" + ), + pytest.param( + EIP196Spec.ECMUL, 2, Precompile.BN128_MUL, id="ec_mul_small_scalar", ), pytest.param( - 0x07, + EIP196Spec.ECMUL, 2**256 - 1, Precompile.BN128_MUL, id="ec_mul_max_scalar", @@ -754,7 +813,7 @@ def test_alt_bn128_uncachable( gsc = fork.gas_costs() precompile_cost = ( gsc.PRECOMPILE_ECMUL - if precompile_address == 0x07 + if precompile_address == EIP196Spec.ECMUL else gsc.PRECOMPILE_ECADD ) attack_block = Op.POP( diff --git a/tests/benchmark/compute/precompile/test_bls12_381.py b/tests/benchmark/compute/precompile/test_bls12_381.py index 40ccfc96415..d6e08db6597 100644 --- a/tests/benchmark/compute/precompile/test_bls12_381.py +++ b/tests/benchmark/compute/precompile/test_bls12_381.py @@ -21,103 +21,71 @@ ) from py_ecc import optimized_bls12_381 as bls_curve +from tests.benchmark.compute.helpers import Precompile from tests.prague.eip2537_bls_12_381_precompiles import spec as bls12381_spec from tests.prague.eip2537_bls_12_381_precompiles.spec import ( build_gas_calculation_function_map, ) -from ..helpers import Precompile, concatenate_parameters - @pytest.mark.parametrize( "precompile_address,calldata,target", [ pytest.param( bls12381_spec.Spec.G1ADD, - concatenate_parameters( - [ - bls12381_spec.Spec.G1, - bls12381_spec.Spec.P1, - ] - ), + bls12381_spec.Spec.G1 + bls12381_spec.Spec.P1, Precompile.BLS12_G1ADD, id="bls12_g1add", marks=pytest.mark.repricing, ), pytest.param( bls12381_spec.Spec.G1MSM, - concatenate_parameters( - [ - ( - bls12381_spec.Spec.P1 - + bls12381_spec.Scalar(bls12381_spec.Spec.Q) - ) - * (len(bls12381_spec.Spec.G1MSM_DISCOUNT_TABLE) - 1), - ] - ), + ( + bls12381_spec.Spec.P1 + + bls12381_spec.Scalar(bls12381_spec.Spec.Q) + ) + * (len(bls12381_spec.Spec.G1MSM_DISCOUNT_TABLE) - 1), Precompile.BLS12_G1MSM, id="bls12_g1msm", ), pytest.param( bls12381_spec.Spec.G2ADD, - concatenate_parameters( - [ - bls12381_spec.Spec.G2, - bls12381_spec.Spec.P2, - ] - ), + bls12381_spec.Spec.G2 + bls12381_spec.Spec.P2, Precompile.BLS12_G2ADD, id="bls12_g2add", marks=pytest.mark.repricing, ), pytest.param( bls12381_spec.Spec.G2MSM, - concatenate_parameters( - [ - # TODO: the //2 is required due to a limitation of the max - # contract size limit. In a further iteration we can insert - # inputs as calldata or storage and avoid doing PUSHes - # which has this limitation. This also applies to G1MSM. - ( - bls12381_spec.Spec.P2 - + bls12381_spec.Scalar(bls12381_spec.Spec.Q) - ) - * (len(bls12381_spec.Spec.G2MSM_DISCOUNT_TABLE) // 2), - ] - ), + # TODO: the //2 is required due to a limitation of the max + # contract size limit. In a further iteration we can insert + # inputs as calldata or storage and avoid doing PUSHes which + # has this limitation. This also applies to G1MSM. + ( + bls12381_spec.Spec.P2 + + bls12381_spec.Scalar(bls12381_spec.Spec.Q) + ) + * (len(bls12381_spec.Spec.G2MSM_DISCOUNT_TABLE) // 2), Precompile.BLS12_G2MSM, id="bls12_g2msm", ), pytest.param( bls12381_spec.Spec.PAIRING, - concatenate_parameters( - [ - bls12381_spec.Spec.G1, - bls12381_spec.Spec.G2, - ] - ), + bls12381_spec.Spec.G1 + bls12381_spec.Spec.G2, Precompile.BLS12_PAIRING, id="bls12_pairing_check", ), pytest.param( bls12381_spec.Spec.MAP_FP_TO_G1, - concatenate_parameters( - [ - bls12381_spec.FP(bls12381_spec.Spec.P - 1), - ] - ), + bls12381_spec.FP(bls12381_spec.Spec.P - 1), Precompile.BLS12_MAP_FP_TO_G1, id="bls12_fp_to_g1", marks=pytest.mark.repricing, ), pytest.param( bls12381_spec.Spec.MAP_FP2_TO_G2, - concatenate_parameters( - [ - bls12381_spec.FP2( - (bls12381_spec.Spec.P - 1, bls12381_spec.Spec.P - 1) - ), - ] + bls12381_spec.FP2( + (bls12381_spec.Spec.P - 1, bls12381_spec.Spec.P - 1) ), Precompile.BLS12_MAP_FP2_TO_G2, id="bls12_fp_to_g2", @@ -309,19 +277,19 @@ def _generate_bls12_pairs(n: int, seed: int = 0) -> Bytes: def _g1add_calldata(seed: int) -> Bytes: """Generate G1ADD calldata with unique first point.""" - return Bytes(_generate_bls12_g1_point(seed) + bytes(bls12381_spec.Spec.P1)) + return Bytes(_generate_bls12_g1_point(seed) + bls12381_spec.Spec.P1) def _g2add_calldata(seed: int) -> Bytes: """Generate G2ADD calldata with unique first point.""" - return Bytes(_generate_bls12_g2_point(seed) + bytes(bls12381_spec.Spec.P2)) + return Bytes(_generate_bls12_g2_point(seed) + bls12381_spec.Spec.P2) def _g1msm_calldata(seed: int) -> Bytes: """Generate G1MSM calldata with unique point.""" return Bytes( _generate_bls12_g1_point(seed) - + bytes(bls12381_spec.Scalar(bls12381_spec.Spec.Q)) + + bls12381_spec.Scalar(bls12381_spec.Spec.Q) ) @@ -329,7 +297,7 @@ def _g2msm_calldata(seed: int) -> Bytes: """Generate G2MSM calldata with unique point.""" return Bytes( _generate_bls12_g2_point(seed) - + bytes(bls12381_spec.Scalar(bls12381_spec.Spec.Q)) + + bls12381_spec.Scalar(bls12381_spec.Spec.Q) ) diff --git a/tests/benchmark/compute/precompile/test_ecrecover.py b/tests/benchmark/compute/precompile/test_ecrecover.py index 7c0193746f9..6d7dec43e11 100644 --- a/tests/benchmark/compute/precompile/test_ecrecover.py +++ b/tests/benchmark/compute/precompile/test_ecrecover.py @@ -9,7 +9,9 @@ Op, ) -from ..helpers import Precompile, concatenate_parameters +from tests.benchmark.compute.helpers import Precompile +from tests.frontier.precompiles.spec import EcrecoverInput +from tests.frontier.precompiles.spec import Spec as EcrecoverSpec @pytest.mark.repricing @@ -17,16 +19,14 @@ "precompile_address,calldata", [ pytest.param( - 0x01, - concatenate_parameters( - [ - # Inputs below are a valid signature, thus ECRECOVER call - # will perform full computation, not blocked by validation. - "38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E", - "000000000000000000000000000000000000000000000000000000000000001B", - "38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E", - "789D1DD423D25F0772D2748D60F7E4B81BB14D086EBA8E8E8EFB6DCFF8A4AE02", - ] + EcrecoverSpec.ECRECOVER, + # Inputs below are a valid signature, thus ECRECOVER call + # will perform full computation, not blocked by validation. + EcrecoverInput( + msg_hash=0x38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E, + v=0x1B, + r=0x38D18ACB67D25C8BB9942764B62F18E17054F66A817BD4295423ADF9ED98873E, + s=0x789D1DD423D25F0772D2748D60F7E4B81BB14D086EBA8E8E8EFB6DCFF8A4AE02, ), id="ecrecover", ) diff --git a/tests/benchmark/compute/precompile/test_identity.py b/tests/benchmark/compute/precompile/test_identity.py index e9e38dcea8c..759ad8d30a6 100644 --- a/tests/benchmark/compute/precompile/test_identity.py +++ b/tests/benchmark/compute/precompile/test_identity.py @@ -16,7 +16,11 @@ WhileGas, ) -from ..helpers import Precompile, calculate_optimal_input_length +from tests.benchmark.compute.helpers import ( + Precompile, + calculate_optimal_input_length, +) +from tests.frontier.identity_precompile.spec import Spec as IdentitySpec def test_identity( @@ -39,7 +43,12 @@ def test_identity( attack_block = Op.POP( Op.STATICCALL( - Op.GAS, 0x04, Op.PUSH0, optimal_input_length, Op.PUSH0, Op.PUSH0 + Op.GAS, + IdentitySpec.IDENTITY, + Op.PUSH0, + optimal_input_length, + Op.PUSH0, + Op.PUSH0, ) ) @@ -59,7 +68,9 @@ def test_identity_fixed_size( ) -> None: """Benchmark IDENTITY with fixed size input.""" attack_block = Op.POP( - Op.STATICCALL(Op.GAS, 0x04, Op.PUSH0, size, Op.PUSH0, Op.PUSH0) + Op.STATICCALL( + Op.GAS, IdentitySpec.IDENTITY, Op.PUSH0, size, Op.PUSH0, Op.PUSH0 + ) ) benchmark_test( @@ -97,7 +108,7 @@ def test_identity_uncachable( Op.MLOAD(0), Op.STATICCALL( gas=Op.GAS, - address=0x04, + address=IdentitySpec.IDENTITY, args_size=size, ret_size=size, # gas accounting diff --git a/tests/benchmark/compute/precompile/test_modexp.py b/tests/benchmark/compute/precompile/test_modexp.py index 098ee3bef59..75c158ac933 100644 --- a/tests/benchmark/compute/precompile/test_modexp.py +++ b/tests/benchmark/compute/precompile/test_modexp.py @@ -488,7 +488,7 @@ def test_modexp_uncachable( attack_block = Op.POP( Op.STATICCALL( gas=Op.GAS, - address=0x05, + address=Spec.MODEXP_ADDRESS, args_size=Op.CALLDATASIZE, ret_offset=96, ret_size=base_length, diff --git a/tests/benchmark/compute/precompile/test_p256verify.py b/tests/benchmark/compute/precompile/test_p256verify.py index 45951cc0d6a..fedb648c51b 100644 --- a/tests/benchmark/compute/precompile/test_p256verify.py +++ b/tests/benchmark/compute/precompile/test_p256verify.py @@ -14,9 +14,9 @@ WhileGas, ) +from tests.benchmark.compute.helpers import Precompile from tests.osaka.eip7951_p256verify_precompiles import spec as p256verify_spec - -from ..helpers import Precompile, concatenate_parameters +from tests.osaka.eip7951_p256verify_precompiles.spec import H, R, S, X, Y @pytest.mark.parametrize( @@ -24,15 +24,11 @@ [ pytest.param( p256verify_spec.Spec.P256VERIFY, - concatenate_parameters( - [ - p256verify_spec.Spec.H0, - p256verify_spec.Spec.R0, - p256verify_spec.Spec.S0, - p256verify_spec.Spec.X0, - p256verify_spec.Spec.Y0, - ] - ), + p256verify_spec.Spec.H0 + + p256verify_spec.Spec.R0 + + p256verify_spec.Spec.S0 + + p256verify_spec.Spec.X0 + + p256verify_spec.Spec.Y0, id="p256verify", marks=[ pytest.mark.eip_checklist( @@ -43,27 +39,39 @@ ), pytest.param( p256verify_spec.Spec.P256VERIFY, - concatenate_parameters( - [ - "235060CAFE19A407880C272BC3E73600E3A12294F56143ED61929C2FF4525ABB", - "182E5CBDF96ACCB859E8EEA1850DE5FF6E430A19D1D9A680ECD5946BBEA8A32B", - "76DDFAE6797FA6777CAAB9FA10E75F52E70A4E6CEB117B3C5B2F445D850BD64C", - "3828736CDFC4C8696008F71999260329AD8B12287846FEDCEDE3BA1205B12729", - "3E5141734E971A8D55015068D9B3666760F4608A49B11F92E500ACEA647978C7", - ] + H( + value=0x235060CAFE19A407880C272BC3E73600E3A12294F56143ED61929C2FF4525ABB + ) + + R( + value=0x182E5CBDF96ACCB859E8EEA1850DE5FF6E430A19D1D9A680ECD5946BBEA8A32B + ) + + S( + value=0x76DDFAE6797FA6777CAAB9FA10E75F52E70A4E6CEB117B3C5B2F445D850BD64C + ) + + X( + value=0x3828736CDFC4C8696008F71999260329AD8B12287846FEDCEDE3BA1205B12729 + ) + + Y( + value=0x3E5141734E971A8D55015068D9B3666760F4608A49B11F92E500ACEA647978C7 ), id="p256verify_wrong_endianness", ), pytest.param( p256verify_spec.Spec.P256VERIFY, - concatenate_parameters( - [ - "BB5A52F42F9C9261ED4361F59422A1E30036E7C32B270C8807A419FECA605023", - "000000000000000000000000000000004319055358E8617B0C46353D039CDAAB", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254E", - "0AD99500288D466940031D72A9F5445A4D43784640855BF0A69874D2DE5FE103", - "C5011E6EF2C42DCD50D5D3D29F99AE6EBA2C80C9244F4C5422F0979FF0C3BA5E", - ] + H( + value=0xBB5A52F42F9C9261ED4361F59422A1E30036E7C32B270C8807A419FECA605023 + ) + + R( + value=0x000000000000000000000000000000004319055358E8617B0C46353D039CDAAB + ) + + S( + value=0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254E + ) + + X( + value=0x0AD99500288D466940031D72A9F5445A4D43784640855BF0A69874D2DE5FE103 + ) + + Y( + value=0xC5011E6EF2C42DCD50D5D3D29F99AE6EBA2C80C9244F4C5422F0979FF0C3BA5E ), id="p256verify_modular_comp_x_coordinate_exceeds_n", ), @@ -101,15 +109,11 @@ def test_p256verify( [ pytest.param( p256verify_spec.Spec.P256VERIFY, - concatenate_parameters( - [ - p256verify_spec.Spec.H0, - p256verify_spec.Spec.R0, - p256verify_spec.Spec.S0, - p256verify_spec.Spec.X0, - p256verify_spec.Spec.Y0, - ] - ), + p256verify_spec.Spec.H0 + + p256verify_spec.Spec.R0 + + p256verify_spec.Spec.S0 + + p256verify_spec.Spec.X0 + + p256verify_spec.Spec.Y0, id="p256verify", ), ], diff --git a/tests/benchmark/compute/precompile/test_point_evaluation.py b/tests/benchmark/compute/precompile/test_point_evaluation.py index c4b76c07962..e8ab7eac799 100644 --- a/tests/benchmark/compute/precompile/test_point_evaluation.py +++ b/tests/benchmark/compute/precompile/test_point_evaluation.py @@ -18,10 +18,10 @@ ) from execution_testing.test_types.blob_types import Blob +from tests.benchmark.compute.helpers import Precompile +from tests.cancun.eip4844_blobs.spec import PointEvaluationInput from tests.cancun.eip4844_blobs.spec import Spec as BlobsSpec -from ..helpers import Precompile, concatenate_parameters - INPUT_SIZE = 192 @@ -31,14 +31,21 @@ [ pytest.param( BlobsSpec.POINT_EVALUATION_PRECOMPILE_ADDRESS, - concatenate_parameters( - [ - "01E798154708FE7789429634053CBF9F99B619F9F084048927333FCE637F549B", - "564C0A11A0F704F4FC3E8ACFE0F8245F0AD1347B378FBF96E206DA11A5D36306", - "24D25032E67A7E6A4910DF5834B8FE70E6BCFEEAC0352434196BDF4B2485D5A1", - "8F59A8D2A1A625A17F3FEA0FE5EB8C896DB3764F3185481BC22F91B4AAFFCCA25F26936857BC3A7C2539EA8EC3A952B7", - "873033E038326E87ED3E1276FD140253FA08E9FC25FB2D9A98527FC22A2C9612FBEAFDAD446CBC7BCDBDCD780AF2C16A", - ] + PointEvaluationInput( + versioned_hash=bytes.fromhex( + "01E798154708FE7789429634053CBF9F" + "99B619F9F084048927333FCE637F549B" + ), + z=0x564C0A11A0F704F4FC3E8ACFE0F8245F0AD1347B378FBF96E206DA11A5D36306, + y=0x24D25032E67A7E6A4910DF5834B8FE70E6BCFEEAC0352434196BDF4B2485D5A1, + commitment=bytes.fromhex( + "8F59A8D2A1A625A17F3FEA0FE5EB8C896DB3764F3185481BC22F91B4AAFFCCA2" + "5F26936857BC3A7C2539EA8EC3A952B7" + ), + proof=bytes.fromhex( + "873033E038326E87ED3E1276FD140253FA08E9FC25FB2D9A98527FC22A2C9612" + "FBEAFDAD446CBC7BCDBDCD780AF2C16A" + ), ), id="point_evaluation", ), @@ -85,7 +92,15 @@ def _generate_point_evaluation_input( proof_bytes, y_bytes = ckzg.compute_kzg_proof( blob_data, z_bytes, trusted_setup ) - return versioned_hash + z_bytes + y_bytes + commitment + proof_bytes + return bytes( + PointEvaluationInput( + versioned_hash=versioned_hash, + z=z, + y=int.from_bytes(y_bytes, "big"), + commitment=commitment, + proof=proof_bytes, + ) + ) @pytest.mark.repricing diff --git a/tests/benchmark/compute/precompile/test_ripemd160.py b/tests/benchmark/compute/precompile/test_ripemd160.py index bd433921301..7527eb48f3e 100644 --- a/tests/benchmark/compute/precompile/test_ripemd160.py +++ b/tests/benchmark/compute/precompile/test_ripemd160.py @@ -16,7 +16,11 @@ WhileGas, ) -from ..helpers import Precompile, calculate_optimal_input_length +from tests.benchmark.compute.helpers import ( + Precompile, + calculate_optimal_input_length, +) +from tests.frontier.precompiles.spec import Spec as PrecompilesSpec def test_ripemd160( @@ -39,7 +43,12 @@ def test_ripemd160( attack_block = Op.POP( Op.STATICCALL( - Op.GAS, 0x03, Op.PUSH0, optimal_input_length, Op.PUSH0, Op.PUSH0 + Op.GAS, + PrecompilesSpec.RIPEMD160, + Op.PUSH0, + optimal_input_length, + Op.PUSH0, + Op.PUSH0, ) ) @@ -59,7 +68,14 @@ def test_ripemd160_fixed_size( ) -> None: """Benchmark RIPEMD160 with fixed size input.""" attack_block = Op.POP( - Op.STATICCALL(Op.GAS, 0x03, Op.PUSH0, size, Op.PUSH0, Op.PUSH0) + Op.STATICCALL( + Op.GAS, + PrecompilesSpec.RIPEMD160, + Op.PUSH0, + size, + Op.PUSH0, + Op.PUSH0, + ) ) benchmark_test( @@ -94,7 +110,7 @@ def test_ripemd160_uncachable( attack_block = Op.POP( Op.STATICCALL( gas=Op.GAS, - address=0x03, + address=PrecompilesSpec.RIPEMD160, args_size=size, ret_size=0x20, # gas accounting diff --git a/tests/benchmark/compute/precompile/test_sha256.py b/tests/benchmark/compute/precompile/test_sha256.py index 967bb4f2218..2960fae90b4 100644 --- a/tests/benchmark/compute/precompile/test_sha256.py +++ b/tests/benchmark/compute/precompile/test_sha256.py @@ -16,7 +16,11 @@ WhileGas, ) -from ..helpers import Precompile, calculate_optimal_input_length +from tests.benchmark.compute.helpers import ( + Precompile, + calculate_optimal_input_length, +) +from tests.frontier.precompiles.spec import Spec as PrecompilesSpec def test_sha256( @@ -39,7 +43,12 @@ def test_sha256( attack_block = Op.POP( Op.STATICCALL( - Op.GAS, 0x02, Op.PUSH0, optimal_input_length, Op.PUSH0, Op.PUSH0 + Op.GAS, + PrecompilesSpec.SHA256, + Op.PUSH0, + optimal_input_length, + Op.PUSH0, + Op.PUSH0, ) ) @@ -59,7 +68,14 @@ def test_sha256_fixed_size( ) -> None: """Benchmark SHA256 with fixed size input.""" attack_block = Op.POP( - Op.STATICCALL(Op.GAS, 0x02, Op.PUSH0, size, Op.PUSH0, Op.PUSH0) + Op.STATICCALL( + Op.GAS, + PrecompilesSpec.SHA256, + Op.PUSH0, + size, + Op.PUSH0, + Op.PUSH0, + ) ) benchmark_test( @@ -93,7 +109,7 @@ def test_sha256_uncachable( attack_block = Op.POP( Op.STATICCALL( gas=Op.GAS, - address=0x02, + address=PrecompilesSpec.SHA256, args_size=size, ret_size=0x20, # gas accounting diff --git a/tests/cancun/eip4844_blobs/spec.py b/tests/cancun/eip4844_blobs/spec.py index 430137bf475..a30a0da24d9 100644 --- a/tests/cancun/eip4844_blobs/spec.py +++ b/tests/cancun/eip4844_blobs/spec.py @@ -7,7 +7,36 @@ from typing import List, Optional, Set, Tuple import pytest -from execution_testing import Fork, ParameterSet, Transaction +from execution_testing import ( + BytesConcatenation, + Fork, + ParameterSet, + Transaction, +) + + +@dataclass(frozen=True) +class PointEvaluationInput(BytesConcatenation): + """ + EIP-4844 KZG point-evaluation precompile input (192 bytes): + versioned_hash (32) || z (32) || y (32) || commitment (48) || proof (48). + """ + + versioned_hash: bytes + z: int + y: int + commitment: bytes + proof: bytes + + def __bytes__(self) -> bytes: + """Convert input to bytes.""" + return ( + self.versioned_hash + + self.z.to_bytes(32, byteorder="big") + + self.y.to_bytes(32, byteorder="big") + + self.commitment + + self.proof + ) @dataclass(frozen=True) diff --git a/tests/frontier/identity_precompile/spec.py b/tests/frontier/identity_precompile/spec.py new file mode 100644 index 00000000000..0d9fce9c5a2 --- /dev/null +++ b/tests/frontier/identity_precompile/spec.py @@ -0,0 +1,12 @@ +"""Defines spec constants for the IDENTITY precompile.""" + +from dataclasses import dataclass + +from execution_testing import Address + + +@dataclass(frozen=True) +class Spec: + """Parameters for the IDENTITY precompile (frontier).""" + + IDENTITY = Address(0x04) diff --git a/tests/frontier/precompiles/spec.py b/tests/frontier/precompiles/spec.py new file mode 100644 index 00000000000..68ecdf7e572 --- /dev/null +++ b/tests/frontier/precompiles/spec.py @@ -0,0 +1,34 @@ +"""Defines spec constants and input types for the ECRECOVER precompile.""" + +from dataclasses import dataclass + +from execution_testing import Address, BytesConcatenation + + +@dataclass(frozen=True) +class EcrecoverInput(BytesConcatenation): + """ + ECRECOVER precompile input: 32-byte message hash, 32-byte v, 32-byte r, + 32-byte s — concatenated big-endian (128 bytes total). + """ + + msg_hash: int + v: int + r: int + s: int + + def __bytes__(self) -> bytes: + """Convert input to bytes.""" + return b"".join( + x.to_bytes(32, byteorder="big") + for x in (self.msg_hash, self.v, self.r, self.s) + ) + + +@dataclass(frozen=True) +class Spec: + """Parameters for the frontier precompiles.""" + + ECRECOVER = Address(0x01) + SHA256 = Address(0x02) + RIPEMD160 = Address(0x03) From 44923d4bcdbcaa48ef1536a453c390a0ebf08220 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 12 May 2026 00:25:36 +0200 Subject: [PATCH 069/186] feat(test-cli): always print full pytest command in ci & add to summary (#2719) * chore(ci): always print the full pytest command in CI Check the `CI` environment variable so that `fill` (and other pytest-based commands) print the resolved `pytest ...` command line in GitHub Actions without requiring `-v`. * doc(test-cli): note that CI prints the resolved pytest command Add a "Debugging CI Failures" subsection to `docs/dev/test_actions_locally.md` pointing readers at the `Executing: pytest ...` line printed when `CI` is set, so failing Github Actions jobs can be reproduced locally without `gh act`. * feat(test-cli): append pytest command to Github Actions job summary When `$GITHUB_STEP_SUMMARY` is set, `PytestRunner` now also appends the resolved `pytest ...` invocation to the step summary as a fenced code block, so it can be copied from the Actions "Summary" panel of a failing run instead of scrolling through the log. Outside Github Actions the env var is unset and behavior is unchanged. --- docs/dev/test_actions_locally.md | 10 ++++++++++ .../cli/pytest_commands/base.py | 20 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/dev/test_actions_locally.md b/docs/dev/test_actions_locally.md index b1c07016988..6a9e890cf02 100644 --- a/docs/dev/test_actions_locally.md +++ b/docs/dev/test_actions_locally.md @@ -111,3 +111,13 @@ It's possible to specify the Docker image used by the `act` tool for a specific ``` This can be added to any `gh act` command. + +## Debugging CI Failures + +The pytest-based CLIs (`fill`, `execute`, ...) print the resolved `pytest ...` invocation at startup whenever the `CI` environment variable is set: + +```text +Executing: pytest ... +``` + +When run under Github Actions, the same command is also appended to the job summary (via `$GITHUB_STEP_SUMMARY`), so it can be copied directly from the "Summary" panel of the failing run without scrolling through the log. diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/base.py b/packages/testing/src/execution_testing/cli/pytest_commands/base.py index 612ecc9ccb3..328342c3904 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/base.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/base.py @@ -1,5 +1,6 @@ """Base classes and utilities for pytest-based CLI commands.""" +import os import sys from abc import ABC, abstractmethod from dataclasses import dataclass, field @@ -57,6 +58,15 @@ class PytestRunner: console: Console = field(default_factory=lambda: Console(highlight=False)) """Console to use for output.""" + error_console: Console = field( + default_factory=lambda: Console(stderr=True, highlight=False) + ) + """Console for diagnostic output. + + Written to stderr so it doesn't pollute stdout captures such as the + `fill --help` subprocess in `docs/scripts/generate_fill_help.py`. + """ + def run_single(self, execution: PytestExecution) -> int: """Run pytest once with the given configuration and arguments.""" root_dir_arg = ["--rootdir", "."] @@ -75,9 +85,15 @@ def run_single(self, execution: PytestExecution) -> int: "execution_testing.cli." "pytest_commands.plugins.fix_package_test_path", ] - if self._is_verbose(execution.args): + if self._is_verbose(execution.args) or "CI" in os.environ: pytest_cmd = f"pytest {' '.join(pytest_args)}" - self.console.print(f"Executing: [bold]{pytest_cmd}[/bold]") + self.error_console.print(f"Executing: [bold]{pytest_cmd}[/bold]") + summary_path = os.environ.get("GITHUB_STEP_SUMMARY") + if summary_path: + with Path(summary_path).open("a") as summary: + summary.write( + f"### Executing\n\n```bash\n{pytest_cmd}\n```\n\n" + ) return pytest.main(pytest_args) From 87c52b41144feac9b42b7b8913a147571d5553c5 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Date: Tue, 12 May 2026 08:33:37 +0200 Subject: [PATCH 070/186] refactor(specs): port state refactor to older forks (#2750) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(specs): apply state refactor to bpo forks * refactor(specs): apply state refactor to post-merge forks Apply the state tracker refactor (originally done for amsterdam) to the remaining post-merge forks: osaka, prague, cancun, shanghai, and paris. For each fork: - Delete fork-specific state.py and trie.py - Add fork-specific state_tracker.py with BlockState, TransactionState, and the associated read/write helpers - Update fork.py to wrap chain.state in a BlockState, thread TransactionState through check_transaction / process_transaction / system transactions / withdrawals, and apply the block diff via apply_changes_to_state at the end of state_transition - Update vm/__init__.py to use BlockState/TransactionState and import Trie from ethereum.merkle_patricia_trie - Update interpreter to use copy_tx_state/restore_tx_state in place of begin/commit/rollback_transaction - Update utils/message.py, vm/eoa_delegation.py, and vm/instructions/* to read state via evm.message.tx_env.state - Update blocks.py docstring cross-refs to the shared state / trie modules * refactor(specs): apply state refactor to pre-merge forks Apply the state tracker refactor (originally done for amsterdam) to the remaining pre-merge forks: gray_glacier, arrow_glacier, london, berlin, muir_glacier, istanbul, constantinople, byzantium, spurious_dragon, tangerine_whistle, dao_fork, homestead, and frontier. For each fork: - Delete fork-specific state.py and trie.py - Add fork-specific state_tracker.py with BlockState, TransactionState, and the associated read/write helpers - Update fork.py to wrap chain.state in a BlockState, thread TransactionState through check_transaction / process_transaction / block-reward payout, and apply the block diff via apply_changes_to_state at the end of state_transition - Update vm/__init__.py to use BlockState/TransactionState and import Trie from ethereum.merkle_patricia_trie - Update interpreter to use copy_tx_state/restore_tx_state in place of begin/commit/rollback_transaction - Update utils/message.py and vm/instructions/* to read state via evm.message.tx_env.state - Update blocks.py docstring cross-refs to the shared state / trie modules For pre-merge forks, the state_tracker also exposes `create_ether` (used for paying ommer/miner rewards) and the pre-EIP-161 forks have `destroy_touched_empty_accounts` and `touch_account`. Pre-byzantium receipts include an intermediate state root, computed by committing the tx's writes to the block state and calling `pre_state.compute_state_root_and_trie_changes` on the accumulated block diff. The DAO fork irregular state transition now creates a throwaway BlockState/TransactionState, applies the moves, and flushes the diff back to `chain.state`. * fix(specs): track storage clears across pre-EIP-6780 destructions Pre-EIP-6780 ``SELFDESTRUCT`` fully wipes an account's storage, and a later ``CREATE2`` at the same address must start from empty storage. After the state refactor, ``destroy_storage`` only removed tx-level writes, so reads still fell through to the pre_state's storage trie — ``CREATE2`` then saw ``account_has_storage`` return True and bailed without bumping the nonce. Track wiped addresses in a new ``storage_clears`` set on ``BlockState``, ``TransactionState``, and ``BlockDiff``. Reads short-circuit on it, and ``compute_state_root_and_trie_changes`` / ``apply_changes_to_state`` drop the corresponding storage tries before re-applying writes, so post-wipe writes begin from empty storage. Applies to Frontier through Shanghai; post-6780 forks leave the set empty. * refactor(evm_tools): wire t8n through ForkLoad accessors The t8n tool kept a mix of direct imports from ``amsterdam`` and raw ``_module(...)`` lookups into each fork's ``state_tracker`` and ``block_access_lists`` modules, and ``ForkLoad`` still carried fallback shims for helpers (``State``, ``set_account``, ``copy_trie``, ``root``, etc.) that now live exclusively in the shared ``ethereum.state`` and ``ethereum.merkle_patricia_trie`` modules. Collapse all three: * Drop the fork-independent shims from ``ForkLoad`` and import the helpers directly at the t8n / fixture-loader call sites. * Expose ``BlockState``, ``TransactionState``, ``extract_block_diff``, ``incorporate_tx_into_block``, ``BlockAccessIndex``, ``BlockAccessListBuilder``, and ``validate_block_access_list_gas_limit`` as ``ForkLoad`` properties so t8n never has to hardcode ``amsterdam`` or reach into ``_module``. * Fix ``pay_block_rewards`` to wrap ``BlockState`` in a ``TransactionState`` via the fork's own state_tracker (the previous code passed the block-scoped state straight to ``create_ether``, which expects the tx-scoped wrapper). * Remove the now-dead ``has_block_state`` feature flag and its fallback branches — every fork has a ``state_tracker`` module. * chore(tests): adjust json_loader tests for the state refactor Point the json_loader tests at the shared ``ethereum.state`` and ``ethereum.merkle_patricia_trie`` modules now that per-fork ``state`` and ``trie`` modules no longer exist, and switch to the State-method accessors (``state.get_storage(...)`` etc.) instead of the old module-level functions. Skip ``test_optimized_state`` wholesale: the optimized state integration still imports per-fork ``state`` modules and exposes a pre-refactor ``destroy_storage(state, addr)`` API, both removed by the refactor. Tracked by https://github.com/ethereum/execution-specs/issues/2256 pending the optimized state redesign. Extend ``vulture_whitelist.py`` to cover the ``@add_item``-registered ``begin_transaction`` / ``commit_transaction`` / ``rollback_transaction`` patches in ``ethereum_optimized.state_db``. * refactor(specs): drop fork_types re-exports of shared state types The state refactor initially re-imported ``Account``, ``Address``, ``EMPTY_ACCOUNT``, and ``EMPTY_CODE_HASH`` from ``ethereum.state`` into each pre-merge fork's ``fork_types.py`` (plus a matching ``__all__``) so existing call sites like ``from .fork_types import Address`` could stay untouched. ``Root`` was similarly duplicated as ``Root = Hash32`` in every fork. ``docc`` does not follow ``__all__`` re-exports when resolving cross-references, which breaks ``just docs-spec`` on the first consumer that imports ``EMPTY_ACCOUNT`` through a fork's ``fork_types``. Drop the re-exports from all 13 pre-merge forks and import the shared symbols directly from ``ethereum.state`` at every call site — matching the shape that shanghai / paris already use. Each ``fork_types.py`` collapses to ``Bloom``, ``encode_account``, and the ``Account`` type import that ``encode_account`` needs. Also update ``tests/json_loader/test_optimized_state.py`` to import ``EMPTY_ACCOUNT`` from ``ethereum.state`` rather than through the dropped ``frontier.fork_types`` re-export. * refactor(specs): address PR #2750 review feedback Apply review suggestions from @SamWilsn: * ``ethereum.state.BlockDiff.storage_clears`` docstring switches to markdown style with a cross-ref to ``storage_changes``, so docc renders the link. * In every fork's ``state_tracker.get_account``, replace the ``isinstance(account, Account)`` guard with an explicit ``if account is None`` check. The ``isinstance`` was a leftover from when ``fork_types.Account`` was a separate class; now that every fork pulls ``Account`` directly from ``ethereum.state``, the ``is None`` form expresses the intent ("is there an account?") rather than the implementation ("is this an account?"). * Reintroduce the ``create_ether`` helper in every post-merge fork's state tracker (paris through bpo5). It was dropped during the post-merge state refactor because the PoS forks no longer ``pay_rewards`` to a miner, but it remains the natural helper for ``process_withdrawals``. Updates the withdrawal call sites in shanghai onwards (paris itself has no caller; ``create_ether`` is added there purely to keep sibling parity with london and shanghai). Also relocate ``create_ether`` in every pre-merge fork from its legacy spot in the trailing "Pre-EIP-161 cleanup" section to immediately after ``move_ether`` — they are structurally the same kind of balance mutator, and the new placement is consistent across every fork. * Rewrite the ``untracked_state`` comment in ``process_checked_system_transaction`` (prague through bpo5) to make the throwaway-scope and "always calls process_unchecked_system_transaction below" contracts explicit. --- src/ethereum/forks/amsterdam/fork.py | 21 +- src/ethereum/forks/amsterdam/state_tracker.py | 29 +- src/ethereum/forks/arrow_glacier/blocks.py | 22 +- src/ethereum/forks/arrow_glacier/fork.py | 91 +- .../forks/arrow_glacier/fork_types.py | 32 +- src/ethereum/forks/arrow_glacier/state.py | 672 --------------- .../forks/arrow_glacier/state_tracker.py | 803 ++++++++++++++++++ .../forks/arrow_glacier/transactions.py | 2 +- src/ethereum/forks/arrow_glacier/trie.py | 498 ----------- .../forks/arrow_glacier/utils/hexadecimal.py | 4 +- .../forks/arrow_glacier/utils/message.py | 8 +- .../forks/arrow_glacier/vm/__init__.py | 15 +- .../vm/instructions/environment.py | 21 +- .../arrow_glacier/vm/instructions/storage.py | 15 +- .../arrow_glacier/vm/instructions/system.py | 40 +- .../forks/arrow_glacier/vm/interpreter.py | 67 +- src/ethereum/forks/berlin/blocks.py | 22 +- src/ethereum/forks/berlin/fork.py | 91 +- src/ethereum/forks/berlin/fork_types.py | 32 +- src/ethereum/forks/berlin/state.py | 672 --------------- src/ethereum/forks/berlin/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/berlin/transactions.py | 2 +- src/ethereum/forks/berlin/trie.py | 498 ----------- .../forks/berlin/utils/hexadecimal.py | 4 +- src/ethereum/forks/berlin/utils/message.py | 8 +- src/ethereum/forks/berlin/vm/__init__.py | 15 +- .../berlin/vm/instructions/environment.py | 21 +- .../forks/berlin/vm/instructions/storage.py | 15 +- .../forks/berlin/vm/instructions/system.py | 40 +- src/ethereum/forks/berlin/vm/interpreter.py | 67 +- src/ethereum/forks/bpo1/blocks.py | 19 +- src/ethereum/forks/bpo1/fork.py | 212 +++-- src/ethereum/forks/bpo1/requests.py | 2 +- src/ethereum/forks/bpo1/state.py | 713 ---------------- src/ethereum/forks/bpo1/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/bpo1/trie.py | 502 ----------- src/ethereum/forks/bpo1/utils/message.py | 9 +- src/ethereum/forks/bpo1/vm/__init__.py | 8 +- src/ethereum/forks/bpo1/vm/eoa_delegation.py | 22 +- .../forks/bpo1/vm/instructions/environment.py | 17 +- .../forks/bpo1/vm/instructions/storage.py | 19 +- .../forks/bpo1/vm/instructions/system.py | 34 +- src/ethereum/forks/bpo1/vm/interpreter.py | 66 +- src/ethereum/forks/bpo2/blocks.py | 19 +- src/ethereum/forks/bpo2/fork.py | 212 +++-- src/ethereum/forks/bpo2/requests.py | 2 +- src/ethereum/forks/bpo2/state.py | 713 ---------------- src/ethereum/forks/bpo2/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/bpo2/trie.py | 502 ----------- src/ethereum/forks/bpo2/utils/message.py | 9 +- src/ethereum/forks/bpo2/vm/__init__.py | 8 +- src/ethereum/forks/bpo2/vm/eoa_delegation.py | 22 +- .../forks/bpo2/vm/instructions/environment.py | 17 +- .../forks/bpo2/vm/instructions/storage.py | 19 +- .../forks/bpo2/vm/instructions/system.py | 34 +- src/ethereum/forks/bpo2/vm/interpreter.py | 66 +- src/ethereum/forks/bpo3/blocks.py | 19 +- src/ethereum/forks/bpo3/fork.py | 212 +++-- src/ethereum/forks/bpo3/requests.py | 2 +- src/ethereum/forks/bpo3/state.py | 713 ---------------- src/ethereum/forks/bpo3/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/bpo3/trie.py | 502 ----------- src/ethereum/forks/bpo3/utils/message.py | 9 +- src/ethereum/forks/bpo3/vm/__init__.py | 8 +- src/ethereum/forks/bpo3/vm/eoa_delegation.py | 22 +- .../forks/bpo3/vm/instructions/environment.py | 17 +- .../forks/bpo3/vm/instructions/storage.py | 19 +- .../forks/bpo3/vm/instructions/system.py | 34 +- src/ethereum/forks/bpo3/vm/interpreter.py | 66 +- src/ethereum/forks/bpo4/blocks.py | 19 +- src/ethereum/forks/bpo4/fork.py | 212 +++-- src/ethereum/forks/bpo4/requests.py | 2 +- src/ethereum/forks/bpo4/state.py | 713 ---------------- src/ethereum/forks/bpo4/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/bpo4/trie.py | 502 ----------- src/ethereum/forks/bpo4/utils/message.py | 9 +- src/ethereum/forks/bpo4/vm/__init__.py | 8 +- src/ethereum/forks/bpo4/vm/eoa_delegation.py | 22 +- .../forks/bpo4/vm/instructions/environment.py | 17 +- .../forks/bpo4/vm/instructions/storage.py | 19 +- .../forks/bpo4/vm/instructions/system.py | 34 +- src/ethereum/forks/bpo4/vm/interpreter.py | 66 +- src/ethereum/forks/bpo5/blocks.py | 19 +- src/ethereum/forks/bpo5/fork.py | 212 +++-- src/ethereum/forks/bpo5/requests.py | 2 +- src/ethereum/forks/bpo5/state.py | 713 ---------------- src/ethereum/forks/bpo5/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/bpo5/trie.py | 502 ----------- src/ethereum/forks/bpo5/utils/message.py | 9 +- src/ethereum/forks/bpo5/vm/__init__.py | 8 +- src/ethereum/forks/bpo5/vm/eoa_delegation.py | 22 +- .../forks/bpo5/vm/instructions/environment.py | 17 +- .../forks/bpo5/vm/instructions/storage.py | 19 +- .../forks/bpo5/vm/instructions/system.py | 34 +- src/ethereum/forks/bpo5/vm/interpreter.py | 66 +- src/ethereum/forks/byzantium/blocks.py | 22 +- src/ethereum/forks/byzantium/fork.py | 91 +- src/ethereum/forks/byzantium/fork_types.py | 31 +- src/ethereum/forks/byzantium/state.py | 611 ------------- src/ethereum/forks/byzantium/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/byzantium/transactions.py | 3 +- src/ethereum/forks/byzantium/trie.py | 498 ----------- .../forks/byzantium/utils/hexadecimal.py | 4 +- src/ethereum/forks/byzantium/utils/message.py | 8 +- src/ethereum/forks/byzantium/vm/__init__.py | 15 +- .../byzantium/vm/instructions/environment.py | 15 +- .../byzantium/vm/instructions/storage.py | 13 +- .../forks/byzantium/vm/instructions/system.py | 42 +- .../forks/byzantium/vm/interpreter.py | 59 +- src/ethereum/forks/cancun/blocks.py | 19 +- src/ethereum/forks/cancun/fork.py | 131 ++- src/ethereum/forks/cancun/state.py | 713 ---------------- src/ethereum/forks/cancun/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/cancun/trie.py | 502 ----------- src/ethereum/forks/cancun/utils/message.py | 10 +- src/ethereum/forks/cancun/vm/__init__.py | 8 +- .../cancun/vm/instructions/environment.py | 17 +- .../forks/cancun/vm/instructions/storage.py | 19 +- .../forks/cancun/vm/instructions/system.py | 38 +- src/ethereum/forks/cancun/vm/interpreter.py | 62 +- src/ethereum/forks/constantinople/blocks.py | 22 +- src/ethereum/forks/constantinople/fork.py | 91 +- .../forks/constantinople/fork_types.py | 32 +- src/ethereum/forks/constantinople/state.py | 611 ------------- .../forks/constantinople/state_tracker.py | 803 ++++++++++++++++++ .../forks/constantinople/transactions.py | 3 +- src/ethereum/forks/constantinople/trie.py | 498 ----------- .../forks/constantinople/utils/hexadecimal.py | 4 +- .../forks/constantinople/utils/message.py | 8 +- .../forks/constantinople/vm/__init__.py | 15 +- .../vm/instructions/environment.py | 19 +- .../constantinople/vm/instructions/storage.py | 13 +- .../constantinople/vm/instructions/system.py | 40 +- .../forks/constantinople/vm/interpreter.py | 59 +- src/ethereum/forks/dao_fork/blocks.py | 22 +- src/ethereum/forks/dao_fork/dao.py | 20 +- src/ethereum/forks/dao_fork/fork.py | 97 ++- src/ethereum/forks/dao_fork/fork_types.py | 32 +- src/ethereum/forks/dao_fork/state.py | 543 ------------ src/ethereum/forks/dao_fork/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/dao_fork/transactions.py | 3 +- src/ethereum/forks/dao_fork/trie.py | 498 ----------- .../forks/dao_fork/utils/hexadecimal.py | 4 +- src/ethereum/forks/dao_fork/utils/message.py | 8 +- src/ethereum/forks/dao_fork/vm/__init__.py | 7 +- src/ethereum/forks/dao_fork/vm/gas.py | 4 +- .../dao_fork/vm/instructions/environment.py | 15 +- .../forks/dao_fork/vm/instructions/storage.py | 13 +- .../forks/dao_fork/vm/instructions/system.py | 38 +- src/ethereum/forks/dao_fork/vm/interpreter.py | 49 +- src/ethereum/forks/frontier/blocks.py | 22 +- src/ethereum/forks/frontier/fork.py | 97 ++- src/ethereum/forks/frontier/fork_types.py | 32 +- src/ethereum/forks/frontier/state.py | 543 ------------ src/ethereum/forks/frontier/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/frontier/transactions.py | 3 +- src/ethereum/forks/frontier/trie.py | 498 ----------- .../forks/frontier/utils/hexadecimal.py | 4 +- src/ethereum/forks/frontier/utils/message.py | 8 +- src/ethereum/forks/frontier/vm/__init__.py | 7 +- src/ethereum/forks/frontier/vm/gas.py | 4 +- .../frontier/vm/instructions/environment.py | 15 +- .../forks/frontier/vm/instructions/storage.py | 13 +- .../forks/frontier/vm/instructions/system.py | 38 +- src/ethereum/forks/frontier/vm/interpreter.py | 47 +- src/ethereum/forks/gray_glacier/blocks.py | 19 +- src/ethereum/forks/gray_glacier/fork.py | 92 +- src/ethereum/forks/gray_glacier/fork_types.py | 32 +- src/ethereum/forks/gray_glacier/state.py | 672 --------------- .../forks/gray_glacier/state_tracker.py | 803 ++++++++++++++++++ .../forks/gray_glacier/transactions.py | 2 +- src/ethereum/forks/gray_glacier/trie.py | 498 ----------- .../forks/gray_glacier/utils/message.py | 8 +- .../forks/gray_glacier/vm/__init__.py | 15 +- .../vm/instructions/environment.py | 21 +- .../gray_glacier/vm/instructions/storage.py | 15 +- .../gray_glacier/vm/instructions/system.py | 40 +- .../forks/gray_glacier/vm/interpreter.py | 67 +- src/ethereum/forks/homestead/blocks.py | 22 +- src/ethereum/forks/homestead/fork.py | 97 ++- src/ethereum/forks/homestead/fork_types.py | 32 +- src/ethereum/forks/homestead/state.py | 543 ------------ src/ethereum/forks/homestead/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/homestead/transactions.py | 3 +- src/ethereum/forks/homestead/trie.py | 498 ----------- .../forks/homestead/utils/hexadecimal.py | 4 +- src/ethereum/forks/homestead/utils/message.py | 8 +- src/ethereum/forks/homestead/vm/__init__.py | 7 +- src/ethereum/forks/homestead/vm/gas.py | 4 +- .../homestead/vm/instructions/environment.py | 15 +- .../homestead/vm/instructions/storage.py | 13 +- .../forks/homestead/vm/instructions/system.py | 38 +- .../forks/homestead/vm/interpreter.py | 49 +- src/ethereum/forks/istanbul/blocks.py | 22 +- src/ethereum/forks/istanbul/fork.py | 91 +- src/ethereum/forks/istanbul/fork_types.py | 32 +- src/ethereum/forks/istanbul/state.py | 672 --------------- src/ethereum/forks/istanbul/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/istanbul/transactions.py | 3 +- src/ethereum/forks/istanbul/trie.py | 498 ----------- .../forks/istanbul/utils/hexadecimal.py | 4 +- src/ethereum/forks/istanbul/utils/message.py | 8 +- src/ethereum/forks/istanbul/vm/__init__.py | 15 +- .../istanbul/vm/instructions/environment.py | 21 +- .../forks/istanbul/vm/instructions/storage.py | 15 +- .../forks/istanbul/vm/instructions/system.py | 40 +- src/ethereum/forks/istanbul/vm/interpreter.py | 67 +- src/ethereum/forks/london/blocks.py | 22 +- src/ethereum/forks/london/fork.py | 91 +- src/ethereum/forks/london/fork_types.py | 32 +- src/ethereum/forks/london/state.py | 672 --------------- src/ethereum/forks/london/state_tracker.py | 803 ++++++++++++++++++ src/ethereum/forks/london/transactions.py | 2 +- src/ethereum/forks/london/trie.py | 498 ----------- .../forks/london/utils/hexadecimal.py | 4 +- src/ethereum/forks/london/utils/message.py | 8 +- src/ethereum/forks/london/vm/__init__.py | 15 +- .../london/vm/instructions/environment.py | 21 +- .../forks/london/vm/instructions/storage.py | 15 +- .../forks/london/vm/instructions/system.py | 40 +- src/ethereum/forks/london/vm/interpreter.py | 67 +- src/ethereum/forks/muir_glacier/blocks.py | 22 +- src/ethereum/forks/muir_glacier/fork.py | 91 +- src/ethereum/forks/muir_glacier/fork_types.py | 32 +- src/ethereum/forks/muir_glacier/state.py | 672 --------------- .../forks/muir_glacier/state_tracker.py | 803 ++++++++++++++++++ .../forks/muir_glacier/transactions.py | 3 +- src/ethereum/forks/muir_glacier/trie.py | 498 ----------- .../forks/muir_glacier/utils/hexadecimal.py | 4 +- .../forks/muir_glacier/utils/message.py | 8 +- .../forks/muir_glacier/vm/__init__.py | 15 +- .../vm/instructions/environment.py | 21 +- .../muir_glacier/vm/instructions/storage.py | 15 +- .../muir_glacier/vm/instructions/system.py | 40 +- .../forks/muir_glacier/vm/interpreter.py | 67 +- src/ethereum/forks/osaka/blocks.py | 19 +- src/ethereum/forks/osaka/fork.py | 212 +++-- src/ethereum/forks/osaka/requests.py | 2 +- src/ethereum/forks/osaka/state.py | 713 ---------------- src/ethereum/forks/osaka/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/osaka/trie.py | 502 ----------- src/ethereum/forks/osaka/utils/message.py | 9 +- src/ethereum/forks/osaka/vm/__init__.py | 8 +- src/ethereum/forks/osaka/vm/eoa_delegation.py | 22 +- .../osaka/vm/instructions/environment.py | 17 +- .../forks/osaka/vm/instructions/storage.py | 19 +- .../forks/osaka/vm/instructions/system.py | 34 +- src/ethereum/forks/osaka/vm/interpreter.py | 66 +- src/ethereum/forks/paris/blocks.py | 19 +- src/ethereum/forks/paris/fork.py | 64 +- src/ethereum/forks/paris/state.py | 635 -------------- src/ethereum/forks/paris/state_tracker.py | 772 +++++++++++++++++ src/ethereum/forks/paris/trie.py | 499 ----------- src/ethereum/forks/paris/utils/message.py | 10 +- src/ethereum/forks/paris/vm/__init__.py | 7 +- .../paris/vm/instructions/environment.py | 17 +- .../forks/paris/vm/instructions/storage.py | 15 +- .../forks/paris/vm/instructions/system.py | 38 +- src/ethereum/forks/paris/vm/interpreter.py | 61 +- src/ethereum/forks/prague/blocks.py | 19 +- src/ethereum/forks/prague/fork.py | 212 +++-- src/ethereum/forks/prague/requests.py | 2 +- src/ethereum/forks/prague/state.py | 713 ---------------- src/ethereum/forks/prague/state_tracker.py | 747 ++++++++++++++++ src/ethereum/forks/prague/trie.py | 502 ----------- src/ethereum/forks/prague/utils/message.py | 9 +- src/ethereum/forks/prague/vm/__init__.py | 8 +- .../forks/prague/vm/eoa_delegation.py | 22 +- .../prague/vm/instructions/environment.py | 17 +- .../forks/prague/vm/instructions/storage.py | 19 +- .../forks/prague/vm/instructions/system.py | 34 +- src/ethereum/forks/prague/vm/interpreter.py | 66 +- src/ethereum/forks/shanghai/blocks.py | 19 +- src/ethereum/forks/shanghai/fork.py | 74 +- src/ethereum/forks/shanghai/state.py | 615 -------------- src/ethereum/forks/shanghai/state_tracker.py | 772 +++++++++++++++++ src/ethereum/forks/shanghai/trie.py | 502 ----------- src/ethereum/forks/shanghai/utils/message.py | 10 +- src/ethereum/forks/shanghai/vm/__init__.py | 7 +- .../shanghai/vm/instructions/environment.py | 17 +- .../forks/shanghai/vm/instructions/storage.py | 15 +- .../forks/shanghai/vm/instructions/system.py | 38 +- src/ethereum/forks/shanghai/vm/interpreter.py | 61 +- src/ethereum/forks/spurious_dragon/blocks.py | 22 +- src/ethereum/forks/spurious_dragon/fork.py | 103 ++- .../forks/spurious_dragon/fork_types.py | 32 +- src/ethereum/forks/spurious_dragon/state.py | 611 ------------- .../forks/spurious_dragon/state_tracker.py | 803 ++++++++++++++++++ .../forks/spurious_dragon/transactions.py | 3 +- src/ethereum/forks/spurious_dragon/trie.py | 498 ----------- .../spurious_dragon/utils/hexadecimal.py | 4 +- .../forks/spurious_dragon/utils/message.py | 8 +- .../forks/spurious_dragon/vm/__init__.py | 15 +- .../vm/instructions/environment.py | 15 +- .../vm/instructions/storage.py | 13 +- .../spurious_dragon/vm/instructions/system.py | 42 +- .../forks/spurious_dragon/vm/interpreter.py | 59 +- .../forks/tangerine_whistle/blocks.py | 22 +- src/ethereum/forks/tangerine_whistle/fork.py | 97 ++- .../forks/tangerine_whistle/fork_types.py | 32 +- src/ethereum/forks/tangerine_whistle/state.py | 543 ------------ .../forks/tangerine_whistle/state_tracker.py | 803 ++++++++++++++++++ .../forks/tangerine_whistle/transactions.py | 3 +- src/ethereum/forks/tangerine_whistle/trie.py | 498 ----------- .../tangerine_whistle/utils/hexadecimal.py | 4 +- .../forks/tangerine_whistle/utils/message.py | 8 +- .../forks/tangerine_whistle/vm/__init__.py | 7 +- .../vm/instructions/environment.py | 15 +- .../vm/instructions/storage.py | 13 +- .../vm/instructions/system.py | 38 +- .../forks/tangerine_whistle/vm/interpreter.py | 49 +- src/ethereum/state.py | 29 +- .../evm_tools/loaders/fixture_loader.py | 8 +- .../evm_tools/loaders/fork_loader.py | 147 +--- .../evm_tools/t8n/__init__.py | 26 +- .../evm_tools/t8n/t8n_types.py | 38 +- .../helpers/load_blockchain_tests.py | 7 +- tests/json_loader/test_genesis.py | 18 +- tests/json_loader/test_optimized_state.py | 30 +- vulture_whitelist.py | 11 + 320 files changed, 21976 insertions(+), 30466 deletions(-) delete mode 100644 src/ethereum/forks/arrow_glacier/state.py create mode 100644 src/ethereum/forks/arrow_glacier/state_tracker.py delete mode 100644 src/ethereum/forks/arrow_glacier/trie.py delete mode 100644 src/ethereum/forks/berlin/state.py create mode 100644 src/ethereum/forks/berlin/state_tracker.py delete mode 100644 src/ethereum/forks/berlin/trie.py delete mode 100644 src/ethereum/forks/bpo1/state.py create mode 100644 src/ethereum/forks/bpo1/state_tracker.py delete mode 100644 src/ethereum/forks/bpo1/trie.py delete mode 100644 src/ethereum/forks/bpo2/state.py create mode 100644 src/ethereum/forks/bpo2/state_tracker.py delete mode 100644 src/ethereum/forks/bpo2/trie.py delete mode 100644 src/ethereum/forks/bpo3/state.py create mode 100644 src/ethereum/forks/bpo3/state_tracker.py delete mode 100644 src/ethereum/forks/bpo3/trie.py delete mode 100644 src/ethereum/forks/bpo4/state.py create mode 100644 src/ethereum/forks/bpo4/state_tracker.py delete mode 100644 src/ethereum/forks/bpo4/trie.py delete mode 100644 src/ethereum/forks/bpo5/state.py create mode 100644 src/ethereum/forks/bpo5/state_tracker.py delete mode 100644 src/ethereum/forks/bpo5/trie.py delete mode 100644 src/ethereum/forks/byzantium/state.py create mode 100644 src/ethereum/forks/byzantium/state_tracker.py delete mode 100644 src/ethereum/forks/byzantium/trie.py delete mode 100644 src/ethereum/forks/cancun/state.py create mode 100644 src/ethereum/forks/cancun/state_tracker.py delete mode 100644 src/ethereum/forks/cancun/trie.py delete mode 100644 src/ethereum/forks/constantinople/state.py create mode 100644 src/ethereum/forks/constantinople/state_tracker.py delete mode 100644 src/ethereum/forks/constantinople/trie.py delete mode 100644 src/ethereum/forks/dao_fork/state.py create mode 100644 src/ethereum/forks/dao_fork/state_tracker.py delete mode 100644 src/ethereum/forks/dao_fork/trie.py delete mode 100644 src/ethereum/forks/frontier/state.py create mode 100644 src/ethereum/forks/frontier/state_tracker.py delete mode 100644 src/ethereum/forks/frontier/trie.py delete mode 100644 src/ethereum/forks/gray_glacier/state.py create mode 100644 src/ethereum/forks/gray_glacier/state_tracker.py delete mode 100644 src/ethereum/forks/gray_glacier/trie.py delete mode 100644 src/ethereum/forks/homestead/state.py create mode 100644 src/ethereum/forks/homestead/state_tracker.py delete mode 100644 src/ethereum/forks/homestead/trie.py delete mode 100644 src/ethereum/forks/istanbul/state.py create mode 100644 src/ethereum/forks/istanbul/state_tracker.py delete mode 100644 src/ethereum/forks/istanbul/trie.py delete mode 100644 src/ethereum/forks/london/state.py create mode 100644 src/ethereum/forks/london/state_tracker.py delete mode 100644 src/ethereum/forks/london/trie.py delete mode 100644 src/ethereum/forks/muir_glacier/state.py create mode 100644 src/ethereum/forks/muir_glacier/state_tracker.py delete mode 100644 src/ethereum/forks/muir_glacier/trie.py delete mode 100644 src/ethereum/forks/osaka/state.py create mode 100644 src/ethereum/forks/osaka/state_tracker.py delete mode 100644 src/ethereum/forks/osaka/trie.py delete mode 100644 src/ethereum/forks/paris/state.py create mode 100644 src/ethereum/forks/paris/state_tracker.py delete mode 100644 src/ethereum/forks/paris/trie.py delete mode 100644 src/ethereum/forks/prague/state.py create mode 100644 src/ethereum/forks/prague/state_tracker.py delete mode 100644 src/ethereum/forks/prague/trie.py delete mode 100644 src/ethereum/forks/shanghai/state.py create mode 100644 src/ethereum/forks/shanghai/state_tracker.py delete mode 100644 src/ethereum/forks/shanghai/trie.py delete mode 100644 src/ethereum/forks/spurious_dragon/state.py create mode 100644 src/ethereum/forks/spurious_dragon/state_tracker.py delete mode 100644 src/ethereum/forks/spurious_dragon/trie.py delete mode 100644 src/ethereum/forks/tangerine_whistle/state.py create mode 100644 src/ethereum/forks/tangerine_whistle/state_tracker.py delete mode 100644 src/ethereum/forks/tangerine_whistle/trie.py diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index 0ff0bf663ed..6ab8d8bcd76 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -71,6 +71,7 @@ BlockState, TransactionState, account_exists_and_is_empty, + create_ether, destroy_account, extract_block_diff, get_account, @@ -696,14 +697,14 @@ def process_checked_system_transaction( Output of processing the system transaction. """ - # Read through BlockState (not pre-state) so that a system contract - # deployed by an earlier transaction in the same block is visible. - # See EIP-7002 and EIP-7251 for this edge case. - # - # This read is not recorded in the state tracker. - # However, this is fine because `process_unchecked_system_transaction` - # does its own get_account on the TransactionState that we do incorporate - # into BlockState. + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( untracked_state, @@ -1108,9 +1109,7 @@ def process_withdrawals( rlp.encode(wd), ) - current_balance = get_account(wd_state, wd.address).balance - new_balance = current_balance + wd.amount * GWEI_TO_WEI - set_account_balance(wd_state, wd.address, new_balance) + create_ether(wd_state, wd.address, wd.amount * GWEI_TO_WEI) incorporate_tx_into_block(wd_state, block_env.block_access_list_builder) diff --git a/src/ethereum/forks/amsterdam/state_tracker.py b/src/ethereum/forks/amsterdam/state_tracker.py index 5d2c099ddc8..c75eb198f53 100644 --- a/src/ethereum/forks/amsterdam/state_tracker.py +++ b/src/ethereum/forks/amsterdam/state_tracker.py @@ -140,10 +140,10 @@ def get_account(tx_state: TransactionState, address: Address) -> Account: """ account = get_account_optional(tx_state, address) - if isinstance(account, Account): - return account - else: + if account is None: return EMPTY_ACCOUNT + else: + return account def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: @@ -568,6 +568,29 @@ def increase_recipient_balance(recipient: Account) -> None: modify_state(tx_state, recipient_address, increase_recipient_balance) +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + def set_account_balance( tx_state: TransactionState, address: Address, amount: U256 ) -> None: diff --git a/src/ethereum/forks/arrow_glacier/blocks.py b/src/ethereum/forks/arrow_glacier/blocks.py index 497a331c0dd..ba2ce71d02a 100644 --- a/src/ethereum/forks/arrow_glacier/blocks.py +++ b/src/ethereum/forks/arrow_glacier/blocks.py @@ -18,8 +18,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import ( AccessListTransaction, FeeMarketTransaction, @@ -69,13 +70,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.arrow_glacier.state.state_root - [Trie]: ref:ethereum.forks.arrow_glacier.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -85,8 +87,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.arrow_glacier.trie.root - [Trie]: ref:ethereum.forks.arrow_glacier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -96,8 +98,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.arrow_glacier.trie.root - [Trie]: ref:ethereum.forks.arrow_glacier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/arrow_glacier/fork.py b/src/ethereum/forks/arrow_glacier/fork.py index 1ca5a51b6ac..d83e3fdffb4 100644 --- a/src/ethereum/forks/arrow_glacier/fork.py +++ b/src/ethereum/forks/arrow_glacier/fork.py @@ -28,6 +28,13 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, encode_receipt @@ -36,17 +43,18 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -59,7 +67,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -174,9 +181,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -191,7 +200,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -209,6 +223,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -430,6 +445,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -442,6 +458,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -472,7 +490,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -581,7 +599,7 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -663,9 +681,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -684,25 +700,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -735,6 +750,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -750,21 +767,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -780,6 +796,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -801,28 +818,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -841,6 +858,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/arrow_glacier/fork_types.py b/src/ethereum/forks/arrow_glacier/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/arrow_glacier/fork_types.py +++ b/src/ethereum/forks/arrow_glacier/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/arrow_glacier/state.py b/src/ethereum/forks/arrow_glacier/state.py deleted file mode 100644 index ce3e80c53fb..00000000000 --- a/src/ethereum/forks/arrow_glacier/state.py +++ /dev/null @@ -1,672 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/arrow_glacier/state_tracker.py b/src/ethereum/forks/arrow_glacier/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/arrow_glacier/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/arrow_glacier/transactions.py b/src/ethereum/forks/arrow_glacier/transactions.py index 0e40010c617..7ee0abbf8ef 100644 --- a/src/ethereum/forks/arrow_glacier/transactions.py +++ b/src/ethereum/forks/arrow_glacier/transactions.py @@ -19,9 +19,9 @@ InvalidSignatureError, NonceOverflowError, ) +from ethereum.state import Address from .exceptions import TransactionTypeError -from .fork_types import Address @slotted_freezable diff --git a/src/ethereum/forks/arrow_glacier/trie.py b/src/ethereum/forks/arrow_glacier/trie.py deleted file mode 100644 index 42be5c84563..00000000000 --- a/src/ethereum/forks/arrow_glacier/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.london import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/arrow_glacier/utils/hexadecimal.py b/src/ethereum/forks/arrow_glacier/utils/hexadecimal.py index 9ea75b7607f..2a648e930b4 100644 --- a/src/ethereum/forks/arrow_glacier/utils/hexadecimal.py +++ b/src/ethereum/forks/arrow_glacier/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/arrow_glacier/utils/message.py b/src/ethereum/forks/arrow_glacier/utils/message.py index 02714198bcd..f490d33bb7e 100644 --- a/src/ethereum/forks/arrow_glacier/utils/message.py +++ b/src/ethereum/forks/arrow_glacier/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/arrow_glacier/vm/__init__.py b/src/ethereum/forks/arrow_glacier/vm/__init__.py index 46462ee6abc..f53d3428ce0 100644 --- a/src/ethereum/forks/arrow_glacier/vm/__init__.py +++ b/src/ethereum/forks/arrow_glacier/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import LegacyTransaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -90,6 +94,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] + state: TransactionState index_in_block: Optional[Uint] tx_hash: Optional[Hash32] @@ -159,7 +164,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) evm.accessed_addresses.update(child_evm.accessed_addresses) @@ -189,7 +194,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py b/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py index 851ab39b142..904a7b8a9d0 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -74,7 +74,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -346,8 +347,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -389,8 +391,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -485,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -517,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py b/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py index 287544f353b..e9d86666668 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -45,9 +45,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -71,11 +70,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -121,7 +120,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/system.py b/src/ethereum/forks/arrow_glacier/vm/instructions/system.py index 0282da0d90e..8d8eeeb8f2c 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/system.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -89,15 +89,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -353,7 +351,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -368,7 +366,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -443,7 +441,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -489,9 +487,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -503,28 +501,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/arrow_glacier/vm/interpreter.py b/src/ethereum/forks/arrow_glacier/vm/interpreter.py index f2262c47175..a57203fdefe 100644 --- a/src/ethereum/forks/arrow_glacier/vm/interpreter.py +++ b/src/ethereum/forks/arrow_glacier/vm/interpreter.py @@ -31,16 +31,16 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -103,12 +103,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -122,9 +122,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -167,14 +165,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -189,15 +198,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -216,7 +224,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -243,13 +251,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -280,9 +291,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/berlin/blocks.py b/src/ethereum/forks/berlin/blocks.py index a52af69baed..112a9846ab6 100644 --- a/src/ethereum/forks/berlin/blocks.py +++ b/src/ethereum/forks/berlin/blocks.py @@ -18,8 +18,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import AccessListTransaction, LegacyTransaction, Transaction @@ -61,13 +62,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.berlin.state.state_root - [Trie]: ref:ethereum.forks.berlin.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -77,8 +79,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.berlin.trie.root - [Trie]: ref:ethereum.forks.berlin.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -88,8 +90,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.berlin.trie.root - [Trie]: ref:ethereum.forks.berlin.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/berlin/fork.py b/src/ethereum/forks/berlin/fork.py index 72d37ec2bae..c97256fddec 100644 --- a/src/ethereum/forks/berlin/fork.py +++ b/src/ethereum/forks/berlin/fork.py @@ -28,21 +28,29 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, encode_receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -54,7 +62,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -167,9 +174,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -183,7 +192,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -201,6 +215,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -351,6 +366,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -363,6 +379,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -385,7 +403,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -474,7 +492,7 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -556,9 +574,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -577,25 +593,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -628,6 +643,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -640,18 +657,17 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -667,6 +683,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -686,28 +703,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -726,6 +743,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/berlin/fork_types.py b/src/ethereum/forks/berlin/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/berlin/fork_types.py +++ b/src/ethereum/forks/berlin/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/berlin/state.py b/src/ethereum/forks/berlin/state.py deleted file mode 100644 index ce3e80c53fb..00000000000 --- a/src/ethereum/forks/berlin/state.py +++ /dev/null @@ -1,672 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/berlin/state_tracker.py b/src/ethereum/forks/berlin/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/berlin/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/berlin/transactions.py b/src/ethereum/forks/berlin/transactions.py index 2721c25520c..cfba0193d4a 100644 --- a/src/ethereum/forks/berlin/transactions.py +++ b/src/ethereum/forks/berlin/transactions.py @@ -19,9 +19,9 @@ InvalidSignatureError, NonceOverflowError, ) +from ethereum.state import Address from .exceptions import TransactionTypeError -from .fork_types import Address @slotted_freezable diff --git a/src/ethereum/forks/berlin/trie.py b/src/ethereum/forks/berlin/trie.py deleted file mode 100644 index f6371c3991f..00000000000 --- a/src/ethereum/forks/berlin/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.muir_glacier import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `eth1spec.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `eth1spec.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/berlin/utils/hexadecimal.py b/src/ethereum/forks/berlin/utils/hexadecimal.py index 2b8bf4c375e..575e02874f7 100644 --- a/src/ethereum/forks/berlin/utils/hexadecimal.py +++ b/src/ethereum/forks/berlin/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/berlin/utils/message.py b/src/ethereum/forks/berlin/utils/message.py index 6c11551b0a8..0a7562ca32c 100644 --- a/src/ethereum/forks/berlin/utils/message.py +++ b/src/ethereum/forks/berlin/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/berlin/vm/__init__.py b/src/ethereum/forks/berlin/vm/__init__.py index e6d9a36081d..85f73a618a2 100644 --- a/src/ethereum/forks/berlin/vm/__init__.py +++ b/src/ethereum/forks/berlin/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import LegacyTransaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -89,6 +93,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] + state: TransactionState index_in_block: Optional[Uint] tx_hash: Optional[Hash32] @@ -158,7 +163,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) evm.accessed_addresses.update(child_evm.accessed_addresses) @@ -188,7 +193,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/berlin/vm/instructions/environment.py b/src/ethereum/forks/berlin/vm/instructions/environment.py index 9e7b817ace6..ec98efa5169 100644 --- a/src/ethereum/forks/berlin/vm/instructions/environment.py +++ b/src/ethereum/forks/berlin/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -74,7 +74,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -346,8 +347,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -389,8 +391,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -485,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -517,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/berlin/vm/instructions/storage.py b/src/ethereum/forks/berlin/vm/instructions/storage.py index 287544f353b..e9d86666668 100644 --- a/src/ethereum/forks/berlin/vm/instructions/storage.py +++ b/src/ethereum/forks/berlin/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -45,9 +45,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -71,11 +70,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -121,7 +120,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/berlin/vm/instructions/system.py b/src/ethereum/forks/berlin/vm/instructions/system.py index 4c0e63d6dbe..42b44718be8 100644 --- a/src/ethereum/forks/berlin/vm/instructions/system.py +++ b/src/ethereum/forks/berlin/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -89,15 +89,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - _code_account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, _code_account.code_hash) + _code_account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, _code_account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -353,7 +351,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -368,7 +366,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -443,7 +441,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -489,9 +487,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -514,28 +512,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/berlin/vm/interpreter.py b/src/ethereum/forks/berlin/vm/interpreter.py index 1f482d07cea..9efc07bc5b4 100644 --- a/src/ethereum/forks/berlin/vm/interpreter.py +++ b/src/ethereum/forks/berlin/vm/interpreter.py @@ -31,16 +31,16 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -102,12 +102,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -121,9 +121,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -166,14 +164,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -185,15 +194,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -212,7 +220,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -239,13 +247,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -276,9 +287,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/bpo1/blocks.py b/src/ethereum/forks/bpo1/blocks.py index 81cf89f57a6..6b6711b29dd 100644 --- a/src/ethereum/forks/bpo1/blocks.py +++ b/src/ethereum/forks/bpo1/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.bpo1.state.state_root - [Trie]: ref:ethereum.forks.bpo1.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo1.trie.root - [Trie]: ref:ethereum.forks.bpo1.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo1.trie.root - [Trie]: ref:ethereum.forks.bpo1.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/bpo1/fork.py b/src/ethereum/forks/bpo1/fork.py index 19ce50f243d..66832bf3a20 100644 --- a/src/ethereum/forks/bpo1/fork.py +++ b/src/ethereum/forks/bpo1/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -51,16 +57,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -75,7 +82,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -220,9 +226,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -239,7 +247,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -265,6 +276,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -396,6 +408,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -408,6 +421,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -466,7 +481,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -534,7 +549,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -585,74 +600,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -677,9 +624,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -688,10 +644,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -710,8 +665,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -728,17 +683,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -872,6 +861,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -889,9 +880,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -901,14 +893,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -929,7 +919,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -962,23 +952,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -998,6 +986,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -1007,9 +997,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1018,7 +1006,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/bpo1/requests.py b/src/ethereum/forks/bpo1/requests.py index 1c1924ef3f7..f58e9753196 100644 --- a/src/ethereum/forks/bpo1/requests.py +++ b/src/ethereum/forks/bpo1/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/bpo1/state.py b/src/ethereum/forks/bpo1/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/bpo1/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/bpo1/state_tracker.py b/src/ethereum/forks/bpo1/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/bpo1/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/bpo1/trie.py b/src/ethereum/forks/bpo1/trie.py deleted file mode 100644 index 81e0fd6c22f..00000000000 --- a/src/ethereum/forks/bpo1/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.osaka import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/bpo1/utils/message.py b/src/ethereum/forks/bpo1/utils/message.py index a8136167cc4..5137add445e 100644 --- a/src/ethereum/forks/bpo1/utils/message.py +++ b/src/ethereum/forks/bpo1/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/bpo1/vm/__init__.py b/src/ethereum/forks/bpo1/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/bpo1/vm/__init__.py +++ b/src/ethereum/forks/bpo1/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/bpo1/vm/eoa_delegation.py b/src/ethereum/forks/bpo1/vm/eoa_delegation.py index 3fd42910817..1ba552f8dd6 100644 --- a/src/ethereum/forks/bpo1/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo1/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,8 +139,8 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -150,7 +150,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -170,7 +170,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -186,8 +186,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -196,7 +196,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -206,15 +206,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/bpo1/vm/instructions/environment.py b/src/ethereum/forks/bpo1/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo1/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/bpo1/vm/instructions/storage.py b/src/ethereum/forks/bpo1/vm/instructions/storage.py index 5aa3cc6746f..99dcce877dd 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo1/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -51,9 +51,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -77,11 +76,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -127,7 +126,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -152,7 +151,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -179,7 +178,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/bpo1/vm/instructions/system.py b/src/ethereum/forks/bpo1/vm/instructions/system.py index 1fe8daf44d5..d71c776bf3d 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/system.py +++ b/src/ethereum/forks/bpo1/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -168,7 +166,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -384,7 +382,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -399,7 +397,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -484,7 +482,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -532,9 +530,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -546,11 +544,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -558,10 +556,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/bpo1/vm/interpreter.py b/src/ethereum/forks/bpo1/vm/interpreter.py index b79580a6429..f637dac044c 100644 --- a/src/ethereum/forks/bpo1/vm/interpreter.py +++ b/src/ethereum/forks/bpo1/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/bpo2/blocks.py b/src/ethereum/forks/bpo2/blocks.py index 5454a305af7..27c85b2382a 100644 --- a/src/ethereum/forks/bpo2/blocks.py +++ b/src/ethereum/forks/bpo2/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.bpo2.state.state_root - [Trie]: ref:ethereum.forks.bpo2.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo2.trie.root - [Trie]: ref:ethereum.forks.bpo2.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo2.trie.root - [Trie]: ref:ethereum.forks.bpo2.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/bpo2/fork.py b/src/ethereum/forks/bpo2/fork.py index 19ce50f243d..66832bf3a20 100644 --- a/src/ethereum/forks/bpo2/fork.py +++ b/src/ethereum/forks/bpo2/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -51,16 +57,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -75,7 +82,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -220,9 +226,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -239,7 +247,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -265,6 +276,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -396,6 +408,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -408,6 +421,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -466,7 +481,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -534,7 +549,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -585,74 +600,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -677,9 +624,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -688,10 +644,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -710,8 +665,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -728,17 +683,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -872,6 +861,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -889,9 +880,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -901,14 +893,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -929,7 +919,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -962,23 +952,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -998,6 +986,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -1007,9 +997,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1018,7 +1006,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/bpo2/requests.py b/src/ethereum/forks/bpo2/requests.py index 38ca79f7009..fbf10d11565 100644 --- a/src/ethereum/forks/bpo2/requests.py +++ b/src/ethereum/forks/bpo2/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/bpo2/state.py b/src/ethereum/forks/bpo2/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/bpo2/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/bpo2/state_tracker.py b/src/ethereum/forks/bpo2/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/bpo2/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/bpo2/trie.py b/src/ethereum/forks/bpo2/trie.py deleted file mode 100644 index 5132bb42fe4..00000000000 --- a/src/ethereum/forks/bpo2/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.bpo1 import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/bpo2/utils/message.py b/src/ethereum/forks/bpo2/utils/message.py index 1186eb612cb..c5691c7b1e0 100644 --- a/src/ethereum/forks/bpo2/utils/message.py +++ b/src/ethereum/forks/bpo2/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/bpo2/vm/__init__.py b/src/ethereum/forks/bpo2/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/bpo2/vm/__init__.py +++ b/src/ethereum/forks/bpo2/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/bpo2/vm/eoa_delegation.py b/src/ethereum/forks/bpo2/vm/eoa_delegation.py index 3fd42910817..1ba552f8dd6 100644 --- a/src/ethereum/forks/bpo2/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo2/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,8 +139,8 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -150,7 +150,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -170,7 +170,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -186,8 +186,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -196,7 +196,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -206,15 +206,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/bpo2/vm/instructions/environment.py b/src/ethereum/forks/bpo2/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo2/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/bpo2/vm/instructions/storage.py b/src/ethereum/forks/bpo2/vm/instructions/storage.py index dbbd8db40ca..437af01941e 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo2/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -48,9 +48,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -74,11 +73,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -124,7 +123,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/bpo2/vm/instructions/system.py b/src/ethereum/forks/bpo2/vm/instructions/system.py index 2d99ac93e61..713a04af13c 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/system.py +++ b/src/ethereum/forks/bpo2/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -167,7 +165,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -383,7 +381,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -398,7 +396,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -483,7 +481,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -531,9 +529,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -545,11 +543,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -557,10 +555,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/bpo2/vm/interpreter.py b/src/ethereum/forks/bpo2/vm/interpreter.py index 31e07e2d968..ac08d1956c4 100644 --- a/src/ethereum/forks/bpo2/vm/interpreter.py +++ b/src/ethereum/forks/bpo2/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/bpo3/blocks.py b/src/ethereum/forks/bpo3/blocks.py index 9ea170b08a7..c057beefa76 100644 --- a/src/ethereum/forks/bpo3/blocks.py +++ b/src/ethereum/forks/bpo3/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.bpo3.state.state_root - [Trie]: ref:ethereum.forks.bpo3.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo3.trie.root - [Trie]: ref:ethereum.forks.bpo3.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo3.trie.root - [Trie]: ref:ethereum.forks.bpo3.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/bpo3/fork.py b/src/ethereum/forks/bpo3/fork.py index 19ce50f243d..66832bf3a20 100644 --- a/src/ethereum/forks/bpo3/fork.py +++ b/src/ethereum/forks/bpo3/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -51,16 +57,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -75,7 +82,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -220,9 +226,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -239,7 +247,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -265,6 +276,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -396,6 +408,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -408,6 +421,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -466,7 +481,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -534,7 +549,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -585,74 +600,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -677,9 +624,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -688,10 +644,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -710,8 +665,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -728,17 +683,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -872,6 +861,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -889,9 +880,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -901,14 +893,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -929,7 +919,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -962,23 +952,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -998,6 +986,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -1007,9 +997,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1018,7 +1006,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/bpo3/requests.py b/src/ethereum/forks/bpo3/requests.py index 7aa0bae522d..1bceb4efbeb 100644 --- a/src/ethereum/forks/bpo3/requests.py +++ b/src/ethereum/forks/bpo3/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/bpo3/state.py b/src/ethereum/forks/bpo3/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/bpo3/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/bpo3/state_tracker.py b/src/ethereum/forks/bpo3/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/bpo3/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/bpo3/trie.py b/src/ethereum/forks/bpo3/trie.py deleted file mode 100644 index edd126ce9c9..00000000000 --- a/src/ethereum/forks/bpo3/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.bpo2 import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/bpo3/utils/message.py b/src/ethereum/forks/bpo3/utils/message.py index 5154350fd43..5e3386c543a 100644 --- a/src/ethereum/forks/bpo3/utils/message.py +++ b/src/ethereum/forks/bpo3/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/bpo3/vm/__init__.py b/src/ethereum/forks/bpo3/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/bpo3/vm/__init__.py +++ b/src/ethereum/forks/bpo3/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/bpo3/vm/eoa_delegation.py b/src/ethereum/forks/bpo3/vm/eoa_delegation.py index 3fd42910817..1ba552f8dd6 100644 --- a/src/ethereum/forks/bpo3/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo3/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,8 +139,8 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -150,7 +150,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -170,7 +170,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -186,8 +186,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -196,7 +196,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -206,15 +206,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/bpo3/vm/instructions/environment.py b/src/ethereum/forks/bpo3/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo3/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/bpo3/vm/instructions/storage.py b/src/ethereum/forks/bpo3/vm/instructions/storage.py index dbbd8db40ca..437af01941e 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo3/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -48,9 +48,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -74,11 +73,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -124,7 +123,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -149,7 +148,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -176,7 +175,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/bpo3/vm/instructions/system.py b/src/ethereum/forks/bpo3/vm/instructions/system.py index 2d99ac93e61..713a04af13c 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/system.py +++ b/src/ethereum/forks/bpo3/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -167,7 +165,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -383,7 +381,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -398,7 +396,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -483,7 +481,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -531,9 +529,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -545,11 +543,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -557,10 +555,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/bpo3/vm/interpreter.py b/src/ethereum/forks/bpo3/vm/interpreter.py index d3c301fc708..3b6ac4aed0a 100644 --- a/src/ethereum/forks/bpo3/vm/interpreter.py +++ b/src/ethereum/forks/bpo3/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/bpo4/blocks.py b/src/ethereum/forks/bpo4/blocks.py index 6216a152188..a6e5ad56b59 100644 --- a/src/ethereum/forks/bpo4/blocks.py +++ b/src/ethereum/forks/bpo4/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.bpo4.state.state_root - [Trie]: ref:ethereum.forks.bpo4.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo4.trie.root - [Trie]: ref:ethereum.forks.bpo4.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo4.trie.root - [Trie]: ref:ethereum.forks.bpo4.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/bpo4/fork.py b/src/ethereum/forks/bpo4/fork.py index 19ce50f243d..66832bf3a20 100644 --- a/src/ethereum/forks/bpo4/fork.py +++ b/src/ethereum/forks/bpo4/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -51,16 +57,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -75,7 +82,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -220,9 +226,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -239,7 +247,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -265,6 +276,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -396,6 +408,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -408,6 +421,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -466,7 +481,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -534,7 +549,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -585,74 +600,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -677,9 +624,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -688,10 +644,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -710,8 +665,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -728,17 +683,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -872,6 +861,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -889,9 +880,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -901,14 +893,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -929,7 +919,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -962,23 +952,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -998,6 +986,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -1007,9 +997,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1018,7 +1006,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/bpo4/requests.py b/src/ethereum/forks/bpo4/requests.py index c6f6f099646..919690c427e 100644 --- a/src/ethereum/forks/bpo4/requests.py +++ b/src/ethereum/forks/bpo4/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/bpo4/state.py b/src/ethereum/forks/bpo4/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/bpo4/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/bpo4/state_tracker.py b/src/ethereum/forks/bpo4/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/bpo4/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/bpo4/trie.py b/src/ethereum/forks/bpo4/trie.py deleted file mode 100644 index bdd3c0456e7..00000000000 --- a/src/ethereum/forks/bpo4/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.bpo3 import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/bpo4/utils/message.py b/src/ethereum/forks/bpo4/utils/message.py index fdcabc34088..cfcd51c6f92 100644 --- a/src/ethereum/forks/bpo4/utils/message.py +++ b/src/ethereum/forks/bpo4/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/bpo4/vm/__init__.py b/src/ethereum/forks/bpo4/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/bpo4/vm/__init__.py +++ b/src/ethereum/forks/bpo4/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/bpo4/vm/eoa_delegation.py b/src/ethereum/forks/bpo4/vm/eoa_delegation.py index 3fd42910817..1ba552f8dd6 100644 --- a/src/ethereum/forks/bpo4/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo4/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,8 +139,8 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -150,7 +150,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -170,7 +170,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -186,8 +186,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -196,7 +196,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -206,15 +206,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/bpo4/vm/instructions/environment.py b/src/ethereum/forks/bpo4/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo4/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/bpo4/vm/instructions/storage.py b/src/ethereum/forks/bpo4/vm/instructions/storage.py index 5aa3cc6746f..99dcce877dd 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo4/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -51,9 +51,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -77,11 +76,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -127,7 +126,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -152,7 +151,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -179,7 +178,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/bpo4/vm/instructions/system.py b/src/ethereum/forks/bpo4/vm/instructions/system.py index 1fe8daf44d5..d71c776bf3d 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/system.py +++ b/src/ethereum/forks/bpo4/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -168,7 +166,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -384,7 +382,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -399,7 +397,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -484,7 +482,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -532,9 +530,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -546,11 +544,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -558,10 +556,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/bpo4/vm/interpreter.py b/src/ethereum/forks/bpo4/vm/interpreter.py index de598138081..7c943b1b4c0 100644 --- a/src/ethereum/forks/bpo4/vm/interpreter.py +++ b/src/ethereum/forks/bpo4/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/bpo5/blocks.py b/src/ethereum/forks/bpo5/blocks.py index ed7138e74e6..87cb7bca1ba 100644 --- a/src/ethereum/forks/bpo5/blocks.py +++ b/src/ethereum/forks/bpo5/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.bpo5.state.state_root - [Trie]: ref:ethereum.forks.bpo5.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo5.trie.root - [Trie]: ref:ethereum.forks.bpo5.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.bpo5.trie.root - [Trie]: ref:ethereum.forks.bpo5.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/bpo5/fork.py b/src/ethereum/forks/bpo5/fork.py index 19ce50f243d..66832bf3a20 100644 --- a/src/ethereum/forks/bpo5/fork.py +++ b/src/ethereum/forks/bpo5/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -51,16 +57,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -75,7 +82,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -220,9 +226,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -239,7 +247,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -265,6 +276,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -396,6 +408,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -408,6 +421,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -466,7 +481,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -534,7 +549,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -585,74 +600,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -677,9 +624,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -688,10 +644,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -710,8 +665,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -728,17 +683,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -872,6 +861,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -889,9 +880,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -901,14 +893,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -929,7 +919,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -962,23 +952,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -998,6 +986,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -1007,9 +997,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1018,7 +1006,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/bpo5/requests.py b/src/ethereum/forks/bpo5/requests.py index a04812d5c80..4bb47dfbafb 100644 --- a/src/ethereum/forks/bpo5/requests.py +++ b/src/ethereum/forks/bpo5/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/bpo5/state.py b/src/ethereum/forks/bpo5/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/bpo5/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/bpo5/state_tracker.py b/src/ethereum/forks/bpo5/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/bpo5/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/bpo5/trie.py b/src/ethereum/forks/bpo5/trie.py deleted file mode 100644 index bcc7ed64c3d..00000000000 --- a/src/ethereum/forks/bpo5/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.bpo4 import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/bpo5/utils/message.py b/src/ethereum/forks/bpo5/utils/message.py index be5c30f8e28..fdc2b6ecc7e 100644 --- a/src/ethereum/forks/bpo5/utils/message.py +++ b/src/ethereum/forks/bpo5/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/bpo5/vm/__init__.py b/src/ethereum/forks/bpo5/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/bpo5/vm/__init__.py +++ b/src/ethereum/forks/bpo5/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/bpo5/vm/eoa_delegation.py b/src/ethereum/forks/bpo5/vm/eoa_delegation.py index 3fd42910817..1ba552f8dd6 100644 --- a/src/ethereum/forks/bpo5/vm/eoa_delegation.py +++ b/src/ethereum/forks/bpo5/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,8 +139,8 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -150,7 +150,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -170,7 +170,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -186,8 +186,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -196,7 +196,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -206,15 +206,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/bpo5/vm/instructions/environment.py b/src/ethereum/forks/bpo5/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo5/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/bpo5/vm/instructions/storage.py b/src/ethereum/forks/bpo5/vm/instructions/storage.py index 5aa3cc6746f..99dcce877dd 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo5/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -51,9 +51,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -77,11 +76,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -127,7 +126,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -152,7 +151,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -179,7 +178,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/bpo5/vm/instructions/system.py b/src/ethereum/forks/bpo5/vm/instructions/system.py index 1fe8daf44d5..d71c776bf3d 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/system.py +++ b/src/ethereum/forks/bpo5/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -168,7 +166,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -384,7 +382,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -399,7 +397,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -484,7 +482,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -532,9 +530,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -546,11 +544,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -558,10 +556,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/bpo5/vm/interpreter.py b/src/ethereum/forks/bpo5/vm/interpreter.py index 138131315c5..c09a3b4ef50 100644 --- a/src/ethereum/forks/bpo5/vm/interpreter.py +++ b/src/ethereum/forks/bpo5/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/byzantium/blocks.py b/src/ethereum/forks/byzantium/blocks.py index 2f027b04dc7..68cabfa1bee 100644 --- a/src/ethereum/forks/byzantium/blocks.py +++ b/src/ethereum/forks/byzantium/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.byzantium.state.state_root - [Trie]: ref:ethereum.forks.byzantium.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.byzantium.trie.root - [Trie]: ref:ethereum.forks.byzantium.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.byzantium.trie.root - [Trie]: ref:ethereum.forks.byzantium.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/byzantium/fork.py b/src/ethereum/forks/byzantium/fork.py index 848a1edf547..66b4ffd8a13 100644 --- a/src/ethereum/forks/byzantium/fork.py +++ b/src/ethereum/forks/byzantium/fork.py @@ -27,21 +27,29 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -49,7 +57,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -162,9 +169,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -178,7 +187,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -196,6 +210,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -346,6 +361,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -358,6 +374,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -380,7 +398,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -466,7 +484,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -548,9 +566,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -569,25 +585,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -620,6 +635,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -627,23 +644,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -663,28 +680,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -703,6 +720,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/byzantium/fork_types.py b/src/ethereum/forks/byzantium/fork_types.py index d61f48f24eb..02907cd2a1a 100644 --- a/src/ethereum/forks/byzantium/fork_types.py +++ b/src/ethereum/forks/byzantium/fork_types.py @@ -11,40 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint +from ethereum_types.bytes import Bytes, Bytes256 -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import Account -Address = Bytes20 -Root = Hash32 Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/byzantium/state.py b/src/ethereum/forks/byzantium/state.py deleted file mode 100644 index 10cf7e419b5..00000000000 --- a/src/ethereum/forks/byzantium/state.py +++ /dev/null @@ -1,611 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/byzantium/state_tracker.py b/src/ethereum/forks/byzantium/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/byzantium/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/byzantium/transactions.py b/src/ethereum/forks/byzantium/transactions.py index e8cde82b198..c2dda52bd71 100644 --- a/src/ethereum/forks/byzantium/transactions.py +++ b/src/ethereum/forks/byzantium/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/byzantium/trie.py b/src/ethereum/forks/byzantium/trie.py deleted file mode 100644 index 42cf24a86f7..00000000000 --- a/src/ethereum/forks/byzantium/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.spurious_dragon import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/byzantium/utils/hexadecimal.py b/src/ethereum/forks/byzantium/utils/hexadecimal.py index 3642c49057f..23ad6606b51 100644 --- a/src/ethereum/forks/byzantium/utils/hexadecimal.py +++ b/src/ethereum/forks/byzantium/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/byzantium/utils/message.py b/src/ethereum/forks/byzantium/utils/message.py index 44026442804..7d2089019df 100644 --- a/src/ethereum/forks/byzantium/utils/message.py +++ b/src/ethereum/forks/byzantium/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -49,7 +49,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -57,8 +57,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/byzantium/vm/__init__.py b/src/ethereum/forks/byzantium/vm/__init__.py index a780c363cf8..657d2f7e6c3 100644 --- a/src/ethereum/forks/byzantium/vm/__init__.py +++ b/src/ethereum/forks/byzantium/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import Transaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -87,6 +91,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] @@ -152,7 +157,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) @@ -180,7 +185,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/byzantium/vm/instructions/environment.py b/src/ethereum/forks/byzantium/vm/instructions/environment.py index c459b2aebec..c58d4b02f17 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/environment.py +++ b/src/ethereum/forks/byzantium/vm/instructions/environment.py @@ -15,7 +15,7 @@ from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -69,7 +69,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -335,8 +336,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -374,8 +376,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) diff --git a/src/ethereum/forks/byzantium/vm/instructions/storage.py b/src/ethereum/forks/byzantium/vm/instructions/storage.py index 0e5aae6031d..faf342b34ab 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/storage.py +++ b/src/ethereum/forks/byzantium/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( @@ -41,9 +41,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -66,8 +65,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -79,7 +78,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/byzantium/vm/instructions/system.py b/src/ethereum/forks/byzantium/vm/instructions/system.py index 01e4048cc67..1f4dc02194b 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/system.py +++ b/src/ethereum/forks/byzantium/vm/instructions/system.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -79,12 +79,12 @@ def create(evm: Evm) -> None: evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -96,20 +96,16 @@ def create(evm: Evm) -> None: push(evm.stack, U256(0)) evm.gas_left += create_message_gas elif account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) else: call_data = memory_read_bytes( evm.memory, memory_start_position, memory_size ) - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -206,8 +202,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -274,7 +270,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -289,7 +285,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -357,7 +353,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -399,9 +395,9 @@ def selfdestruct(evm: Evm) -> None: # GAS gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -423,28 +419,28 @@ def selfdestruct(evm: Evm) -> None: raise WriteInStaticContext beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/byzantium/vm/interpreter.py b/src/ethereum/forks/byzantium/vm/interpreter.py index a5a72762dbd..89639e94588 100644 --- a/src/ethereum/forks/byzantium/vm/interpreter.py +++ b/src/ethereum/forks/byzantium/vm/interpreter.py @@ -31,15 +31,15 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -101,12 +101,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -120,9 +120,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -165,11 +163,20 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -181,15 +188,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -208,7 +214,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -233,13 +239,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -270,9 +279,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/cancun/blocks.py b/src/ethereum/forks/cancun/blocks.py index 957be343495..981f9c7be6a 100644 --- a/src/ethereum/forks/cancun/blocks.py +++ b/src/ethereum/forks/cancun/blocks.py @@ -106,13 +106,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.cancun.state.state_root - [Trie]: ref:ethereum.forks.cancun.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -122,8 +123,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.cancun.trie.root - [Trie]: ref:ethereum.forks.cancun.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -133,8 +134,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.cancun.trie.root - [Trie]: ref:ethereum.forks.cancun.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index ac5373fac95..19afbffcbc4 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -42,16 +48,17 @@ TransactionTypeContractCreationError, ) from .fork_types import VersionedHash -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -65,7 +72,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -192,9 +198,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -211,7 +219,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -234,6 +245,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_output.blob_gas_used != block.header.blob_gas_used: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -365,6 +377,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -377,6 +390,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -430,7 +445,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, (FeeMarketTransaction, BlobTransaction)): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -531,17 +546,14 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( +def process_unchecked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, - system_contract_code: Bytes, data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction with the given code. - - Prefer calling `process_unchecked_system_transaction` unless the contract - code has already been read from the state. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -549,8 +561,6 @@ def process_system_transaction( The block scoped environment. target_address : Address of the contract to call. - system_contract_code : - Code of the contract to call. data : Data to pass to the contract. @@ -560,13 +570,19 @@ def process_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + tx_env = vm.TransactionEnvironment( origin=SYSTEM_ADDRESS, gas_price=block_env.base_fee_per_gas, gas=SYSTEM_TRANSACTION_GAS, access_list_addresses=set(), access_list_storage_keys=set(), - transient_storage=TransientStorage(), + state=system_tx_state, blob_versioned_hashes=(), index_in_block=None, tx_hash=None, @@ -593,43 +609,9 @@ def process_system_transaction( system_tx_output = process_message_call(system_tx_message) - return system_tx_output - + incorporate_tx_into_block(system_tx_state) -def process_unchecked_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, - ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, - ) + return system_tx_output def apply_body( @@ -708,6 +690,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -725,9 +709,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -737,14 +722,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -763,7 +746,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), @@ -786,23 +769,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -822,6 +803,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -831,9 +814,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -842,7 +823,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/cancun/state.py b/src/ethereum/forks/cancun/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/cancun/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/cancun/state_tracker.py b/src/ethereum/forks/cancun/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/cancun/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/cancun/trie.py b/src/ethereum/forks/cancun/trie.py deleted file mode 100644 index 979117f1c9d..00000000000 --- a/src/ethereum/forks/cancun/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.shanghai import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/cancun/utils/message.py b/src/ethereum/forks/cancun/utils/message.py index 4b068489857..162f32c809f 100644 --- a/src/ethereum/forks/cancun/utils/message.py +++ b/src/ethereum/forks/cancun/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,9 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) - + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/cancun/vm/__init__.py b/src/ethereum/forks/cancun/vm/__init__.py index 042a64de69d..e2214f4810f 100644 --- a/src/ethereum/forks/cancun/vm/__init__.py +++ b/src/ethereum/forks/cancun/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -100,7 +100,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] index_in_block: Optional[Uint] tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/cancun/vm/instructions/environment.py b/src/ethereum/forks/cancun/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/cancun/vm/instructions/environment.py +++ b/src/ethereum/forks/cancun/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/cancun/vm/instructions/storage.py b/src/ethereum/forks/cancun/vm/instructions/storage.py index 5aa3cc6746f..99dcce877dd 100644 --- a/src/ethereum/forks/cancun/vm/instructions/storage.py +++ b/src/ethereum/forks/cancun/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -51,9 +51,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -77,11 +76,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -127,7 +126,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -152,7 +151,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -179,7 +178,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/cancun/vm/instructions/system.py b/src/ethereum/forks/cancun/vm/instructions/system.py index 0808eb1f7a7..5b880be7285 100644 --- a/src/ethereum/forks/cancun/vm/instructions/system.py +++ b/src/ethereum/forks/cancun/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -166,7 +164,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -297,8 +295,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - state = evm.message.block_env.state - code = get_code(state, get_account(state, code_address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, code_address).code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -373,7 +371,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -388,7 +386,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -463,7 +461,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -509,9 +507,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -523,11 +521,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -535,10 +533,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/cancun/vm/interpreter.py b/src/ethereum/forks/cancun/vm/interpreter.py index 05d14c7aebe..1157d0cf0c1 100644 --- a/src/ethereum/forks/cancun/vm/interpreter.py +++ b/src/ethereum/forks/cancun/vm/interpreter.py @@ -31,15 +31,15 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -100,12 +100,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -156,17 +156,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -181,15 +190,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -208,8 +216,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -235,11 +242,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -270,9 +280,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/constantinople/blocks.py b/src/ethereum/forks/constantinople/blocks.py index e53cf2c1c65..f34abc2db12 100644 --- a/src/ethereum/forks/constantinople/blocks.py +++ b/src/ethereum/forks/constantinople/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.constantinople.state.state_root - [Trie]: ref:ethereum.forks.constantinople.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.constantinople.trie.root - [Trie]: ref:ethereum.forks.constantinople.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.constantinople.trie.root - [Trie]: ref:ethereum.forks.constantinople.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/constantinople/fork.py b/src/ethereum/forks/constantinople/fork.py index a75b6656f14..855faf3acb4 100644 --- a/src/ethereum/forks/constantinople/fork.py +++ b/src/ethereum/forks/constantinople/fork.py @@ -27,21 +27,29 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -49,7 +57,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -162,9 +169,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -178,7 +187,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -196,6 +210,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -346,6 +361,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -358,6 +374,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -380,7 +398,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -466,7 +484,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -548,9 +566,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -569,25 +585,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -620,6 +635,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -627,23 +644,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -663,28 +680,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -703,6 +720,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/constantinople/fork_types.py b/src/ethereum/forks/constantinople/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/constantinople/fork_types.py +++ b/src/ethereum/forks/constantinople/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/constantinople/state.py b/src/ethereum/forks/constantinople/state.py deleted file mode 100644 index 10cf7e419b5..00000000000 --- a/src/ethereum/forks/constantinople/state.py +++ /dev/null @@ -1,611 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/constantinople/state_tracker.py b/src/ethereum/forks/constantinople/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/constantinople/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/constantinople/transactions.py b/src/ethereum/forks/constantinople/transactions.py index e8cde82b198..c2dda52bd71 100644 --- a/src/ethereum/forks/constantinople/transactions.py +++ b/src/ethereum/forks/constantinople/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/constantinople/trie.py b/src/ethereum/forks/constantinople/trie.py deleted file mode 100644 index 493fda074c4..00000000000 --- a/src/ethereum/forks/constantinople/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.byzantium import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/constantinople/utils/hexadecimal.py b/src/ethereum/forks/constantinople/utils/hexadecimal.py index b083db39398..7992f556e4f 100644 --- a/src/ethereum/forks/constantinople/utils/hexadecimal.py +++ b/src/ethereum/forks/constantinople/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/constantinople/utils/message.py b/src/ethereum/forks/constantinople/utils/message.py index ecfb46224ff..c02aac36d77 100644 --- a/src/ethereum/forks/constantinople/utils/message.py +++ b/src/ethereum/forks/constantinople/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -49,7 +49,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -57,8 +57,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/constantinople/vm/__init__.py b/src/ethereum/forks/constantinople/vm/__init__.py index a780c363cf8..657d2f7e6c3 100644 --- a/src/ethereum/forks/constantinople/vm/__init__.py +++ b/src/ethereum/forks/constantinople/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import Transaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -87,6 +91,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] @@ -152,7 +157,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) @@ -180,7 +185,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/constantinople/vm/instructions/environment.py b/src/ethereum/forks/constantinople/vm/instructions/environment.py index 2761ffda5fe..cd1a43130d8 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/environment.py +++ b/src/ethereum/forks/constantinople/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -70,7 +70,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -336,8 +337,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -375,8 +377,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -465,7 +468,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTCODEHASH) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) diff --git a/src/ethereum/forks/constantinople/vm/instructions/storage.py b/src/ethereum/forks/constantinople/vm/instructions/storage.py index 0e5aae6031d..faf342b34ab 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/storage.py +++ b/src/ethereum/forks/constantinople/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..exceptions import WriteInStaticContext from ..gas import ( @@ -41,9 +41,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -66,8 +65,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -79,7 +78,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/constantinople/vm/instructions/system.py b/src/ethereum/forks/constantinople/vm/instructions/system.py index bd66624215d..d9faf756729 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/system.py +++ b/src/ethereum/forks/constantinople/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -87,11 +87,9 @@ def generic_create( return if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return @@ -99,7 +97,7 @@ def generic_create( evm.memory, memory_start_position, memory_size ) - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -345,7 +343,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -360,7 +358,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -428,7 +426,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -470,9 +468,9 @@ def selfdestruct(evm: Evm) -> None: # GAS gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -495,28 +493,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/constantinople/vm/interpreter.py b/src/ethereum/forks/constantinople/vm/interpreter.py index ffd3e29a5b7..af3266e95c4 100644 --- a/src/ethereum/forks/constantinople/vm/interpreter.py +++ b/src/ethereum/forks/constantinople/vm/interpreter.py @@ -31,15 +31,15 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -101,12 +101,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -120,9 +120,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -165,11 +163,20 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -181,15 +188,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -208,7 +214,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -233,13 +239,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -270,9 +279,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/dao_fork/blocks.py b/src/ethereum/forks/dao_fork/blocks.py index f0de09559a1..ef30c3f0351 100644 --- a/src/ethereum/forks/dao_fork/blocks.py +++ b/src/ethereum/forks/dao_fork/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.dao_fork.state.state_root - [Trie]: ref:ethereum.forks.dao_fork.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.dao_fork.trie.root - [Trie]: ref:ethereum.forks.dao_fork.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.dao_fork.trie.root - [Trie]: ref:ethereum.forks.dao_fork.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/dao_fork/dao.py b/src/ethereum/forks/dao_fork/dao.py index c76a24e116d..93bed096cdb 100644 --- a/src/ethereum/forks/dao_fork/dao.py +++ b/src/ethereum/forks/dao_fork/dao.py @@ -5,7 +5,9 @@ The recovery contract was previously created using normal contract deployment. """ -from .state import State, get_account, move_ether +from ethereum.state import State + +from .state_tracker import TransactionState, get_account, move_ether from .utils.hexadecimal import hex_to_address DAO_ACCOUNTS = [ @@ -352,6 +354,18 @@ def apply_dao(state: State) -> None: [`DAO_ACCOUNTS`]: ref:ethereum.forks.dao_fork.dao.DAO_ACCOUNTS [`DAO_RECOVERY`]: ref:ethereum.forks.dao_fork.dao.DAO_RECOVERY """ + from ethereum.state import apply_changes_to_state + + from .state_tracker import ( + BlockState, + extract_block_diff, + incorporate_tx_into_block, + ) + + block_state = BlockState(pre_state=state) + tx_state = TransactionState(parent=block_state) for address in DAO_ACCOUNTS: - balance = get_account(state, address).balance - move_ether(state, address, DAO_RECOVERY, balance) + balance = get_account(tx_state, address).balance + move_ether(tx_state, address, DAO_RECOVERY, balance) + incorporate_tx_into_block(tx_state) + apply_changes_to_state(state, extract_block_diff(block_state)) diff --git a/src/ethereum/forks/dao_fork/fork.py b/src/ethereum/forks/dao_fork/fork.py index 8dae3e9f95a..4098bed5463 100644 --- a/src/ethereum/forks/dao_fork/fork.py +++ b/src/ethereum/forks/dao_fork/fork.py @@ -30,20 +30,28 @@ NonceMismatchError, ) from ethereum.fork_criteria import ByBlockNumber +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import FORK_CRITERIA, vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom from .dao import apply_dao -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, create_ether, destroy_account, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -51,7 +59,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -170,9 +177,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -186,7 +195,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -204,6 +218,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -361,6 +376,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -373,6 +389,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -395,7 +413,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -481,7 +499,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -563,9 +581,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -584,25 +600,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -635,6 +650,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -642,23 +659,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -678,26 +695,38 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, block_env.coinbase, coinbase_balance_after_mining_fee + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund + incorporate_tx_into_block(tx_state) + + block_state = block_env.state + block_diff = extract_block_diff(block_state) + intermediate_state_root, _ = ( + block_state.pre_state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) + ) + receipt = make_receipt( - state_root(block_env.state), + intermediate_state_root, block_output.block_gas_used, tx_output.logs, ) diff --git a/src/ethereum/forks/dao_fork/fork_types.py b/src/ethereum/forks/dao_fork/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/dao_fork/fork_types.py +++ b/src/ethereum/forks/dao_fork/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/dao_fork/state.py b/src/ethereum/forks/dao_fork/state.py deleted file mode 100644 index 69f5cca8dc0..00000000000 --- a/src/ethereum/forks/dao_fork/state.py +++ /dev/null @@ -1,543 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) diff --git a/src/ethereum/forks/dao_fork/state_tracker.py b/src/ethereum/forks/dao_fork/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/dao_fork/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/dao_fork/transactions.py b/src/ethereum/forks/dao_fork/transactions.py index e17bafae49d..1458316ce5b 100644 --- a/src/ethereum/forks/dao_fork/transactions.py +++ b/src/ethereum/forks/dao_fork/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/dao_fork/trie.py b/src/ethereum/forks/dao_fork/trie.py deleted file mode 100644 index d8db45abac2..00000000000 --- a/src/ethereum/forks/dao_fork/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.homestead import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/dao_fork/utils/hexadecimal.py b/src/ethereum/forks/dao_fork/utils/hexadecimal.py index 5d870803263..8e7002ee631 100644 --- a/src/ethereum/forks/dao_fork/utils/hexadecimal.py +++ b/src/ethereum/forks/dao_fork/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/dao_fork/utils/message.py b/src/ethereum/forks/dao_fork/utils/message.py index 5dfcf4af121..b4d0194dee7 100644 --- a/src/ethereum/forks/dao_fork/utils/message.py +++ b/src/ethereum/forks/dao_fork/utils/message.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -48,7 +48,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -56,8 +56,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/dao_fork/vm/__init__.py b/src/ethereum/forks/dao_fork/vm/__init__.py index e318eaa7482..3b5007aa541 100644 --- a/src/ethereum/forks/dao_fork/vm/__init__.py +++ b/src/ethereum/forks/dao_fork/vm/__init__.py @@ -20,12 +20,12 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State +from ..state_tracker import BlockState, TransactionState from ..transactions import Transaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -37,7 +37,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -86,6 +86,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/dao_fork/vm/gas.py b/src/ethereum/forks/dao_fork/vm/gas.py index 7c36dfd1ca2..1fc39a94593 100644 --- a/src/ethereum/forks/dao_fork/vm/gas.py +++ b/src/ethereum/forks/dao_fork/vm/gas.py @@ -20,7 +20,7 @@ from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 -from ..state import State, account_exists +from ..state_tracker import TransactionState, account_exists from . import Evm from .exceptions import OutOfGasError @@ -268,7 +268,7 @@ def calculate_gas_extend_memory( def calculate_message_call_gas( - state: State, gas: Uint, to: Address, value: U256 + state: TransactionState, gas: Uint, to: Address, value: U256 ) -> MessageCallGas: """ Calculates the gas amount for executing Opcodes `CALL` and `CALLCODE`. diff --git a/src/ethereum/forks/dao_fork/vm/instructions/environment.py b/src/ethereum/forks/dao_fork/vm/instructions/environment.py index d930368fdd9..d85aaf0c97a 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/environment.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/environment.py @@ -15,7 +15,7 @@ from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -68,7 +68,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -334,8 +335,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -373,8 +375,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/storage.py b/src/ethereum/forks/dao_fork/vm/instructions/storage.py index 0b2a1cce8aa..16921a1a7fb 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/storage.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..gas import ( GasCosts, @@ -40,9 +40,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -65,8 +64,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -78,7 +77,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) # OPERATION - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/system.py b/src/ethereum/forks/dao_fork/vm/instructions/system.py index c40a241886a..7fe3234231f 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/system.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/system.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -73,12 +73,12 @@ def create(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -90,20 +90,16 @@ def create(evm: Evm) -> None: push(evm.stack, U256(0)) evm.gas_left += create_message_gas elif account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) else: call_data = memory_read_bytes( evm.memory, memory_start_position, memory_size ) - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -194,8 +190,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account_to_call = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account_to_call.code_hash) + account_to_call = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account_to_call.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -259,14 +255,14 @@ def call(evm: Evm) -> None: code_address = to message_call_gas = calculate_message_call_gas( - evm.message.block_env.state, gas, to, value + evm.message.tx_env.state, gas, to, value ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -320,14 +316,14 @@ def callcode(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - evm.message.block_env.state, gas, to, value + evm.message.tx_env.state, gas, to, value ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -382,22 +378,22 @@ def selfdestruct(evm: Evm) -> None: # OPERATION beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/dao_fork/vm/interpreter.py b/src/ethereum/forks/dao_fork/vm/interpreter.py index 40bdffcc071..9ad12ee6428 100644 --- a/src/ethereum/forks/dao_fork/vm/interpreter.py +++ b/src/ethereum/forks/dao_fork/vm/interpreter.py @@ -31,13 +31,13 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -94,12 +94,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -150,9 +150,16 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` call. + destroy_storage(tx_state, message.current_target) evm = process_message(message) if not evm.error: @@ -163,14 +170,13 @@ def process_create_message(message: Message) -> Evm: try: charge_gas(evm, contract_code_gas) except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -189,7 +195,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -212,13 +218,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -245,9 +254,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/frontier/blocks.py b/src/ethereum/forks/frontier/blocks.py index b9fe4f377f5..3d19ab42f4b 100644 --- a/src/ethereum/forks/frontier/blocks.py +++ b/src/ethereum/forks/frontier/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.frontier.state.state_root - [Trie]: ref:ethereum.forks.frontier.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.frontier.trie.root - [Trie]: ref:ethereum.forks.frontier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.frontier.trie.root - [Trie]: ref:ethereum.forks.frontier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/frontier/fork.py b/src/ethereum/forks/frontier/fork.py index 70c52a0c056..125ecfa001b 100644 --- a/src/ethereum/forks/frontier/fork.py +++ b/src/ethereum/forks/frontier/fork.py @@ -27,19 +27,27 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, create_ether, destroy_account, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -47,7 +55,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -158,9 +165,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -174,7 +183,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -192,6 +206,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -340,6 +355,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -352,6 +368,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -374,7 +392,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -460,7 +478,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -542,9 +560,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -563,25 +579,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -614,6 +629,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -621,23 +638,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -657,26 +674,38 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, block_env.coinbase, coinbase_balance_after_mining_fee + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund + incorporate_tx_into_block(tx_state) + + block_state = block_env.state + block_diff = extract_block_diff(block_state) + intermediate_state_root, _ = ( + block_state.pre_state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) + ) + receipt = make_receipt( - state_root(block_env.state), + intermediate_state_root, block_output.block_gas_used, tx_output.logs, ) diff --git a/src/ethereum/forks/frontier/fork_types.py b/src/ethereum/forks/frontier/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/frontier/fork_types.py +++ b/src/ethereum/forks/frontier/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/frontier/state.py b/src/ethereum/forks/frontier/state.py deleted file mode 100644 index 69f5cca8dc0..00000000000 --- a/src/ethereum/forks/frontier/state.py +++ /dev/null @@ -1,543 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) diff --git a/src/ethereum/forks/frontier/state_tracker.py b/src/ethereum/forks/frontier/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/frontier/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/frontier/transactions.py b/src/ethereum/forks/frontier/transactions.py index 69b9ec52083..f08d2e435ef 100644 --- a/src/ethereum/forks/frontier/transactions.py +++ b/src/ethereum/forks/frontier/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/frontier/trie.py b/src/ethereum/forks/frontier/trie.py deleted file mode 100644 index a1aed10f30f..00000000000 --- a/src/ethereum/forks/frontier/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_never, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - assert_never(node) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/frontier/utils/hexadecimal.py b/src/ethereum/forks/frontier/utils/hexadecimal.py index a3701b48a20..cefa7b4e893 100644 --- a/src/ethereum/forks/frontier/utils/hexadecimal.py +++ b/src/ethereum/forks/frontier/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/frontier/utils/message.py b/src/ethereum/forks/frontier/utils/message.py index 9da2edea5e7..4579edd3447 100644 --- a/src/ethereum/forks/frontier/utils/message.py +++ b/src/ethereum/forks/frontier/utils/message.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -48,7 +48,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -56,8 +56,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/frontier/vm/__init__.py b/src/ethereum/forks/frontier/vm/__init__.py index e4673225bc0..d2e566bde19 100644 --- a/src/ethereum/forks/frontier/vm/__init__.py +++ b/src/ethereum/forks/frontier/vm/__init__.py @@ -20,12 +20,12 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State +from ..state_tracker import BlockState, TransactionState from ..transactions import Transaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -37,7 +37,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -86,6 +86,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/frontier/vm/gas.py b/src/ethereum/forks/frontier/vm/gas.py index a47c26419c1..e73c9b2e925 100644 --- a/src/ethereum/forks/frontier/vm/gas.py +++ b/src/ethereum/forks/frontier/vm/gas.py @@ -20,7 +20,7 @@ from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 -from ..state import State, account_exists +from ..state_tracker import TransactionState, account_exists from . import Evm from .exceptions import OutOfGasError @@ -266,7 +266,7 @@ def calculate_gas_extend_memory( def calculate_message_call_gas( - state: State, gas: Uint, to: Address, value: U256 + state: TransactionState, gas: Uint, to: Address, value: U256 ) -> MessageCallGas: """ Calculates the gas amount for executing Opcodes `CALL` and `CALLCODE`. diff --git a/src/ethereum/forks/frontier/vm/instructions/environment.py b/src/ethereum/forks/frontier/vm/instructions/environment.py index d930368fdd9..d85aaf0c97a 100644 --- a/src/ethereum/forks/frontier/vm/instructions/environment.py +++ b/src/ethereum/forks/frontier/vm/instructions/environment.py @@ -15,7 +15,7 @@ from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -68,7 +68,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -334,8 +335,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -373,8 +375,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) diff --git a/src/ethereum/forks/frontier/vm/instructions/storage.py b/src/ethereum/forks/frontier/vm/instructions/storage.py index 0b2a1cce8aa..16921a1a7fb 100644 --- a/src/ethereum/forks/frontier/vm/instructions/storage.py +++ b/src/ethereum/forks/frontier/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..gas import ( GasCosts, @@ -40,9 +40,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -65,8 +64,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -78,7 +77,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) # OPERATION - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/frontier/vm/instructions/system.py b/src/ethereum/forks/frontier/vm/instructions/system.py index 6426fbfa04c..cf978c5a295 100644 --- a/src/ethereum/forks/frontier/vm/instructions/system.py +++ b/src/ethereum/forks/frontier/vm/instructions/system.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -73,12 +73,12 @@ def create(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -90,20 +90,16 @@ def create(evm: Evm) -> None: push(evm.stack, U256(0)) evm.gas_left += create_message_gas elif account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) else: call_data = memory_read_bytes( evm.memory, memory_start_position, memory_size ) - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -192,8 +188,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account_to_call = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account_to_call.code_hash) + account_to_call = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account_to_call.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -256,14 +252,14 @@ def call(evm: Evm) -> None: code_address = to message_call_gas = calculate_message_call_gas( - evm.message.block_env.state, gas, to, value + evm.message.tx_env.state, gas, to, value ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -316,14 +312,14 @@ def callcode(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - evm.message.block_env.state, gas, to, value + evm.message.tx_env.state, gas, to, value ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -377,22 +373,22 @@ def selfdestruct(evm: Evm) -> None: # OPERATION beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/frontier/vm/interpreter.py b/src/ethereum/forks/frontier/vm/interpreter.py index 90e59a193f0..c2a6e0d7c19 100644 --- a/src/ethereum/forks/frontier/vm/interpreter.py +++ b/src/ethereum/forks/frontier/vm/interpreter.py @@ -31,13 +31,13 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -94,12 +94,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -150,9 +150,16 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` call. + destroy_storage(tx_state, message.current_target) evm = process_message(message) if not evm.error: @@ -165,10 +172,9 @@ def process_create_message(message: Message) -> Evm: except ExceptionalHalt: evm.output = b"" else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -187,7 +193,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -210,13 +216,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -243,9 +252,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/gray_glacier/blocks.py b/src/ethereum/forks/gray_glacier/blocks.py index 0b0ec871bfb..6735da330b3 100644 --- a/src/ethereum/forks/gray_glacier/blocks.py +++ b/src/ethereum/forks/gray_glacier/blocks.py @@ -70,13 +70,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.gray_glacier.state.state_root - [Trie]: ref:ethereum.forks.gray_glacier.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -86,8 +87,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.gray_glacier.trie.root - [Trie]: ref:ethereum.forks.gray_glacier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -97,8 +98,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.gray_glacier.trie.root - [Trie]: ref:ethereum.forks.gray_glacier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/gray_glacier/fork.py b/src/ethereum/forks/gray_glacier/fork.py index a5e2080c744..9d44f903b3e 100644 --- a/src/ethereum/forks/gray_glacier/fork.py +++ b/src/ethereum/forks/gray_glacier/fork.py @@ -28,7 +28,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, encode_receipt @@ -37,17 +43,18 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .fork_types import Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -60,7 +67,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -175,9 +181,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -192,7 +200,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -210,6 +223,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -431,6 +445,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -443,6 +458,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -473,7 +490,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -582,7 +599,7 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -664,9 +681,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -685,25 +700,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -736,6 +750,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -751,21 +767,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -781,6 +796,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -802,28 +818,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -842,6 +858,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/gray_glacier/fork_types.py b/src/ethereum/forks/gray_glacier/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/gray_glacier/fork_types.py +++ b/src/ethereum/forks/gray_glacier/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/gray_glacier/state.py b/src/ethereum/forks/gray_glacier/state.py deleted file mode 100644 index ce3e80c53fb..00000000000 --- a/src/ethereum/forks/gray_glacier/state.py +++ /dev/null @@ -1,672 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/gray_glacier/state_tracker.py b/src/ethereum/forks/gray_glacier/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/gray_glacier/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/gray_glacier/transactions.py b/src/ethereum/forks/gray_glacier/transactions.py index 0e40010c617..7ee0abbf8ef 100644 --- a/src/ethereum/forks/gray_glacier/transactions.py +++ b/src/ethereum/forks/gray_glacier/transactions.py @@ -19,9 +19,9 @@ InvalidSignatureError, NonceOverflowError, ) +from ethereum.state import Address from .exceptions import TransactionTypeError -from .fork_types import Address @slotted_freezable diff --git a/src/ethereum/forks/gray_glacier/trie.py b/src/ethereum/forks/gray_glacier/trie.py deleted file mode 100644 index 4dc21a25737..00000000000 --- a/src/ethereum/forks/gray_glacier/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.arrow_glacier import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/gray_glacier/utils/message.py b/src/ethereum/forks/gray_glacier/utils/message.py index 30703e718ff..38303c5e7c6 100644 --- a/src/ethereum/forks/gray_glacier/utils/message.py +++ b/src/ethereum/forks/gray_glacier/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/gray_glacier/vm/__init__.py b/src/ethereum/forks/gray_glacier/vm/__init__.py index 46462ee6abc..f53d3428ce0 100644 --- a/src/ethereum/forks/gray_glacier/vm/__init__.py +++ b/src/ethereum/forks/gray_glacier/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import LegacyTransaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -90,6 +94,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] + state: TransactionState index_in_block: Optional[Uint] tx_hash: Optional[Hash32] @@ -159,7 +164,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) evm.accessed_addresses.update(child_evm.accessed_addresses) @@ -189,7 +194,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/environment.py b/src/ethereum/forks/gray_glacier/vm/instructions/environment.py index 851ab39b142..904a7b8a9d0 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -74,7 +74,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -346,8 +347,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -389,8 +391,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -485,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -517,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/storage.py b/src/ethereum/forks/gray_glacier/vm/instructions/storage.py index 287544f353b..e9d86666668 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -45,9 +45,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -71,11 +70,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -121,7 +120,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/system.py b/src/ethereum/forks/gray_glacier/vm/instructions/system.py index 55c72f0fa9a..a4c1044a687 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/system.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -89,15 +89,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -353,7 +351,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -368,7 +366,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -443,7 +441,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -489,9 +487,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -503,28 +501,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/gray_glacier/vm/interpreter.py b/src/ethereum/forks/gray_glacier/vm/interpreter.py index 434147299b0..945f839fa45 100644 --- a/src/ethereum/forks/gray_glacier/vm/interpreter.py +++ b/src/ethereum/forks/gray_glacier/vm/interpreter.py @@ -31,16 +31,16 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -103,12 +103,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -122,9 +122,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -167,14 +165,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -189,15 +198,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -216,7 +224,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -243,13 +251,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -280,9 +291,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/homestead/blocks.py b/src/ethereum/forks/homestead/blocks.py index 2b71f1d74ce..12dca22e7f6 100644 --- a/src/ethereum/forks/homestead/blocks.py +++ b/src/ethereum/forks/homestead/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.homestead.state.state_root - [Trie]: ref:ethereum.forks.homestead.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.homestead.trie.root - [Trie]: ref:ethereum.forks.homestead.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.homestead.trie.root - [Trie]: ref:ethereum.forks.homestead.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/homestead/fork.py b/src/ethereum/forks/homestead/fork.py index 78592e2d770..03dc0e80928 100644 --- a/src/ethereum/forks/homestead/fork.py +++ b/src/ethereum/forks/homestead/fork.py @@ -27,19 +27,27 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, create_ether, destroy_account, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -47,7 +55,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -158,9 +165,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -174,7 +183,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -192,6 +206,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -340,6 +355,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -352,6 +368,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -374,7 +392,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -460,7 +478,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -542,9 +560,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -563,25 +579,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -614,6 +629,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -621,23 +638,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -657,26 +674,38 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, block_env.coinbase, coinbase_balance_after_mining_fee + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund + incorporate_tx_into_block(tx_state) + + block_state = block_env.state + block_diff = extract_block_diff(block_state) + intermediate_state_root, _ = ( + block_state.pre_state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) + ) + receipt = make_receipt( - state_root(block_env.state), + intermediate_state_root, block_output.block_gas_used, tx_output.logs, ) diff --git a/src/ethereum/forks/homestead/fork_types.py b/src/ethereum/forks/homestead/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/homestead/fork_types.py +++ b/src/ethereum/forks/homestead/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/homestead/state.py b/src/ethereum/forks/homestead/state.py deleted file mode 100644 index 69f5cca8dc0..00000000000 --- a/src/ethereum/forks/homestead/state.py +++ /dev/null @@ -1,543 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) diff --git a/src/ethereum/forks/homestead/state_tracker.py b/src/ethereum/forks/homestead/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/homestead/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/homestead/transactions.py b/src/ethereum/forks/homestead/transactions.py index e17bafae49d..1458316ce5b 100644 --- a/src/ethereum/forks/homestead/transactions.py +++ b/src/ethereum/forks/homestead/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/homestead/trie.py b/src/ethereum/forks/homestead/trie.py deleted file mode 100644 index d037bec1c51..00000000000 --- a/src/ethereum/forks/homestead/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.frontier import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/homestead/utils/hexadecimal.py b/src/ethereum/forks/homestead/utils/hexadecimal.py index 896d015043b..47fcffe57d1 100644 --- a/src/ethereum/forks/homestead/utils/hexadecimal.py +++ b/src/ethereum/forks/homestead/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/homestead/utils/message.py b/src/ethereum/forks/homestead/utils/message.py index 636846b49c9..1595631b841 100644 --- a/src/ethereum/forks/homestead/utils/message.py +++ b/src/ethereum/forks/homestead/utils/message.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -48,7 +48,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -56,8 +56,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/homestead/vm/__init__.py b/src/ethereum/forks/homestead/vm/__init__.py index e318eaa7482..3b5007aa541 100644 --- a/src/ethereum/forks/homestead/vm/__init__.py +++ b/src/ethereum/forks/homestead/vm/__init__.py @@ -20,12 +20,12 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State +from ..state_tracker import BlockState, TransactionState from ..transactions import Transaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -37,7 +37,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -86,6 +86,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/homestead/vm/gas.py b/src/ethereum/forks/homestead/vm/gas.py index 7c36dfd1ca2..1fc39a94593 100644 --- a/src/ethereum/forks/homestead/vm/gas.py +++ b/src/ethereum/forks/homestead/vm/gas.py @@ -20,7 +20,7 @@ from ethereum.trace import GasAndRefund, evm_trace from ethereum.utils.numeric import ceil32 -from ..state import State, account_exists +from ..state_tracker import TransactionState, account_exists from . import Evm from .exceptions import OutOfGasError @@ -268,7 +268,7 @@ def calculate_gas_extend_memory( def calculate_message_call_gas( - state: State, gas: Uint, to: Address, value: U256 + state: TransactionState, gas: Uint, to: Address, value: U256 ) -> MessageCallGas: """ Calculates the gas amount for executing Opcodes `CALL` and `CALLCODE`. diff --git a/src/ethereum/forks/homestead/vm/instructions/environment.py b/src/ethereum/forks/homestead/vm/instructions/environment.py index d930368fdd9..d85aaf0c97a 100644 --- a/src/ethereum/forks/homestead/vm/instructions/environment.py +++ b/src/ethereum/forks/homestead/vm/instructions/environment.py @@ -15,7 +15,7 @@ from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -68,7 +68,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -334,8 +335,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -373,8 +375,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) diff --git a/src/ethereum/forks/homestead/vm/instructions/storage.py b/src/ethereum/forks/homestead/vm/instructions/storage.py index 0b2a1cce8aa..16921a1a7fb 100644 --- a/src/ethereum/forks/homestead/vm/instructions/storage.py +++ b/src/ethereum/forks/homestead/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..gas import ( GasCosts, @@ -40,9 +40,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -65,8 +64,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -78,7 +77,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) # OPERATION - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/homestead/vm/instructions/system.py b/src/ethereum/forks/homestead/vm/instructions/system.py index c40a241886a..7fe3234231f 100644 --- a/src/ethereum/forks/homestead/vm/instructions/system.py +++ b/src/ethereum/forks/homestead/vm/instructions/system.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -73,12 +73,12 @@ def create(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -90,20 +90,16 @@ def create(evm: Evm) -> None: push(evm.stack, U256(0)) evm.gas_left += create_message_gas elif account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) else: call_data = memory_read_bytes( evm.memory, memory_start_position, memory_size ) - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -194,8 +190,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account_to_call = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account_to_call.code_hash) + account_to_call = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account_to_call.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -259,14 +255,14 @@ def call(evm: Evm) -> None: code_address = to message_call_gas = calculate_message_call_gas( - evm.message.block_env.state, gas, to, value + evm.message.tx_env.state, gas, to, value ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -320,14 +316,14 @@ def callcode(evm: Evm) -> None: ], ) message_call_gas = calculate_message_call_gas( - evm.message.block_env.state, gas, to, value + evm.message.tx_env.state, gas, to, value ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -382,22 +378,22 @@ def selfdestruct(evm: Evm) -> None: # OPERATION beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/homestead/vm/interpreter.py b/src/ethereum/forks/homestead/vm/interpreter.py index 7d12402e037..25062166f80 100644 --- a/src/ethereum/forks/homestead/vm/interpreter.py +++ b/src/ethereum/forks/homestead/vm/interpreter.py @@ -31,13 +31,13 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -94,12 +94,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -150,9 +150,16 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` call. + destroy_storage(tx_state, message.current_target) evm = process_message(message) if not evm.error: @@ -163,14 +170,13 @@ def process_create_message(message: Message) -> Evm: try: charge_gas(evm, contract_code_gas) except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -189,7 +195,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -212,13 +218,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -245,9 +254,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/istanbul/blocks.py b/src/ethereum/forks/istanbul/blocks.py index e3f124bcd58..7573703a19d 100644 --- a/src/ethereum/forks/istanbul/blocks.py +++ b/src/ethereum/forks/istanbul/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.istanbul.state.state_root - [Trie]: ref:ethereum.forks.istanbul.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.istanbul.trie.root - [Trie]: ref:ethereum.forks.istanbul.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.istanbul.trie.root - [Trie]: ref:ethereum.forks.istanbul.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/istanbul/fork.py b/src/ethereum/forks/istanbul/fork.py index 7765455cdb8..3738b0bfc6e 100644 --- a/src/ethereum/forks/istanbul/fork.py +++ b/src/ethereum/forks/istanbul/fork.py @@ -27,21 +27,29 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -49,7 +57,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -162,9 +169,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -178,7 +187,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -196,6 +210,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -346,6 +361,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -358,6 +374,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -380,7 +398,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -466,7 +484,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -548,9 +566,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -569,25 +585,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -620,6 +635,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -627,23 +644,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -663,28 +680,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -703,6 +720,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/istanbul/fork_types.py b/src/ethereum/forks/istanbul/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/istanbul/fork_types.py +++ b/src/ethereum/forks/istanbul/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/istanbul/state.py b/src/ethereum/forks/istanbul/state.py deleted file mode 100644 index ce3e80c53fb..00000000000 --- a/src/ethereum/forks/istanbul/state.py +++ /dev/null @@ -1,672 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/istanbul/state_tracker.py b/src/ethereum/forks/istanbul/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/istanbul/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/istanbul/transactions.py b/src/ethereum/forks/istanbul/transactions.py index e8cde82b198..c2dda52bd71 100644 --- a/src/ethereum/forks/istanbul/transactions.py +++ b/src/ethereum/forks/istanbul/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/istanbul/trie.py b/src/ethereum/forks/istanbul/trie.py deleted file mode 100644 index 52e1dd2ea50..00000000000 --- a/src/ethereum/forks/istanbul/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.constantinople import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/istanbul/utils/hexadecimal.py b/src/ethereum/forks/istanbul/utils/hexadecimal.py index 1fc4508bbf7..23db29aaa47 100644 --- a/src/ethereum/forks/istanbul/utils/hexadecimal.py +++ b/src/ethereum/forks/istanbul/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/istanbul/utils/message.py b/src/ethereum/forks/istanbul/utils/message.py index 8f4ab635a24..8bfe3071570 100644 --- a/src/ethereum/forks/istanbul/utils/message.py +++ b/src/ethereum/forks/istanbul/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -49,7 +49,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -57,8 +57,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/istanbul/vm/__init__.py b/src/ethereum/forks/istanbul/vm/__init__.py index a780c363cf8..657d2f7e6c3 100644 --- a/src/ethereum/forks/istanbul/vm/__init__.py +++ b/src/ethereum/forks/istanbul/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import Transaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -87,6 +91,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] @@ -152,7 +157,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) @@ -180,7 +185,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/istanbul/vm/instructions/environment.py b/src/ethereum/forks/istanbul/vm/instructions/environment.py index b3ac54a689a..87860dbd693 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/environment.py +++ b/src/ethereum/forks/istanbul/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -70,7 +70,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -336,8 +337,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -375,8 +377,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -465,7 +468,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTCODEHASH) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -497,7 +500,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/istanbul/vm/instructions/storage.py b/src/ethereum/forks/istanbul/vm/instructions/storage.py index c34e6f31912..07ba90a057c 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/storage.py +++ b/src/ethereum/forks/istanbul/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -41,9 +41,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -67,11 +66,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) if original_value == current_value and current_value != new_value: if original_value == 0: @@ -107,7 +106,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/istanbul/vm/instructions/system.py b/src/ethereum/forks/istanbul/vm/instructions/system.py index 12f69d1131d..cca5876670a 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/system.py +++ b/src/ethereum/forks/istanbul/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -87,11 +87,9 @@ def generic_create( return if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return @@ -99,7 +97,7 @@ def generic_create( evm.memory, memory_start_position, memory_size ) - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - code_account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, code_account.code_hash) + code_account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, code_account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -345,7 +343,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -360,7 +358,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -428,7 +426,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -470,9 +468,9 @@ def selfdestruct(evm: Evm) -> None: # GAS gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -495,28 +493,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/istanbul/vm/interpreter.py b/src/ethereum/forks/istanbul/vm/interpreter.py index 2e3e5d6af2d..f812a5139be 100644 --- a/src/ethereum/forks/istanbul/vm/interpreter.py +++ b/src/ethereum/forks/istanbul/vm/interpreter.py @@ -31,16 +31,16 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -102,12 +102,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -121,9 +121,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -166,14 +164,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -185,15 +194,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -212,7 +220,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -237,13 +245,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -274,9 +285,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/london/blocks.py b/src/ethereum/forks/london/blocks.py index 20971a661c0..812df3325f9 100644 --- a/src/ethereum/forks/london/blocks.py +++ b/src/ethereum/forks/london/blocks.py @@ -18,8 +18,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import ( AccessListTransaction, FeeMarketTransaction, @@ -69,13 +70,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.london.state.state_root - [Trie]: ref:ethereum.forks.london.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -85,8 +87,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.london.trie.root - [Trie]: ref:ethereum.forks.london.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -96,8 +98,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.london.trie.root - [Trie]: ref:ethereum.forks.london.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/london/fork.py b/src/ethereum/forks/london/fork.py index 026a6824881..2bf18f3e413 100644 --- a/src/ethereum/forks/london/fork.py +++ b/src/ethereum/forks/london/fork.py @@ -29,6 +29,13 @@ NonceMismatchError, ) from ethereum.fork_criteria import ByBlockNumber +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import FORK_CRITERIA, vm from .blocks import Block, Header, Log, Receipt, encode_receipt @@ -37,17 +44,18 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -60,7 +68,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -176,9 +183,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -193,7 +202,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -211,6 +225,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -439,6 +454,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -451,6 +467,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -481,7 +499,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -590,7 +608,7 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -672,9 +690,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -693,25 +709,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -744,6 +759,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -759,21 +776,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -789,6 +805,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -810,28 +827,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -850,6 +867,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/london/fork_types.py b/src/ethereum/forks/london/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/london/fork_types.py +++ b/src/ethereum/forks/london/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/london/state.py b/src/ethereum/forks/london/state.py deleted file mode 100644 index ce3e80c53fb..00000000000 --- a/src/ethereum/forks/london/state.py +++ /dev/null @@ -1,672 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/london/state_tracker.py b/src/ethereum/forks/london/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/london/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/london/transactions.py b/src/ethereum/forks/london/transactions.py index 0e40010c617..7ee0abbf8ef 100644 --- a/src/ethereum/forks/london/transactions.py +++ b/src/ethereum/forks/london/transactions.py @@ -19,9 +19,9 @@ InvalidSignatureError, NonceOverflowError, ) +from ethereum.state import Address from .exceptions import TransactionTypeError -from .fork_types import Address @slotted_freezable diff --git a/src/ethereum/forks/london/trie.py b/src/ethereum/forks/london/trie.py deleted file mode 100644 index b0a751f1c9a..00000000000 --- a/src/ethereum/forks/london/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.berlin import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/london/utils/hexadecimal.py b/src/ethereum/forks/london/utils/hexadecimal.py index dacf228fb61..dff7d71434b 100644 --- a/src/ethereum/forks/london/utils/hexadecimal.py +++ b/src/ethereum/forks/london/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/london/utils/message.py b/src/ethereum/forks/london/utils/message.py index 9e09d85d6ef..61028ce170c 100644 --- a/src/ethereum/forks/london/utils/message.py +++ b/src/ethereum/forks/london/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/london/vm/__init__.py b/src/ethereum/forks/london/vm/__init__.py index 46462ee6abc..f53d3428ce0 100644 --- a/src/ethereum/forks/london/vm/__init__.py +++ b/src/ethereum/forks/london/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import LegacyTransaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -90,6 +94,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] + state: TransactionState index_in_block: Optional[Uint] tx_hash: Optional[Hash32] @@ -159,7 +164,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) evm.accessed_addresses.update(child_evm.accessed_addresses) @@ -189,7 +194,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/london/vm/instructions/environment.py b/src/ethereum/forks/london/vm/instructions/environment.py index 851ab39b142..904a7b8a9d0 100644 --- a/src/ethereum/forks/london/vm/instructions/environment.py +++ b/src/ethereum/forks/london/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -74,7 +74,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -346,8 +347,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -389,8 +391,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -485,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -517,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/london/vm/instructions/storage.py b/src/ethereum/forks/london/vm/instructions/storage.py index 287544f353b..e9d86666668 100644 --- a/src/ethereum/forks/london/vm/instructions/storage.py +++ b/src/ethereum/forks/london/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -45,9 +45,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -71,11 +70,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -121,7 +120,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/london/vm/instructions/system.py b/src/ethereum/forks/london/vm/instructions/system.py index 55c72f0fa9a..a4c1044a687 100644 --- a/src/ethereum/forks/london/vm/instructions/system.py +++ b/src/ethereum/forks/london/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -89,15 +89,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -353,7 +351,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -368,7 +366,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -443,7 +441,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -489,9 +487,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -503,28 +501,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/london/vm/interpreter.py b/src/ethereum/forks/london/vm/interpreter.py index eb067c2bb4d..5f32151ff55 100644 --- a/src/ethereum/forks/london/vm/interpreter.py +++ b/src/ethereum/forks/london/vm/interpreter.py @@ -31,16 +31,16 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -103,12 +103,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -122,9 +122,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -167,14 +165,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -189,15 +198,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -216,7 +224,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -243,13 +251,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -281,9 +292,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/muir_glacier/blocks.py b/src/ethereum/forks/muir_glacier/blocks.py index 05dd03d1c05..ca5968194b4 100644 --- a/src/ethereum/forks/muir_glacier/blocks.py +++ b/src/ethereum/forks/muir_glacier/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.muir_glacier.state.state_root - [Trie]: ref:ethereum.forks.muir_glacier.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.muir_glacier.trie.root - [Trie]: ref:ethereum.forks.muir_glacier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.muir_glacier.trie.root - [Trie]: ref:ethereum.forks.muir_glacier.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/muir_glacier/fork.py b/src/ethereum/forks/muir_glacier/fork.py index dc79ce95617..451d36a80de 100644 --- a/src/ethereum/forks/muir_glacier/fork.py +++ b/src/ethereum/forks/muir_glacier/fork.py @@ -27,21 +27,29 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -49,7 +57,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -162,9 +169,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -178,7 +187,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -196,6 +210,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -346,6 +361,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -358,6 +374,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -380,7 +398,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -468,7 +486,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -550,9 +568,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -571,25 +587,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -622,6 +637,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -629,23 +646,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -665,28 +682,28 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund @@ -705,6 +722,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/muir_glacier/fork_types.py b/src/ethereum/forks/muir_glacier/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/muir_glacier/fork_types.py +++ b/src/ethereum/forks/muir_glacier/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/muir_glacier/state.py b/src/ethereum/forks/muir_glacier/state.py deleted file mode 100644 index ce3e80c53fb..00000000000 --- a/src/ethereum/forks/muir_glacier/state.py +++ /dev/null @@ -1,672 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/muir_glacier/state_tracker.py b/src/ethereum/forks/muir_glacier/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/muir_glacier/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/muir_glacier/transactions.py b/src/ethereum/forks/muir_glacier/transactions.py index e8cde82b198..c2dda52bd71 100644 --- a/src/ethereum/forks/muir_glacier/transactions.py +++ b/src/ethereum/forks/muir_glacier/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/muir_glacier/trie.py b/src/ethereum/forks/muir_glacier/trie.py deleted file mode 100644 index 04487f25266..00000000000 --- a/src/ethereum/forks/muir_glacier/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.istanbul import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/muir_glacier/utils/hexadecimal.py b/src/ethereum/forks/muir_glacier/utils/hexadecimal.py index b3f17b7ef73..6b16780334f 100644 --- a/src/ethereum/forks/muir_glacier/utils/hexadecimal.py +++ b/src/ethereum/forks/muir_glacier/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/muir_glacier/utils/message.py b/src/ethereum/forks/muir_glacier/utils/message.py index fd119dfbb2c..425f6c5bea1 100644 --- a/src/ethereum/forks/muir_glacier/utils/message.py +++ b/src/ethereum/forks/muir_glacier/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -49,7 +49,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -57,8 +57,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/muir_glacier/vm/__init__.py b/src/ethereum/forks/muir_glacier/vm/__init__.py index a780c363cf8..657d2f7e6c3 100644 --- a/src/ethereum/forks/muir_glacier/vm/__init__.py +++ b/src/ethereum/forks/muir_glacier/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import Transaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -87,6 +91,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] @@ -152,7 +157,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) @@ -180,7 +185,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/environment.py b/src/ethereum/forks/muir_glacier/vm/instructions/environment.py index b3ac54a689a..87860dbd693 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/environment.py @@ -13,10 +13,10 @@ from ethereum_types.numeric import U256, Uint, ulen +from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...fork_types import EMPTY_ACCOUNT -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -70,7 +70,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -336,8 +337,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -375,8 +377,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -465,7 +468,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTCODEHASH) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -497,7 +500,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/storage.py b/src/ethereum/forks/muir_glacier/vm/instructions/storage.py index c34e6f31912..07ba90a057c 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -41,9 +41,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -67,11 +66,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) if original_value == current_value and current_value != new_value: if original_value == 0: @@ -107,7 +106,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/system.py b/src/ethereum/forks/muir_glacier/vm/instructions/system.py index 12f69d1131d..cca5876670a 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/system.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -75,7 +75,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -87,11 +87,9 @@ def generic_create( return if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return @@ -99,7 +97,7 @@ def generic_create( evm.memory, memory_start_position, memory_size ) - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -156,7 +154,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -277,8 +275,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - code_account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, code_account.code_hash) + code_account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, code_account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -345,7 +343,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -360,7 +358,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -428,7 +426,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -470,9 +468,9 @@ def selfdestruct(evm: Evm) -> None: # GAS gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -495,28 +493,28 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/muir_glacier/vm/interpreter.py b/src/ethereum/forks/muir_glacier/vm/interpreter.py index 66db7006918..684e677145a 100644 --- a/src/ethereum/forks/muir_glacier/vm/interpreter.py +++ b/src/ethereum/forks/muir_glacier/vm/interpreter.py @@ -31,16 +31,16 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -102,12 +102,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -121,9 +121,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -166,14 +164,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -185,15 +194,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -212,7 +220,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -237,13 +245,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -274,9 +285,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/osaka/blocks.py b/src/ethereum/forks/osaka/blocks.py index c0d1de37f12..121b925021a 100644 --- a/src/ethereum/forks/osaka/blocks.py +++ b/src/ethereum/forks/osaka/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.osaka.state.state_root - [Trie]: ref:ethereum.forks.osaka.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.osaka.trie.root - [Trie]: ref:ethereum.forks.osaka.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.osaka.trie.root - [Trie]: ref:ethereum.forks.osaka.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index 19ce50f243d..66832bf3a20 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -51,16 +57,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -75,7 +82,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -220,9 +226,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -239,7 +247,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -265,6 +276,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -396,6 +408,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -408,6 +421,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -466,7 +481,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -534,7 +549,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -585,74 +600,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -677,9 +624,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -688,10 +644,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -710,8 +665,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -728,17 +683,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -872,6 +861,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -889,9 +880,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -901,14 +893,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -929,7 +919,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -962,23 +952,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -998,6 +986,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -1007,9 +997,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1018,7 +1006,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/osaka/requests.py b/src/ethereum/forks/osaka/requests.py index b53f81a33bf..ad50fc25331 100644 --- a/src/ethereum/forks/osaka/requests.py +++ b/src/ethereum/forks/osaka/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/osaka/state.py b/src/ethereum/forks/osaka/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/osaka/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/osaka/state_tracker.py b/src/ethereum/forks/osaka/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/osaka/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/osaka/trie.py b/src/ethereum/forks/osaka/trie.py deleted file mode 100644 index a99b562bfea..00000000000 --- a/src/ethereum/forks/osaka/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.prague import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/osaka/utils/message.py b/src/ethereum/forks/osaka/utils/message.py index ae60e5e78da..6c8a3d5aae1 100644 --- a/src/ethereum/forks/osaka/utils/message.py +++ b/src/ethereum/forks/osaka/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/osaka/vm/__init__.py b/src/ethereum/forks/osaka/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/osaka/vm/__init__.py +++ b/src/ethereum/forks/osaka/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/osaka/vm/eoa_delegation.py b/src/ethereum/forks/osaka/vm/eoa_delegation.py index 474ca9ae033..62193fe0819 100644 --- a/src/ethereum/forks/osaka/vm/eoa_delegation.py +++ b/src/ethereum/forks/osaka/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,9 +139,9 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -151,7 +151,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -171,7 +171,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -187,8 +187,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -197,7 +197,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -207,15 +207,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/osaka/vm/instructions/environment.py b/src/ethereum/forks/osaka/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/osaka/vm/instructions/environment.py +++ b/src/ethereum/forks/osaka/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/osaka/vm/instructions/storage.py b/src/ethereum/forks/osaka/vm/instructions/storage.py index a782cd0db25..63fda6bc3f3 100644 --- a/src/ethereum/forks/osaka/vm/instructions/storage.py +++ b/src/ethereum/forks/osaka/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -51,9 +51,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -77,11 +76,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -122,7 +121,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -147,7 +146,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -174,7 +173,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/osaka/vm/instructions/system.py b/src/ethereum/forks/osaka/vm/instructions/system.py index 0708c9041e2..b431ce264ef 100644 --- a/src/ethereum/forks/osaka/vm/instructions/system.py +++ b/src/ethereum/forks/osaka/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -168,7 +166,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -384,7 +382,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -399,7 +397,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -484,7 +482,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, + evm.message.tx_env.state, evm.message.current_target, ).balance if sender_balance < value: @@ -533,9 +531,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, + evm.message.tx_env.state, evm.message.current_target, ).balance != 0 @@ -548,11 +546,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -560,10 +558,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/osaka/vm/interpreter.py b/src/ethereum/forks/osaka/vm/interpreter.py index b956f824d0e..76e524c7196 100644 --- a/src/ethereum/forks/osaka/vm/interpreter.py +++ b/src/ethereum/forks/osaka/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/paris/blocks.py b/src/ethereum/forks/paris/blocks.py index 72a0ffd79de..7e5af5891ff 100644 --- a/src/ethereum/forks/paris/blocks.py +++ b/src/ethereum/forks/paris/blocks.py @@ -72,13 +72,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.paris.state.state_root - [Trie]: ref:ethereum.forks.paris.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -88,8 +89,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.paris.trie.root - [Trie]: ref:ethereum.forks.paris.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -99,8 +100,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.paris.trie.root - [Trie]: ref:ethereum.forks.paris.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 18be9678a70..624539868b5 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, encode_receipt @@ -36,13 +42,15 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, destroy_account, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -55,7 +63,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -167,9 +174,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -183,7 +192,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_env=block_env, transactions=block.transactions, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -201,6 +215,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -328,6 +343,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -340,6 +356,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -370,7 +388,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -508,6 +526,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -523,21 +543,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -553,6 +572,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -574,23 +594,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund @@ -609,6 +627,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ diff --git a/src/ethereum/forks/paris/state.py b/src/ethereum/forks/paris/state.py deleted file mode 100644 index ab1b0d39a90..00000000000 --- a/src/ethereum/forks/paris/state.py +++ /dev/null @@ -1,635 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Return the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Return the bytecode for a given code hash. - - Parameters - ---------- - state: - The current state. - code_hash: - The hash of the code to retrieve. - - Returns - ------- - code : `Bytes` - The bytecode for the given hash. - - """ - return state.get_code(code_hash) - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in the code store and return its hash. - - Parameters - ---------- - state: - The current state. - code: - The bytecode to store. - - Returns - ------- - code_hash : `Hash32` - The keccak256 hash of the stored bytecode. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = store_code(state, code) - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value diff --git a/src/ethereum/forks/paris/state_tracker.py b/src/ethereum/forks/paris/state_tracker.py new file mode 100644 index 00000000000..178ffa0a79f --- /dev/null +++ b/src/ethereum/forks/paris/state_tracker.py @@ -0,0 +1,772 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) diff --git a/src/ethereum/forks/paris/trie.py b/src/ethereum/forks/paris/trie.py deleted file mode 100644 index 35882f949fc..00000000000 --- a/src/ethereum/forks/paris/trie.py +++ /dev/null @@ -1,499 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.gray_glacier import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.RLP` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/paris/utils/message.py b/src/ethereum/forks/paris/utils/message.py index a8ff2e48d08..63b7e852e7f 100644 --- a/src/ethereum/forks/paris/utils/message.py +++ b/src/ethereum/forks/paris/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,9 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) - + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/paris/vm/__init__.py b/src/ethereum/forks/paris/vm/__init__.py index a07bfac29cd..40b2000ce7f 100644 --- a/src/ethereum/forks/paris/vm/__init__.py +++ b/src/ethereum/forks/paris/vm/__init__.py @@ -20,12 +20,12 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -37,7 +37,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -89,6 +89,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] + state: TransactionState index_in_block: Optional[Uint] tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/paris/vm/instructions/environment.py b/src/ethereum/forks/paris/vm/instructions/environment.py index 588022b5722..ff0a4044f73 100644 --- a/src/ethereum/forks/paris/vm/instructions/environment.py +++ b/src/ethereum/forks/paris/vm/instructions/environment.py @@ -16,7 +16,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -74,7 +74,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -346,8 +347,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -389,8 +390,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -485,7 +486,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -517,7 +518,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/paris/vm/instructions/storage.py b/src/ethereum/forks/paris/vm/instructions/storage.py index 287544f353b..e9d86666668 100644 --- a/src/ethereum/forks/paris/vm/instructions/storage.py +++ b/src/ethereum/forks/paris/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import ( @@ -45,9 +45,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -71,11 +70,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -121,7 +120,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/paris/vm/instructions/system.py b/src/ethereum/forks/paris/vm/instructions/system.py index 01791beb50f..50eb3136a1d 100644 --- a/src/ethereum/forks/paris/vm/instructions/system.py +++ b/src/ethereum/forks/paris/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -74,7 +74,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -88,15 +88,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -155,7 +153,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -276,8 +274,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - state = evm.message.block_env.state - code = get_code(state, get_account(state, code_address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, code_address).code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -352,7 +350,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -367,7 +365,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -442,7 +440,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -488,9 +486,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -502,22 +500,22 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/paris/vm/interpreter.py b/src/ethereum/forks/paris/vm/interpreter.py index 32cb2e3b4de..f1db0ca736f 100644 --- a/src/ethereum/forks/paris/vm/interpreter.py +++ b/src/ethereum/forks/paris/vm/interpreter.py @@ -31,15 +31,15 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -99,12 +99,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -155,14 +155,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -177,15 +188,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -204,7 +214,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -230,11 +240,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -265,9 +278,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/prague/blocks.py b/src/ethereum/forks/prague/blocks.py index acc2a77c199..766f7e8b6e4 100644 --- a/src/ethereum/forks/prague/blocks.py +++ b/src/ethereum/forks/prague/blocks.py @@ -107,13 +107,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.prague.state.state_root - [Trie]: ref:ethereum.forks.prague.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -123,8 +124,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.prague.trie.root - [Trie]: ref:ethereum.forks.prague.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -134,8 +135,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.prague.trie.root - [Trie]: ref:ethereum.forks.prague.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index 9a14a702850..e39016d12db 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -50,16 +56,17 @@ compute_requests_hash, parse_deposit_requests, ) -from .state import ( - State, - TransientStorage, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( BlobTransaction, @@ -74,7 +81,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message @@ -212,9 +218,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -231,7 +239,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -257,6 +268,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if requests_hash != block.header.requests_hash: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -388,6 +400,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint, Tuple[VersionedHash, ...], U64]: """ Check if the transaction is includable in the block. @@ -400,6 +413,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -456,7 +471,7 @@ def check_transaction( raise BlobGasLimitExceededError("blob gas limit exceeded") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance( tx, (FeeMarketTransaction, BlobTransaction, SetCodeTransaction) @@ -519,7 +534,7 @@ def check_transaction( if Uint(sender_account.balance) < max_gas_fee + Uint(tx.value): raise InsufficientBalanceError("insufficient sender balance") - sender_code = get_code(block_env.state, sender_account.code_hash) + sender_code = get_code(tx_state, sender_account.code_hash) if sender_account.code_hash != EMPTY_CODE_HASH and not is_valid_delegation( sender_code ): @@ -570,74 +585,6 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - system_contract_code: Bytes, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction with the given code. - - Prefer calling `process_checked_system_transaction` or - `process_unchecked_system_transaction` depending on whether missing code or - an execution error should cause the block to be rejected. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - system_contract_code : - Code of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - tx_env = vm.TransactionEnvironment( - origin=SYSTEM_ADDRESS, - gas_price=block_env.base_fee_per_gas, - gas=SYSTEM_TRANSACTION_GAS, - access_list_addresses=set(), - access_list_storage_keys=set(), - transient_storage=TransientStorage(), - blob_versioned_hashes=(), - authorizations=(), - index_in_block=None, - tx_hash=None, - ) - - system_tx_message = Message( - block_env=block_env, - tx_env=tx_env, - caller=SYSTEM_ADDRESS, - target=target_address, - gas=SYSTEM_TRANSACTION_GAS, - value=U256(0), - data=data, - code=system_contract_code, - depth=Uint(0), - current_target=target_address, - code_address=target_address, - should_transfer_value=False, - is_static=False, - accessed_addresses=set(), - accessed_storage_keys=set(), - disable_precompiles=False, - parent_evm=None, - ) - - system_tx_output = process_message_call(system_tx_message) - - return system_tx_output - - def process_checked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, @@ -662,9 +609,18 @@ def process_checked_system_transaction( Output of processing the system transaction. """ + # Pre-check that the system contract has code. We use a throwaway + # TransactionState here that is *never* propagated back to BlockState + # (no incorporate_tx_into_block call); the same get_account / get_code + # lookups are performed and properly tracked by + # process_unchecked_system_transaction below, which this function + # always calls. Reading via a TransactionState (rather than directly + # against pre_state) lets us see system contracts deployed earlier in + # the same block — see EIP-7002 and EIP-7251 for this edge case. + untracked_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + untracked_state, + get_account(untracked_state, target_address).code_hash, ) if len(system_contract_code) == 0: @@ -673,10 +629,9 @@ def process_checked_system_transaction( "contain code" ) - system_tx_output = process_system_transaction( + system_tx_output = process_unchecked_system_transaction( block_env, target_address, - system_contract_code, data, ) @@ -695,8 +650,8 @@ def process_unchecked_system_transaction( data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -713,17 +668,51 @@ def process_unchecked_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, + system_tx_state, + get_account(system_tx_state, target_address).code_hash, ) - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + blob_versioned_hashes=(), + authorizations=(), + index_in_block=None, + tx_hash=None, ) + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + current_target=target_address, + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + disable_precompiles=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + def apply_body( block_env: vm.BlockEnvironment, @@ -857,6 +846,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -874,9 +865,10 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) if isinstance(tx, BlobTransaction): blob_gas_fee = calculate_data_fee(block_env.excess_blob_gas, tx) @@ -886,14 +878,12 @@ def process_transaction( effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -914,7 +904,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, - transient_storage=TransientStorage(), + state=tx_state, blob_versioned_hashes=blob_versioned_hashes, authorizations=authorizations, index_in_block=index, @@ -947,23 +937,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund block_output.blob_gas_used += tx_blob_gas_used @@ -983,6 +971,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -992,9 +982,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -1003,7 +991,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/prague/requests.py b/src/ethereum/forks/prague/requests.py index 08b28c61115..c0e624ae62b 100644 --- a/src/ethereum/forks/prague/requests.py +++ b/src/ethereum/forks/prague/requests.py @@ -35,10 +35,10 @@ from ethereum_types.numeric import Uint, ulen from ethereum.exceptions import InvalidBlock +from ethereum.merkle_patricia_trie import trie_get from ethereum.utils.hexadecimal import hex_to_bytes32 from .blocks import decode_receipt -from .trie import trie_get from .utils.hexadecimal import hex_to_address from .vm import BlockOutput diff --git a/src/ethereum/forks/prague/state.py b/src/ethereum/forks/prague/state.py deleted file mode 100644 index 342bda1a1cd..00000000000 --- a/src/ethereum/forks/prague/state.py +++ /dev/null @@ -1,713 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -@dataclass -class TransientStorage: - """ - Contains all information that is preserved between message calls - within a transaction. - """ - - _tries: Dict[Address, Trie[Bytes32, U256]] = field(default_factory=dict) - _snapshots: List[Dict[Address, Trie[Bytes32, U256]]] = field( - default_factory=list - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - transient_storage._snapshots.append( - {k: copy_trie(t) for (k, t) in transient_storage._tries.items()} - ) - - -def commit_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._snapshots.pop() - - -def rollback_transaction( - state: State, transient_storage: TransientStorage -) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - transient_storage : TransientStorage - The transient storage of the transaction. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - transient_storage._tries = transient_storage._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase, and to respect the constraints added to SELFDESTRUCT by - EIP-6780. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value - - -def get_transient_storage( - transient_storage: TransientStorage, address: Address, key: Bytes32 -) -> U256: - """ - Get a value at a storage key on an account from transient storage. - Returns `U256(0)` if the storage key has not been set previously. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_transient_storage( - transient_storage: TransientStorage, - address: Address, - key: Bytes32, - value: U256, -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - transient_storage: `TransientStorage` - The transient storage - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - trie = transient_storage._tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - transient_storage._tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del transient_storage._tries[address] diff --git a/src/ethereum/forks/prague/state_tracker.py b/src/ethereum/forks/prague/state_tracker.py new file mode 100644 index 00000000000..09348663439 --- /dev/null +++ b/src/ethereum/forks/prague/state_tracker.py @@ -0,0 +1,747 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if tx_state.parent.storage_writes.get(address): + return True + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + ) diff --git a/src/ethereum/forks/prague/trie.py b/src/ethereum/forks/prague/trie.py deleted file mode 100644 index a25868fbeff..00000000000 --- a/src/ethereum/forks/prague/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.cancun import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/prague/utils/message.py b/src/ethereum/forks/prague/utils/message.py index bce79e84019..08e3bb77ac6 100644 --- a/src/ethereum/forks/prague/utils/message.py +++ b/src/ethereum/forks/prague/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,8 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/prague/vm/__init__.py b/src/ethereum/forks/prague/vm/__init__.py index 37d0a327974..64cb272d02b 100644 --- a/src/ethereum/forks/prague/vm/__init__.py +++ b/src/ethereum/forks/prague/vm/__init__.py @@ -20,13 +20,13 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal from ..fork_types import Authorization, VersionedHash -from ..state import State, TransientStorage +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -38,7 +38,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -103,7 +103,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] - transient_storage: TransientStorage + state: TransactionState blob_versioned_hashes: Tuple[VersionedHash, ...] authorizations: Tuple[Authorization, ...] index_in_block: Optional[Uint] diff --git a/src/ethereum/forks/prague/vm/eoa_delegation.py b/src/ethereum/forks/prague/vm/eoa_delegation.py index 3fd42910817..1ba552f8dd6 100644 --- a/src/ethereum/forks/prague/vm/eoa_delegation.py +++ b/src/ethereum/forks/prague/vm/eoa_delegation.py @@ -14,7 +14,7 @@ from ethereum.state import Address from ..fork_types import Authorization -from ..state import ( +from ..state_tracker import ( account_exists, get_account, get_code, @@ -139,8 +139,8 @@ def access_delegation( The delegation address, code, and access gas cost. """ - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) if not is_valid_delegation(code): return False, address, code, Uint(0) @@ -150,7 +150,7 @@ def access_delegation( else: evm.accessed_addresses.add(address) access_gas_cost = GasCosts.COLD_ACCOUNT_ACCESS - code = get_code(state, get_account(state, address).code_hash) + code = get_code(tx_state, get_account(tx_state, address).code_hash) return True, address, code, access_gas_cost @@ -170,7 +170,7 @@ def set_delegation(message: Message) -> U256: Refund from authority which already exists in state. """ - state = message.block_env.state + tx_state = message.tx_env.state refund_counter = U256(0) for auth in message.tx_env.authorizations: if auth.chain_id not in (message.block_env.chain_id, U256(0)): @@ -186,8 +186,8 @@ def set_delegation(message: Message) -> U256: message.accessed_addresses.add(authority) - authority_account = get_account(state, authority) - authority_code = get_code(state, authority_account.code_hash) + authority_account = get_account(tx_state, authority) + authority_code = get_code(tx_state, authority_account.code_hash) if authority_code and not is_valid_delegation(authority_code): continue @@ -196,7 +196,7 @@ def set_delegation(message: Message) -> U256: if authority_nonce != auth.nonce: continue - if account_exists(state, authority): + if account_exists(tx_state, authority): refund_counter += U256( GasCosts.AUTH_PER_EMPTY_ACCOUNT - REFUND_AUTH_PER_EXISTING_ACCOUNT @@ -206,15 +206,15 @@ def set_delegation(message: Message) -> U256: code_to_set = b"" else: code_to_set = EOA_DELEGATION_MARKER + auth.address - set_code(state, authority, code_to_set) + set_code(tx_state, authority, code_to_set) - increment_nonce(state, authority) + increment_nonce(tx_state, authority) if message.code_address is None: raise InvalidBlock("Invalid type 4 transaction: no target") message.code = get_code( - state, get_account(state, message.code_address).code_hash + tx_state, get_account(tx_state, message.code_address).code_hash ) return refund_counter diff --git a/src/ethereum/forks/prague/vm/instructions/environment.py b/src/ethereum/forks/prague/vm/instructions/environment.py index 7fa57b90d8b..b6bf713df27 100644 --- a/src/ethereum/forks/prague/vm/instructions/environment.py +++ b/src/ethereum/forks/prague/vm/instructions/environment.py @@ -17,7 +17,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -76,7 +76,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -348,8 +349,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -391,8 +392,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -487,7 +488,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -519,7 +520,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/prague/vm/instructions/storage.py b/src/ethereum/forks/prague/vm/instructions/storage.py index 5aa3cc6746f..99dcce877dd 100644 --- a/src/ethereum/forks/prague/vm/instructions/storage.py +++ b/src/ethereum/forks/prague/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import ( +from ...state_tracker import ( get_storage, get_storage_original, get_transient_storage, @@ -51,9 +51,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -77,11 +76,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -127,7 +126,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) @@ -152,7 +151,7 @@ def tload(evm: Evm) -> None: # OPERATION value = get_transient_storage( - evm.message.tx_env.transient_storage, evm.message.current_target, key + evm.message.tx_env.state, evm.message.current_target, key ) push(evm.stack, value) @@ -179,7 +178,7 @@ def tstore(evm: Evm) -> None: if evm.message.is_static: raise WriteInStaticContext set_transient_storage( - evm.message.tx_env.transient_storage, + evm.message.tx_env.state, evm.message.current_target, key, new_value, diff --git a/src/ethereum/forks/prague/vm/instructions/system.py b/src/ethereum/forks/prague/vm/instructions/system.py index 2d99ac93e61..713a04af13c 100644 --- a/src/ethereum/forks/prague/vm/instructions/system.py +++ b/src/ethereum/forks/prague/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -82,7 +82,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -96,15 +96,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -167,7 +165,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -383,7 +381,7 @@ def call(evm: Evm) -> None: access_gas_cost += delegated_access_gas_cost create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -398,7 +396,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -483,7 +481,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -531,9 +529,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -545,11 +543,11 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance move_ether( - evm.message.block_env.state, + evm.message.tx_env.state, originator, beneficiary, originator_balance, @@ -557,10 +555,10 @@ def selfdestruct(evm: Evm) -> None: # register account for deletion only if it was created # in the same transaction - if originator in evm.message.block_env.state.created_accounts: + if originator in evm.message.tx_env.state.created_accounts: # If beneficiary is the same as originator, then # the ether is burnt. - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) evm.accounts_to_delete.add(originator) # HALT the execution diff --git a/src/ethereum/forks/prague/vm/interpreter.py b/src/ethereum/forks/prague/vm/interpreter.py index fd41c59a310..e41c070b463 100644 --- a/src/ethereum/forks/prague/vm/interpreter.py +++ b/src/ethereum/forks/prague/vm/interpreter.py @@ -31,17 +31,17 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, get_account, get_code, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -105,12 +105,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -131,8 +131,8 @@ def process_message_call(message: Message) -> MessageCallOutput: message.disable_precompiles = True message.accessed_addresses.add(delegated_address) message.code = get_code( - block_env.state, - get_account(block_env.state, delegated_address).code_hash, + tx_state, + get_account(tx_state, delegated_address).code_hash, ) message.code_address = delegated_address @@ -176,17 +176,26 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state - transient_storage = message.tx_env.transient_storage + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state, transient_storage) - - # The list of created accounts is used by `get_storage_original`. - # Additionally, the list is needed to respect the constraints + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. This tracking is also needed to respect the constraints # added to SELFDESTRUCT by EIP-6780. - mark_account_created(state, message.current_target) + mark_account_created(tx_state, message.current_target) - increment_nonce(state, message.current_target) + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -201,15 +210,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state, transient_storage) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm @@ -228,11 +236,10 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") - transient_storage = message.tx_env.transient_storage code = message.code valid_jump_destinations = get_valid_jump_destinations(code) evm = Evm( @@ -255,11 +262,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state, transient_storage) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -291,9 +301,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state, transient_storage) - else: - commit_transaction(state, transient_storage) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/shanghai/blocks.py b/src/ethereum/forks/shanghai/blocks.py index d1747c7c702..0c56be4303f 100644 --- a/src/ethereum/forks/shanghai/blocks.py +++ b/src/ethereum/forks/shanghai/blocks.py @@ -105,13 +105,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.shanghai.state.state_root - [Trie]: ref:ethereum.forks.shanghai.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -121,8 +122,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.shanghai.trie.root - [Trie]: ref:ethereum.forks.shanghai.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -132,8 +133,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.shanghai.trie.root - [Trie]: ref:ethereum.forks.shanghai.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 7604389956a..cb1c9a52161 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -27,7 +27,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Account, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -36,14 +42,16 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, + create_ether, destroy_account, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, - modify_state, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -56,7 +64,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -168,9 +175,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -185,7 +194,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -206,6 +220,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if withdrawals_root != block.header.withdrawals_root: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -333,6 +348,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -345,6 +361,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -375,7 +393,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -520,6 +538,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -535,21 +555,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -566,6 +585,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -587,23 +607,21 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund @@ -622,6 +640,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, @@ -631,9 +651,7 @@ def process_withdrawals( """ Increase the balance of the withdrawing account. """ - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += wd.amount * U256(10**9) + wd_state = TransactionState(parent=block_env.state) for i, wd in enumerate(withdrawals): trie_set( @@ -642,7 +660,9 @@ def increase_recipient_balance(recipient: Account) -> None: rlp.encode(wd), ) - modify_state(block_env.state, wd.address, increase_recipient_balance) + create_ether(wd_state, wd.address, wd.amount * U256(10**9)) + + incorporate_tx_into_block(wd_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: diff --git a/src/ethereum/forks/shanghai/state.py b/src/ethereum/forks/shanghai/state.py deleted file mode 100644 index d2cbd10ff8f..00000000000 --- a/src/ethereum/forks/shanghai/state.py +++ /dev/null @@ -1,615 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Set, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import ( - EMPTY_ACCOUNT, - EMPTY_CODE_HASH, - Account, - Address, - Root, -) - -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - created_accounts: Set[Address] = field(default_factory=set) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - def get_code(self, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return self._code_store[code_hash] - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state.created_accounts - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - if not state._snapshots: - state.created_accounts.clear() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - - Return ``b""`` for ``EMPTY_CODE_HASH``. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State`` and return its hash. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def mark_account_created(state: State, address: Address) -> None: - """ - Mark an account as having been created in the current transaction. - This information is used by `get_storage_original()` to handle an obscure - edgecase. - - The marker is not removed even if the account creation reverts. Since the - account cannot have had code prior to its creation and can't call - `get_storage_original()`, this is harmless. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account that has been created. - - """ - state.created_accounts.add(address) - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. If, after modification, the account - exists and has zero nonce, empty code, and zero balance, it is destroyed. - """ - set_account(state, address, modify(get_account(state, address), f)) - - account = get_account_optional(state, address) - account_exists_and_is_empty = ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - if account_exists_and_is_empty: - destroy_account(state, address) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = store_code(state, code) - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def get_storage_original(state: State, address: Address, key: Bytes32) -> U256: - """ - Get the original value in a storage slot i.e. the value before the current - transaction began. This function reads the value from the snapshots taken - before executing the transaction. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to read the value from. - key: - Key of the storage slot. - - """ - # In the transaction where an account is created, its preexisting storage - # is ignored. - if address in state.created_accounts: - return U256(0) - - _, original_trie = state._snapshots[0] - original_account_trie = original_trie.get(address) - - if original_account_trie is None: - original_value = U256(0) - else: - original_value = trie_get(original_account_trie, key) - - assert isinstance(original_value, U256) - - return original_value diff --git a/src/ethereum/forks/shanghai/state_tracker.py b/src/ethereum/forks/shanghai/state_tracker.py new file mode 100644 index 00000000000..178ffa0a79f --- /dev/null +++ b/src/ethereum/forks/shanghai/state_tracker.py @@ -0,0 +1,772 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. If, after modification, the + account exists and has zero nonce, empty code, and zero balance, it + is destroyed. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) diff --git a/src/ethereum/forks/shanghai/trie.py b/src/ethereum/forks/shanghai/trie.py deleted file mode 100644 index 2cf4cf73fe7..00000000000 --- a/src/ethereum/forks/shanghai/trie.py +++ /dev/null @@ -1,502 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.paris import trie as previous_trie -from ethereum.state import Account, Address, Root -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/shanghai/utils/message.py b/src/ethereum/forks/shanghai/utils/message.py index 1df8f3cfda6..a42594161a3 100644 --- a/src/ethereum/forks/shanghai/utils/message.py +++ b/src/ethereum/forks/shanghai/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS @@ -55,7 +55,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -63,9 +63,9 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - state = block_env.state - code = get_code(state, get_account(state, tx.to).code_hash) - + code = get_code( + tx_env.state, get_account(tx_env.state, tx.to).code_hash + ) code_address = tx.to else: raise AssertionError("Target must be address or empty bytes") diff --git a/src/ethereum/forks/shanghai/vm/__init__.py b/src/ethereum/forks/shanghai/vm/__init__.py index df7e7e63a88..147b1971c7d 100644 --- a/src/ethereum/forks/shanghai/vm/__init__.py +++ b/src/ethereum/forks/shanghai/vm/__init__.py @@ -20,12 +20,12 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt, Withdrawal -from ..state import State +from ..state_tracker import BlockState, TransactionState from ..transactions import LegacyTransaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -37,7 +37,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -94,6 +94,7 @@ class TransactionEnvironment: gas: Uint access_list_addresses: Set[Address] access_list_storage_keys: Set[Tuple[Address, Bytes32]] + state: TransactionState index_in_block: Optional[Uint] tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/shanghai/vm/instructions/environment.py b/src/ethereum/forks/shanghai/vm/instructions/environment.py index 588022b5722..ff0a4044f73 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/environment.py +++ b/src/ethereum/forks/shanghai/vm/instructions/environment.py @@ -16,7 +16,7 @@ from ethereum.state import EMPTY_ACCOUNT from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -74,7 +74,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -346,8 +347,8 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -389,8 +390,8 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - state = evm.message.block_env.state - code = get_code(state, get_account(state, address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, address).code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) @@ -485,7 +486,7 @@ def extcodehash(evm: Evm) -> None: charge_gas(evm, access_gas_cost) # OPERATION - account = get_account(evm.message.block_env.state, address) + account = get_account(evm.message.tx_env.state, address) if account == EMPTY_ACCOUNT: codehash = U256(0) @@ -517,7 +518,7 @@ def self_balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance push(evm.stack, balance) diff --git a/src/ethereum/forks/shanghai/vm/instructions/storage.py b/src/ethereum/forks/shanghai/vm/instructions/storage.py index 0936a10b1e1..c3fe02532ad 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/storage.py +++ b/src/ethereum/forks/shanghai/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, get_storage_original, set_storage +from ...state_tracker import get_storage, get_storage_original, set_storage from .. import Evm from ..exceptions import OutOfGasError, WriteInStaticContext from ..gas import GasCosts, charge_gas @@ -42,9 +42,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.COLD_STORAGE_ACCESS) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -68,11 +67,11 @@ def sstore(evm: Evm) -> None: if evm.gas_left <= GasCosts.CALL_STIPEND: raise OutOfGasError - state = evm.message.block_env.state + tx_state = evm.message.tx_env.state original_value = get_storage_original( - state, evm.message.current_target, key + tx_state, evm.message.current_target, key ) - current_value = get_storage(state, evm.message.current_target, key) + current_value = get_storage(tx_state, evm.message.current_target, key) gas_cost = Uint(0) @@ -118,7 +117,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) if evm.message.is_static: raise WriteInStaticContext - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/shanghai/vm/instructions/system.py b/src/ethereum/forks/shanghai/vm/instructions/system.py index b3fc0cd3dbb..b83e201eff2 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/system.py +++ b/src/ethereum/forks/shanghai/vm/instructions/system.py @@ -17,7 +17,7 @@ from ethereum.state import Address from ethereum.utils.numeric import ceil32 -from ...state import ( +from ...state_tracker import ( account_has_code_or_nonce, account_has_storage, get_account, @@ -81,7 +81,7 @@ def generic_create( evm.return_data = b"" sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) if ( sender.balance < endowment @@ -95,15 +95,13 @@ def generic_create( evm.accessed_addresses.add(contract_address) if account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) return - increment_nonce(evm.message.block_env.state, evm.message.current_target) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -165,7 +163,7 @@ def create(evm: Evm) -> None: contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -296,8 +294,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - state = evm.message.block_env.state - code = get_code(state, get_account(state, code_address).code_hash) + tx_state = evm.message.tx_env.state + code = get_code(tx_state, get_account(tx_state, code_address).code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -372,7 +370,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -387,7 +385,7 @@ def call(evm: Evm) -> None: raise WriteInStaticContext evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -462,7 +460,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -508,9 +506,9 @@ def selfdestruct(evm: Evm) -> None: gas_cost += GasCosts.COLD_ACCOUNT_ACCESS if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -522,22 +520,22 @@ def selfdestruct(evm: Evm) -> None: originator = evm.message.current_target beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/shanghai/vm/interpreter.py b/src/ethereum/forks/shanghai/vm/interpreter.py index d4ec312b4fa..84c6af3660f 100644 --- a/src/ethereum/forks/shanghai/vm/interpreter.py +++ b/src/ethereum/forks/shanghai/vm/interpreter.py @@ -31,15 +31,15 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, mark_account_created, move_ether, - rollback_transaction, + restore_tx_state, set_code, ) from ..vm import Message @@ -100,12 +100,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -156,14 +156,25 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - # The list of created accounts is used by `get_storage_original`. - mark_account_created(state, message.current_target) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + # In the previously mentioned edge case the preexisting storage is ignored + # for gas refund purposes. In order to do this we must track created + # accounts. + mark_account_created(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -178,15 +189,14 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.output = b"" evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -205,7 +215,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -231,11 +241,14 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -266,9 +279,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/spurious_dragon/blocks.py b/src/ethereum/forks/spurious_dragon/blocks.py index 507546a8f9b..79ddf72c20f 100644 --- a/src/ethereum/forks/spurious_dragon/blocks.py +++ b/src/ethereum/forks/spurious_dragon/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.spurious_dragon.state.state_root - [Trie]: ref:ethereum.forks.spurious_dragon.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.spurious_dragon.trie.root - [Trie]: ref:ethereum.forks.spurious_dragon.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.spurious_dragon.trie.root - [Trie]: ref:ethereum.forks.spurious_dragon.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/spurious_dragon/fork.py b/src/ethereum/forks/spurious_dragon/fork.py index 7c3101d25a3..1d4f4e809d6 100644 --- a/src/ethereum/forks/spurious_dragon/fork.py +++ b/src/ethereum/forks/spurious_dragon/fork.py @@ -27,21 +27,29 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, account_exists_and_is_empty, create_ether, destroy_account, destroy_touched_empty_accounts, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -49,7 +57,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -160,9 +167,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -176,7 +185,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -194,6 +208,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -342,6 +357,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -354,6 +370,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -376,7 +394,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -462,7 +480,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -544,9 +562,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -565,25 +581,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -616,6 +631,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -623,23 +640,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -659,33 +676,45 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) if coinbase_balance_after_mining_fee != 0: set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) - elif account_exists_and_is_empty(block_env.state, block_env.coinbase): - destroy_account(block_env.state, block_env.coinbase) + elif account_exists_and_is_empty(tx_state, block_env.coinbase): + destroy_account(tx_state, block_env.coinbase) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) - destroy_touched_empty_accounts(block_env.state, tx_output.touched_accounts) + destroy_touched_empty_accounts(tx_state, tx_output.touched_accounts) block_output.block_gas_used += tx_gas_used_after_refund + incorporate_tx_into_block(tx_state) + + block_state = block_env.state + block_diff = extract_block_diff(block_state) + intermediate_state_root, _ = ( + block_state.pre_state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) + ) + receipt = make_receipt( - state_root(block_env.state), + intermediate_state_root, block_output.block_gas_used, tx_output.logs, ) diff --git a/src/ethereum/forks/spurious_dragon/fork_types.py b/src/ethereum/forks/spurious_dragon/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/spurious_dragon/fork_types.py +++ b/src/ethereum/forks/spurious_dragon/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/spurious_dragon/state.py b/src/ethereum/forks/spurious_dragon/state.py deleted file mode 100644 index 10cf7e419b5..00000000000 --- a/src/ethereum/forks/spurious_dragon/state.py +++ /dev/null @@ -1,611 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, Iterable, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def account_exists_and_is_empty(state: State, address: Address) -> bool: - """ - Checks if an account exists and has zero nonce, empty code and zero - balance. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - exists_and_is_empty : `bool` - True if an account exists and has zero nonce, empty code and zero - balance, False otherwise. - - """ - account = get_account_optional(state, address) - return ( - account is not None - and account.nonce == Uint(0) - and account.code_hash == EMPTY_CODE_HASH - and account.balance == 0 - ) - - -def is_account_alive(state: State, address: Address) -> bool: - """ - Check whether an account is both in the state and non-empty. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - is_alive : `bool` - True if the account is alive. - - """ - account = get_account_optional(state, address) - return account is not None and account != EMPTY_ACCOUNT - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) - - -def destroy_touched_empty_accounts( - state: State, touched_accounts: Iterable[Address] -) -> None: - """ - Destroy all touched accounts that are empty. - - Parameters - ---------- - state: `State` - The current state. - touched_accounts: `Iterable[Address]` - All the accounts that have been touched in the current transaction. - - """ - for address in touched_accounts: - if account_exists_and_is_empty(state, address): - destroy_account(state, address) diff --git a/src/ethereum/forks/spurious_dragon/state_tracker.py b/src/ethereum/forks/spurious_dragon/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/spurious_dragon/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/spurious_dragon/transactions.py b/src/ethereum/forks/spurious_dragon/transactions.py index e8cde82b198..c2dda52bd71 100644 --- a/src/ethereum/forks/spurious_dragon/transactions.py +++ b/src/ethereum/forks/spurious_dragon/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/spurious_dragon/trie.py b/src/ethereum/forks/spurious_dragon/trie.py deleted file mode 100644 index 132537161aa..00000000000 --- a/src/ethereum/forks/spurious_dragon/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.tangerine_whistle import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/spurious_dragon/utils/hexadecimal.py b/src/ethereum/forks/spurious_dragon/utils/hexadecimal.py index 303561c837e..12a1e3f4167 100644 --- a/src/ethereum/forks/spurious_dragon/utils/hexadecimal.py +++ b/src/ethereum/forks/spurious_dragon/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/spurious_dragon/utils/message.py b/src/ethereum/forks/spurious_dragon/utils/message.py index f08934cc2e9..dad6858f5a7 100644 --- a/src/ethereum/forks/spurious_dragon/utils/message.py +++ b/src/ethereum/forks/spurious_dragon/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -49,7 +49,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -57,8 +57,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/spurious_dragon/vm/__init__.py b/src/ethereum/forks/spurious_dragon/vm/__init__.py index c588025cee7..f5ada743d6d 100644 --- a/src/ethereum/forks/spurious_dragon/vm/__init__.py +++ b/src/ethereum/forks/spurious_dragon/vm/__init__.py @@ -20,12 +20,16 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State, account_exists_and_is_empty +from ..state_tracker import ( + BlockState, + TransactionState, + account_exists_and_is_empty, +) from ..transactions import Transaction -from ..trie import Trie from .precompiled_contracts import RIPEMD160_ADDRESS __all__ = ("Environment", "Evm", "Message") @@ -38,7 +42,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -87,6 +91,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] @@ -150,7 +155,7 @@ def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: evm.accounts_to_delete.update(child_evm.accounts_to_delete) evm.touched_accounts.update(child_evm.touched_accounts) if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(child_evm.message.current_target) @@ -178,7 +183,7 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: evm.touched_accounts.add(RIPEMD160_ADDRESS) if child_evm.message.current_target == RIPEMD160_ADDRESS: if account_exists_and_is_empty( - evm.message.block_env.state, child_evm.message.current_target + evm.message.tx_env.state, child_evm.message.current_target ): evm.touched_accounts.add(RIPEMD160_ADDRESS) evm.gas_left += child_evm.gas_left diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py b/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py index d930368fdd9..d85aaf0c97a 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py @@ -15,7 +15,7 @@ from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -68,7 +68,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -334,8 +335,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -373,8 +375,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py b/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py index 0b2a1cce8aa..16921a1a7fb 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..gas import ( GasCosts, @@ -40,9 +40,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -65,8 +64,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -78,7 +77,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) # OPERATION - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/system.py b/src/ethereum/forks/spurious_dragon/vm/instructions/system.py index 037a54da3f9..b5ff4bb23bc 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/system.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/system.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ...state import ( +from ...state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, @@ -76,12 +76,12 @@ def create(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -93,20 +93,16 @@ def create(evm: Evm) -> None: push(evm.stack, U256(0)) evm.gas_left += create_message_gas elif account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) else: call_data = memory_read_bytes( evm.memory, memory_start_position, memory_size ) - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -197,8 +193,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -262,7 +258,7 @@ def call(evm: Evm) -> None: code_address = to create_gas_cost = GasCosts.NEW_ACCOUNT - if value == 0 or is_account_alive(evm.message.block_env.state, to): + if value == 0 or is_account_alive(evm.message.tx_env.state, to): create_gas_cost = Uint(0) transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -277,7 +273,7 @@ def call(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -343,7 +339,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -383,9 +379,9 @@ def selfdestruct(evm: Evm) -> None: # GAS gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE if ( - not is_account_alive(evm.message.block_env.state, beneficiary) + not is_account_alive(evm.message.tx_env.state, beneficiary) and get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance != 0 ): @@ -405,28 +401,28 @@ def selfdestruct(evm: Evm) -> None: charge_gas(evm, gas_cost) beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) # mark beneficiary as touched - if account_exists_and_is_empty(evm.message.block_env.state, beneficiary): + if account_exists_and_is_empty(evm.message.tx_env.state, beneficiary): evm.touched_accounts.add(beneficiary) # HALT the execution diff --git a/src/ethereum/forks/spurious_dragon/vm/interpreter.py b/src/ethereum/forks/spurious_dragon/vm/interpreter.py index c970cbc1ee4..788b93aa336 100644 --- a/src/ethereum/forks/spurious_dragon/vm/interpreter.py +++ b/src/ethereum/forks/spurious_dragon/vm/interpreter.py @@ -31,15 +31,15 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_exists_and_is_empty, account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, increment_nonce, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -100,12 +100,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -119,9 +119,7 @@ def process_message_call(message: Message) -> MessageCallOutput: evm = process_create_message(message) else: evm = process_message(message) - if account_exists_and_is_empty( - block_env.state, Address(message.target) - ): + if account_exists_and_is_empty(tx_state, Address(message.target)): evm.touched_accounts.add(Address(message.target)) if evm.error: @@ -164,11 +162,20 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) - - increment_nonce(state, message.current_target) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` or `CREATE2` call. + # * The first `CREATE` happened before Spurious Dragon and left empty + # code. + destroy_storage(tx_state, message.current_target) + + increment_nonce(tx_state, message.current_target) evm = process_message(message) if not evm.error: contract_code = evm.output @@ -180,14 +187,13 @@ def process_create_message(message: Message) -> Evm: if len(contract_code) > MAX_CODE_SIZE: raise OutOfGasError except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -206,7 +212,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -230,13 +236,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -263,9 +272,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/forks/tangerine_whistle/blocks.py b/src/ethereum/forks/tangerine_whistle/blocks.py index 664418b9f72..e9d4c3c3fe7 100644 --- a/src/ethereum/forks/tangerine_whistle/blocks.py +++ b/src/ethereum/forks/tangerine_whistle/blocks.py @@ -17,8 +17,9 @@ from ethereum_types.numeric import U256, Uint from ethereum.crypto.hash import Hash32 +from ethereum.state import Address, Root -from .fork_types import Address, Bloom, Root +from .fork_types import Bloom from .transactions import Transaction @@ -60,13 +61,14 @@ class Header: Root hash ([`keccak256`]) of the state trie after executing all transactions in this block. It represents the state of the Ethereum Virtual Machine (EVM) after all transactions in this block have been processed. It - is computed using the [`state_root()`] function, which computes the root - of the Merkle-Patricia [Trie] representing the Ethereum world state. + is computed using [`compute_state_root_and_trie_changes()`][changes], + which computes the root of the Merkle-Patricia [Trie] representing the + Ethereum world state after applying the block's state changes. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`state_root()`]: ref:ethereum.forks.tangerine_whistle.state.state_root - [Trie]: ref:ethereum.forks.tangerine_whistle.trie.Trie - """ + [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes + [Trie]: ref:ethereum.merkle_patricia_trie.Trie + """ # noqa: E501 transactions_root: Root """ @@ -76,8 +78,8 @@ class Header: transactions as the parameter. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.tangerine_whistle.trie.root - [Trie]: ref:ethereum.forks.tangerine_whistle.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ receipt_root: Root @@ -87,8 +89,8 @@ class Header: function over the Merkle-Patricia [trie] constructed from the receipts. [`keccak256`]: ref:ethereum.crypto.hash.keccak256 - [`root()`]: ref:ethereum.forks.tangerine_whistle.trie.root - [Trie]: ref:ethereum.forks.tangerine_whistle.trie.Trie + [`root()`]: ref:ethereum.merkle_patricia_trie.root + [Trie]: ref:ethereum.merkle_patricia_trie.Trie """ bloom: Bloom diff --git a/src/ethereum/forks/tangerine_whistle/fork.py b/src/ethereum/forks/tangerine_whistle/fork.py index 78592e2d770..03dc0e80928 100644 --- a/src/ethereum/forks/tangerine_whistle/fork.py +++ b/src/ethereum/forks/tangerine_whistle/fork.py @@ -27,19 +27,27 @@ InvalidSenderError, NonceMismatchError, ) +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt from .bloom import logs_bloom -from .fork_types import EMPTY_CODE_HASH, Address -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, create_ether, destroy_account, + extract_block_diff, get_account, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( Transaction, @@ -47,7 +55,6 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.message import prepare_message from .vm.gas import GasCosts from .vm.interpreter import process_message_call @@ -158,9 +165,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: validate_header(chain, block.header) validate_ommers(block.ommers, block.header, chain) + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -174,7 +183,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, ommers=block.ommers, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -192,6 +206,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -340,6 +355,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Address: """ Check if the transaction is includable in the block. @@ -352,6 +368,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -374,7 +392,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) max_gas_fee = tx.gas * tx.gas_price @@ -460,7 +478,7 @@ def apply_body( for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env.state, block_env.number, block_env.coinbase, ommers) + pay_rewards(block_env, ommers) return block_output @@ -542,9 +560,7 @@ def validate_ommers( def pay_rewards( - state: State, - block_number: Uint, - coinbase: Address, + block_env: vm.BlockEnvironment, ommers: Tuple[Header, ...], ) -> None: """ @@ -563,25 +579,24 @@ def pay_rewards( Parameters ---------- - state : - Current account state. - block_number : - Position of the block within the chain. - coinbase : - Address of account which receives block reward and transaction fees. + block_env : + The block scoped environment. ommers : List of ommers mentioned in the current block. """ + rewards_state = TransactionState(parent=block_env.state) ommer_count = U256(len(ommers)) miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(state, coinbase, miner_reward) + create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in ommers: # Ommer age with respect to the current block. - ommer_age = U256(block_number - ommer.number) + ommer_age = U256(block_env.number - ommer.number) ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(state, ommer.coinbase, ommer_miner_reward) + create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) + + incorporate_tx_into_block(rewards_state) def process_transaction( @@ -614,6 +629,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set(block_output.transactions_trie, rlp.encode(Uint(index)), tx) intrinsic_gas = validate_transaction(tx) @@ -621,23 +638,23 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) gas_fee = tx.gas * tx.gas_price sender_balance_after_gas_fee = Uint(sender_account.balance) - gas_fee - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) tx_env = vm.TransactionEnvironment( origin=sender, gas_price=tx.gas_price, gas=gas, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(tx), ) @@ -657,26 +674,38 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * tx.gas_price # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, block_env.coinbase, coinbase_balance_after_mining_fee + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund + incorporate_tx_into_block(tx_state) + + block_state = block_env.state + block_diff = extract_block_diff(block_state) + intermediate_state_root, _ = ( + block_state.pre_state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) + ) + receipt = make_receipt( - state_root(block_env.state), + intermediate_state_root, block_output.block_gas_used, tx_output.logs, ) diff --git a/src/ethereum/forks/tangerine_whistle/fork_types.py b/src/ethereum/forks/tangerine_whistle/fork_types.py index ae4525bbbdd..02907cd2a1a 100644 --- a/src/ethereum/forks/tangerine_whistle/fork_types.py +++ b/src/ethereum/forks/tangerine_whistle/fork_types.py @@ -11,41 +11,13 @@ Types reused throughout the specification, which are specific to Ethereum. """ -from dataclasses import dataclass - from ethereum_rlp import rlp -from ethereum_types.bytes import Bytes, Bytes20, Bytes256 -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 +from ethereum_types.bytes import Bytes, Bytes256 -Address = Bytes20 -Root = Hash32 +from ethereum.state import Account Bloom = Bytes256 -EMPTY_CODE_HASH = keccak256(b"") - - -@slotted_freezable -@dataclass -class Account: - """ - State associated with an address. - """ - - nonce: Uint - balance: U256 - code_hash: Hash32 - - -EMPTY_ACCOUNT = Account( - nonce=Uint(0), - balance=U256(0), - code_hash=EMPTY_CODE_HASH, -) - def encode_account(raw_account_data: Account, storage_root: Bytes) -> Bytes: """ diff --git a/src/ethereum/forks/tangerine_whistle/state.py b/src/ethereum/forks/tangerine_whistle/state.py deleted file mode 100644 index 69f5cca8dc0..00000000000 --- a/src/ethereum/forks/tangerine_whistle/state.py +++ /dev/null @@ -1,543 +0,0 @@ -""" -State. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state contains all information that is preserved between transactions. - -It consists of a main account trie and storage tries for each contract. - -There is a distinction between an account that does not exist and -`EMPTY_ACCOUNT`. -""" - -from dataclasses import dataclass, field -from typing import Callable, Dict, List, Optional, Tuple - -from ethereum_types.bytes import Bytes, Bytes32 -from ethereum_types.frozen import modify -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import Hash32, keccak256 - -from .fork_types import EMPTY_ACCOUNT, EMPTY_CODE_HASH, Account, Address, Root -from .trie import EMPTY_TRIE_ROOT, Trie, copy_trie, root, trie_get, trie_set - - -@dataclass -class State: - """ - Contains all information that is preserved between transactions. - """ - - _main_trie: Trie[Address, Optional[Account]] = field( - default_factory=lambda: Trie(secured=True, default=None) - ) - _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field( - default_factory=dict - ) - _snapshots: List[ - Tuple[ - Trie[Address, Optional[Account]], - Dict[Address, Trie[Bytes32, U256]], - ] - ] = field(default_factory=list) - _code_store: Dict[Hash32, Bytes] = field( - default_factory=dict, compare=False - ) - - -def close_state(state: State) -> None: - """ - Free resources held by the state. Used by optimized implementations to - release file descriptors. - """ - del state._main_trie - del state._storage_tries - del state._snapshots - del state._code_store - - -def begin_transaction(state: State) -> None: - """ - Start a state transaction. - - Transactions are entirely implicit and can be nested. It is not possible to - calculate the state root during a transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.append( - ( - copy_trie(state._main_trie), - {k: copy_trie(t) for (k, t) in state._storage_tries.items()}, - ) - ) - - -def commit_transaction(state: State) -> None: - """ - Commit a state transaction. - - Parameters - ---------- - state : State - The state. - - """ - state._snapshots.pop() - - -def rollback_transaction(state: State) -> None: - """ - Rollback a state transaction, resetting the state to the point when the - corresponding `begin_transaction()` call was made. - - Parameters - ---------- - state : State - The state. - - """ - state._main_trie, state._storage_tries = state._snapshots.pop() - - -def get_account(state: State, address: Address) -> Account: - """ - Get the `Account` object at an address. Returns `EMPTY_ACCOUNT` if there - is no account at the address. - - Use `get_account_optional()` if you care about the difference between a - non-existent account and `EMPTY_ACCOUNT`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = get_account_optional(state, address) - if isinstance(account, Account): - return account - else: - return EMPTY_ACCOUNT - - -def get_account_optional(state: State, address: Address) -> Optional[Account]: - """ - Get the `Account` object at an address. Returns `None` (rather than - `EMPTY_ACCOUNT`) if there is no account at the address. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to lookup. - - Returns - ------- - account : `Account` - Account at address. - - """ - account = trie_get(state._main_trie, address) - return account - - -def get_code(state: State, code_hash: Hash32) -> Bytes: - """ - Get the bytecode for a given code hash. - """ - if code_hash == EMPTY_CODE_HASH: - return b"" - return state._code_store[code_hash] - - -def store_code(state: State, code: Bytes) -> Hash32: - """ - Store bytecode in ``State``. - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - return code_hash - - -def set_account( - state: State, address: Address, account: Optional[Account] -) -> None: - """ - Set the `Account` object at an address. Setting to `None` deletes - the account (but not its storage, see `destroy_account()`). - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address to set. - account : `Account` - Account to set at address. - - """ - trie_set(state._main_trie, address, account) - - -def destroy_account(state: State, address: Address) -> None: - """ - Completely remove the account at `address` and all of its storage. - - This function is made available exclusively for the `SELFDESTRUCT` - opcode. It is expected that `SELFDESTRUCT` will be disabled in a future - hardfork and this function will be removed. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account to destroy. - - """ - destroy_storage(state, address) - set_account(state, address, None) - - -def destroy_storage(state: State, address: Address) -> None: - """ - Completely remove the storage at `address`. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of account whose storage is to be deleted. - - """ - if address in state._storage_tries: - del state._storage_tries[address] - - -def get_storage(state: State, address: Address, key: Bytes32) -> U256: - """ - Get a value at a storage key on an account. Returns `U256(0)` if the - storage key has not been set previously. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to lookup. - - Returns - ------- - value : `U256` - Value at the key. - - """ - trie = state._storage_tries.get(address) - if trie is None: - return U256(0) - - value = trie_get(trie, key) - - assert isinstance(value, U256) - return value - - -def set_storage( - state: State, address: Address, key: Bytes32, value: U256 -) -> None: - """ - Set a value at a storage key on an account. Setting to `U256(0)` deletes - the key. - - Parameters - ---------- - state: `State` - The state - address : `Address` - Address of the account. - key : `Bytes` - Key to set. - value : `U256` - Value to set at the key. - - """ - assert trie_get(state._main_trie, address) is not None - - trie = state._storage_tries.get(address) - if trie is None: - trie = Trie(secured=True, default=U256(0)) - state._storage_tries[address] = trie - trie_set(trie, key, value) - if trie._data == {}: - del state._storage_tries[address] - - -def storage_root(state: State, address: Address) -> Root: - """ - Calculate the storage root of an account. - - Parameters - ---------- - state: - The state - address : - Address of the account. - - Returns - ------- - root : `Root` - Storage root of the account. - - """ - assert not state._snapshots - if address in state._storage_tries: - return root(state._storage_tries[address]) - else: - return EMPTY_TRIE_ROOT - - -def state_root(state: State) -> Root: - """ - Calculate the state root. - - Parameters - ---------- - state: - The current state. - - Returns - ------- - root : `Root` - The state root. - - """ - assert not state._snapshots - - def get_storage_root(address: Address) -> Root: - return storage_root(state, address) - - return root(state._main_trie, get_storage_root=get_storage_root) - - -def account_exists(state: State, address: Address) -> bool: - """ - Checks if an account exists in the state trie. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - account_exists : `bool` - True if account exists in the state trie, False otherwise - - """ - return get_account_optional(state, address) is not None - - -def account_has_code_or_nonce(state: State, address: Address) -> bool: - """ - Checks if an account has non-zero nonce or non-empty code. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_code_or_nonce : `bool` - True if the account has non-zero nonce or non-empty code, - False otherwise. - - """ - account = get_account(state, address) - return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH - - -def account_has_storage(state: State, address: Address) -> bool: - """ - Checks if an account has storage. - - Parameters - ---------- - state: - The state - address: - Address of the account that needs to be checked. - - Returns - ------- - has_storage : `bool` - True if the account has storage, False otherwise. - - """ - return address in state._storage_tries - - -def modify_state( - state: State, address: Address, f: Callable[[Account], None] -) -> None: - """ - Modify an `Account` in the `State`. - """ - set_account(state, address, modify(get_account(state, address), f)) - - -def move_ether( - state: State, - sender_address: Address, - recipient_address: Address, - amount: U256, -) -> None: - """ - Move funds between accounts. - """ - - def reduce_sender_balance(sender: Account) -> None: - if sender.balance < amount: - raise AssertionError - sender.balance -= amount - - def increase_recipient_balance(recipient: Account) -> None: - recipient.balance += amount - - modify_state(state, sender_address, reduce_sender_balance) - modify_state(state, recipient_address, increase_recipient_balance) - - -def set_account_balance(state: State, address: Address, amount: U256) -> None: - """ - Sets the balance of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - amount: - The amount that needs to be set in the balance. - - """ - - def set_balance(account: Account) -> None: - account.balance = amount - - modify_state(state, address, set_balance) - - -def touch_account(state: State, address: Address) -> None: - """ - Initializes an account to state. - - Parameters - ---------- - state: - The current state. - - address: - The address of the account that needs to be initialized. - - """ - if not account_exists(state, address): - set_account(state, address, EMPTY_ACCOUNT) - - -def increment_nonce(state: State, address: Address) -> None: - """ - Increments the nonce of an account. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose nonce needs to be incremented. - - """ - - def increase_nonce(sender: Account) -> None: - sender.nonce += Uint(1) - - modify_state(state, address, increase_nonce) - - -def set_code(state: State, address: Address, code: Bytes) -> None: - """ - Sets Account code. - - Parameters - ---------- - state: - The current state. - - address: - Address of the account whose code needs to be updated. - - code: - The bytecode that needs to be set. - - """ - code_hash = keccak256(code) - if code_hash != EMPTY_CODE_HASH: - state._code_store[code_hash] = code - - def write_code(sender: Account) -> None: - sender.code_hash = code_hash - - modify_state(state, address, write_code) - - -def create_ether(state: State, address: Address, amount: U256) -> None: - """ - Add newly created ether to an account. - - Parameters - ---------- - state: - The current state. - address: - Address of the account to which ether is added. - amount: - The amount of ether to be added to the account of interest. - - """ - - def increase_balance(account: Account) -> None: - account.balance += amount - - modify_state(state, address, increase_balance) diff --git a/src/ethereum/forks/tangerine_whistle/state_tracker.py b/src/ethereum/forks/tangerine_whistle/state_tracker.py new file mode 100644 index 00000000000..f6702729bc2 --- /dev/null +++ b/src/ethereum/forks/tangerine_whistle/state_tracker.py @@ -0,0 +1,803 @@ +""" +State Tracking for Block Execution. + +Track state changes on top of a read-only ``PreState``. At block end, +accumulated diffs feed into +``PreState.compute_state_root_and_trie_changes()``. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +Replace the mutable ``State`` class with lightweight state trackers that +record diffs. ``BlockState`` accumulates committed transaction +changes across a block. ``TransactionState`` tracks in-flight changes +within a single transaction and supports copy-on-write rollback. +""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Optional, Set, Tuple + +from ethereum_types.bytes import Bytes, Bytes32 +from ethereum_types.frozen import modify +from ethereum_types.numeric import U256, Uint + +from ethereum.crypto.hash import Hash32, keccak256 +from ethereum.state import ( + EMPTY_ACCOUNT, + EMPTY_CODE_HASH, + Account, + Address, + BlockDiff, + PreState, +) + + +@dataclass +class BlockState: + """ + Accumulate committed transaction-level changes across a block. + + Read chain: block writes -> pre_state. + + ``storage_clears`` records addresses whose storage was wiped by + a pre-EIP-6780 ``SELFDESTRUCT`` earlier in the block, so later + reads must not fall back to ``pre_state`` storage. + """ + + pre_state: PreState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + storage_clears: Set[Address] = field(default_factory=set) + + +@dataclass +class TransactionState: + """ + Track in-flight state changes within a single transaction. + + Read chain: tx writes -> block writes -> pre_state. + """ + + parent: BlockState + account_writes: Dict[Address, Optional[Account]] = field( + default_factory=dict + ) + storage_writes: Dict[Address, Dict[Bytes32, U256]] = field( + default_factory=dict + ) + code_writes: Dict[Hash32, Bytes] = field(default_factory=dict) + created_accounts: Set[Address] = field(default_factory=set) + storage_clears: Set[Address] = field(default_factory=set) + transient_storage: Dict[Tuple[Address, Bytes32], U256] = field( + default_factory=dict + ) + + +def get_account_optional( + tx_state: TransactionState, address: Address +) -> Optional[Account]: + """ + Get the ``Account`` object at an address. Return ``None`` (rather than + ``EMPTY_ACCOUNT``) if there is no account at the address. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Optional[Account]`` + Account at address. + + """ + if address in tx_state.account_writes: + return tx_state.account_writes[address] + if address in tx_state.parent.account_writes: + return tx_state.parent.account_writes[address] + return tx_state.parent.pre_state.get_account_optional(address) + + +def get_account(tx_state: TransactionState, address: Address) -> Account: + """ + Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT`` + if there is no account at the address. + + Use ``get_account_optional()`` if you care about the difference + between a non-existent account and ``EMPTY_ACCOUNT``. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to look up. + + Returns + ------- + account : ``Account`` + Account at address. + + """ + account = get_account_optional(tx_state, address) + if account is None: + return EMPTY_ACCOUNT + else: + return account + + +def get_code(tx_state: TransactionState, code_hash: Hash32) -> Bytes: + """ + Get the bytecode for a given code hash. + + Read chain: tx code_writes -> block code_writes -> pre_state. + + Parameters + ---------- + tx_state : + The transaction state. + code_hash : + Hash of the code to look up. + + Returns + ------- + code : ``Bytes`` + The bytecode. + + """ + if code_hash == EMPTY_CODE_HASH: + return b"" + if code_hash in tx_state.code_writes: + return tx_state.code_writes[code_hash] + if code_hash in tx_state.parent.code_writes: + return tx_state.parent.code_writes[code_hash] + return tx_state.parent.pre_state.get_code(code_hash) + + +def get_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account. Return ``U256(0)`` if + the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + if address in tx_state.storage_writes: + if key in tx_state.storage_writes[address]: + return tx_state.storage_writes[address][key] + if address in tx_state.storage_clears: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_storage_original( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get the original value in a storage slot i.e. the value before the + current transaction began. Read from block-level writes, then + pre_state. Return ``U256(0)`` for accounts created in the current + transaction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to read the value from. + key : + Key of the storage slot. + + """ + if address in tx_state.created_accounts: + return U256(0) + if address in tx_state.parent.storage_writes: + if key in tx_state.parent.storage_writes[address]: + return tx_state.parent.storage_writes[address][key] + if address in tx_state.parent.storage_clears: + return U256(0) + return tx_state.parent.pre_state.get_storage(address, key) + + +def get_transient_storage( + tx_state: TransactionState, address: Address, key: Bytes32 +) -> U256: + """ + Get a value at a storage key on an account from transient storage. + Return ``U256(0)`` if the storage key has not been set previously. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to look up. + + Returns + ------- + value : ``U256`` + Value at the key. + + """ + return tx_state.transient_storage.get((address, key), U256(0)) + + +def account_exists(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account exists in the state trie. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + account_exists : ``bool`` + True if account exists in the state trie, False otherwise. + + """ + return get_account_optional(tx_state, address) is not None + + +def account_has_code_or_nonce( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account has non-zero nonce or non-empty code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_code_or_nonce : ``bool`` + True if the account has non-zero nonce or non-empty code, + False otherwise. + + """ + account = get_account(tx_state, address) + return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH + + +def account_has_storage(tx_state: TransactionState, address: Address) -> bool: + """ + Check if an account has storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + has_storage : ``bool`` + True if the account has storage, False otherwise. + + """ + if tx_state.storage_writes.get(address): + return True + if address in tx_state.storage_clears: + return False + if tx_state.parent.storage_writes.get(address): + return True + if address in tx_state.parent.storage_clears: + return False + return tx_state.parent.pre_state.account_has_storage(address) + + +def account_exists_and_is_empty( + tx_state: TransactionState, address: Address +) -> bool: + """ + Check if an account exists and has zero nonce, empty code and zero + balance. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + exists_and_is_empty : ``bool`` + True if an account exists and has zero nonce, empty code and + zero balance, False otherwise. + + """ + account = get_account_optional(tx_state, address) + return ( + account is not None + and account.nonce == Uint(0) + and account.code_hash == EMPTY_CODE_HASH + and account.balance == 0 + ) + + +def is_account_alive(tx_state: TransactionState, address: Address) -> bool: + """ + Check whether an account is both in the state and non-empty. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be checked. + + Returns + ------- + is_alive : ``bool`` + True if the account is alive. + + """ + account = get_account_optional(tx_state, address) + return account is not None and account != EMPTY_ACCOUNT + + +def set_account( + tx_state: TransactionState, + address: Address, + account: Optional[Account], +) -> None: + """ + Set the ``Account`` object at an address. Setting to ``None`` + deletes the account (but not its storage, see + ``destroy_account()``). + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address to set. + account : + Account to set at address. + + """ + tx_state.account_writes[address] = account + + +def set_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + assert get_account_optional(tx_state, address) is not None + if address not in tx_state.storage_writes: + tx_state.storage_writes[address] = {} + tx_state.storage_writes[address][key] = value + + +def destroy_account(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the account at ``address`` and all of its storage. + + This function is made available exclusively for the ``SELFDESTRUCT`` + opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a + future hardfork and this function will be removed. Only supports same + transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account to destroy. + + """ + destroy_storage(tx_state, address) + set_account(tx_state, address, None) + + +def destroy_storage(tx_state: TransactionState, address: Address) -> None: + """ + Completely remove the storage at ``address``. + + Only supports same transaction destruction. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of account whose storage is to be deleted. + + """ + if address in tx_state.storage_writes: + del tx_state.storage_writes[address] + tx_state.storage_clears.add(address) + + +def mark_account_created(tx_state: TransactionState, address: Address) -> None: + """ + Mark an account as having been created in the current transaction. + This information is used by ``get_storage_original()`` to handle an + obscure edgecase, and to respect the constraints added to + SELFDESTRUCT by EIP-6780. + + The marker is not removed even if the account creation reverts. + Since the account cannot have had code prior to its creation and + can't call ``get_storage_original()``, this is harmless. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that has been created. + + """ + tx_state.created_accounts.add(address) + + +def set_transient_storage( + tx_state: TransactionState, + address: Address, + key: Bytes32, + value: U256, +) -> None: + """ + Set a value at a storage key on an account in transient storage. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account. + key : + Key to set. + value : + Value to set at the key. + + """ + if value == U256(0): + tx_state.transient_storage.pop((address, key), None) + else: + tx_state.transient_storage[(address, key)] = value + + +def modify_state( + tx_state: TransactionState, + address: Address, + f: Callable[[Account], None], +) -> None: + """ + Modify an ``Account`` in the state. + """ + set_account(tx_state, address, modify(get_account(tx_state, address), f)) + + +def move_ether( + tx_state: TransactionState, + sender_address: Address, + recipient_address: Address, + amount: U256, +) -> None: + """ + Move funds between accounts. + + Parameters + ---------- + tx_state : + The transaction state. + sender_address : + Address of the sender. + recipient_address : + Address of the recipient. + amount : + The amount to transfer. + + """ + + def reduce_sender_balance(sender: Account) -> None: + if sender.balance < amount: + raise AssertionError + sender.balance -= amount + + def increase_recipient_balance(recipient: Account) -> None: + recipient.balance += amount + + modify_state(tx_state, sender_address, reduce_sender_balance) + modify_state(tx_state, recipient_address, increase_recipient_balance) + + +def create_ether( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Add newly created ether to an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account to which ether is added. + amount : + The amount of ether to be added to the account of interest. + + """ + + def increase_balance(account: Account) -> None: + account.balance += amount + + modify_state(tx_state, address, increase_balance) + + +def set_account_balance( + tx_state: TransactionState, address: Address, amount: U256 +) -> None: + """ + Set the balance of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose balance needs to be set. + amount : + The amount that needs to be set in the balance. + + """ + + def set_balance(account: Account) -> None: + account.balance = amount + + modify_state(tx_state, address, set_balance) + + +def increment_nonce(tx_state: TransactionState, address: Address) -> None: + """ + Increment the nonce of an account. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose nonce needs to be incremented. + + """ + + def increase_nonce(sender: Account) -> None: + sender.nonce += Uint(1) + + modify_state(tx_state, address, increase_nonce) + + +def set_code( + tx_state: TransactionState, address: Address, code: Bytes +) -> None: + """ + Set Account code. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account whose code needs to be updated. + code : + The bytecode that needs to be set. + + """ + code_hash = keccak256(code) + if code_hash != EMPTY_CODE_HASH: + tx_state.code_writes[code_hash] = code + + def write_code_hash(sender: Account) -> None: + sender.code_hash = code_hash + + modify_state(tx_state, address, write_code_hash) + + +# -- Snapshot / Rollback --------------------------------------------------- + + +def copy_tx_state(tx_state: TransactionState) -> TransactionState: + """ + Create a snapshot of the transaction state for rollback. + + Deep-copy writes and transient storage. The parent reference and + ``created_accounts`` are shared (not rolled back). + + Parameters + ---------- + tx_state : + The transaction state to snapshot. + + Returns + ------- + snapshot : ``TransactionState`` + A copy of the transaction state. + + """ + return TransactionState( + parent=tx_state.parent, + account_writes=dict(tx_state.account_writes), + storage_writes={ + addr: dict(slots) + for addr, slots in tx_state.storage_writes.items() + }, + code_writes=dict(tx_state.code_writes), + created_accounts=tx_state.created_accounts, + storage_clears=set(tx_state.storage_clears), + transient_storage=dict(tx_state.transient_storage), + ) + + +def restore_tx_state( + tx_state: TransactionState, snapshot: TransactionState +) -> None: + """ + Restore transaction state from a snapshot (rollback on failure). + + Parameters + ---------- + tx_state : + The transaction state to restore. + snapshot : + The snapshot to restore from. + + """ + tx_state.account_writes = snapshot.account_writes + tx_state.storage_writes = snapshot.storage_writes + tx_state.code_writes = snapshot.code_writes + tx_state.storage_clears = snapshot.storage_clears + tx_state.transient_storage = snapshot.transient_storage + + +# -- Lifecycle -------------------------------------------------------------- + + +def incorporate_tx_into_block(tx_state: TransactionState) -> None: + """ + Merge transaction writes into the block state and clear for reuse. + + Parameters + ---------- + tx_state : + The transaction state to commit. + + """ + block = tx_state.parent + + for address, account in tx_state.account_writes.items(): + block.account_writes[address] = account + + for address in tx_state.storage_clears: + block.storage_clears.add(address) + block.storage_writes.pop(address, None) + + for address, slots in tx_state.storage_writes.items(): + if address not in block.storage_writes: + block.storage_writes[address] = {} + block.storage_writes[address].update(slots) + + block.code_writes.update(tx_state.code_writes) + + tx_state.account_writes.clear() + tx_state.storage_writes.clear() + tx_state.code_writes.clear() + tx_state.created_accounts.clear() + tx_state.storage_clears.clear() + tx_state.transient_storage.clear() + + +def extract_block_diff(block_state: BlockState) -> BlockDiff: + """ + Extract account, storage, and code diff from the block state. + + Parameters + ---------- + block_state : + The block state. + + Returns + ------- + diff : `BlockDiff` + Account, storage, and code changes accumulated during block execution. + + """ + return BlockDiff( + account_changes=block_state.account_writes, + storage_changes=block_state.storage_writes, + code_changes=block_state.code_writes, + storage_clears=block_state.storage_clears, + ) + + +def destroy_touched_empty_accounts( + tx_state: TransactionState, touched_accounts: Set[Address] +) -> None: + """ + Destroy all touched accounts that are empty. + + Parameters + ---------- + tx_state : + The transaction state. + touched_accounts : + All the accounts that have been touched in the current transaction. + + """ + for address in touched_accounts: + if account_exists_and_is_empty(tx_state, address): + destroy_account(tx_state, address) + + +def touch_account(tx_state: TransactionState, address: Address) -> None: + """ + Initialize an account to state. + + Parameters + ---------- + tx_state : + The transaction state. + address : + Address of the account that needs to be initialized. + + """ + if not account_exists(tx_state, address): + set_account(tx_state, address, EMPTY_ACCOUNT) diff --git a/src/ethereum/forks/tangerine_whistle/transactions.py b/src/ethereum/forks/tangerine_whistle/transactions.py index e17bafae49d..1458316ce5b 100644 --- a/src/ethereum/forks/tangerine_whistle/transactions.py +++ b/src/ethereum/forks/tangerine_whistle/transactions.py @@ -18,8 +18,7 @@ InvalidSignatureError, NonceOverflowError, ) - -from .fork_types import Address +from ethereum.state import Address @slotted_freezable diff --git a/src/ethereum/forks/tangerine_whistle/trie.py b/src/ethereum/forks/tangerine_whistle/trie.py deleted file mode 100644 index efc44cfd117..00000000000 --- a/src/ethereum/forks/tangerine_whistle/trie.py +++ /dev/null @@ -1,498 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - assert_type, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.dao_fork import trie as previous_trie -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt -from .fork_types import Account, Address, Root, encode_account -from .transactions import Transaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | Transaction | Receipt | Uint | U256 -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[Transaction], - Optional[Receipt], - Uint, - U256, -) - - -@slotted_freezable -@dataclass -class LeafNode: - """Leaf node in the Merkle Trie.""" - - rest_of_key: Bytes - value: Extended - - -@slotted_freezable -@dataclass -class ExtensionNode: - """Extension node in the Merkle Trie.""" - - key_segment: Bytes - subnode: Extended - - -BranchSubnodes = Tuple[ - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, - Extended, -] - - -@slotted_freezable -@dataclass -class BranchNode: - """Branch node in the Merkle Trie.""" - - subnodes: BranchSubnodes - value: Extended - - -InternalNode = LeafNode | ExtensionNode | BranchNode - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `rlp.Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256, Uint)): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) diff --git a/src/ethereum/forks/tangerine_whistle/utils/hexadecimal.py b/src/ethereum/forks/tangerine_whistle/utils/hexadecimal.py index aa4663dfe39..02610396104 100644 --- a/src/ethereum/forks/tangerine_whistle/utils/hexadecimal.py +++ b/src/ethereum/forks/tangerine_whistle/utils/hexadecimal.py @@ -14,11 +14,9 @@ from ethereum_types.bytes import Bytes -from ethereum.state import Address +from ethereum.state import Address, Root from ethereum.utils.hexadecimal import remove_hex_prefix -from ..fork_types import Root - def hex_to_root(hex_string: str) -> Root: """ diff --git a/src/ethereum/forks/tangerine_whistle/utils/message.py b/src/ethereum/forks/tangerine_whistle/utils/message.py index 58d03b76540..e8e99160dbb 100644 --- a/src/ethereum/forks/tangerine_whistle/utils/message.py +++ b/src/ethereum/forks/tangerine_whistle/utils/message.py @@ -17,7 +17,7 @@ from ethereum.state import Address -from ..state import get_account, get_code +from ..state_tracker import get_account, get_code from ..transactions import Transaction from ..vm import BlockEnvironment, Message, TransactionEnvironment from .address import compute_contract_address @@ -49,7 +49,7 @@ def prepare_message( if isinstance(tx.to, Bytes0): current_target = compute_contract_address( tx_env.origin, - get_account(block_env.state, tx_env.origin).nonce - Uint(1), + get_account(tx_env.state, tx_env.origin).nonce - Uint(1), ) msg_data = Bytes(b"") code = tx.data @@ -57,8 +57,8 @@ def prepare_message( elif isinstance(tx.to, Address): current_target = tx.to msg_data = tx.data - account = get_account(block_env.state, tx.to) - code = get_code(block_env.state, account.code_hash) + account = get_account(tx_env.state, tx.to) + code = get_code(tx_env.state, account.code_hash) code_address = tx.to else: diff --git a/src/ethereum/forks/tangerine_whistle/vm/__init__.py b/src/ethereum/forks/tangerine_whistle/vm/__init__.py index e318eaa7482..3b5007aa541 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/__init__.py +++ b/src/ethereum/forks/tangerine_whistle/vm/__init__.py @@ -20,12 +20,12 @@ from ethereum.crypto.hash import Hash32 from ethereum.exceptions import EthereumException +from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address from ..blocks import Log, Receipt -from ..state import State +from ..state_tracker import BlockState, TransactionState from ..transactions import Transaction -from ..trie import Trie __all__ = ("Environment", "Evm", "Message") @@ -37,7 +37,7 @@ class BlockEnvironment: """ chain_id: U64 - state: State + state: BlockState block_gas_limit: Uint block_hashes: List[Hash32] coinbase: Address @@ -86,6 +86,7 @@ class TransactionEnvironment: origin: Address gas_price: Uint gas: Uint + state: TransactionState index_in_block: Uint tx_hash: Optional[Hash32] diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py index d930368fdd9..d85aaf0c97a 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py @@ -15,7 +15,7 @@ from ethereum.utils.numeric import ceil32 -from ...state import get_account, get_code +from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write from .. import Evm @@ -68,7 +68,8 @@ def balance(evm: Evm) -> None: # OPERATION # Non-existent accounts default to EMPTY_ACCOUNT, which has balance 0. - balance = get_account(evm.message.block_env.state, address).balance + tx_state = evm.message.tx_env.state + balance = get_account(tx_state, address).balance push(evm.stack, balance) @@ -334,8 +335,9 @@ def extcodesize(evm: Evm) -> None: charge_gas(evm, GasCosts.OPCODE_EXTERNAL_BASE) # OPERATION - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) codesize = U256(len(code)) push(evm.stack, codesize) @@ -373,8 +375,9 @@ def extcodecopy(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by - account = get_account(evm.message.block_env.state, address) - code = get_code(evm.message.block_env.state, account.code_hash) + tx_state = evm.message.tx_env.state + account = get_account(tx_state, address) + code = get_code(tx_state, account.code_hash) value = buffer_read(code, code_start_index, size) memory_write(evm.memory, memory_start_index, value) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py index 0b2a1cce8aa..16921a1a7fb 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py @@ -13,7 +13,7 @@ from ethereum_types.numeric import Uint -from ...state import get_storage, set_storage +from ...state_tracker import get_storage, set_storage from .. import Evm from ..gas import ( GasCosts, @@ -40,9 +40,8 @@ def sload(evm: Evm) -> None: charge_gas(evm, GasCosts.SLOAD) # OPERATION - value = get_storage( - evm.message.block_env.state, evm.message.current_target, key - ) + tx_state = evm.message.tx_env.state + value = get_storage(tx_state, evm.message.current_target, key) push(evm.stack, value) @@ -65,8 +64,8 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - state = evm.message.block_env.state - current_value = get_storage(state, evm.message.current_target, key) + tx_state = evm.message.tx_env.state + current_value = get_storage(tx_state, evm.message.current_target, key) if new_value != 0 and current_value == 0: gas_cost = GasCosts.STORAGE_SET else: @@ -78,7 +77,7 @@ def sstore(evm: Evm) -> None: charge_gas(evm, gas_cost) # OPERATION - set_storage(state, evm.message.current_target, key, new_value) + set_storage(tx_state, evm.message.current_target, key, new_value) # PROGRAM COUNTER evm.pc += Uint(1) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py index 6ef0f1a0015..f09665e1701 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/system.py @@ -16,7 +16,7 @@ from ethereum.state import Address -from ...state import ( +from ...state_tracker import ( account_exists, account_has_code_or_nonce, account_has_storage, @@ -75,12 +75,12 @@ def create(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_address = evm.message.current_target - sender = get_account(evm.message.block_env.state, sender_address) + sender = get_account(evm.message.tx_env.state, sender_address) contract_address = compute_contract_address( evm.message.current_target, get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).nonce, ) @@ -92,20 +92,16 @@ def create(evm: Evm) -> None: push(evm.stack, U256(0)) evm.gas_left += create_message_gas elif account_has_code_or_nonce( - evm.message.block_env.state, contract_address - ) or account_has_storage(evm.message.block_env.state, contract_address): - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + evm.message.tx_env.state, contract_address + ) or account_has_storage(evm.message.tx_env.state, contract_address): + increment_nonce(evm.message.tx_env.state, evm.message.current_target) push(evm.stack, U256(0)) else: call_data = memory_read_bytes( evm.memory, memory_start_position, memory_size ) - increment_nonce( - evm.message.block_env.state, evm.message.current_target - ) + increment_nonce(evm.message.tx_env.state, evm.message.current_target) child_message = Message( block_env=evm.message.block_env, @@ -196,8 +192,8 @@ def generic_call( call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) - account = get_account(evm.message.block_env.state, code_address) - code = get_code(evm.message.block_env.state, account.code_hash) + account = get_account(evm.message.tx_env.state, code_address) + code = get_code(evm.message.tx_env.state, account.code_hash) child_message = Message( block_env=evm.message.block_env, tx_env=evm.message.tx_env, @@ -260,7 +256,7 @@ def call(evm: Evm) -> None: code_address = to - _account_exists = account_exists(evm.message.block_env.state, to) + _account_exists = account_exists(evm.message.tx_env.state, to) create_gas_cost = Uint(0) if _account_exists else GasCosts.NEW_ACCOUNT transfer_gas_cost = Uint(0) if value == 0 else GasCosts.CALL_VALUE message_call_gas = calculate_message_call_gas( @@ -275,7 +271,7 @@ def call(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -341,7 +337,7 @@ def callcode(evm: Evm) -> None: # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account( - evm.message.block_env.state, evm.message.current_target + evm.message.tx_env.state, evm.message.current_target ).balance if sender_balance < value: push(evm.stack, U256(0)) @@ -380,7 +376,7 @@ def selfdestruct(evm: Evm) -> None: # GAS gas_cost = GasCosts.OPCODE_SELFDESTRUCT_BASE - if not account_exists(evm.message.block_env.state, beneficiary): + if not account_exists(evm.message.tx_env.state, beneficiary): gas_cost += GasCosts.OPCODE_SELFDESTRUCT_NEW_ACCOUNT originator = evm.message.current_target @@ -398,22 +394,22 @@ def selfdestruct(evm: Evm) -> None: # OPERATION beneficiary_balance = get_account( - evm.message.block_env.state, beneficiary + evm.message.tx_env.state, beneficiary ).balance originator_balance = get_account( - evm.message.block_env.state, originator + evm.message.tx_env.state, originator ).balance # First Transfer to beneficiary set_account_balance( - evm.message.block_env.state, + evm.message.tx_env.state, beneficiary, beneficiary_balance + originator_balance, ) # Next, Zero the balance of the address being deleted (must come after # sending to beneficiary in case the contract named itself as the # beneficiary). - set_account_balance(evm.message.block_env.state, originator, U256(0)) + set_account_balance(evm.message.tx_env.state, originator, U256(0)) # register account for deletion evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/tangerine_whistle/vm/interpreter.py b/src/ethereum/forks/tangerine_whistle/vm/interpreter.py index a687e748de3..669e8eb652a 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/interpreter.py +++ b/src/ethereum/forks/tangerine_whistle/vm/interpreter.py @@ -31,13 +31,13 @@ ) from ..blocks import Log -from ..state import ( +from ..state_tracker import ( account_has_code_or_nonce, account_has_storage, - begin_transaction, - commit_transaction, + copy_tx_state, + destroy_storage, move_ether, - rollback_transaction, + restore_tx_state, set_code, touch_account, ) @@ -94,12 +94,12 @@ def process_message_call(message: Message) -> MessageCallOutput: Output of the message call """ - block_env = message.block_env + tx_state = message.tx_env.state refund_counter = U256(0) if message.target == Bytes0(b""): is_collision = account_has_code_or_nonce( - block_env.state, message.current_target - ) or account_has_storage(block_env.state, message.current_target) + tx_state, message.current_target + ) or account_has_storage(tx_state, message.current_target) if is_collision: return MessageCallOutput( gas_left=Uint(0), @@ -150,9 +150,16 @@ def process_create_message(message: Message) -> Evm: Items containing execution specific objects. """ - state = message.block_env.state + tx_state = message.tx_env.state # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) + + # If the address where the account is being created has storage, it is + # destroyed. This can only happen in the following highly unlikely + # circumstances: + # * The address created by a `CREATE` call collides with a subsequent + # `CREATE` call. + destroy_storage(tx_state, message.current_target) evm = process_message(message) if not evm.error: @@ -163,14 +170,13 @@ def process_create_message(message: Message) -> Evm: try: charge_gas(evm, contract_code_gas) except ExceptionalHalt as error: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) evm.gas_left = Uint(0) evm.error = error else: - set_code(state, message.current_target, contract_code) - commit_transaction(state) + set_code(tx_state, message.current_target, contract_code) else: - rollback_transaction(state) + restore_tx_state(tx_state, snapshot) return evm @@ -189,7 +195,7 @@ def process_message(message: Message) -> Evm: Items containing execution specific objects """ - state = message.block_env.state + tx_state = message.tx_env.state if message.depth > STACK_DEPTH_LIMIT: raise StackDepthLimitError("Stack depth limit reached") @@ -212,13 +218,16 @@ def process_message(message: Message) -> Evm: ) # take snapshot of state before processing the message - begin_transaction(state) + snapshot = copy_tx_state(tx_state) - touch_account(state, message.current_target) + touch_account(tx_state, message.current_target) if message.should_transfer_value and message.value != 0: move_ether( - state, message.caller, message.current_target, message.value + tx_state, + message.caller, + message.current_target, + message.value, ) try: @@ -245,9 +254,5 @@ def process_message(message: Message) -> Evm: evm.error = error if evm.error: - # revert state to the last saved checkpoint - # since the message call resulted in an error - rollback_transaction(state) - else: - commit_transaction(state) + restore_tx_state(tx_state, snapshot) return evm diff --git a/src/ethereum/state.py b/src/ethereum/state.py index 8f62b960d32..0de00ffe85d 100644 --- a/src/ethereum/state.py +++ b/src/ethereum/state.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import Dict, List, Optional, Protocol, Tuple +from typing import AbstractSet, Dict, List, Optional, Protocol, Set, Tuple from ethereum_types.bytes import Bytes, Bytes20, Bytes32 from ethereum_types.frozen import slotted_freezable @@ -71,6 +71,16 @@ class BlockDiff: code_changes: Dict[Hash32, Bytes] """New bytecodes (keyed by code hash) introduced by execution.""" + storage_clears: Set[Address] = field(default_factory=set) + """ + Addresses whose pre-existing storage was wiped during block + execution (via a pre-EIP-6780 `SELFDESTRUCT`). Their storage + tries are dropped before [`storage_changes`][sc] is applied, so any + post-wipe writes begin from empty storage. + + [sc]: ref:ethereum.state.BlockDiff.storage_changes + """ + class PreState(Protocol): """ @@ -116,10 +126,15 @@ def compute_state_root_and_trie_changes( self, account_changes: Dict[Address, Optional[Account]], storage_changes: Dict[Address, Dict[Bytes32, U256]], + storage_clears: AbstractSet[Address] = frozenset(), ) -> Tuple[Root, List["InternalNode"]]: """ Compute the state root after applying changes to the pre-state. + ``storage_clears`` lists addresses whose pre-existing storage + tries must be dropped before ``storage_changes`` is applied, so + any post-wipe writes begin from empty storage. + Return the new state root together with the internal trie nodes that were created or modified. """ @@ -187,16 +202,23 @@ def compute_state_root_and_trie_changes( self, account_changes: Dict[Address, Optional[Account]], storage_changes: Dict[Address, Dict[Bytes32, U256]], + storage_clears: AbstractSet[Address] = frozenset(), ) -> Tuple[Root, List["InternalNode"]]: """ Compute the state root after applying changes to the pre-state. + ``storage_clears`` lists addresses whose pre-existing storage + tries are dropped before ``storage_changes`` is applied, so any + post-wipe writes begin from empty storage. + Return the new state root together with the internal trie nodes that were created or modified. """ main_trie = copy_trie(self._main_trie) storage_tries = { - k: copy_trie(v) for k, v in self._storage_tries.items() + k: copy_trie(v) + for k, v in self._storage_tries.items() + if k not in storage_clears } for address, account in account_changes.items(): @@ -244,6 +266,9 @@ def apply_changes_to_state(state: State, diff: BlockDiff) -> None: Account, storage, and code changes to apply. """ + for address in diff.storage_clears: + state._storage_tries.pop(address, None) + for address, account in diff.account_changes.items(): trie_set(state._main_trie, address, account) diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py index eebb994a187..2ca816dbbf0 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py @@ -12,6 +12,7 @@ from ethereum.crypto.hash import Hash32, keccak256 from ethereum.exceptions import StateWithEmptyAccount +from ethereum.state import State, set_account, set_storage, store_code from ethereum.utils.hexadecimal import ( hex_to_bytes, hex_to_bytes8, @@ -59,8 +60,7 @@ def __init__(self, fork_module: str | Hardfork): def json_to_state(self, raw: Any) -> Any: """Converts json state data to a state object.""" - state = self.fork.State() - set_storage = self.fork.set_storage + state = State() EMPTY_ACCOUNT = self.fork.EMPTY_ACCOUNT # noqa N806 for address_hex, account_state in raw.items(): @@ -69,7 +69,7 @@ def json_to_state(self, raw: Any) -> Any: balance = U256(hex_to_uint(account_state.get("balance", "0x0"))) code = hex_to_bytes(account_state.get("code", "")) - code_hash = self.fork.store_code(state, code) + code_hash = store_code(state, code) account = self.fork.Account( nonce=nonce, balance=balance, @@ -79,7 +79,7 @@ def json_to_state(self, raw: Any) -> Any: if self.fork.proof_of_stake and account == EMPTY_ACCOUNT: raise StateWithEmptyAccount(f"Empty account at {address_hex}.") - self.fork.set_account(state, address, account) + set_account(state, address, account) for k, v in account_state.get("storage", {}).items(): set_storage( diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py index 327bf0096d6..7953f97db4f 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py @@ -144,27 +144,11 @@ def build_block_access_list(self) -> Any: """build_block_access_list function of the fork.""" return self._module("block_access_lists").build_block_access_list - @property - def BlockAccessIndex(self) -> Any: - """BlockAccessIndex class of the fork.""" - return self._module("block_access_lists").BlockAccessIndex - - @property - def BlockAccessListBuilder(self) -> Any: - """BlockAccessListBuilder class of the fork.""" - return self._module("block_access_lists").BlockAccessListBuilder - @property def hash_block_access_list(self) -> Any: """hash_block_access_list function of the fork.""" return self._module("block_access_lists").hash_block_access_list - @property - def validate_block_access_list_gas_limit(self) -> Any: - """validate_block_access_list_gas_limit function of the fork.""" - block_access_lists = self._module("block_access_lists") - return block_access_lists.validate_block_access_list_gas_limit - @property def has_hash_block_access_list(self) -> bool: """Check if the fork has a `hash_block_access_list` function.""" @@ -174,6 +158,23 @@ def has_hash_block_access_list(self) -> bool: return False return hasattr(module, "hash_block_access_list") + @property + def BlockAccessIndex(self) -> Any: + """BlockAccessIndex type of the fork.""" + return self._module("block_access_lists").BlockAccessIndex + + @property + def BlockAccessListBuilder(self) -> Any: + """BlockAccessListBuilder class of the fork.""" + return self._module("block_access_lists").BlockAccessListBuilder + + @property + def validate_block_access_list_gas_limit(self) -> Any: + """validate_block_access_list_gas_limit function of the fork.""" + return self._module( + "block_access_lists" + ).validate_block_access_list_gas_limit + @property def signing_hash_2930(self) -> Any: """signing_hash_2930 function of the fork.""" @@ -311,124 +312,30 @@ def has_decode_transaction(self) -> bool: """Check if this fork has a `decode_transaction`.""" return hasattr(self._module("transactions"), "decode_transaction") - @property - def has_block_state(self) -> bool: - """Check if the fork uses BlockState instead of State.""" - try: - module = self._module("state_tracker") - except ModuleNotFoundError: - return False - return hasattr(module, "BlockState") - @property def BlockState(self) -> Any: """BlockState class of the fork.""" return self._module("state_tracker").BlockState @property - def extract_block_diff(self) -> Any: - """extract_block_diff function of the fork.""" - return self._module("state_tracker").extract_block_diff + def TransactionState(self) -> Any: + """TransactionState class of the fork.""" + return self._module("state_tracker").TransactionState @property - def State(self) -> Any: - """State class of the fork.""" - try: - return self._module("state").State - except ModuleNotFoundError: - from ethereum.state import State - - return State + def incorporate_tx_into_block(self) -> Any: + """incorporate_tx_into_block function of the fork.""" + return self._module("state_tracker").incorporate_tx_into_block @property - def set_account(self) -> Any: - """set_account function of the fork.""" - try: - return self._module("state").set_account - except ModuleNotFoundError: - from ethereum.state import set_account - - return set_account - - @property - def store_code(self) -> Any: - """store_code function of the fork.""" - try: - return getattr(self._module("state"), "store_code", None) - except ModuleNotFoundError: - from ethereum.state import store_code - - return store_code - - @property - def set_storage(self) -> Any: - """set_storage function of the fork.""" - try: - return self._module("state").set_storage - except ModuleNotFoundError: - from ethereum.state import set_storage - - return set_storage - - @property - def state_root(self) -> Any: - """state_root function of the fork.""" - try: - return self._module("state").state_root - except ModuleNotFoundError: - from ethereum.state import state_root - - return state_root - - @property - def close_state(self) -> Any: - """close_state function of the fork.""" - try: - return self._module("state").close_state - except ModuleNotFoundError: - from ethereum.state import close_state - - return close_state + def extract_block_diff(self) -> Any: + """extract_block_diff function of the fork.""" + return self._module("state_tracker").extract_block_diff @property def create_ether(self) -> Any: """create_ether function of the fork.""" - try: - return self._module("state").create_ether - except ModuleNotFoundError: - import ethereum.state - - return getattr(ethereum.state, "create_ether", None) - - @property - def root(self) -> Any: - """Root function of the fork.""" - try: - return self._module("trie").root - except ModuleNotFoundError: - from ethereum.merkle_patricia_trie import root - - return root - - @property - def copy_trie(self) -> Any: - """copy_trie function of the fork.""" - try: - return self._module("trie").copy_trie - except ModuleNotFoundError: - from ethereum.merkle_patricia_trie import copy_trie - - return copy_trie - - @property - def trie_get(self) -> Any: - """trie_get function of the fork.""" - try: - return self._module("trie").trie_get - except ModuleNotFoundError: - from ethereum.merkle_patricia_trie import trie_get - - return trie_get + return self._module("state_tracker").create_ether @property def hex_to_address(self) -> Any: diff --git a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py index 8175015e5b6..e17cde49005 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py @@ -17,6 +17,7 @@ from ethereum import trace from ethereum.exceptions import EthereumException, InvalidBlock from ethereum.fork_criteria import ByBlockNumber, ByTimestamp, Unscheduled +from ethereum.merkle_patricia_trie import copy_trie from ethereum_spec_tools.forks import Hardfork, TemporaryHardfork from ..loaders.fixture_loader import Load @@ -375,12 +376,9 @@ def block_environment(self) -> Any: "chain_id": self.chain_id, } - if self.fork.has_block_state: - block_state = self.fork.BlockState(pre_state=self.alloc.state) - kw_arguments["state"] = block_state - self._block_state = block_state - else: - kw_arguments["state"] = self.alloc.state + block_state = self.fork.BlockState(pre_state=self.alloc.state) + kw_arguments["state"] = block_state + self._block_state = block_state block_environment = self.fork.BlockEnvironment @@ -408,10 +406,9 @@ def block_environment(self) -> Any: def backup_state(self) -> None: """Back up the state in order to restore in case of an error.""" state = self.alloc.state - main_trie = self.fork.copy_trie(state._main_trie) + main_trie = copy_trie(state._main_trie) storage_tries = { - k: self.fork.copy_trie(t) - for (k, t) in state._storage_tries.items() + k: copy_trie(t) for (k, t) in state._storage_tries.items() } self.alloc.state_backup = ( main_trie, @@ -432,9 +429,10 @@ def pay_block_rewards(self, block_reward: U256, block_env: Any) -> None: miner_reward = block_reward + ( ommer_count * (block_reward // U256(32)) ) - self.fork.create_ether( - block_env.state, block_env.coinbase, miner_reward - ) + + rewards_state = self.fork.TransactionState(parent=block_env.state) + + self.fork.create_ether(rewards_state, block_env.coinbase, miner_reward) for ommer in self.env.ommers: # Ommer age with respect to the current block. @@ -443,9 +441,11 @@ def pay_block_rewards(self, block_reward: U256, block_env: Any) -> None: (U256(8) - ommer_age) * block_reward ) // U256(8) self.fork.create_ether( - block_env.state, ommer.coinbase, ommer_miner_reward + rewards_state, ommer.coinbase, ommer_miner_reward ) + self.fork.incorporate_tx_into_block(rewards_state) + def run_state_test(self) -> Any: """ Apply a single transaction on pre-state. No system operations diff --git a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py index 902b7e7c29b..fb3139c7b5c 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/t8n_types.py @@ -11,7 +11,8 @@ from ethereum_types.numeric import U64, U256, Uint from ethereum.crypto.hash import Hash32, keccak256 -from ethereum.state import EMPTY_CODE_HASH +from ethereum.merkle_patricia_trie import root, trie_get +from ethereum.state import EMPTY_CODE_HASH, apply_changes_to_state from ethereum.utils.hexadecimal import hex_to_bytes, hex_to_u256, hex_to_uint from ..loaders.transaction_loader import TransactionLoad, UnsupportedTxError @@ -286,8 +287,8 @@ def get_receipts_from_output( """ receipts: List[Any] = [] for key in block_output.receipt_keys: - tx = t8n.fork.trie_get(block_output.transactions_trie, key) - receipt = t8n.fork.trie_get(block_output.receipts_trie, key) + tx = trie_get(block_output.transactions_trie, key) + receipt = trie_get(block_output.receipts_trie, key) assert tx is not None assert receipt is not None @@ -308,33 +309,28 @@ def update(self, t8n: "T8N", block_env: Any, block_output: Any) -> None: Update the result after processing the inputs. """ self.gas_used = block_output.block_gas_used - self.tx_root = t8n.fork.root(block_output.transactions_trie) - self.receipt_root = t8n.fork.root(block_output.receipts_trie) + self.tx_root = root(block_output.transactions_trie) + self.receipt_root = root(block_output.receipts_trie) self.bloom = t8n.fork.logs_bloom(block_output.block_logs) self.logs_hash = keccak256(rlp.encode(block_output.block_logs)) - if t8n.fork.has_block_state: - from ethereum.state import apply_changes_to_state - - block_diff = t8n.fork.extract_block_diff(t8n._block_state) - state_root_value, _ = ( - t8n.alloc.state.compute_state_root_and_trie_changes( - block_diff.account_changes, block_diff.storage_changes - ) + block_diff = t8n.fork.extract_block_diff(t8n._block_state) + state_root_value, _ = ( + t8n.alloc.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, ) - self.state_root = state_root_value - # Apply diffs to pre-state for alloc output - apply_changes_to_state(t8n.alloc.state, block_diff) - else: - self.state_root = t8n.fork.state_root(block_env.state) + ) + self.state_root = state_root_value + # Apply diffs to pre-state for alloc output + apply_changes_to_state(t8n.alloc.state, block_diff) self.receipts = self.get_receipts_from_output(t8n, block_output) if hasattr(block_env, "base_fee_per_gas"): self.base_fee = block_env.base_fee_per_gas if hasattr(block_output, "withdrawals_trie"): - self.withdrawals_root = t8n.fork.root( - block_output.withdrawals_trie - ) + self.withdrawals_root = root(block_output.withdrawals_trie) if hasattr(block_env, "excess_blob_gas"): self.excess_blob_gas = block_env.excess_blob_gas diff --git a/tests/json_loader/helpers/load_blockchain_tests.py b/tests/json_loader/helpers/load_blockchain_tests.py index 8bab4269ddf..487df2411fb 100644 --- a/tests/json_loader/helpers/load_blockchain_tests.py +++ b/tests/json_loader/helpers/load_blockchain_tests.py @@ -12,6 +12,7 @@ from ethereum.crypto.hash import keccak256 from ethereum.exceptions import EthereumException, StateWithEmptyAccount +from ethereum.state import close_state from ethereum.utils.hexadecimal import hex_to_bytes from ethereum_spec_tools.evm_tools.loaders.fixture_loader import Load @@ -176,7 +177,7 @@ def runtest(self) -> None: # of all of them. with pytest.raises((EthereumException, RLPException)): add_block_to_chain(chain, json_block, load, mock_pow) - load.fork.close_state(chain.state) + close_state(chain.state) return else: add_block_to_chain(chain, json_block, load, mock_pow) @@ -188,8 +189,8 @@ def runtest(self) -> None: expected_post_state = load.json_to_state(json_data["postState"]) assert chain.state == expected_post_state - load.fork.close_state(chain.state) - load.fork.close_state(expected_post_state) + close_state(chain.state) + close_state(expected_post_state) def reportinfo(self) -> Tuple[Path, int, str]: """Return information for test reporting.""" diff --git a/tests/json_loader/test_genesis.py b/tests/json_loader/test_genesis.py index a29fded25d5..5fb45fcd887 100644 --- a/tests/json_loader/test_genesis.py +++ b/tests/json_loader/test_genesis.py @@ -8,21 +8,21 @@ from ethereum.forks.frontier.blocks import Block, Header from ethereum.forks.frontier.fork import BlockChain from ethereum.forks.frontier.fork_types import Account, Bloom -from ethereum.forks.frontier.state import ( - State, - set_account, - set_storage, - state_root, - store_code, -) -from ethereum.forks.frontier.trie import Trie, root from ethereum.forks.frontier.utils.hexadecimal import hex_to_address from ethereum.genesis import ( GenesisFork, add_genesis_block, get_genesis_configuration, ) -from ethereum.state import Address +from ethereum.merkle_patricia_trie import Trie, root +from ethereum.state import ( + Address, + State, + set_account, + set_storage, + state_root, + store_code, +) from ethereum.utils.hexadecimal import hex_to_hash from ethereum_spec_tools.forks import Hardfork diff --git a/tests/json_loader/test_optimized_state.py b/tests/json_loader/test_optimized_state.py index 418f00399a1..28763cee324 100644 --- a/tests/json_loader/test_optimized_state.py +++ b/tests/json_loader/test_optimized_state.py @@ -1,16 +1,24 @@ """Tests for the optimized state implementation.""" -import sys from typing import Any, cast import pytest from ethereum_types.numeric import U256 -import ethereum.forks.frontier.state as state -from ethereum.forks.frontier.fork_types import EMPTY_ACCOUNT +import ethereum.state as state from ethereum.forks.tangerine_whistle.utils.hexadecimal import hex_to_address +from ethereum.state import EMPTY_ACCOUNT from ethereum_spec_tools.forks import Hardfork +# The optimized state integration predates the ``State`` refactor and has +# not yet been rewired onto ``PreState``/``state_tracker`` — see +# https://github.com/ethereum/execution-specs/issues/2256. Until then, +# both ``get_optimized_state_patches`` and the per-fork ``destroy_storage`` +# API these tests assume no longer load, so the tests are skipped wholesale. +pytestmark = pytest.mark.skip( + reason="optimized state pending redesign (see issue #2256)" +) + try: import ethereum_optimized.state_db as state_db @@ -33,10 +41,6 @@ class OptimizedState: STORAGE_FOO = U256(101).to_be_bytes32() -@pytest.mark.skipif( - "ethereum_optimized.state_db" not in sys.modules, - reason="missing dependency (use `pip install 'ethereum[optimized]'`)", -) def test_storage_key() -> None: """ Tests that optimized state storage operations match the normal @@ -52,18 +56,14 @@ def actions(impl: Any) -> Any: state_normal = actions(state) state_optimized = actions(optimized_state) - assert state.get_storage( - state_normal, ADDRESS_FOO, STORAGE_FOO + assert state_normal.get_storage( + ADDRESS_FOO, STORAGE_FOO ) == optimized_state.get_storage(state_optimized, ADDRESS_FOO, STORAGE_FOO) assert state.state_root(state_normal) == optimized_state.state_root( state_optimized ) -@pytest.mark.skipif( - "ethereum_optimized.state_db" not in sys.modules, - reason="missing dependency (use `pip install 'ethereum[optimized]'`)", -) def test_resurrection() -> None: """Tests that optimized state handles storage resurrection correctly.""" @@ -80,8 +80,8 @@ def actions(impl: Any) -> Any: state_normal = actions(state) state_optimized = actions(optimized_state) optimized_state.state_root(state_optimized) - assert state.get_storage( - state_normal, ADDRESS_FOO, STORAGE_FOO + assert state_normal.get_storage( + ADDRESS_FOO, STORAGE_FOO ) == optimized_state.get_storage(state_optimized, ADDRESS_FOO, STORAGE_FOO) assert state.state_root(state_normal) == optimized_state.state_root( state_optimized diff --git a/vulture_whitelist.py b/vulture_whitelist.py index f550b98e4df..6f0d557c766 100644 --- a/vulture_whitelist.py +++ b/vulture_whitelist.py @@ -53,6 +53,17 @@ # src/ethereum/optimized/state_db.py State.rollback_db_transaction +# src/ethereum_optimized/state_db.py - registered as patches via @add_item +from ethereum_optimized.state_db import ( + begin_transaction, + commit_transaction, + rollback_transaction, +) + +begin_transaction +commit_transaction +rollback_transaction + # src/ethereum_spec_tools/docc.py docc.EthereumDiscover docc.EthereumBuilder From e45c0eda7c4d4a66efce430c93acd7a07ee94215 Mon Sep 17 00:00:00 2001 From: felipe Date: Wed, 13 May 2026 02:25:29 -0600 Subject: [PATCH 071/186] feat(test): Increase BAL coverage with tests and BAL expectations for some existing (#2834) --- .../test_block_access_lists.py | 25 +- .../test_block_access_lists_eip7702.py | 188 +++++++++++++ .../test_block_access_lists_opcodes.py | 225 ++++++++++++++++ .../test_cases.md | 16 +- .../eip214_staticcall/test_staticcall.py | 8 +- .../test_create_oog_from_eoa_refunds.py | 2 +- .../test_selfdestruct_revert.py | 2 +- .../test_call_and_callcode_gas_calculation.py | 2 +- tests/frontier/validation/test_header.py | 2 +- .../test_initcollision.py | 2 +- tests/prague/eip7702_set_code_tx/test_gas.py | 2 +- .../eip7702_set_code_tx/test_set_code_txs.py | 247 ++++++++++++++++-- .../test_eip150_selfdestruct.py | 104 +++++++- 13 files changed, 776 insertions(+), 49 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 2226d9f78ff..13851dc6d02 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -1502,29 +1502,26 @@ def test_bal_precompile_funded( ) -@pytest.mark.parametrize_by_fork( - "precompile", - lambda fork: [ - pytest.param(addr, id=f"0x{int.from_bytes(addr, 'big'):02x}") - for addr in fork.precompiles() - ], -) -def test_bal_precompile_call( +@pytest.mark.with_all_precompiles +@pytest.mark.with_all_call_opcodes +def test_bal_precompile_call_opcode( pre: Alloc, blockchain_test: BlockchainTestFiller, - precompile: Address, + precompile: int, + call_opcode: Op, ) -> None: """ - Ensure BAL records precompile when called via contract. + Ensure BAL records the precompile address regardless of call opcode. - Alice calls Oracle contract which calls precompile. - BAL must include precompile with no balance/storage/code changes. + Alice calls Oracle contract which invokes the precompile via the + parametrized call opcode. For DELEGATECALL/CALLCODE the precompile + provides the code but is not the call target, so its access has to + be recorded explicitly rather than incidentally. """ alice = pre.fund_eoa() - # Oracle contract that calls the precompile oracle = pre.deploy_contract( - code=Op.CALL(100_000, precompile, 0, 0, 0, 0, 0) + Op.STOP + code=call_opcode(gas=100_000, address=precompile) + Op.STOP ) tx = Transaction( diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py index d26a26f55a9..8824b61b97b 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py @@ -1,8 +1,12 @@ """Tests for the effects of EIP-7702 transactions on EIP-7928.""" +from typing import Dict + import pytest from execution_testing import ( + EOA, Account, + Address, Alloc, AuthorizationTuple, BalAccountExpectation, @@ -515,6 +519,72 @@ def test_bal_7702_invalid_nonce_authorization( ) +@pytest.mark.pre_alloc_mutable() +def test_bal_7702_invalid_authority_has_code_authorization( + pre: Alloc, + blockchain_test: BlockchainTestFiller, +) -> None: + """ + Ensure BAL handles failed authorization where the authority already has + non-empty, non-delegation code (EIP-7702 step-5 rejection, post-load). + """ + # Pre-existing non-delegation code on the authority blocks the 7702 + # delegation at step 5, after the authority is already loaded. + alice = pre.fund_eoa(amount=0, code=Op.STOP, nonce=1) + bob = pre.fund_eoa(amount=0) + relayer = pre.fund_eoa() + oracle = pre.deploy_contract(code=Op.STOP) + + tx = Transaction( + sender=relayer, # Sponsored transaction + to=bob, + value=10, + gas_limit=1_000_000, + gas_price=0xA, + authorization_list=[ + AuthorizationTuple( + address=oracle, + nonce=alice.nonce, + signer=alice, + ) + ], + ) + + block = Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + bob: BalAccountExpectation( + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=10) + ] + ), + relayer: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + # Alice loaded at step 4 then step 5 rejects. + alice: BalAccountExpectation.empty(), + # Oracle never loaded as delegation target. + oracle: None, + } + ), + ) + + post = { + relayer: Account(nonce=1), + bob: Account(balance=10), + alice: Account(code=Op.STOP, nonce=1), + } + + blockchain_test( + pre=pre, + blocks=[block], + post=post, + ) + + def test_bal_7702_invalid_chain_id_authorization( pre: Alloc, blockchain_test: BlockchainTestFiller, @@ -639,6 +709,124 @@ def test_bal_7702_delegated_via_call_opcode( ) +@pytest.mark.parametrize( + "destination_is_loop", + [False, True], + ids=["chain", "loop"], +) +def test_bal_7702_multi_hop_delegation_chain( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + destination_is_loop: bool, +) -> None: + """ + Multi-hop EIP-7702 delegation: `chain` resolves A->B->C; `loop` + resolves A->B->A. In both cases the EVM follows the delegation once + and runs B's `0xef0100` bytecode as legacy code, which aborts + on the INVALID `0xef` opcode. For `chain`, C MUST NOT appear in the + BAL (second-hop target is never loaded as an execution target). For + `loop`, A is already in the BAL via the first delegation; the CALL + still fails. + """ + alice = pre.fund_eoa() + auth_a = pre.fund_eoa(amount=0) + auth_b = pre.fund_eoa(amount=0) + target_c = pre.deploy_contract(code=Op.STOP) + second_destination = auth_a if destination_is_loop else target_c + + entry_code = Op.SSTORE(0, Op.CALL(50_000, auth_a, 0, 0, 0, 0, 0)) + Op.STOP + entry_address = pre.deploy_contract( + code=entry_code, + storage={0: 0xDEAD}, + ) + + tx = Transaction( + sender=alice, + to=entry_address, + gas_limit=1_000_000, + gas_price=0xA, + authorization_list=[ + AuthorizationTuple( + address=auth_b, + nonce=0, + signer=auth_a, + ), + AuthorizationTuple( + address=second_destination, + nonce=0, + signer=auth_b, + ), + ], + ) + + account_expectations: Dict[EOA | Address, BalAccountExpectation | None] = { + alice: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + ), + auth_a: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec7702.delegation_designation(auth_b), + ) + ], + ), + auth_b: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec7702.delegation_designation( + second_destination + ), + ) + ], + ), + # CALL returned 0; SSTORE(0, 0) overwrites the 0xDEAD witness. + entry_address: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange(block_access_index=1, post_value=0) + ], + ) + ], + storage_reads=[], + ), + } + if not destination_is_loop: + account_expectations[target_c] = None + + block = Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations + ), + ) + + post: Dict[EOA | Address, Account] = { + auth_a: Account( + nonce=1, + code=Spec7702.delegation_designation(auth_b), + ), + auth_b: Account( + nonce=1, + code=Spec7702.delegation_designation(second_destination), + ), + entry_address: Account(storage={0: 0}), + } + if not destination_is_loop: + post[target_c] = Account(code=bytes(Op.STOP), nonce=1) + + blockchain_test( + pre=pre, + blocks=[block], + post=post, + ) + + def test_bal_7702_null_address_delegation_no_code_change( pre: Alloc, blockchain_test: BlockchainTestFiller, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index 5b40643303b..de18e83bc98 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -33,6 +33,7 @@ BlockAccessListExpectation, BlockchainTestFiller, Bytecode, + Conditional, Fork, Initcode, Op, @@ -3150,3 +3151,227 @@ def test_bal_create_early_failure( would_be_contract_address: Account.NONEXISTENT, }, ) + + +@pytest.mark.with_all_create_opcodes +@pytest.mark.parametrize( + "storage_op", + ["read", "write"], + ids=["sload_then_selfdestruct", "sstore_then_selfdestruct"], +) +def test_bal_create_storage_op_then_selfdestruct_same_tx( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + create_opcode: Op, + storage_op: str, +) -> None: + """ + Same-tx CREATE/CREATE2 + storage_op + SELFDESTRUCT. + + The deterministic address A is pre-funded. A single tx deploys a + contract at A via the parametrized create opcode; init code performs + SLOAD or SSTORE on slot B then SELFDESTRUCTs. Because the contract + is destroyed in the same tx, slot B MUST appear in `storage_reads` + and MUST NOT appear in `storage_changes` (writes demoted to reads + per EIP-7928). + """ + alice = pre.fund_eoa() + beneficiary = pre.fund_eoa(amount=0) + fund_amount = 100 + slot_b = 0x07 + + if storage_op == "read": + initcode = Op.POP(Op.SLOAD(slot_b)) + Op.SELFDESTRUCT(beneficiary) + else: + initcode = Op.SSTORE(slot_b, 0xCAFE) + Op.SELFDESTRUCT(beneficiary) + initcode_bytes = bytes(initcode) + + salt = 0 + is_create2 = create_opcode == Op.CREATE2 + if is_create2: + deploy_op = Op.CREATE2( + value=0, offset=0, size=Op.CALLDATASIZE, salt=salt + ) + else: + deploy_op = Op.CREATE(value=0, offset=0, size=Op.CALLDATASIZE) + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE(0, deploy_op) + + Op.STOP + ) + factory = pre.deploy_contract(code=factory_code) + target_a = compute_create_address( + address=factory, + nonce=1, + salt=salt, + initcode=initcode_bytes, + opcode=create_opcode, + ) + pre.fund_address(target_a, fund_amount) + + tx = Transaction( + sender=alice, + to=factory, + data=initcode_bytes, + gas_limit=1_000_000, + ) + + block = Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + target_a: BalAccountExpectation( + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0), + ], + storage_reads=[slot_b], + storage_changes=[], + code_changes=[], + nonce_changes=[], + ), + beneficiary: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, + post_balance=fund_amount, + ) + ], + ), + } + ), + ) + + blockchain_test( + pre=pre, + blocks=[block], + post={ + target_a: Account.NONEXISTENT, + beneficiary: Account(balance=fund_amount), + factory: Account(nonce=2, storage={0: target_a}), + }, + ) + + +@pytest.mark.parametrize( + "pre_balance", + [0, 100], + ids=["no_balance", "with_balance"], +) +def test_bal_create2_selfdestruct_then_recreate_same_block( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + pre_balance: int, +) -> None: + """ + Tx1 CREATE2+SELFDESTRUCT, Tx2 CREATE2 resurrection at same address. + + Two identical txs invoke the same factory with the same initcode + (same hash => same CREATE2 address A). The factory branches on its + own storage slot 1: on the first tx, the slot is 0 so the factory + CREATE2's then CALLs A (runtime SELFDESTRUCTs) and records the + CALL's return code in slot 1; on the second tx, slot 1 is non-zero + so only CREATE2 runs and A persists with the runtime code. + + Per EIP-7928 SELFDESTRUCT-in-tx semantics, Tx1's destructed A has no + `nonce_changes` or `code_changes`; only `balance_changes` if it was + pre-funded. Tx2's fresh A has `nonce_changes` (post=1) and + `code_changes` (post=runtime). + """ + alice = pre.fund_eoa() + beneficiary = pre.fund_eoa(amount=0) + salt = 0 + + runtime = Op.SELFDESTRUCT(beneficiary) + runtime_bytes = bytes(runtime) + initcode_bytes = bytes(Initcode(deploy_code=runtime)) + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE( + 0, + Op.CREATE2(value=0, offset=0, size=Op.CALLDATASIZE, salt=salt), + ) + + Conditional( + condition=Op.ISZERO(Op.SLOAD(1)), + if_true=Op.SSTORE(1, Op.CALL(50_000, Op.SLOAD(0), 0, 0, 0, 0, 0)), + if_false=Op.STOP, + ) + + Op.STOP + ) + factory = pre.deploy_contract(code=factory_code) + target_a = compute_create_address( + address=factory, + salt=salt, + initcode=initcode_bytes, + opcode=Op.CREATE2, + ) + + if pre_balance > 0: + pre.fund_address(target_a, pre_balance) + + tx1 = Transaction( + sender=alice, + to=factory, + data=initcode_bytes, + gas_limit=500_000, + ) + tx2 = Transaction( + sender=alice, + to=factory, + data=initcode_bytes, + gas_limit=500_000, + ) + + target_a_balance_changes = [] + if pre_balance > 0: + target_a_balance_changes = [ + BalBalanceChange(block_access_index=1, post_balance=0), + ] + beneficiary_expectation = BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=pre_balance + ) + ], + ) + else: + # SELFDESTRUCT touches the beneficiary even with 0 value; no + # balance change is recorded. + beneficiary_expectation = BalAccountExpectation.empty() + + block = Block( + txs=[tx1, tx2], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + target_a: BalAccountExpectation( + # Tx1 destruction (EIP-7928 #165): no nonce/code changes. + # Tx2 resurrection: fresh contract with nonce=1, runtime. + nonce_changes=[ + BalNonceChange(block_access_index=2, post_nonce=1), + ], + code_changes=[ + BalCodeChange( + block_access_index=2, new_code=runtime_bytes + ), + ], + balance_changes=target_a_balance_changes, + storage_changes=[], + storage_reads=[], + ), + beneficiary: beneficiary_expectation, + } + ), + ) + + blockchain_test( + pre=pre, + blocks=[block], + post={ + target_a: Account(nonce=1, balance=0, code=runtime_bytes), + beneficiary: Account(balance=pre_balance) + if pre_balance > 0 + else Account.NONEXISTENT, + factory: Account(nonce=3, storage={0: target_a, 1: 1}), + }, + ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 6d990d5b3e2..73eaebe3c36 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -37,10 +37,9 @@ | `test_bal_aborted_storage_access` | Ensure BAL captures storage access in aborted transactions correctly | Alice calls contract that reads storage slot `0x01`, writes to slot `0x02`, then aborts with `REVERT`/`INVALID` | BAL MUST include storage_reads for slots `0x01` and `0x02` (aborted writes become reads), empty storage_changes. Only nonce changes for Alice. | ✅ Completed | | `test_bal_aborted_account_access` | Ensure BAL captures account access in aborted transactions for all account accessing opcodes | Alice calls `AbortContract` that performs account access operations (`BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) on `TargetContract` and aborts via `REVERT`/`INVALID` | BAL MUST include Alice, `TargetContract`, and `AbortContract` in account_changes and nonce changes for Alice. | ✅ Completed | | `test_bal_pure_contract_call` | Ensure BAL captures contract access for pure computation calls | Alice calls `PureContract` that performs pure arithmetic (ADD operation) without storage or balance changes | BAL MUST include Alice and `PureContract` in `account_changes`, and `nonce_changes` for Alice. | ✅ Completed | -| `test_bal_create2_to_A_read_then_selfdestruct` | BAL records balance change for A and storage access (no persistent change) | Tx0: Alice sends ETH to address **A**. Tx1: Deployer `CREATE2` a contract **at A**; contract does `SLOAD(B)` and immediately `SELFDESTRUCT(beneficiary=X)` in the same tx. | BAL **MUST** include **A** with `balance_changes` (funding in Tx0 and transfer on selfdestruct in Tx1). BAL **MUST** include storage key **B** as an accessed `StorageKey`, and **MUST NOT** include **B** under `storage_changes` (no persistence due to same-tx create+destruct). | 🟡 Planned | -| `test_bal_create2_to_A_write_then_selfdestruct` | BAL records balance change for A and storage access even if a write occurred (no persistent change) | Tx0: Alice sends ETH to **A**. Tx1: Deployer `CREATE2` contract **at A**; contract does `SSTORE(B, v)` (optionally `SLOAD(B)`), then `SELFDESTRUCT(beneficiary=Y)` in the same tx. | BAL **MUST** include **A** with `balance_changes` (Tx0 fund; Tx1 outflow to `Y`). BAL **MUST** include **B** as `StorageKey` accessed, and **MUST NOT** include **B** under `storage_changes` (ephemeral write discarded because the contract was created and destroyed in the same tx). | 🟡 Planned | +| `test_bal_create_storage_op_then_selfdestruct_same_tx` | BAL correctly demotes ephemeral storage operations to `storage_reads` when a contract is created and destroyed in the same tx (combined coverage for `read` and `write` storage_op cases — replaces `test_bal_create2_to_A_read_then_selfdestruct` and `test_bal_create2_to_A_write_then_selfdestruct`). Parametrized: `@pytest.mark.with_all_create_opcodes` + `storage_op ∈ ["read", "write"]`. | Address A is pre-funded via `pre.fund_address`. Alice sends a single tx calling a factory that deploys a contract at A via the parametrized create opcode; init code is either `SLOAD(B)+SELFDESTRUCT` or `SSTORE(B, v)+SELFDESTRUCT` (beneficiary = separate EOA). | BAL **MUST** include **A** with `balance_changes` `[(1, 0)]` (outflow to beneficiary on destruction). Slot **B** **MUST** appear under `storage_reads`, **NOT** `storage_changes` (write demoted to read because the contract is destroyed same-tx). A **MUST NOT** have `nonce_changes` or `code_changes`. Beneficiary has `balance_changes` reflecting receipt of `fund` at index 1. | ✅ Completed | | `test_bal_precompile_funded` | BAL records precompile value transfer with or without balance change | Alice sends value to precompile (all precompiles) via direct transaction. Parameterized: (1) with value (1 ETH), (2) without value (0 ETH). | For with_value: BAL **MUST** include precompile with `balance_changes`. For no_value: BAL **MUST** include precompile with empty `balance_changes`. No `storage_changes` or `code_changes` in either case. | ✅ Completed | -| `test_bal_precompile_call` | BAL records precompile when called via contract | Alice calls Oracle contract which calls precompile (all precompiles) via CALL opcode with 0 ETH | BAL **MUST** include Alice with `nonce_changes`, Oracle with empty changes, and precompile with empty changes. No `balance_changes`, `storage_changes`, or `code_changes` for precompile. | ✅ Completed | +| `test_bal_precompile_call_opcode` | BAL records the precompile address regardless of call opcode. | Parametrized: `@pytest.mark.with_all_precompiles × @pytest.mark.with_all_call_opcodes`. Alice calls Oracle which invokes the precompile via the parametrized call opcode. For DELEGATECALL/CALLCODE the precompile provides the code but is not the call target, so its access has to be recorded explicitly rather than incidentally. | BAL **MUST** include the precompile address with empty changes for all four call opcodes. Oracle has empty changes (called but no state mutation), Alice has `nonce_changes`. | ✅ Completed | | `test_bal_7702_delegated_create` | BAL tracks EIP-7702 delegation indicator write and contract creation | Alice sends a type-4 (7702) tx authorizing herself to delegate to `Deployer` code which executes `CREATE` | BAL MUST include for **Alice**: `code_changes` (delegation indicator), `nonce_changes` (increment from 7702 processing), and `balance_changes` (post-gas). For **Child**: `code_changes` (runtime bytecode) and `nonce_changes = 1`. | ✅ Completed | | `test_bal_7702_delegation_create` | Ensure BAL captures creation of EOA delegation | Alice authorizes delegation to contract `Oracle`. Transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends 7702 tx herself. (2) Sponsored: `Relayer` sends 7702 tx on Alice's behalf. | BAL **MUST** include Alice: `code_changes` (delegation designation `0xef0100\|\|address(Oracle)`),`nonce_changes` (increment). Bob: `balance_changes` (receives 10 wei). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes`.`Oracle` **MUST NOT** be present in BAL - the account is never accessed. | ✅ Completed | | `test_bal_7702_delegation_update` | Ensure BAL captures update of existing EOA delegation | Alice first delegates to `Oracle1`, then in second tx updates delegation to `Oracle2`. Each transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends both 7702 txs herself. (2) Sponsored: `Relayer` sends both 7702 txs on Alice's behalf. | BAL **MUST** include Alice: first tx has `code_changes` (delegation designation `0xef0100\|\|address(Oracle1)`),`nonce_changes`. Second tx has`code_changes` (delegation designation `0xef0100\|\|address(Oracle2)`),`nonce_changes`. Bob:`balance_changes` (receives 10 wei on each tx). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes` for both transactions. `Oracle1` and `Oracle2` **MUST NOT** be present in BAL - accounts are never accessed. | ✅ Completed | @@ -48,6 +47,13 @@ | `test_bal_7702_delegated_storage_access` | Ensure BAL captures storage operations when calling a delegated EIP-7702 account | Alice has delegated her account to `Oracle`. `Oracle` contract contains code that reads from storage slot `0x01` and writes to storage slot `0x02`. Bob sends 10 wei to Alice (the delegated account), which executes `Oracle`'s code. | BAL **MUST** include Alice: `balance_changes` (receives 10 wei), `storage_changes` for slot `0x02` (write operation performed in Alice's storage), `storage_reads` for slot `0x01` (read operation from Alice's storage). Bob: `nonce_changes` (sender), `balance_changes` (loses 10 wei plus gas costs). `Oracle` (account access). | ✅ Completed | | `test_bal_7702_invalid_nonce_authorization` | Ensure BAL handles failed authorization due to wrong nonce | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect nonce, causing silent authorization failure | BAL **MUST** include Alice with empty changes (account access), Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include `Oracle` (authorization failed, no delegation) | ✅ Completed | | `test_bal_7702_invalid_chain_id_authorization` | Ensure BAL handles failed authorization due to wrong chain id | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect chain id, causing authorization failure before account access | BAL **MUST** include Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include Alice (authorization fails before loading account) or `Oracle` (authorization failed, no delegation) | ✅ Completed | +| `test_call_into_self_delegating_set_code` | Self-delegation degenerate one-hop case (companion to `test_call_into_chain_delegating_set_code`). File: `tests/prague/eip7702_set_code_tx/test_set_code_txs.py`. Parametrized over `@pytest.mark.with_all_call_opcodes`. | `auth_signer` auths itself as its own delegation target. `entry_address` issues `call_opcode(auth_signer)`. EVM resolves once: `auth_signer`'s code is the designator pointing back to `auth_signer`; the second hop is not followed, so the `0xef0100...` bytecode runs as legacy code → INVALID → returns 0. | `auth_signer` **MUST** appear with `nonce_changes` and `code_changes` (delegation designator to itself). `entry_address` **MUST** have `storage_reads=[0]` (no-op SSTORE demoted). No additional delegation-target entry is created because the target coincides with the authority. | ✅ Completed | +| `test_bal_7702_invalid_authority_has_code_authorization` | Ensure BAL handles failed authorization where the authority already has non-empty, non-delegation code (EIP-7702 step-5 rejection, post-load). | Alice is pre-allocated with `code=Op.STOP` and `nonce=1`. `Relayer` sends sponsored tx to Bob (10 wei transfer). Authorization tuple delegates Alice to `Oracle` with matching nonce. EIP-7702 step 5 rejects because Alice's code is non-empty and not a delegation designator. | BAL **MUST** include Bob with `balance_changes` (10 wei), Relayer with `nonce_changes`, and Alice with empty changes (loaded at step 4 then rejected at step 5). **MUST NOT** include `Oracle` (delegation target never loaded). | ✅ Completed | +| `test_signature_s_out_of_range` | Ensure BAL excludes the authority when the EIP-7702 auth signature has an out-of-range `s` value (EIP-2 low-s rule, ecrecover fails before authority is loaded). File: `tests/prague/eip7702_set_code_tx/test_set_code_txs.py`. | `auth_signer` signs a normal auth tuple delegating to `set_code_to_address`; the tuple is then mutated so `s = SECP256K1N - s` and `v` is flipped, producing a high-`s` signature. Sender (a separate EOA) sends the tx to `entry_address` which executes `SSTORE(1, 1)`. | BAL **MUST** include sender with `nonce_changes` at `block_access_index=1` and `entry_address` with `storage_changes` for slot 1 (post=1). BAL **MUST NOT** include `auth_signer` (auth fails at ecrecover, before the authority is added to `accessed_addresses`) or `set_code_to_address` (target is never loaded as an execution target). | ✅ Completed | +| `test_nonce_validity` | Ensure BAL correctly records EIP-7702 auth-tuple nonce-field validity across pre-load (`nonce >= 2**64-1`), success, and post-load (account.nonce != auth.nonce) branches. File: `tests/prague/eip7702_set_code_tx/test_set_code_txs.py`. | Parametrized over `(account_nonce, authorization_nonce)`: (1) `(MAX, MAX)` pre-load rejection at step 2, (2) `(MAX-1, MAX-1)` successful auth, (3) `(0, 1)` post-load nonce mismatch, (4) `(1, 0)` post-load nonce mismatch. `entry_address` always does `SSTORE(success_slot, 1) + CALL(auth_signer) + SSTORE(return_slot, RETURNDATASIZE)`. | Valid auth (case 2): `auth_signer` **MUST** have `nonce_changes` (post=`account_nonce+1`) and `code_changes` (delegation designation); `set_code_to_address` **MUST** appear with empty changes (loaded as execution target via delegation dispatch); `entry_address` has `storage_changes` for both slot 1 and slot 2 (post=1). Invalid auth (cases 1, 3, 4): `auth_signer` **MUST** appear with empty changes (the subsequent CALL touches it, even though the auth processing did or did not add it); `set_code_to_address` **MUST NOT** be in BAL; `entry_address` has `storage_changes` for slot 1 and `storage_reads` for slot 2 (the `SSTORE(0, 0)` no-op is demoted per EIP-7928). Sender always has `nonce_changes`. | ✅ Completed | +| `test_call_into_chain_delegating_set_code` | Ensure BAL respects EIP-7702 one-hop delegation resolution when `A` delegates to `B` and `B` delegates back to `A`. File: `tests/prague/eip7702_set_code_tx/test_set_code_txs.py`. Parameterized over `@pytest.mark.with_all_call_opcodes`. | Two auths: `auth_signer_1` -> `auth_signer_2`, then `auth_signer_2` -> `auth_signer_1`. `entry_address` issues `call_opcode(auth_signer_1)` and stores the return code in slot 0. The EVM resolves `A` -> `B` once, then runs `B`'s `0xef0100...` bytecode as legacy code; `0xef` is INVALID, so the call frame aborts and returns 0. | BAL **MUST** include only `auth_signer_1` and `auth_signer_2` from the delegation chain (each with `nonce_changes` and `code_changes` for its delegation designator). No third address is ever loaded because the second hop is never followed. `entry_address` **MUST** have `storage_reads` for slot 0 (the `SSTORE(slot, 0)` is a no-op write and is demoted per EIP-7928) and no `storage_changes`. Sender has `nonce_changes`. | ✅ Completed | +| `test_bal_7702_multi_hop_delegation_chain` | Multi-hop EIP-7702 delegation: `chain` resolves A→B→C and `loop` resolves A→B→A. In both cases the EVM follows the delegation once and runs B's `0xef0100` bytecode, which aborts on the INVALID `0xef` opcode. Parametrized over `destination_is_loop ∈ [False, True]`. | `auth_a` delegates to `auth_b`; `auth_b` delegates to either `target_c` (chain) or back to `auth_a` (loop). Entry contract has `storage[0] = 0xDEAD` (witness) and issues `CALL(auth_a)` then stores the return code in slot 0. | `auth_a` and `auth_b` **MUST** appear with `nonce_changes` and `code_changes` (each successful auth). In `chain`, `target_c` **MUST NOT** appear in BAL. `entry_address` has `storage_changes` for slot 0 with `post_value=0` (0xDEAD overwritten by the failed CALL's return code 0). Sender has `nonce_changes`. | ✅ Completed | +| `test_set_code_to_precompile` | Covers the BAL recording of a precompile address when reached via EIP-7702 delegation dispatch — across all 4 call opcodes and all precompiles. Companion to `test_bal_precompile_call_opcode` for the direct-call path. File: `tests/prague/eip7702_set_code_tx/test_set_code_txs.py`. | `@pytest.mark.with_all_call_opcodes × @pytest.mark.with_all_precompiles`. EOA `auth_signer` delegates to a precompile address. A caller contract invokes `call_opcode(auth_signer)`; EIP-7702 resolves the delegation to the precompile (whose code is treated as empty per spec). | When EIP-7928 is enabled, BAL **MUST** include `auth_signer` with `nonce_changes` and `code_changes` (delegation designator), and **MUST** include the precompile address with empty changes (loaded as execution target via delegation dispatch). | ✅ Completed | | `test_bal_7702_delegated_via_call_opcode` | Ensure BAL captures delegation target when a contract uses *CALL opcodes to call a delegated account | Pre-deployed contract `Alice` delegated to `Oracle`. `Caller` contract uses CALL/CALLCODE/DELEGATECALL/STATICCALL to call `Alice`. Bob sends transaction to `Caller`. | BAL **MUST** include Bob: `nonce_changes`. `Caller`: empty changes (account access). `Alice`: empty changes (account access - delegated account being called). `Oracle`: empty changes (delegation target access). | ✅ Completed | | `test_bal_7702_null_address_delegation_no_code_change` | Ensure BAL does not record spurious code changes for net-zero code operations | Alice sends transaction with authorization delegating to NULL_ADDRESS (0x0), which sets code to `b""` on an account that already has `b""` code. Transaction sends 10 wei to Bob. | BAL **MUST** include Alice with `nonce_changes` (tx nonce + auth nonce increment) but **MUST NOT** include `code_changes` (setting `b"" -> b""` is net-zero and filtered out). Bob: `balance_changes` (receives 10 wei). This ensures net-zero code change is not recorded. | ✅ Completed | | `test_bal_7702_double_auth_reset` | Ensure BAL tracks multiple 7702 nonce increments but filters net-zero code change | Single transaction contains two EIP-7702 authorizations for `Alice`: (1) first auth sets delegation `0xef0100\|\|Oracle`, (2) second auth clears delegation back to empty. Transaction sends 10 wei to `Bob`. Two variants: (a) Self-funded: `Alice` is tx sender (one tx nonce bump + two auth bumps → nonce 0→3). (b) Sponsored: `Relayer` is tx sender (`Alice` only in auths → nonce 0→2 for `Alice`, plus one nonce bump for `Relayer`). | Variant (a): BAL **MUST** include `Alice` with `nonce_changes` 0→3. Variant (b): BAL **MUST** include `Alice` with `nonce_changes` 0→2 and `Relayer` with its own `nonce_changes`. For both variants, BAL **MUST NOT** include `code_changes` for `Alice` (net code is empty), **MUST** include `Bob` with `balance_changes` (receives 10 wei), and `Oracle` **MUST NOT** appear in BAL. | ✅ Completed | @@ -130,7 +136,7 @@ | `test_bal_4788_query` | Ensure BAL captures storage reads when querying beacon root (valid and invalid queries) with optional value transfer | Parameterized test: Block 1 stores beacon root at timestamp 12. Block 2 queries with three timestamp scenarios (valid=12, invalid non-zero=42, invalid zero=0) and value (0 or 100 wei). Valid query (timestamp=12): reads both timestamp and root slots, writes returned value. If value > 0, beacon root contract receives balance. Invalid query with non-zero timestamp (timestamp=42): reads only timestamp slot before reverting, query contract has implicit SLOAD recorded (SSTORE reverts), no value transferred. Invalid query with zero timestamp (timestamp=0): reverts immediately without any storage access, query contract has implicit SLOAD recorded, no value transferred. | Block 1 BAL: System call writes. Block 2 BAL **MUST** include at `block_access_index=0`: System call writes for block 2. Valid case (timestamp=12) at `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with `storage_reads` [timestamp_slot, root_slot] and `balance_changes` if value > 0, query contract with `storage_changes`. Invalid non-zero case (timestamp=42) at `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with `storage_reads` [timestamp_slot only] and NO `balance_changes` (reverted), query contract with `storage_reads` [0] and NO `storage_changes`. Invalid zero case (timestamp=0) at `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes`, query contract with `storage_reads` [0] and NO `storage_changes`. | ✅ Completed | | `test_bal_4788_invalid_calldata_size` | Ensure BAL correctly handles EIP-4788 queries with invalid calldata size | Parameterized test: Query contract calls `BEACON_ROOTS_ADDRESS` with variable-size calldata (0, 31, or 33 bytes) and value (0 or 100 wei). EIP-4788 requires exactly 32 bytes of calldata; any other size reverts before any storage access. | BAL **MUST** include at `block_access_index=0`: `BEACON_ROOTS_ADDRESS` with `storage_changes` from system call. At `block_access_index=1`: `BEACON_ROOTS_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes` (value not transferred), query contract with `storage_reads` [0] (implicit from no-op SSTORE) and NO `storage_changes`. If value > 0, query contract retains balance. Alice with `nonce_changes`. | ✅ Completed | | `test_bal_4788_selfdestruct_to_beacon_root` | Ensure BAL captures `SELFDESTRUCT` to beacon root address alongside system call storage writes | Single block: Pre-execution system call writes beacon root to storage. Transaction: Alice calls contract (pre-funded with 100 wei) that selfdestructs with `BEACON_ROOTS_ADDRESS` as beneficiary. | BAL **MUST** include at `block_access_index=0`: `BEACON_ROOTS_ADDRESS` with `storage_changes` (timestamp and root slots from system call). At `block_access_index=1`: Alice with `nonce_changes`, contract with `balance_changes` (100→0), `BEACON_ROOTS_ADDRESS` with `balance_changes` (receives 100 wei). | ✅ Completed | -| `test_bal_selfdestruct_send_to_sender` | Ensure BAL tracks SELFDESTRUCT sending all funds back to the tx sender (no burn) | Pre-state: contract `C` exists from a prior transaction with non-empty code and balance = 100 wei. EOA `Alice` sends a transaction calling `C`. `C`’s code executes `SELFDESTRUCT(Alice)`. Under EIP-6780, because `C` was not created in this transaction, SELFDESTRUCT does not delete code or storage; it only transfers the entire 100 wei balance from `C` to `Alice`. Final post-state: `C` still exists with the same code and balance = 0; `Alice`’s balance increased by 100 wei (ignoring gas for this test). | BAL **MUST** include `Alice` with `nonce_changes` (tx sender) and `balance_changes` reflecting receipt of 100 wei, and **MUST** include `C` with `balance_changes` 100→0 and no `code_changes`. BAL **MUST NOT** include any other accounts. This test ensures SELFDESTRUCT-to-sender is modeled as a pure value transfer (no burn, no code deletion). | 🟡 Planned | +| `test_selfdestruct_send_to_sender` | Ensure BAL tracks SELFDESTRUCT sending all funds back to the tx sender (no burn). Multi-fork: valid_from TangerineWhistle, BAL expectations applied from Amsterdam via `is_eip_enabled(7928)`. File: `tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py`. | Parametrized over `originator_balance: [0, 100]`. Pre-deployed contract `victim` with `code=SELFDESTRUCT(CALLER)` and the given balance. Alice (tx.sender) sends tx directly to `victim`; no intermediate caller. Pre-Cancun: victim destroyed. >=Cancun (EIP-6780, non-same-tx): victim preserved with balance 0. | When EIP-7928 is enabled, BAL **MUST** include Alice with `nonce_changes` coalesced with `balance_changes` (Alice is both sender and beneficiary). Victim has `balance_changes` 100→0 when funded, otherwise empty changes — and **MUST NOT** have `code_changes` or `nonce_changes`. | ✅ Completed | | `test_bal_7002_clean_sweep` | Ensure BAL correctly tracks "clean sweep" where all withdrawal requests are dequeued in same block (requests ≤ MAX). Parameterized: (1) pubkey first 32 bytes zero / non-zero, (2) amount zero / non-zero | Alice sends transaction to `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS` with 1 withdrawal request. Validator pubkey has either first 32 bytes zero or non-zero. Amount is either zero or non-zero. Since 1 ≤ MAX_WITHDRAWAL_REQUESTS_PER_BLOCK, post-execution system call dequeues all requests ("clean sweep"), resetting head and tail to 0. | BAL **MUST** include Alice with `nonce_changes` at `block_access_index=1`. `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS` **MUST** have: `balance_changes` at `block_access_index=1` (receives fee), `storage_reads` for excess, head, and slot 5 (first 32 bytes of pubkey) if zero. At `block_access_index=1` (tx enqueue): `storage_changes` for count (0→1), tail (0→1), slot 4 (source address), slot 5 (first 32 bytes, **ONLY** if non-zero), slot 6. At `block_access_index=2` (post-exec dequeue): `storage_changes` for count (1→0), tail (1→0). Clean sweep invariant: when all requests dequeued, both head and tail reset to 0. | ✅ Completed | | `test_bal_7002_partial_sweep` | Ensure BAL correctly tracks queue overflow when requests exceed MAX, demonstrating partial sweep in block 1 and cleanup in block 2 | Block 1: 20 different EOAs each send withdrawal request to `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS`. Since 20 > MAX_WITHDRAWAL_REQUESTS_PER_BLOCK, only first MAX requests dequeued ("partial sweep"), leaving 4 in queue. Block 2: Empty block (no transactions), remaining 4 requests dequeued ("clean sweep"), queue becomes empty. | Block 1 BAL **MUST** include all 20 senders with `nonce_changes` at respective `block_access_index` (1-20). `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS` at each tx: `storage_changes` for count (increments to 20), tail (increments to 20). At `block_access_index=21` (post-exec partial dequeue): `storage_changes` for count (20→0), head (0→MAX). Partial sweep: head advances by MAX, tail stays 20, queue has 4 remaining (tail - head = 4). Block 2 BAL **MUST** include `WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS` at `block_access_index=1` (post-exec clean sweep): `storage_changes` for head (MAX→0), tail (20→0). Clean sweep: both head and tail reset to 0, queue empty. |✅ Completed | | `test_bal_7002_no_withdrawal_requests` | Ensure BAL captures EIP-7002 system contract dequeue operation even when block has no withdrawal requests | Block with 1 transaction: Alice sends 10 wei to Bob. No withdrawal requests submitted. | BAL **MUST** include Alice with `nonce_changes` at `block_access_index=1`. BAL **MUST** include Bob with `balance_changes` at `block_access_index=1`. BAL **MUST** include EIP-7002 system contract (`WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS`) with `storage_reads` for slots: excess (slot 0), count (slot 1), head (slot 2), tail (slot 3). System contract **MUST NOT** have `storage_changes` (no writes occur when queue is empty). This test demonstrates that the post-execution dequeue operation always runs and reads queue state, even when no requests are present. | ✅ Completed | @@ -152,7 +158,7 @@ | `test_bal_2935_query` | Ensure BAL captures storage reads when querying EIP-2935 historical block hashes (valid and invalid queries) with optional value transfer | Parameterized test: Block 1 (empty, stores genesis hash via system call). Block 2: Oracle contract queries `HISTORY_STORAGE_ADDRESS` with block number. Two block number scenarios (valid=0 genesis hash, invalid=1042 out of range) and value (0 or 100 wei). Valid query (block_number=0): reads genesis hash slot, oracle writes returned value. If value > 0, history storage contract receives balance. Invalid query (block_number=1042, out of range): reverts before storage access, oracle has implicit SLOAD recorded, value stays in oracle (not transferred to history storage). | Block 2 BAL **MUST** include: Valid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with `storage_reads` [slot 0] and `balance_changes` if value > 0, oracle with `storage_changes` (empty `slot_changes`). Invalid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes`, oracle with `storage_reads` [0], NO `storage_changes`, and `balance_changes` if value > 0 (value stays in oracle). Alice with `nonce_changes` at `block_access_index=1`. | ✅ Completed | | `test_bal_2935_selfdestruct_to_history_storage` | Ensure BAL captures `SELFDESTRUCT` to EIP-2935 history storage address | Single block: Transaction where Alice calls contract (pre-funded with 100 wei) that selfdestructs with `HISTORY_STORAGE_ADDRESS` as beneficiary. | BAL **MUST** include at `block_access_index=1`: Alice with `nonce_changes`, contract with `balance_changes` (100→0), `HISTORY_STORAGE_ADDRESS` with `balance_changes` (receives 100 wei). | ✅ Completed | | `test_bal_2935_invalid_calldata_size` | Ensure BAL correctly handles EIP-2935 queries with invalid calldata size (reverts before any storage access) | Parameterized test: Block 1 stores genesis hash via system call. Block 2: Oracle contract calls `HISTORY_STORAGE_ADDRESS` with invalid calldata sizes (0, 31, 33 bytes). EIP-2935 requires exactly 32 bytes calldata; any other size causes immediate revert before storage access. Optional value transfer (0 or 100 wei). | Block 2 BAL **MUST** include: `HISTORY_STORAGE_ADDRESS` with NO `storage_reads` (calldata size check fails before any SLOAD) and NO `balance_changes` (call reverts). Oracle with `storage_reads` [0] (implicit SLOAD from no-op SSTORE), NO `storage_changes`, and `balance_changes` if value > 0 (value stays in oracle on revert). Alice with `nonce_changes`. | ✅ Completed | -| `test_bal_create2_selfdestruct_then_recreate_same_block` | Ensure BAL handles **(tx1) create+SELFDESTRUCT** then **(tx2) CREATE2 "resurrection"** of the *same address* in the same block | Parameterized: `@pytest.mark.with_all_create_opcodes` for Tx1 create opcode (CREATE or CREATE2), and whether **A** has a pre-existing balance or not. **Tx1:** `Factory` executes `create_opcode` to deploy contract at **A** (for CREATE2: fixed `salt`, fixed `initcode` → deterministic address). The created contract optionally does `SLOAD/SSTORE` (to prove state touches), then `SELFDESTRUCT(beneficiary=B)` **in the same tx** (so under EIP-6780 the account is actually deleted after Tx1). **Tx2:** `Factory` executes `CREATE2(salt, initcode)` to recreate **A** at the same deterministic address, and this time the runtime code persists (no SELFDESTRUCT). | BAL **MUST** include: **Tx1 (`block_access_index=1`)**: (1) `Factory` with `nonce_changes` (create opcode increments nonce), and `balance_changes` if it endows A. (2) **A** in `account_changes` (it was accessed/created) but **MUST NOT** have persistent `code_changes`, `nonce_changes`, or `storage_changes` (it ends Tx1 non-existent due to same-tx create+SELFDESTRUCT). Any attempted `SSTORE` in A before SELFDESTRUCT **MUST NOT** appear in `storage_changes` (ephemeral). If A had a pre-existing balance, it **MUST** have `balance_changes` reflecting the transfer to B. (3) `B` with `balance_changes` if A had balance transferred on SELFDESTRUCT. **Tx2 (`block_access_index=2`)**: (1) `Factory` with another `nonce_changes`. (2) **A** with `code_changes` (runtime bytecode present), `nonce_changes = 1`, plus any `storage_changes` performed in Tx2. (3) If Tx2 endows or transfers value, include corresponding `balance_changes` for involved accounts. | 🟡 Planned | +| `test_bal_create2_selfdestruct_then_recreate_same_block` | Ensure BAL handles **(tx1) CREATE2+SELFDESTRUCT** then **(tx2) CREATE2 "resurrection"** of the *same address* in the same block. Parametrized over `pre_balance: [0, 100]`. | Two identical txs invoke the same factory with the same initcode (same hash → same CREATE2 address A). The factory branches on its own `storage[1]`: on the first tx, slot 1 is 0 so the factory CREATE2's then CALLs A (runtime SELFDESTRUCTs to beneficiary) and records the CALL's return code in slot 1; on the second tx, slot 1 is non-zero so only CREATE2 runs and A persists. When `pre_balance > 0`, A is pre-funded so Tx1's SELFDESTRUCT transfers a real balance. | At `block_access_index=1` (destructed A): **MUST NOT** include `nonce_changes` or `code_changes` for A (EIP-7928 SELFDESTRUCT-in-tx semantics). `balance_changes` for A appears only when pre-funded. Beneficiary appears with `balance_changes` if pre-funded, otherwise `empty()` (SELFDESTRUCT touches the beneficiary even with 0 value). At `block_access_index=2` (resurrection): A has `nonce_changes` (post=1) and `code_changes` (post=runtime). Factory's `storage[1] = 1` confirms the Tx1 CALL went through. | ✅ Completed | | `test_bal_call_with_value_in_static_context` | CALL with nonzero value in static context: target NOT in BAL | Parametrized: `target_is_warm` (cold/warm via access list), `target_has_code` (EOA/contract). Static check must fire before account access. | `target` **MUST NOT** appear in BAL. Balances unchanged. | ✅ Completed | | `test_bal_create_in_static_context` | CREATE/CREATE2 in static context: created address NOT in BAL | Parametrized: `@pytest.mark.with_all_create_opcodes`, `value` (0/1). Static check must fire before balance check, address computation, or nonce increment. | Created address **MUST NOT** appear in BAL. Factory nonce unchanged. | ✅ Completed | | `test_bal_selfdestruct_in_static_context` | SELFDESTRUCT in static context: beneficiary NOT in BAL | Parametrized: `beneficiary_is_warm` (cold/warm via access list), `caller_balance` (0/100). Static check must fire before beneficiary access or balance transfer. | `beneficiary` **MUST NOT** appear in BAL. Balances unchanged. | ✅ Completed | diff --git a/tests/byzantium/eip214_staticcall/test_staticcall.py b/tests/byzantium/eip214_staticcall/test_staticcall.py index b408d7817a3..5c0999a6fc5 100644 --- a/tests/byzantium/eip214_staticcall/test_staticcall.py +++ b/tests/byzantium/eip214_staticcall/test_staticcall.py @@ -152,7 +152,7 @@ def test_staticcall_reentrant_call_to_precompile( ) bal_expectation = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): # Target contract always receives tx value target_balance_changes = [ BalBalanceChange( @@ -255,7 +255,7 @@ def test_staticcall_call_to_precompile( staticcall_result = 1 if call_value == 0 else 0 bal_expectation = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): contract_a_balance_changes = [ BalBalanceChange( block_access_index=1, @@ -393,7 +393,7 @@ def test_staticcall_nested_call_to_precompile( staticcall_result = 1 if call_value == 0 else 0 bal_expectation = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): # slot 1 read when call_value > 0 account_expectations: dict[Address, BalAccountExpectation | None] = { contract_a: ( @@ -554,7 +554,7 @@ def test_staticcall_call_to_precompile_from_contract_init( staticcall_result = 1 if call_value == 0 else 0 bal_expectation = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): # stores created_contract in slot 1, receives tx value account_expectations: dict[Address, BalAccountExpectation | None] = { contract_a: BalAccountExpectation( diff --git a/tests/cancun/create/test_create_oog_from_eoa_refunds.py b/tests/cancun/create/test_create_oog_from_eoa_refunds.py index 050f54c91e0..179efb0f22d 100644 --- a/tests/cancun/create/test_create_oog_from_eoa_refunds.py +++ b/tests/cancun/create/test_create_oog_from_eoa_refunds.py @@ -345,7 +345,7 @@ def test_create_oog_from_eoa_refunds( ) bal_expectation = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): if oog_scenario == OogScenario.NO_OOG: # Success: storage write to slot 0 persists expected_nonce = ( diff --git a/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py b/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py index 634bfac8222..4892d1dfe11 100644 --- a/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py +++ b/tests/cancun/eip6780_selfdestruct/test_selfdestruct_revert.py @@ -437,7 +437,7 @@ def test_selfdestruct_created_in_same_tx_with_revert( # noqa SC200 ) expected_block_access_list = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): account_expectations = {} if selfdestruct_on_outer_call > 0: diff --git a/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py b/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py index 198045b3e3d..c44e26616d2 100644 --- a/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py +++ b/tests/frontier/opcodes/test_call_and_callcode_gas_calculation.py @@ -230,7 +230,7 @@ def expected_block_access_list( gas_shortage: int, ) -> None | BlockAccessListExpectation: """The expected block access list for >=Amsterdam cases.""" - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): if callee_opcode == Op.CALL: if gas_shortage: # call runs OOG after state access due to `is_account_alive` in diff --git a/tests/frontier/validation/test_header.py b/tests/frontier/validation/test_header.py index 0ab911f719d..f53ef2e43be 100644 --- a/tests/frontier/validation/test_header.py +++ b/tests/frontier/validation/test_header.py @@ -47,7 +47,7 @@ def test_gas_limit_below_minimum( if gas_limit < 5000: block.rlp_modifier = Header(**modified_fields) block.exception = BlockException.INVALID_GASLIMIT - elif fork.header_bal_hash_required(): + elif fork.is_eip_enabled(7928): block.exception = BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED blockchain_test(pre=pre, post={}, blocks=[block], genesis_environment=env) diff --git a/tests/paris/eip7610_create_collision/test_initcollision.py b/tests/paris/eip7610_create_collision/test_initcollision.py index 8b54cf775eb..e7f4fe032fd 100644 --- a/tests/paris/eip7610_create_collision/test_initcollision.py +++ b/tests/paris/eip7610_create_collision/test_initcollision.py @@ -95,7 +95,7 @@ def test_init_collision_create_tx( ) expected_block_access_list = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): expected_block_access_list = BlockAccessListExpectation( account_expectations={ created_contract_address: BalAccountExpectation.empty() diff --git a/tests/prague/eip7702_set_code_tx/test_gas.py b/tests/prague/eip7702_set_code_tx/test_gas.py index 7aea82b335a..0f594171faf 100644 --- a/tests/prague/eip7702_set_code_tx/test_gas.py +++ b/tests/prague/eip7702_set_code_tx/test_gas.py @@ -1263,7 +1263,7 @@ def test_call_to_pre_authorized_oog( ) expected_block_access_list = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): # Sender nonce changes, callee is accessed but storage unchanged (OOG) # auth_signer is tracked (we read its code to check delegation) # delegation is NOT tracked (OOG before reading it) 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 fe48936c1d5..0a08b2cbfb9 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 @@ -17,7 +17,13 @@ Address, Alloc, AuthorizationTuple, + BalAccountExpectation, + BalCodeChange, + BalNonceChange, + BalStorageChange, + BalStorageSlot, Block, + BlockAccessListExpectation, BlockchainTestFiller, Bytecode, Bytes, @@ -1130,22 +1136,17 @@ def test_call_into_self_delegating_set_code( state_test: StateTestFiller, pre: Alloc, call_opcode: Op, + fork: Fork, ) -> None: """Test call into a set-code account that delegates to itself.""" auth_signer = pre.fund_eoa(auth_account_start_balance) storage = Storage() + return_slot = storage.store_next( + call_return_code(opcode=call_opcode, success=False) + ) entry_code = ( - Op.SSTORE( - storage.store_next( - call_return_code( - opcode=call_opcode, - success=False, - ) - ), - call_opcode(address=auth_signer), - ) - + Op.STOP + Op.SSTORE(return_slot, call_opcode(address=auth_signer)) + Op.STOP ) entry_address = pre.deploy_contract(entry_code) @@ -1163,6 +1164,36 @@ def test_call_into_self_delegating_set_code( sender=pre.fund_eoa(), ) + expected_block_access_list = None + if fork.is_eip_enabled(7928): + # Degenerate one-hop: auth_signer's delegation target IS itself. + # CALL(auth_signer) resolves once, runs the 0xef0100... designator + # as bytecode -> INVALID -> returns 0. SSTORE(slot, 0) is no-op. + expected_block_access_list = BlockAccessListExpectation( + account_expectations={ + tx.sender: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + entry_address: BalAccountExpectation( + storage_changes=[], + storage_reads=[return_slot], + ), + auth_signer: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec.delegation_designation(auth_signer), + ) + ], + ), + } + ) + state_test( env=Environment(), pre=pre, @@ -1173,6 +1204,7 @@ def test_call_into_self_delegating_set_code( nonce=1, code=Spec.delegation_designation(auth_signer) ), }, + expected_block_access_list=expected_block_access_list, ) @@ -1181,6 +1213,7 @@ def test_call_into_chain_delegating_set_code( state_test: StateTestFiller, pre: Alloc, call_opcode: Op, + fork: Fork, ) -> None: """ Test call into a set-code account that delegates to another set-code @@ -1190,14 +1223,15 @@ def test_call_into_chain_delegating_set_code( auth_signer_2 = pre.fund_eoa(auth_account_start_balance) storage = Storage() + return_slot = storage.store_next( + call_return_code( + opcode=call_opcode, + success=False, + ) + ) entry_code = ( Op.SSTORE( - storage.store_next( - call_return_code( - opcode=call_opcode, - success=False, - ) - ), + return_slot, call_opcode(address=auth_signer_1), ) + Op.STOP @@ -1223,6 +1257,51 @@ def test_call_into_chain_delegating_set_code( sender=pre.fund_eoa(), ) + expected_block_access_list = None + if fork.is_eip_enabled(7928): + # One-hop delegation resolution: CALL(A) resolves A->B once; B's + # 0xef0100... bytecode aborts as INVALID. CALL returns 0, so + # SSTORE(slot, 0) is a no-op write and is demoted to storage_reads. + expected_block_access_list = BlockAccessListExpectation( + account_expectations={ + tx.sender: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + entry_address: BalAccountExpectation( + storage_changes=[], + storage_reads=[return_slot], + ), + auth_signer_1: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec.delegation_designation( + auth_signer_2 + ), + ) + ], + ), + auth_signer_2: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec.delegation_designation( + auth_signer_1 + ), + ) + ], + ), + } + ) + state_test( env=Environment(), pre=pre, @@ -1236,6 +1315,7 @@ def test_call_into_chain_delegating_set_code( nonce=1, code=Spec.delegation_designation(auth_signer_1) ), }, + expected_block_access_list=expected_block_access_list, ) @@ -2465,6 +2545,7 @@ def test_signature_s_out_of_range( state_test: StateTestFiller, pre: Alloc, chain_config: ChainConfig, + fork: Fork, ) -> None: """ Test sending a transaction with an authorization tuple where the signature @@ -2500,6 +2581,33 @@ def test_signature_s_out_of_range( sender=pre.fund_eoa(), ) + expected_block_access_list = None + if fork.is_eip_enabled(7928): + # High-s rejected pre-load -> authority not in BAL (EIP-7928). + expected_block_access_list = BlockAccessListExpectation( + account_expectations={ + tx.sender: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + entry_address: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=success_slot, + slot_changes=[ + BalStorageChange( + block_access_index=1, post_value=1 + ) + ], + ) + ], + ), + auth_signer: None, + set_code_to_address: None, + } + ) + state_test( env=Environment(), pre=pre, @@ -2510,6 +2618,7 @@ def test_signature_s_out_of_range( storage={success_slot: 1}, ), }, + expected_block_access_list=expected_block_access_list, ) @@ -2636,6 +2745,7 @@ def test_nonce_validity( pre: Alloc, account_nonce: int, authorization_nonce: int, + fork: Fork, ) -> None: """ Test sending a transaction where the nonce field of an authorization almost @@ -2677,6 +2787,83 @@ def test_nonce_validity( sender=pre.fund_eoa(), ) + expected_block_access_list = None + if fork.is_eip_enabled(7928): + # Invalid auth -> CALL(auth_signer) returns 0; SSTORE(return_slot, 0) + # is a no-op write and is demoted to storage_reads per EIP-7928. + if valid_authorization: + entry_expectation = BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=success_slot, + slot_changes=[ + BalStorageChange( + block_access_index=1, post_value=1 + ) + ], + ), + BalStorageSlot( + slot=return_slot, + slot_changes=[ + BalStorageChange( + block_access_index=1, post_value=1 + ) + ], + ), + ], + ) + auth_signer_expectation: BalAccountExpectation | None = ( + BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=1, + post_nonce=account_nonce + 1, + ) + ], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec.delegation_designation( + set_code_to_address + ), + ) + ], + ) + ) + set_code_target_expectation: BalAccountExpectation | None = ( + BalAccountExpectation.empty() + ) + else: + entry_expectation = BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=success_slot, + slot_changes=[ + BalStorageChange( + block_access_index=1, post_value=1 + ) + ], + ), + ], + storage_reads=[return_slot], + ) + # Auth failed; subsequent CALL still touches the signer. + auth_signer_expectation = BalAccountExpectation.empty() + set_code_target_expectation = None + + expected_block_access_list = BlockAccessListExpectation( + account_expectations={ + tx.sender: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + entry_address: entry_expectation, + auth_signer: auth_signer_expectation, + set_code_to_address: set_code_target_expectation, + } + ) + state_test( env=Environment(), pre=pre, @@ -2699,6 +2886,7 @@ def test_nonce_validity( }, ), }, + expected_block_access_list=expected_block_access_list, ) @@ -2843,6 +3031,7 @@ def test_set_code_to_precompile( pre: Alloc, precompile: int, call_opcode: Op, + fork: Fork, ) -> None: """ Test setting the code of an account to a pre-compile address and executing @@ -2882,6 +3071,31 @@ def test_set_code_to_precompile( ], ) + expected_block_access_list = None + if fork.is_eip_enabled(7928): + # Precompile is loaded as execution target via delegation dispatch + # for all 4 call opcodes. For DELEGATECALL/CALLCODE the precompile + # provides the code but is not the call target, so its access has + # to be recorded explicitly. + expected_block_access_list = BlockAccessListExpectation( + account_expectations={ + auth_signer: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec.delegation_designation( + Address(precompile) + ), + ) + ], + ), + Address(precompile): BalAccountExpectation.empty(), + } + ) + state_test( env=Environment(), pre=pre, @@ -2895,6 +3109,7 @@ def test_set_code_to_precompile( storage=caller_code_storage, ), }, + expected_block_access_list=expected_block_access_list, ) diff --git a/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py b/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py index c81aff2a27b..49cc095d44c 100644 --- a/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py +++ b/tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py @@ -145,7 +145,7 @@ def build_bal_expectations( beneficiary_in_bal: bool, ) -> BlockAccessListExpectation | None: """Build BAL expectations for >=Amsterdam.""" - if not fork.header_bal_hash_required(): + if not fork.is_eip_enabled(7928): return None victim_code = Op.SELFDESTRUCT(beneficiary) @@ -830,7 +830,7 @@ def test_selfdestruct_to_system_contract( # Build minimal BAL expectations for test-specific accounts only expected_bal: BlockAccessListExpectation | None = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): account_expectations: Dict[Address, BalAccountExpectation | None] = { alice: BalAccountExpectation( nonce_changes=[ @@ -1006,7 +1006,7 @@ def test_selfdestruct_to_self( # Build BAL expectations expected_bal: BlockAccessListExpectation | None = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): if same_tx: if is_success: # Created and destroyed in same tx - no net changes for victim @@ -1160,7 +1160,7 @@ def test_initcode_selfdestruct_to_self( # Build BAL expectations expected_bal: BlockAccessListExpectation | None = None - if fork.header_bal_hash_required(): + if fork.is_eip_enabled(7928): # Contract created and immediately destroyed - no net changes # for victim caller_expectation = BalAccountExpectation( @@ -1195,3 +1195,99 @@ def test_initcode_selfdestruct_to_self( blocks=[Block(txs=[tx], expected_block_access_list=expected_bal)], post=post, ) + + +@pytest.mark.parametrize( + "originator_balance", + [0, 100], + ids=["no_balance", "has_balance"], +) +@pytest.mark.valid_from("TangerineWhistle") +def test_selfdestruct_send_to_sender( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + fork: Fork, + originator_balance: int, +) -> None: + """ + SELFDESTRUCT on pre-existing contract where beneficiary is tx.sender. + + Alice calls victim directly; victim runs `SELFDESTRUCT(CALLER)`. The + beneficiary coincides with tx.sender, so alice's BAL entry coalesces + `nonce_changes` (as sender) with `balance_changes` (as beneficiary). + Pre-Cancun: victim destroyed. >=Cancun: victim preserved with balance 0 + (EIP-6780 — victim was not created same-tx). + """ + alice_initial_balance = 10**18 + alice = pre.fund_eoa(amount=alice_initial_balance) + victim_code = Op.SELFDESTRUCT( + Op.CALLER, address_warm=True, account_new=False + ) + victim = pre.deploy_contract(code=victim_code, balance=originator_balance) + + gas_price = 0xA + gas_limit = 100_000 + tx = Transaction( + sender=alice, + to=victim, + gas_limit=gas_limit, + gas_price=gas_price, + protected=fork.supports_protected_txs(), + ) + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=b"", contract_creation=False + ) + execution_gas = victim_code.gas_cost(fork) + alice_final_balance = ( + alice_initial_balance + + originator_balance + - (intrinsic_gas + execution_gas) * gas_price + ) + + expected_bal: BlockAccessListExpectation | None = None + if fork.is_eip_enabled(7928): + alice_expectation = BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=alice_final_balance + ) + ], + ) + if originator_balance > 0: + victim_expectation = BalAccountExpectation( + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0) + ], + code_changes=[], + nonce_changes=[], + storage_changes=[], + storage_reads=[], + ) + else: + victim_expectation = BalAccountExpectation.empty() + expected_bal = BlockAccessListExpectation( + account_expectations={ + alice: alice_expectation, + victim: victim_expectation, + } + ) + + contract_destroyed = fork < Cancun + if contract_destroyed: + post: Dict[Address | EOA, Account | object] = { + alice: Account(nonce=1), + victim: Account.NONEXISTENT, + } + else: + post = { + alice: Account(nonce=1), + victim: Account(balance=0, code=victim_code), + } + + blockchain_test( + pre=pre, + blocks=[Block(txs=[tx], expected_block_access_list=expected_bal)], + post=post, + ) From 5c6cec742e4cae8614fc23541f0b6b9c767b50c2 Mon Sep 17 00:00:00 2001 From: Stefan <22667037+qu0b@users.noreply.github.com> Date: Wed, 13 May 2026 16:34:45 +0200 Subject: [PATCH 072/186] Update besu repo reference from hyperledger/besu to besu-eth/besu (#2488) --- .github/actions/build-evm-client/besu/action.yaml | 2 +- docs/filling_tests/transition_tool_support.md | 2 +- .../plugins/consume/tests/release_information.json | 2 +- src/ethereum/forks/arrow_glacier/__init__.py | 2 +- src/ethereum/forks/berlin/__init__.py | 2 +- src/ethereum/forks/cancun/__init__.py | 2 +- src/ethereum/forks/gray_glacier/__init__.py | 2 +- src/ethereum/forks/istanbul/__init__.py | 2 +- src/ethereum/forks/london/__init__.py | 2 +- src/ethereum/forks/muir_glacier/__init__.py | 2 +- src/ethereum/forks/paris/__init__.py | 2 +- src/ethereum/forks/shanghai/__init__.py | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/actions/build-evm-client/besu/action.yaml b/.github/actions/build-evm-client/besu/action.yaml index 99099eb9d9a..fdbbd4d0fe9 100644 --- a/.github/actions/build-evm-client/besu/action.yaml +++ b/.github/actions/build-evm-client/besu/action.yaml @@ -4,7 +4,7 @@ inputs: repo: description: 'Source repository to use to build the EVM binary' required: true - default: 'hyperledger/besu' + default: 'besu-eth/besu' ref: description: 'Reference to branch, commit, or tag to use to build the EVM binary' required: true diff --git a/docs/filling_tests/transition_tool_support.md b/docs/filling_tests/transition_tool_support.md index 6049c37b436..f151f05a7d6 100644 --- a/docs/filling_tests/transition_tool_support.md +++ b/docs/filling_tests/transition_tool_support.md @@ -8,5 +8,5 @@ The following transition tools are supported by the framework: | [ethereum/execution-specs](https://github.com/ethereum/execution-specs) | [`ethereum-spec-evm t8n`](https://github.com/ethereum/execution-specs/tree/a48e0b381d5225a6c3de2d06cd9ee7ae0b6ca9bb/src/ethereum_spec_tools/evm_tools/t8n) | Yes | | [ethereumjs](https://github.com/ethereumjs/ethereumjs-monorepo) | [`ethereumjs-t8ntool.sh`](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/vm/test/t8n) | No | | [ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) | [`evm t8n`](https://github.com/ethereum/go-ethereum/tree/master/cmd/evm) | Yes | -| [hyperledger/besu](https://github.com/hyperledger/besu/tree/main/ethereum/evmtool) | [`evmtool t8n-server`](https://github.com/hyperledger/besu/tree/main/ethereum/evmtool) | Yes | +| [besu-eth/besu](https://github.com/besu-eth/besu/tree/main/ethereum/evmtool) | [`evmtool t8n-server`](https://github.com/besu-eth/besu/tree/main/ethereum/evmtool) | Yes | | [status-im/nimbus-eth1](https://github.com/status-im/nimbus-eth1) | [`t8n`](https://github.com/status-im/nimbus-eth1/blob/master/tools/t8n/readme.md) | Yes | diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/release_information.json b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/release_information.json index 89bf18fe6e4..8223f696ee8 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/release_information.json +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/release_information.json @@ -1341,7 +1341,7 @@ ], "tarball_url": "https://api.github.com/repos/ethereum/execution-spec-tests/tarball/eip7692@v1.1.1", "zipball_url": "https://api.github.com/repos/ethereum/execution-spec-tests/zipball/eip7692@v1.1.1", - "body": "Filled using Besu commit https://github.com/hyperledger/besu/commit/0d6395515890280c29ee2402c03b1ee81bde3bab\r\n\r\n## What's Changed\r\n* new(tests): EOF - EIP-7620 EOFCREATE gas testing by @pdobacz in https://github.com/ethereum/execution-spec-tests/pull/785\r\n\r\n**Full Changelog**: https://github.com/ethereum/execution-spec-tests/compare/eip7692@v1.1.0...eip7692@v1.1.1", + "body": "Filled using Besu commit https://github.com/besu-eth/besu/commit/0d6395515890280c29ee2402c03b1ee81bde3bab\r\n\r\n## What's Changed\r\n* new(tests): EOF - EIP-7620 EOFCREATE gas testing by @pdobacz in https://github.com/ethereum/execution-spec-tests/pull/785\r\n\r\n**Full Changelog**: https://github.com/ethereum/execution-spec-tests/compare/eip7692@v1.1.0...eip7692@v1.1.1", "mentions_count": 1 }, { diff --git a/src/ethereum/forks/arrow_glacier/__init__.py b/src/ethereum/forks/arrow_glacier/__init__.py index 6e8798e713e..b8210ed2894 100644 --- a/src/ethereum/forks/arrow_glacier/__init__.py +++ b/src/ethereum/forks/arrow_glacier/__init__.py @@ -21,7 +21,7 @@ - [Nethermind 1.11.7][nm] [EIP-4345]: https://eips.ethereum.org/EIPS/eip-4345 -[Besu 21.10.0]: https://github.com/hyperledger/besu/releases/tag/21.10.0 +[Besu 21.10.0]: https://github.com/besu-eth/besu/releases/tag/21.10.0 [e]: https://github.com/ledgerwatch/erigon/releases/tag/v2021.11.01 [js]: https://github.com/ethereumjs/ethereumjs-monorepo/releases/tag/%40ethereumjs%2Fvm%405.6.0 [Geth 1.10.12]: https://github.com/ethereum/go-ethereum/releases/tag/v1.10.12 diff --git a/src/ethereum/forks/berlin/__init__.py b/src/ethereum/forks/berlin/__init__.py index 3bc09c7878a..52bee472924 100644 --- a/src/ethereum/forks/berlin/__init__.py +++ b/src/ethereum/forks/berlin/__init__.py @@ -31,7 +31,7 @@ [EIP-2929]: https://eips.ethereum.org/EIPS/eip-2929 [EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 [EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 -[Besu 21.1.2]: https://github.com/hyperledger/besu/releases/tag/21.1.2 +[Besu 21.1.2]: https://github.com/besu-eth/besu/releases/tag/21.1.2 [js]: https://github.com/ethereumjs/ethereumjs-monorepo/releases/tag/%40ethereumjs%2Fvm%405.2.0 [Geth 1.10.1]: https://github.com/ethereum/go-ethereum/releases/tag/v1.10.1 [n]: https://github.com/NethermindEth/nethermind/releases/tag/1.10.58 diff --git a/src/ethereum/forks/cancun/__init__.py b/src/ethereum/forks/cancun/__init__.py index fe0e897ee01..ec03abf7d41 100644 --- a/src/ethereum/forks/cancun/__init__.py +++ b/src/ethereum/forks/cancun/__init__.py @@ -37,7 +37,7 @@ [EIP-5656]: https://eips.ethereum.org/EIPS/eip-5656 [EIP-6780]: https://eips.ethereum.org/EIPS/eip-6780 [EIP-7516]: https://eips.ethereum.org/EIPS/eip-7516 -[Besu 24.1.2]: https://github.com/hyperledger/besu/releases/tag/24.1.2 +[Besu 24.1.2]: https://github.com/besu-eth/besu/releases/tag/24.1.2 [e]: https://github.com/ledgerwatch/erigon/releases/tag/v2.58.1 [Geth 1.13.13]: https://github.com/ethereum/go-ethereum/releases/tag/v1.13.13 [n]: https://github.com/NethermindEth/nethermind/releases/tag/1.25.4 diff --git a/src/ethereum/forks/gray_glacier/__init__.py b/src/ethereum/forks/gray_glacier/__init__.py index c16a952fb9b..36432ca55b3 100644 --- a/src/ethereum/forks/gray_glacier/__init__.py +++ b/src/ethereum/forks/gray_glacier/__init__.py @@ -23,7 +23,7 @@ [EIP-5133]: https://eips.ethereum.org/EIPS/eip-5133 [Geth 1.10.19]: https://github.com/ethereum/go-ethereum/releases/tag/v1.10.19 -[Besu 22.4.3]: https://github.com/hyperledger/besu/releases/tag/22.4.3 +[Besu 22.4.3]: https://github.com/besu-eth/besu/releases/tag/22.4.3 [e]: https://github.com/ledgerwatch/erigon/releases/tag/v2022.06.03 [js]: https://github.com/ethereumjs/ethereumjs-monorepo/releases/tag/@ethereumjs/vm@5.9.3 [n]: https://github.com/NethermindEth/nethermind/releases/tag/1.13.3 diff --git a/src/ethereum/forks/istanbul/__init__.py b/src/ethereum/forks/istanbul/__init__.py index 1b4f3b61532..f42251a66fb 100644 --- a/src/ethereum/forks/istanbul/__init__.py +++ b/src/ethereum/forks/istanbul/__init__.py @@ -40,7 +40,7 @@ [EIP-2028]: https://eips.ethereum.org/EIPS/eip-2028 [EIP-2200]: https://eips.ethereum.org/EIPS/eip-2200 [a]: https://github.com/ethereum/aleth/releases/tag/v1.7.1 -[Besu 1.3.6]: https://github.com/hyperledger/besu/releases/tag/1.3.6 +[Besu 1.3.6]: https://github.com/besu-eth/besu/releases/tag/1.3.6 [js]: https://github.com/ethereumjs/ethereumjs-blockchain/releases/tag/v4.0.2 [Geth 1.9.9]: https://github.com/ethereum/go-ethereum/releases/tag/v1.9.9 [n]: https://github.com/NethermindEth/nethermind/releases/tag/1.2.3 diff --git a/src/ethereum/forks/london/__init__.py b/src/ethereum/forks/london/__init__.py index 95caf15ed4c..c13617d1c49 100644 --- a/src/ethereum/forks/london/__init__.py +++ b/src/ethereum/forks/london/__init__.py @@ -35,7 +35,7 @@ [EIP-3529]: https://eips.ethereum.org/EIPS/eip-3529 [EIP-3541]: https://eips.ethereum.org/EIPS/eip-3541 [EIP-3554]: https://eips.ethereum.org/EIPS/eip-3554 -[Besu 21.7.2]: https://github.com/hyperledger/besu/releases/tag/21.7.2 +[Besu 21.7.2]: https://github.com/besu-eth/besu/releases/tag/21.7.2 [e]: https://github.com/ledgerwatch/erigon/releases/tag/v2021.07.04 [js]: https://github.com/ethereumjs/ethereumjs-monorepo/releases/tag/%40ethereumjs%2Fvm%405.5.0 [Geth 1.10.6]: https://github.com/ethereum/go-ethereum/releases/tag/v1.10.6 diff --git a/src/ethereum/forks/muir_glacier/__init__.py b/src/ethereum/forks/muir_glacier/__init__.py index a722576f950..5a53311245d 100644 --- a/src/ethereum/forks/muir_glacier/__init__.py +++ b/src/ethereum/forks/muir_glacier/__init__.py @@ -26,7 +26,7 @@ [EIP-2384]: https://eips.ethereum.org/EIPS/eip-2384 [Geth 1.9.9]: https://github.com/ethereum/go-ethereum/releases/tag/v1.9.9 [p]: https://github.com/paritytech/parity-ethereum/releases/tag/v2.6.8 -[Besu 1.3.7]: https://github.com/hyperledger/besu/releases/tag/1.3.7 +[Besu 1.3.7]: https://github.com/besu-eth/besu/releases/tag/1.3.7 [n]: https://github.com/NethermindEth/nethermind/releases/tag/1.2.6 [js]: https://github.com/ethereumjs/ethereumjs-vm/releases/tag/v4.1.2 [a]: https://github.com/ethereum/aleth/releases/tag/v1.8.0 diff --git a/src/ethereum/forks/paris/__init__.py b/src/ethereum/forks/paris/__init__.py index 9e1f07470d7..788625171cc 100644 --- a/src/ethereum/forks/paris/__init__.py +++ b/src/ethereum/forks/paris/__init__.py @@ -28,7 +28,7 @@ [consensus layer]: https://github.com/ethereum/consensus-specs [EIP-3675]: https://eips.ethereum.org/EIPS/eip-3675 [EIP-4399]: https://eips.ethereum.org/EIPS/eip-4399 -[Besu 22.7.2]: https://github.com/hyperledger/besu/releases/tag/22.7.2 +[Besu 22.7.2]: https://github.com/besu-eth/besu/releases/tag/22.7.2 [e]: https://github.com/ledgerwatch/erigon/releases/tag/v2022.09.01 [Geth 1.10.23]: https://github.com/ethereum/go-ethereum/releases/tag/v1.10.23 [nm]: https://github.com/NethermindEth/nethermind/releases/tag/1.14.1 diff --git a/src/ethereum/forks/shanghai/__init__.py b/src/ethereum/forks/shanghai/__init__.py index d231ca9648d..63b04b7062d 100644 --- a/src/ethereum/forks/shanghai/__init__.py +++ b/src/ethereum/forks/shanghai/__init__.py @@ -36,7 +36,7 @@ [EIP-3860]: https://eips.ethereum.org/EIPS/eip-3860 [EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 [Geth 1.11.5]: https://github.com/ethereum/go-ethereum/releases/tag/v1.11.5 -[Besu 23.1.2]: https://github.com/hyperledger/besu/releases/tag/23.1.2 +[Besu 23.1.2]: https://github.com/besu-eth/besu/releases/tag/23.1.2 [n]: https://github.com/NethermindEth/nethermind/releases/tag/1.17.3 [e]: https://github.com/ledgerwatch/erigon/releases/tag/v2.41.0 [js]: https://github.com/ethereumjs/ethereumjs-monorepo/releases/tag/%40ethereumjs%2Fvm%406.4.0 From 2037311529b307e7029004f26dd3471eec364fcd Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 13 May 2026 13:47:26 -0400 Subject: [PATCH 073/186] feat(spec-specs, spec-tests): add EIP-7708 ETH transfers emit a log (#2844) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(spec-specs): Add transfer log for all `CALL*` and `SELFDESTRUCT` fix(spec-specs): correct CR issues, fix formatting fix(spec-specs): inline `execute_code()` to `process_message()` chore(spec-specs): backport changes fix(spec-specs): trim out whitespace in topic hash to match tests feat(spec-specs): add selfdestruct event topic and logging function feat(spec-specs): selfdestruct to self emits selfdestruct event feat(spec-specs): define call success constant feat(spec-specs): emit selfdestruct finalization log for remaining balance * fix(spec-specs): emit account closure logs in lexicographical order * feat(test-tests): add eip-7708 eth transfer log tests test(test-tests): add selfdestruct topic and use empty account test(test-tests): add nested calls log ordering test feat(test-tests): add selfdestruct finalization test fix(test-tests): use spaces in event signature to match spec * fix(spec-specs): Refactor topic strings to match EIP * fix(spec-tests): formatting fixes so static checks pass * fix(spec-specs): Move account closure log emission before priority fee charges (#2059) * fix(spec-specs): Move account closure log emission before priority fee charges * fix(spec-specs): formatting and spelling tweaks * fix(spec-specs): remove duplicate WriteInStaticContext check * refactor(spec-specs): align memory expansion with other opcodes * fix(testing/test): Fix unit test expectation * refactor(spec-specs): move post-mining coinbase balance calculation --------- Co-authored-by: Mario Vega * feat(test-specs): add extra eip-7708 test coverage (#2062) * feat(test-specs): add/refactor tests, add mainnet marked, checklist, coverage check * feat(test-specs): add fork transition test for selfdestruct logs * fix: tests * chore(test-specs): fix fork transition tests * test(test-specs): add code deposit oog test case --------- Co-authored-by: carsons-eels Co-authored-by: Mario Vega * feat(spec,test): EIP-7708 spec updates for self as target (#2086) * fix(spec,text): Updates to EIP-7708 spec for bal-devnet-2 - fix(spec,test): EIP-7708 emit selfdestruct logs only in same tx - fix(spec,test): EIP-7708, only emit on transfers to other accounts - Add more tests that match these edge cases * feat(test): tests for finalization selfdest + bal transfer in lexicographic order * fix: changes from comments on PR #2086 * add more variants to test_selfdestruct_same_tx_via_call * fix: docstring * refactor: improvements from comments on PR #2086 * Update test to use dynamic addresses --------- Co-authored-by: Mario Vega * feat(test): extend EIP-7708 tests from cases in tracker (#1875) (#2106) - Add CREATE2 support via with_all_create_opcodes marker - Add tests for SELFDESTRUCT to coinbase - revealed a change needed since the last update was made to the EIP that should be included in the currect refspec (miner fees paid before finalization LOG2). * fix(test): Use new ``pre_alloc_mutable`` marker for eip7708 test (#2199) * fix(test): Update test to account for recent Initcode updates * 🧹 chore: Remove duplicate test (#2210) Co-authored-by: raxhvl * ♻️ refactor(tests): Rename EIP 7708 selfdestruct log to burn (#2211) * ♻️ refactor: Rename selfdestruct log to burn * 🥢 nit: * chore(tests): fix stale selfdestruct references and rename to burn --------- Co-authored-by: raxhvl Co-authored-by: spencer-tb * fix(specs): Merge issues * fix(tests): Merge issues * refactor(test-forks): Add EIP-7708 * refactor(tests): Condition EIP-7708 tests to EIP inclusion * feat(tests): EIP-7708 - finalization burn log ordering + coinbase fee no-log (#2717) * feat(tests): EIP-7708 - multi-account finalization burn log ordering Adds a dedicated test that proves finalization burn logs are emitted in lexicographical address order when multiple accounts are marked for deletion in the same transaction. Parametrized over N in {2, 5}. N accounts are created and SELFDESTRUCT'd in the same tx, then funded via payer contracts called in REVERSE sorted address order with distinct nonzero amounts. Each destroyed account ends with a unique nonzero balance at finalization, so ordering by address vs. by call order is always distinguishable. Addresses issue #2691. * feat(tests): EIP-7708 - coinbase priority fee must not emit transfer log Adds a dedicated test proving the coinbase priority fee payment does not produce a Transfer log. A contract CALLs the coinbase address with nonzero value while the tx pays a nonzero priority fee to that same coinbase. Only the CALL-with-value must produce a Transfer log; the priority fee credit happens outside the EVM as a protocol-level balance change. An implementation that hooks every balance addition (instead of only CALL / SELFDESTRUCT / tx-level value transfers) would emit an extra Transfer log for the fee and fail the exact-log assertion. Addresses issue #2692. * feat(tests): add single account multi transfer test * fix(tests): minor nit --------- Co-authored-by: marioevz * fix(tests): rename GAS_CODE_DEPOSIT_PER_BYTE to CODE_DEPOSIT_PER_BYTE Align EIP-7708 selfdestruct finalization test with the gas constant rename on forks/amsterdam. * fix(tests): EIP-7708 + 8037 cross-EIP fixes * feat(tests): Add EIP-7708 checks to 6780 tests (#2743) * feat(tests): Add EIP-7708 checks to 6780 tests * fix: add another call and properly accumulate so that burn logs are validated * fix(tests): Review fixes --------- Co-authored-by: carsons-eels * feat(tests): cover EIP-7708 CREATE log rollback on outer revert (#2785) * feat(tests): cover EIP-7708 CREATE log rollback on outer revert Mirror `test_inner_call_succeeds_outer_reverts_no_log` for the bal-devnet-5 update that brings CREATE/CREATE2 under EIP-7708. A factory CREATEs a child with value (the deployment succeeds and a `factory -> created` log is emitted in the child frame) and then REVERTs; the receipt must record no logs because the outer revert discards the factory's frame along with every log it produced. * feat(tests): Review comments --------- Co-authored-by: marioevz * fix(specs-spec, tests): CR comment fixes * Apply suggestion from @marioevz --------- Co-authored-by: spencer-tb Co-authored-by: Mario Vega Co-authored-by: spencer Co-authored-by: felipe Co-authored-by: raxhvl Co-authored-by: raxhvl <10168946+raxhvl@users.noreply.github.com> Co-authored-by: danceratopz --- .../forks/forks/eips/amsterdam/eip_7708.py | 15 + src/ethereum/forks/amsterdam/fork.py | 26 +- src/ethereum/forks/amsterdam/vm/__init__.py | 82 +- .../forks/amsterdam/vm/instructions/system.py | 18 +- .../forks/amsterdam/vm/interpreter.py | 8 +- .../eip7708_eth_transfer_logs/__init__.py | 1 + .../eip_checklist_external_coverage.txt | 3 + .../eip_checklist_not_applicable.txt | 14 + .../eip7708_eth_transfer_logs/spec.py | 61 + .../test_burn_logs.py | 930 ++++++++++ .../test_eip_mainnet.py | 102 ++ .../test_fork_transition.py | 200 +++ .../test_transfer_logs.py | 1533 +++++++++++++++++ .../test_journal_revert.py | 11 + .../test_reentrancy_selfdestruct_revert.py | 89 +- .../eip6780_selfdestruct/test_selfdestruct.py | 427 ++++- 16 files changed, 3472 insertions(+), 48 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7708.py create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/__init__.py create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_external_coverage.txt create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_not_applicable.txt create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/spec.py create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/test_burn_logs.py create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/test_eip_mainnet.py create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/test_fork_transition.py create mode 100644 tests/amsterdam/eip7708_eth_transfer_logs/test_transfer_logs.py diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7708.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7708.py new file mode 100644 index 00000000000..f968d1b6d60 --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7708.py @@ -0,0 +1,15 @@ +""" +EIP-7708: ETH transfers and burns emit a log. + +All ETH transfers and burns emit a log. + +https://eips.ethereum.org/EIPS/eip-7708 +""" + +from ....base_fork import BaseFork + + +class EIP7708(BaseFork): + """EIP-7708 class.""" + + pass diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index 6ab8d8bcd76..bbb1d832193 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -37,6 +37,7 @@ State, apply_changes_to_state, ) +from ethereum.utils.byte import left_pad_zero_bytes from . import vm from .block_access_lists import ( @@ -1055,6 +1056,7 @@ def process_transaction( ) set_account_balance(tx_state, sender, sender_balance_after_refund) + # transfer miner fees coinbase_balance_after_mining_fee = get_account( tx_state, block_env.coinbase ).balance + U256(transaction_fee) @@ -1063,6 +1065,26 @@ def process_transaction( tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) + # EIP-7708: Emit burn logs for balances held by accounts marked for + # deletion AFTER miner fee transfer. + finalization_logs: List[Log] = [] + for address in sorted(tx_output.accounts_to_delete): + balance = get_account(tx_state, address).balance + if balance > U256(0): + padded_address = left_pad_zero_bytes(address, 32) + finalization_logs.append( + Log( + address=vm.SYSTEM_ADDRESS, + topics=( + vm.BURN_TOPIC, + Hash32(padded_address), + ), + data=balance.to_be_bytes32(), + ) + ) + + all_logs = tx_output.logs + tuple(finalization_logs) + if coinbase_balance_after_mining_fee == 0 and account_exists_and_is_empty( tx_state, block_env.coinbase ): @@ -1072,7 +1094,7 @@ def process_transaction( block_output.blob_gas_used += tx_blob_gas_used receipt = make_receipt( - tx, tx_output.error, block_output.block_gas_used, tx_output.logs + tx, tx_output.error, block_output.block_gas_used, all_logs ) receipt_key = rlp.encode(Uint(index)) @@ -1084,7 +1106,7 @@ def process_transaction( receipt, ) - block_output.block_logs += tx_output.logs + block_output.block_logs += all_logs for address in tx_output.accounts_to_delete: destroy_account(tx_state, address) diff --git a/src/ethereum/forks/amsterdam/vm/__init__.py b/src/ethereum/forks/amsterdam/vm/__init__.py index 44135d5e72a..2ae8d4c984c 100644 --- a/src/ethereum/forks/amsterdam/vm/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/__init__.py @@ -18,10 +18,11 @@ from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint -from ethereum.crypto.hash import Hash32 +from ethereum.crypto.hash import Hash32, keccak256 from ethereum.exceptions import EthereumException from ethereum.merkle_patricia_trie import Trie from ethereum.state import Address +from ethereum.utils.byte import left_pad_zero_bytes from ..block_access_lists import BlockAccessList, BlockAccessListBuilder from ..blocks import Log, Receipt, Withdrawal @@ -30,6 +31,12 @@ from ..transactions import LegacyTransaction __all__ = ("Environment", "Evm", "Message") +TRANSFER_TOPIC = keccak256(b"Transfer(address,address,uint256)") +BURN_TOPIC = keccak256(b"Burn(address,uint256)") +SYSTEM_ADDRESS = Address( + bytes.fromhex("fffffffffffffffffffffffffffffffffffffffe") +) +CALL_SUCCESS = U256(1) @dataclass @@ -195,3 +202,76 @@ def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: """ evm.gas_left += child_evm.gas_left + + +def emit_transfer_log( + evm: Evm, + sender: Address, + recipient: Address, + transfer_amount: U256, +) -> None: + """ + Emit a LOG3 for all ETH transfers satisfying EIP-7708. + + Parameters + ---------- + evm : + The state of the ethereum virtual machine + sender : + The account address sending the transfer + recipient : + The account address receiving the transfer + transfer_amount : + The amount of ETH transacted + + """ + if transfer_amount == 0: + return + + padded_sender = left_pad_zero_bytes(sender, 32) + padded_recipient = left_pad_zero_bytes(recipient, 32) + log_entry = Log( + address=SYSTEM_ADDRESS, + topics=( + TRANSFER_TOPIC, + Hash32(padded_sender), + Hash32(padded_recipient), + ), + data=transfer_amount.to_be_bytes32(), + ) + + evm.logs = evm.logs + (log_entry,) + + +def emit_burn_log( + evm: Evm, + account: Address, + amount: U256, +) -> None: + """ + Emit a LOG2 for ETH burn per EIP-7708. + + Parameters + ---------- + evm : + The state of the ethereum virtual machine + account : + The account address whose ETH is being burned + amount : + The amount of ETH being burned + + """ + if amount == 0: + return + + padded_account = left_pad_zero_bytes(account, 32) + log_entry = Log( + address=SYSTEM_ADDRESS, + topics=( + BURN_TOPIC, + Hash32(padded_account), + ), + data=amount.to_be_bytes32(), + ) + + evm.logs = evm.logs + (log_entry,) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/system.py b/src/ethereum/forks/amsterdam/vm/instructions/system.py index 42a4643f9c0..b5d0c9c3990 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/system.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/system.py @@ -36,8 +36,11 @@ calculate_delegation_cost, ) from .. import ( + CALL_SUCCESS, Evm, Message, + emit_burn_log, + emit_transfer_log, incorporate_child_on_error, incorporate_child_on_success, ) @@ -338,7 +341,7 @@ def generic_call( else: incorporate_child_on_success(evm, child_evm) evm.return_data = child_evm.output - push(evm.stack, U256(1)) + push(evm.stack, CALL_SUCCESS) actual_output_size = min(memory_output_size, U256(len(child_evm.output))) memory_write( @@ -428,6 +431,7 @@ def call(evm: Evm) -> None: ) charge_gas(evm, message_call_gas.cost + extend_memory.cost) + # OPERATION evm.memory += b"\x00" * extend_memory.expand_by sender_balance = get_account(tx_state, evm.message.current_target).balance if sender_balance < value: @@ -606,11 +610,15 @@ def selfdestruct(evm: Evm) -> None: # Transfer balance move_ether(tx_state, originator, beneficiary, originator_balance) - # register account for deletion only if it was created - # in the same transaction + # Emit transfer or burn log + if originator in tx_state.created_accounts and beneficiary == originator: + emit_burn_log(evm, originator, originator_balance) + elif beneficiary != originator: + emit_transfer_log(evm, originator, beneficiary, originator_balance) + + # Register account for deletion iff created in same transaction if originator in tx_state.created_accounts: - # If beneficiary is the same as originator, then - # the ether is burnt. + # If beneficiary and originator are the same then the ether is burnt. set_account_balance(tx_state, originator, U256(0)) evm.accounts_to_delete.add(originator) diff --git a/src/ethereum/forks/amsterdam/vm/interpreter.py b/src/ethereum/forks/amsterdam/vm/interpreter.py index 80b30bd7ab2..522411b5018 100644 --- a/src/ethereum/forks/amsterdam/vm/interpreter.py +++ b/src/ethereum/forks/amsterdam/vm/interpreter.py @@ -48,7 +48,7 @@ from ..vm.eoa_delegation import get_delegated_code_address, set_delegation from ..vm.gas import GasCosts, charge_gas from ..vm.precompiled_contracts.mapping import PRE_COMPILED_CONTRACTS -from . import Evm +from . import Evm, emit_transfer_log from .exceptions import ( AddressCollision, ExceptionalHalt, @@ -262,7 +262,6 @@ def process_message(message: Message) -> Evm: accessed_storage_keys=message.accessed_storage_keys, ) - # take snapshot of state before processing the message snapshot = copy_tx_state(tx_state) if message.should_transfer_value and message.value != 0: @@ -272,7 +271,12 @@ def process_message(message: Message) -> Evm: message.current_target, message.value, ) + if message.caller != message.current_target: + emit_transfer_log( + evm, message.caller, message.current_target, message.value + ) + # Execute message code and handle errors try: if evm.message.code_address in PRE_COMPILED_CONTRACTS: if not message.disable_precompiles: diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/__init__.py b/tests/amsterdam/eip7708_eth_transfer_logs/__init__.py new file mode 100644 index 00000000000..2f36477a667 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/__init__.py @@ -0,0 +1 @@ +"""Cross-client EIP-7708 Tests.""" diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_external_coverage.txt b/tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_external_coverage.txt new file mode 100644 index 00000000000..bba1c4cfb18 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_external_coverage.txt @@ -0,0 +1,3 @@ +general/code_coverage/eels = EIP-7708 specific code (emit_transfer_log in vm/__init__.py) has full coverage; check codecov for src/ethereum/forks/amsterdam/vm/__init__.py and src/ethereum/forks/amsterdam/vm/interpreter.py +general/code_coverage/test_coverage = Run with `--cov` flag; 99% coverage on vm/__init__.py, 92% on interpreter.py +general/code_coverage/missed_lines = Missed lines are general VM infrastructure (static context errors, gas accounting, error handling) not related to EIP-7708 diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_not_applicable.txt b/tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_not_applicable.txt new file mode 100644 index 00000000000..48ce20d19f8 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/eip_checklist_not_applicable.txt @@ -0,0 +1,14 @@ +opcode = EIP does not introduce a new opcode +precompile = EIP does not introduce a new precompile +removed_precompile = EIP does not remove a precompile +system_contract = EIP does not introduce a new system contract +transaction_type = EIP does not introduce a new transaction type +block_header_field = EIP does not add any new block header fields +block_body_field = EIP does not add any new block body fields +gas_cost_changes = EIP does not introduce any gas cost changes +gas_refunds_changes = EIP does not introduce any gas refund changes +blob_count_changes = EIP does not introduce any blob count changes +execution_layer_request = EIP does not introduce an execution layer request +new_transaction_validity_constraint = EIP does not introduce a new transaction validity constraint +modified_transaction_validity_constraint = EIP does not introduce a modified transaction validity constraint +block_level_constraint = EIP does not introduce a block-level validation constraint diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/spec.py b/tests/amsterdam/eip7708_eth_transfer_logs/spec.py new file mode 100644 index 00000000000..f95378a6380 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/spec.py @@ -0,0 +1,61 @@ +"""Defines EIP-7708 specification constants and functions.""" + +from dataclasses import dataclass + +from execution_testing import Address, Bytes, Hash, TransactionLog, keccak256 + + +@dataclass(frozen=True) +class ReferenceSpec: + """Defines the reference spec version and git path.""" + + git_path: str + version: str + + +ref_spec_7708 = ReferenceSpec( + "EIPS/eip-7708.md", "43a7f15cd1105f308086bed6a61e3155039271fc" +) + + +@dataclass(frozen=True) +class Spec: + """ + Parameters from the EIP-7708 specifications as defined at + https://eips.ethereum.org/EIPS/eip-7708. + """ + + SYSTEM_ADDRESS: Address = Address( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + ) + TRANSFER_TOPIC: Hash = Hash( + keccak256(b"Transfer(address,address,uint256)") + ) + BURN_TOPIC: Hash = Hash(keccak256(b"Burn(address,uint256)")) + + +def transfer_log( + sender: Address, recipient: Address, amount: int +) -> TransactionLog: + """Create an expected Transfer log for EIP-7708.""" + return TransactionLog( + address=Spec.SYSTEM_ADDRESS, + topics=[ + Spec.TRANSFER_TOPIC, + Hash(bytes(sender).rjust(32, b"\x00")), + Hash(bytes(recipient).rjust(32, b"\x00")), + ], + data=Bytes(amount.to_bytes(32, "big")), + ) + + +def burn_log(contract_address: Address, amount: int | None) -> TransactionLog: + """Create an expected Burn log for EIP-7708.""" + return TransactionLog( + address=Spec.SYSTEM_ADDRESS, + topics=[ + Spec.BURN_TOPIC, + Hash(bytes(contract_address).rjust(32, b"\x00")), + ], + data=Bytes(amount.to_bytes(32, "big")) if amount is not None else None, + ) diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/test_burn_logs.py b/tests/amsterdam/eip7708_eth_transfer_logs/test_burn_logs.py new file mode 100644 index 00000000000..f8f8c5eeeff --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/test_burn_logs.py @@ -0,0 +1,930 @@ +""" +Tests for EIP-7708 Burn logs. + +Tests for the Burn(address,uint256) log emitted when: +- SELFDESTRUCT to self with nonzero balance +- Account created and destroyed in the same transaction +""" + +import pytest +from execution_testing import ( + EOA, + Account, + Address, + Alloc, + Block, + BlockchainTestFiller, + Bytecode, + Conditional, + Environment, + Fork, + Header, + Initcode, + Op, + Opcodes, + StateTestFiller, + Transaction, + TransactionReceipt, + compute_create_address, +) +from execution_testing import ( + Macros as Om, +) + +from .spec import burn_log, ref_spec_7708, transfer_log + +REFERENCE_SPEC_GIT_PATH = ref_spec_7708.git_path +REFERENCE_SPEC_VERSION = ref_spec_7708.version + +pytestmark = pytest.mark.valid_from("EIP7708") + + +def test_selfdestruct_to_self_pre_existing_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test that selfdestruct-to-self emits NO log for pre-existing contracts. + + Burn log only emitted when created and destroyed in same tx. + """ + contract_balance = 2000 + + contract_code = Op.SELFDESTRUCT(Op.ADDRESS) + contract = pre.deploy_contract(contract_code, balance=contract_balance) + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=100_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + # Contract keeps its balance (not destroyed since not created in same tx) + state_test( + env=env, + pre=pre, + post={contract: Account(balance=contract_balance)}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "contract_balance", + [ + pytest.param(2000, id="with_balance"), + pytest.param(0, id="zero_balance"), + ], +) +@pytest.mark.with_all_create_opcodes +def test_selfdestruct_to_self_same_tx( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + contract_balance: int, + create_opcode: Op, +) -> None: + """ + Test selfdestruct-to-self for same-tx created contracts. + + - With balance, Burn log emitted (burns ETH). + - No balance, no logs expected. + """ + initcode = Op.SELFDESTRUCT(Op.ADDRESS) + initcode_bytes = bytes(initcode) + initcode_len = len(initcode_bytes) + + factory_code = Op.MSTORE( + 0, Op.PUSH32(initcode_bytes.rjust(32, b"\x00")) + ) + create_opcode( + value=Op.CALLVALUE, offset=32 - initcode_len, size=initcode_len + ) + + factory = pre.deploy_contract(factory_code) + created_address = compute_create_address( + address=factory, + nonce=1, + salt=0, + initcode=initcode_bytes, + opcode=create_opcode, + ) + + if contract_balance > 0: + expected_logs = [ + transfer_log(sender, factory, contract_balance), + transfer_log(factory, created_address, contract_balance), + burn_log(created_address, contract_balance), + ] + else: + expected_logs = [] + + tx = Transaction( + sender=sender, + to=factory, + value=contract_balance, + gas_limit=200_000, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "contract_balance", + [ + pytest.param(2000, id="with_balance"), + pytest.param(0, id="zero_balance"), + ], +) +@pytest.mark.with_all_create_opcodes +def test_selfdestruct_to_different_address_same_tx( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + contract_balance: int, + create_opcode: Op, +) -> None: + """ + Test same-tx selfdestruct to different address. + + With balance: Transfer log emitted. Zero balance: no logs. + """ + beneficiary = pre.deploy_contract(Op.STOP) + + initcode = Op.SELFDESTRUCT(beneficiary) + initcode_bytes = bytes(initcode) + initcode_len = len(initcode_bytes) + + factory_code = Op.MSTORE( + 0, Op.PUSH32(initcode_bytes.rjust(32, b"\x00")) + ) + create_opcode( + value=Op.CALLVALUE, offset=32 - initcode_len, size=initcode_len + ) + + factory = pre.deploy_contract(factory_code) + created_address = compute_create_address( + address=factory, + nonce=1, + salt=0, + initcode=initcode_bytes, + opcode=create_opcode, + ) + + if contract_balance > 0: + expected_logs = [ + transfer_log(sender, factory, contract_balance), + transfer_log(factory, created_address, contract_balance), + transfer_log(created_address, beneficiary, contract_balance), + ] + post = {beneficiary: Account(balance=contract_balance)} + else: + expected_logs = [] + post = {} + + tx = Transaction( + sender=sender, + to=factory, + value=contract_balance, + gas_limit=200_000, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "to_self", + [ + pytest.param(True, id="to_self"), + pytest.param(False, id="to_other"), + ], +) +@pytest.mark.parametrize( + "call_twice,second_call_value", + [ + pytest.param(True, 1, id="call_twice_with_value"), + pytest.param(True, 0, id="call_twice"), + pytest.param(False, 0, id="call_once"), + ], +) +@pytest.mark.parametrize( + "transfer_during_create", + [ + pytest.param(True, id="transfer_during_create"), + pytest.param(False, id="transfer_during_call"), + ], +) +def test_selfdestruct_same_tx_via_call( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + to_self: bool, + call_twice: bool, + second_call_value: int, + transfer_during_create: bool, +) -> None: + """ + Test selfdestruct via CREATE-then-CALL (not initcode selfdestruct). + + Factory CREATEs contract with runtime code, then CALLs the contract that + was just created to trigger SELFDESTRUCT (depending on + `transfer_during_create`, the value of the contract is transferred during + the CREATE or CALL opcodes). Contract is still in created_accounts. + + Depending on `call_twice`, the contract can be called twice during the + same call frame where it was created. + """ + contract_balance = 2000 + beneficiary = pre.deploy_contract(Op.STOP) + + if to_self: + runtime_code = Op.SELFDESTRUCT(Op.ADDRESS) + else: + runtime_code = Op.SELFDESTRUCT(beneficiary) + + initcode = Initcode(deploy_code=runtime_code) + initcode_len = len(initcode) + + if transfer_during_create: + create_value = contract_balance + first_call_value = 0 + else: + create_value = 0 + first_call_value = contract_balance + + factory_code = ( + Om.MSTORE(initcode, 0) + + Op.SSTORE( + 0, Op.CREATE(value=create_value, offset=0, size=initcode_len) + ) + + Op.SSTORE( + 1, + Op.CALL(gas=100_000, address=Op.SLOAD(0), value=first_call_value), + ) + ) + if call_twice: + factory_code += Op.SSTORE( + 2, + Op.CALL(gas=100_000, address=Op.SLOAD(0), value=second_call_value), + ) + + factory = pre.deploy_contract( + factory_code, balance=contract_balance + second_call_value + ) + created_address = compute_create_address(address=factory, nonce=1) + + factory_storage = { + 0: created_address, + 1: 1, + } + if call_twice: + factory_storage[2] = 1 + + if to_self: + expected_logs = [ + transfer_log(factory, created_address, contract_balance), + burn_log(created_address, contract_balance), + ] + if call_twice and second_call_value > 0: + expected_logs += [ + transfer_log(factory, created_address, second_call_value), + burn_log(created_address, second_call_value), + ] + post = {factory: Account(storage=factory_storage)} + else: + expected_logs = [ + transfer_log(factory, created_address, contract_balance), + transfer_log(created_address, beneficiary, contract_balance), + ] + if call_twice and second_call_value > 0: + expected_logs += [ + transfer_log(factory, created_address, second_call_value), + transfer_log(created_address, beneficiary, second_call_value), + ] + post = { + beneficiary: Account(balance=contract_balance + second_call_value), + factory: Account(storage=factory_storage), + } + + tx = Transaction( + sender=sender, + to=factory, + value=0, + gas_limit=300_000, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "payer_code,eth_transferred", + [ + pytest.param( + Op.SELFDESTRUCT(Op.CALLDATALOAD(0)), + True, + id="via_selfdestruct", + ), + pytest.param( + Op.CALL( + gas=50_000, + address=Op.CALLDATALOAD(0), + value=Op.BALANCE(Op.ADDRESS), + ), + True, + id="via_call", + ), + pytest.param( + Op.CALL( + gas=50_000, + address=Op.CALLDATALOAD(0), + value=Op.BALANCE(Op.ADDRESS), + ) + + Op.REVERT(0, 0), + False, + id="via_call_revert", + ), + ], +) +@pytest.mark.parametrize( + "to_self", + [ + pytest.param(False, id="to_beneficiary"), + pytest.param(True, id="to_self"), + ], +) +def test_finalization_burn_logs( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + payer_code: Bytecode, + eth_transferred: bool, + to_self: bool, +) -> None: + """ + Test Burn logs at finalization for post-selfdestruct balance. + + X contracts (x1, x2, x3) selfdestruct, then receive ETH via payer contracts + (p1, p2, p3). At finalization, X contracts emit Burn logs for their + in lexicographical address order (only if they received ETH). + + When to_self=True, X contracts SELFDESTRUCT to themselves (burning ETH + with LOG2). When to_self=False, X contracts SELFDESTRUCT to a beneficiary + (Transfer LOG3). + """ + beneficiary = pre.deploy_contract(Op.STOP) + + # Pre-compute factory address and created contract addresses + # so we can call them in reverse sorted order to prove finalization + # logs are sorted by address, not by call order + factory_address = compute_create_address( + address=sender, nonce=sender.nonce + ) + x1 = compute_create_address(address=factory_address, nonce=1) + x2 = compute_create_address(address=factory_address, nonce=2) + x3 = compute_create_address(address=factory_address, nonce=3) + + # sort() + call in REVERSE order to prove finalization + # lexicographical sorting + sorted_addrs = sorted([x1, x2, x3]) + reverse_sorted = list(reversed(sorted_addrs)) + + # Runtime: selfdestruct on first call, STOP on subsequent calls + target: Address | Opcodes = Op.ADDRESS if to_self else beneficiary + runtime = Conditional( + condition=Op.ISZERO(Op.TLOAD(0)), + if_true=Op.TSTORE(0, 1) + Op.SELFDESTRUCT(target), + if_false=Op.STOP, + ) + initcode = Initcode(deploy_code=runtime) + initcode_len = len(initcode) + + # Payer contracts (p1, p2, p3) will send ETH to created contracts + p1 = pre.deploy_contract(payer_code, balance=100) + p2 = pre.deploy_contract(payer_code, balance=200) + p3 = pre.deploy_contract(payer_code, balance=300) + + # Call p1/p2/p3 targeting addresses in REVERSE sorted order + # This proves finalization logs are sorted by address, not call order + factory_code = ( + Om.MSTORE(initcode, 0) + # Create x1, x2, x3 + + Op.TSTORE(0, Op.CREATE(value=1000, offset=0, size=initcode_len)) + + Op.TSTORE(1, Op.CREATE(value=2000, offset=0, size=initcode_len)) + + Op.TSTORE(2, Op.CREATE(value=3000, offset=0, size=initcode_len)) + # Call x1, x2, x3 to trigger SELFDESTRUCT + + Op.CALL(gas=100_000, address=Op.TLOAD(0), value=0) + + Op.CALL(gas=100_000, address=Op.TLOAD(1), value=0) + + Op.CALL(gas=100_000, address=Op.TLOAD(2), value=0) + # p1/p2/p3 send ETH in REVERSE sorted address order + + Op.MSTORE(0, reverse_sorted[0]) + + Op.CALL(gas=100_000, address=p1, args_offset=0, args_size=32) + + Op.MSTORE(0, reverse_sorted[1]) + + Op.CALL(gas=100_000, address=p2, args_offset=0, args_size=32) + + Op.MSTORE(0, reverse_sorted[2]) + + Op.CALL(gas=100_000, address=p3, args_offset=0, args_size=32) + ) + + factory_balance = 1000 + 2000 + 3000 + pre.fund_address(factory_address, factory_balance) + + # Amounts based on reverse call order: + # p1→reverse[0], p2→reverse[1], p3→reverse[2] + amounts = { + reverse_sorted[0]: 100, + reverse_sorted[1]: 200, + reverse_sorted[2]: 300, + } + + # Execution logs: + # 1. CREATE x1, x2, x3 → LOG3 Transfer (factory → created) + # 2. CALL x1, x2, x3 → LOG3 or LOG2 depending on `to_self` + # 3. p1/p2/p3 send to reverse_sorted order + execution_logs = [ + transfer_log(factory_address, x1, 1000), + transfer_log(factory_address, x2, 2000), + transfer_log(factory_address, x3, 3000), + ] + + if to_self: + # SELFDESTRUCT to self burns ETH → LOG2 Burn + execution_logs.extend( + [ + burn_log(x1, 1000), + burn_log(x2, 2000), + burn_log(x3, 3000), + ] + ) + beneficiary_balance = 0 + else: + # SELFDESTRUCT to beneficiary → LOG3 Transfer + execution_logs.extend( + [ + transfer_log(x1, beneficiary, 1000), + transfer_log(x2, beneficiary, 2000), + transfer_log(x3, beneficiary, 3000), + ] + ) + beneficiary_balance = factory_balance + + if not eth_transferred: + # Reverted CALLs emit no logs, no ETH transferred, no finalization logs + finalization_logs = [] + post = { + x1: Account.NONEXISTENT, + x2: Account.NONEXISTENT, + x3: Account.NONEXISTENT, + beneficiary: Account(balance=beneficiary_balance), + p1: Account(balance=100), + p2: Account(balance=200), + p3: Account(balance=300), + } + else: + # p1/p2/p3 send ETH in reverse sorted order + execution_logs.extend( + [ + transfer_log(p1, reverse_sorted[0], 100), + transfer_log(p2, reverse_sorted[1], 200), + transfer_log(p3, reverse_sorted[2], 300), + ] + ) + # Finalization logs emitted in SORTED address order (not call order) + finalization_logs = [ + burn_log(addr, amounts[addr]) for addr in sorted_addrs + ] + post = { + x1: Account.NONEXISTENT, + x2: Account.NONEXISTENT, + x3: Account.NONEXISTENT, + beneficiary: Account(balance=beneficiary_balance), + p1: Account(balance=0), + p2: Account(balance=0), + p3: Account(balance=0), + } + + tx = Transaction( + sender=sender, + to=None, + value=0, + data=factory_code, + gas_limit=1_000_000, + expected_receipt=TransactionReceipt( + logs=execution_logs + finalization_logs + ), + ) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "num_accounts", + [ + pytest.param(2, id="two_accounts"), + pytest.param(5, id="five_accounts"), + ], +) +def test_finalization_burn_logs_multi_account_ordering( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, + num_accounts: int, +) -> None: + """ + Verify finalization burn logs are sorted lexicographically by address + when multiple accounts are marked for deletion in the same transaction. + + N accounts are created and SELFDESTRUCT'd in the same tx, then each + is funded by a dedicated payer contract called in REVERSE sorted + address order with a distinct nonzero amount. Every destroyed account + ends with a distinct nonzero balance at finalization, so a Burn log + is emitted for each. The resulting sequence of finalization burn logs + must appear in ascending address order regardless of call order. + """ + beneficiary = pre.deploy_contract(Op.STOP) + + factory_address = compute_create_address( + address=sender, nonce=sender.nonce + ) + created_addrs = [ + compute_create_address(address=factory_address, nonce=i + 1) + for i in range(num_accounts) + ] + sorted_addrs = sorted(created_addrs) + reverse_sorted = list(reversed(sorted_addrs)) + + # Each created contract is CALLed exactly once (to trigger SELFDESTRUCT); + # payers then forward via their own SELFDESTRUCT, so the created + # contracts are never re-invoked — no call-once guard is needed. + runtime = Op.SELFDESTRUCT(beneficiary) + initcode = Initcode(deploy_code=runtime) + initcode_len = len(initcode) + + create_balances = [1000 * (i + 1) for i in range(num_accounts)] + factory_balance = sum(create_balances) + pre.fund_address(factory_address, factory_balance) + + payer_code = Op.SELFDESTRUCT(Op.CALLDATALOAD(0)) + funding_amounts = [100 * (i + 1) for i in range(num_accounts)] + payers = [ + pre.deploy_contract(payer_code, balance=funding_amounts[i]) + for i in range(num_accounts) + ] + + factory_code: Bytecode = Om.MSTORE(initcode, 0) + for i in range(num_accounts): + factory_code += Op.TSTORE( + i, + Op.CREATE(value=create_balances[i], offset=0, size=initcode_len), + ) + for i in range(num_accounts): + factory_code += Op.CALL(gas=Op.GAS, address=Op.TLOAD(i), value=0) + for i in range(num_accounts): + factory_code += Op.MSTORE(0, reverse_sorted[i]) + factory_code += Op.CALL( + gas=Op.GAS, + address=payers[i], + args_offset=0, + args_size=32, + ) + + execution_logs = [ + transfer_log(factory_address, addr, create_balances[i]) + for i, addr in enumerate(created_addrs) + ] + execution_logs.extend( + transfer_log(addr, beneficiary, create_balances[i]) + for i, addr in enumerate(created_addrs) + ) + execution_logs.extend( + transfer_log(payers[i], reverse_sorted[i], funding_amounts[i]) + for i in range(num_accounts) + ) + + amount_by_addr = dict(zip(reverse_sorted, funding_amounts, strict=True)) + finalization_logs = [ + burn_log(addr, amount_by_addr[addr]) for addr in sorted_addrs + ] + + tx = Transaction( + sender=sender, + to=None, + value=0, + data=factory_code, + gas_limit=fork.transaction_gas_limit_cap(), + expected_receipt=TransactionReceipt( + logs=execution_logs + finalization_logs + ), + ) + + post: dict[Address, Account | None] = dict.fromkeys( + created_addrs, Account.NONEXISTENT + ) + post[beneficiary] = Account(balance=factory_balance) + for payer in payers: + post[payer] = Account(balance=0) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "num_transfers", + [ + pytest.param(2, id="two_transfers"), + pytest.param(5, id="five_transfers"), + ], +) +def test_finalization_burn_log_single_account_multiple_transfers( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, + num_transfers: int, +) -> None: + """ + Verify finalization emits a single Burn log summing multiple ETH transfers + to one to-be-destructed account. + + A single account is created and SELFDESTRUCT'd in the same tx, then N + payer contracts each send a distinct nonzero amount to it. Exactly ONE + Burn log MUST be emitted at finalization with the combined residual + balance, a client emitting one log per transfer would fail. + """ + beneficiary = pre.deploy_contract(Op.STOP) + + factory_address = compute_create_address( + address=sender, nonce=sender.nonce + ) + x = compute_create_address(address=factory_address, nonce=1) + + # x is only CALLed once (to trigger SELFDESTRUCT); payers forward via + # their own SELFDESTRUCT, so no call-once guard is needed. + runtime = Op.SELFDESTRUCT(beneficiary) + initcode = Initcode(deploy_code=runtime) + initcode_len = len(initcode) + + create_balance = 1000 + pre.fund_address(factory_address, create_balance) + + # N payer contracts, each sending a distinct nonzero amount to x + payer_code = Op.SELFDESTRUCT(x) + funding_amounts = [100 * (i + 1) for i in range(num_transfers)] + payers = [ + pre.deploy_contract(payer_code, balance=funding_amounts[i]) + for i in range(num_transfers) + ] + + # Factory creates x, triggers its SELFDESTRUCT, then calls each payer with + # x as the beneficiary so each payer's balance is forwarded to x. + factory_code: Bytecode = ( + Om.MSTORE(initcode, 0) + + Op.SSTORE( + 0, Op.CREATE(value=create_balance, offset=0, size=initcode_len) + ) + + Op.SSTORE( + 1, + Op.CALL(gas=Op.GAS, address=Op.SLOAD(0), value=0), + ) + ) + for i in range(num_transfers): + factory_code += Op.SSTORE( + 2 + i, + Op.CALL( + gas=Op.GAS, + address=payers[i], + args_offset=0, + args_size=32, + ), + ) + + execution_logs = [ + transfer_log(factory_address, x, create_balance), + transfer_log(x, beneficiary, create_balance), + ] + execution_logs.extend( + transfer_log(payers[i], x, funding_amounts[i]) + for i in range(num_transfers) + ) + + # Exactly one burn log with the SUM of transferred amounts + total_residual = sum(funding_amounts) + finalization_logs = [burn_log(x, total_residual)] + + tx = Transaction( + sender=sender, + to=None, + value=0, + data=factory_code, + gas_limit=fork.transaction_gas_limit_cap(), + expected_receipt=TransactionReceipt( + logs=execution_logs + finalization_logs + ), + ) + + factory_storage = {0: x, 1: 1} + for i in range(num_transfers): + factory_storage[2 + i] = 1 + + post: dict[Address, Account | None] = { + x: Account.NONEXISTENT, + beneficiary: Account(balance=create_balance), + factory_address: Account(storage=factory_storage), + } + for payer in payers: + post[payer] = Account(balance=0) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "funded_after_selfdestruct", + [ + pytest.param(True, id="funded_after_selfdestruct"), + pytest.param(False, id="miner_fee_only"), + ], +) +def test_selfdestruct_finalization_after_priority_fee( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, + funded_after_selfdestruct: bool, +) -> None: + """ + Verify finalization burn logs are emitted after priority fee payment. + + Sets coinbase to a contract that self-destructs in the same tx. The + finalization burn log includes the priority fee, proving finalization + happens after fee payment per EIP-7708. + + funded_after_selfdestruct: + - if True: payer sends ETH, finalization = funding + priority_fee + - if False: no payer, finalization = priority_fee only + """ + genesis_base_fee = 7 + env = Environment(base_fee_per_gas=genesis_base_fee) + contract_balance = 1000 + funding_amount = 10_000 if funded_after_selfdestruct else 0 + + sender = pre.fund_eoa() + + factory_address = compute_create_address(address=sender, nonce=0) + created_address = compute_create_address(address=factory_address, nonce=1) + coinbase = created_address # coinbase == self-destructed contract + + # inner contract: simple SELFDESTRUCT to self + runtime_code = ( + Op.SELFDESTRUCT( + Op.ADDRESS, + # Gas accounting + address_warm=True, + account_new=False, + self_destructed_account=True, + self_destructed_account_code_deposit=len( + Op.SELFDESTRUCT(address=Op.ADDRESS) + ), + ) + if fork.is_eip_enabled(8037) + else Op.SELFDESTRUCT( + Op.ADDRESS, + # Gas accounting + address_warm=True, + account_new=False, + ) + ) + initcode = Initcode(deploy_code=runtime_code) + initcode_len = len(initcode) + + gas_costs = fork.gas_costs() + mem_after_mstore = ((initcode_len + 31) // 32) * 32 + + # The base factory code: CREATE + CALL to trigger selfdestruct + call_gas = 100_000 + if fork.is_eip_enabled(8037): + call_gas = 500_000 + factory_code = Om.MSTORE( + initcode, 0, new_memory_size=mem_after_mstore + ) + Op.CALL( + gas=call_gas, + address=Op.CREATE( + value=contract_balance, + offset=0, + size=initcode_len, + init_code_size=initcode_len, + ), + address_warm=True, + ) + + # optionally add payer call to fund coinbase after selfdestruct + payer = None + payer_runtime_gas = 0 + if funded_after_selfdestruct: + payer_code = Op.SELFDESTRUCT(Op.CALLDATALOAD(0)) + payer = pre.deploy_contract(payer_code, balance=funding_amount) + factory_code += Op.MSTORE(0, created_address) + factory_code += Op.CALL( + gas=call_gas, address=payer, args_offset=0, args_size=32 + ) + payer_runtime_gas = Op.SELFDESTRUCT( + Op.CALLDATALOAD(0), address_warm=True, account_new=False + ).gas_cost(fork) + + pre.fund_address(factory_address, contract_balance) + + # prio fee calc + gas_price = 10 + base_fee = fork.base_fee_per_gas_calculator()( + parent_base_fee_per_gas=genesis_base_fee, + parent_gas_used=0, + parent_gas_limit=env.gas_limit, + ) + priority_fee_per_gas = gas_price - base_fee + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=bytes(factory_code), + contract_creation=True, + ) + factory_gas = factory_code.gas_cost(fork) + initcode_exec_gas = initcode.execution_gas(fork) + code_deposit_gas = len(runtime_code) * gas_costs.CODE_DEPOSIT_PER_BYTE + inner_runtime_gas = runtime_code.gas_cost(fork) + + gas_used = ( + intrinsic_gas + + factory_gas + + initcode_exec_gas + + code_deposit_gas + + inner_runtime_gas + + payer_runtime_gas + ) + + inner_runtime_refund = runtime_code.refund(fork) + gas_refunds = inner_runtime_refund + discount = min( + gas_refunds, + gas_used // 5, # max discount EIP-3529 + ) + priority_fee = priority_fee_per_gas * (gas_used - discount) + + # Finalization burn log proves coinbase received priority fee before log + finalization_balance: int | None = funding_amount + priority_fee + + expected_logs = [ + transfer_log(factory_address, created_address, contract_balance), + burn_log(created_address, contract_balance), + ] + + # if funded after selfdestruct, expect transfer log from payer + if funded_after_selfdestruct: + assert payer is not None + expected_logs.append( + transfer_log(payer, created_address, funding_amount) + ) + + # finalization burn log + if fork.is_eip_enabled(8037): + raise Exception( + "Test needs update: recompute exact gas usage with 8037" + ) + + expected_logs.append(burn_log(created_address, finalization_balance)) + gas_limit = 500_000 + if fork.is_eip_enabled(8037): + gas_limit = 2_000_000 + + tx = Transaction( + sender=sender, + to=None, + value=0, + data=factory_code, + gas_limit=gas_limit, + gas_price=gas_price, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + post: dict[Address, Account | None] = { + created_address: Account.NONEXISTENT, + } + if payer is not None: + post[payer] = Account(balance=0) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx], + fee_recipient=coinbase, + header_verify=Header(base_fee_per_gas=base_fee), + ) + ], + post=post, + genesis_environment=env, + ) diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/test_eip_mainnet.py b/tests/amsterdam/eip7708_eth_transfer_logs/test_eip_mainnet.py new file mode 100644 index 00000000000..73edc070e00 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/test_eip_mainnet.py @@ -0,0 +1,102 @@ +""" +Mainnet marked execute checklist tests for +[EIP-7708: ETH transfers emit a log](https://eips.ethereum.org/EIPS/eip-7708). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Fork, + Op, + StateTestFiller, + Transaction, + TransactionReceipt, +) + +from .spec import ref_spec_7708, transfer_log + +REFERENCE_SPEC_GIT_PATH = ref_spec_7708.git_path +REFERENCE_SPEC_VERSION = ref_spec_7708.version + +pytestmark = [pytest.mark.valid_at("EIP7708"), pytest.mark.mainnet] + + +def test_simple_transfer_mainnet( + state_test: StateTestFiller, + pre: Alloc, +) -> None: + """Test that a simple ETH transfer emits a transfer log on mainnet.""" + sender = pre.fund_eoa() + recipient = pre.nonexistent_account() + + tx = Transaction( + ty=0x02, + sender=sender, + to=recipient, + value=1, + gas_limit=21_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient, 1)] + ), + ) + + post = {recipient: Account(balance=1)} + state_test(pre=pre, post=post, tx=tx) + + +def test_call_with_value_mainnet( + state_test: StateTestFiller, + pre: Alloc, +) -> None: + """Test that CALL with value emits a transfer log on mainnet.""" + sender = pre.fund_eoa() + recipient = pre.deploy_contract(Op.STOP) + + contract_code = Op.CALL(gas=50_000, address=recipient, value=100) + contract = pre.deploy_contract(contract_code, balance=100) + + tx = Transaction( + ty=0x02, + sender=sender, + to=contract, + value=0, + gas_limit=100_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(contract, recipient, 100)] + ), + ) + + post = {recipient: Account(balance=100)} + state_test(pre=pre, post=post, tx=tx) + + +def test_selfdestruct_mainnet( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """Test that SELFDESTRUCT emits a transfer log on mainnet.""" + sender = pre.fund_eoa() + beneficiary = pre.nonexistent_account() + + contract_code = Op.SELFDESTRUCT(beneficiary) + contract = pre.deploy_contract(contract_code, balance=500) + + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + + tx = Transaction( + ty=0x02, + sender=sender, + to=contract, + value=0, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt( + logs=[transfer_log(contract, beneficiary, 500)] + ), + ) + + post = {beneficiary: Account(balance=500)} + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/test_fork_transition.py b/tests/amsterdam/eip7708_eth_transfer_logs/test_fork_transition.py new file mode 100644 index 00000000000..4125f1a8273 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/test_fork_transition.py @@ -0,0 +1,200 @@ +""" +Tests for EIP-7708 fork transition behavior. + +Tests that verify transfer logs are emitted correctly at the Amsterdam fork +transition boundary. +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Block, + BlockchainTestFiller, + Op, + Transaction, + TransactionReceipt, + compute_create_address, +) + +from .spec import burn_log, ref_spec_7708, transfer_log + +REFERENCE_SPEC_GIT_PATH = ref_spec_7708.git_path +REFERENCE_SPEC_VERSION = ref_spec_7708.version + + +@pytest.mark.parametrize( + "same_tx,to_self", + [ + pytest.param(True, True, id="same_tx_to_self"), + pytest.param(False, True, id="pre_existing_to_self"), + pytest.param(False, False, id="pre_existing_to_other"), + ], +) +@pytest.mark.valid_at_transition_to("EIP7708") +def test_burn_log_at_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + same_tx: bool, + to_self: bool, +) -> None: + """ + Test burn log emission across the EIP-7708 fork transition. + + same_tx_to_self: Factory CREATEs and selfdestructs to self in one tx. + At/after Amsterdam emits a CREATE transfer log + Burn log. + + pre_existing_to_self: Pre-existing contract selfdestructs to self. + No logs at any fork — SELFDESTRUCT to same account emits nothing. + + pre_existing_to_other: Pre-existing contract selfdestructs to a different + account. At/after Amsterdam emits a Transfer log. + """ + sender = pre.fund_eoa() + contract_balance = 1000 + + if same_tx: + initcode = Op.SELFDESTRUCT(Op.ADDRESS) + initcode_bytes = bytes(initcode) + initcode_len = len(initcode_bytes) + + factory_code = Op.MSTORE( + 0, Op.PUSH32(initcode_bytes.rjust(32, b"\x00")) + ) + Op.CREATE( + value=contract_balance, offset=32 - initcode_len, size=initcode_len + ) + + factory = pre.deploy_contract( + factory_code, balance=contract_balance * 3 + ) + created = [ + compute_create_address(address=factory, nonce=n) + for n in range(1, 4) + ] + targets = [factory] * 3 + + expected_logs = [ + [], + [ + transfer_log(factory, created[1], contract_balance), + burn_log(created[1], contract_balance), + ], + [ + transfer_log(factory, created[2], contract_balance), + burn_log(created[2], contract_balance), + ], + ] + post: dict = { + sender: Account(nonce=3), + created[0]: Account.NONEXISTENT, + created[1]: Account.NONEXISTENT, + created[2]: Account.NONEXISTENT, + } + elif to_self: + targets = [ + pre.deploy_contract( + Op.SELFDESTRUCT(Op.ADDRESS), balance=contract_balance + ) + for _ in range(3) + ] + expected_logs = [[], [], []] + post = {sender: Account(nonce=3)} + else: + beneficiary = pre.nonexistent_account() + targets = [ + pre.deploy_contract( + Op.SELFDESTRUCT(beneficiary), balance=contract_balance + ) + for _ in range(3) + ] + expected_logs = [ + [], + [transfer_log(targets[1], beneficiary, contract_balance)], + [transfer_log(targets[2], beneficiary, contract_balance)], + ] + post = { + sender: Account(nonce=3), + beneficiary: Account(balance=contract_balance * 3), + } + + blocks = [ + Block( + timestamp=ts, + txs=[ + Transaction( + to=targets[i], + sender=sender, + gas_limit=200_000, + expected_receipt=TransactionReceipt(logs=expected_logs[i]), + ) + ], + ) + for i, ts in enumerate([14_999, 15_000, 15_001]) + ] + + blockchain_test(pre=pre, blocks=blocks, post=post) + + +@pytest.mark.valid_at_transition_to("EIP7708") +def test_transfer_log_fork_transition( + blockchain_test: BlockchainTestFiller, pre: Alloc +) -> None: + """ + Test ETH transfer log behavior at fork transition. + + Before Amsterdam: ETH transfers do NOT emit logs. + At/after Amsterdam: ETH transfers emit Transfer logs. + """ + sender = pre.fund_eoa() + recipient = pre.nonexistent_account() + + blocks = [ + Block( + timestamp=14_999, + txs=[ + Transaction( + to=recipient, + sender=sender, + value=100, + gas_limit=21_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + ], + ), + Block( + timestamp=15_000, + txs=[ + Transaction( + to=recipient, + sender=sender, + value=100, + gas_limit=21_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient, 100)] + ), + ) + ], + ), + Block( + timestamp=15_001, + txs=[ + Transaction( + to=recipient, + sender=sender, + value=100, + gas_limit=21_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient, 100)] + ), + ) + ], + ), + ] + + blockchain_test( + pre=pre, + blocks=blocks, + post={ + recipient: Account(balance=300), + }, + ) diff --git a/tests/amsterdam/eip7708_eth_transfer_logs/test_transfer_logs.py b/tests/amsterdam/eip7708_eth_transfer_logs/test_transfer_logs.py new file mode 100644 index 00000000000..61c216406f8 --- /dev/null +++ b/tests/amsterdam/eip7708_eth_transfer_logs/test_transfer_logs.py @@ -0,0 +1,1533 @@ +""" +Tests for EIP-7708 Transfer logs. + +Tests for the Transfer(address,address,uint256) log emitted when: +- Nonzero-value-transferring transaction +- Nonzero-value-transferring CALL +- Nonzero-value-transferring SELFDESTRUCT to a different account +""" + +import pytest +from execution_testing import ( + EOA, + Account, + Address, + Alloc, + Block, + BlockchainTestFiller, + Bytecode, + Bytes, + Environment, + Fork, + Initcode, + Op, + StateTestFiller, + Storage, + Transaction, + TransactionLog, + TransactionReceipt, + compute_create2_address, + compute_create_address, +) +from execution_testing.base_types import ZeroPaddedHexNumber + +from .spec import Spec, ref_spec_7708, transfer_log + +REFERENCE_SPEC_GIT_PATH = ref_spec_7708.git_path +REFERENCE_SPEC_VERSION = ref_spec_7708.version + +pytestmark = pytest.mark.valid_from("EIP7708") + + +def test_simple_transfer_emits_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """Test that a simple ETH transfer emits a transfer log.""" + recipient = pre.nonexistent_account() + + tx = Transaction( + sender=sender, + to=recipient, + value=1, + gas_limit=21_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient, 1)] + ), + ) + + post = {recipient: Account(balance=1)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_transfer_to_delegated_account_emits_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test that transfer to EIP-7702 delegated account emits correct log. + + The transfer log should show the EOA address as recipient, + not the delegation target address. + """ + delegation_target = pre.deploy_contract(code=Op.STOP) + recipient = pre.fund_eoa(amount=0, delegation=delegation_target) + + tx = Transaction( + sender=sender, + to=recipient, + value=1, + gas_limit=100_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient, 1)] + ), + ) + + post = {recipient: Account(balance=1)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_transfer_to_self_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """Test that a transaction sending value to self emits no transfer log.""" + tx = Transaction( + sender=sender, + to=sender, + value=1, + gas_limit=21_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +def test_zero_value_transfer_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """Test that a zero-value transfer does NOT emit a transfer log.""" + recipient = pre.nonexistent_account() + + tx = Transaction( + sender=sender, + to=recipient, + value=0, + gas_limit=21_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "tx_value,expect_log", + [ + pytest.param(1000, True, id="with_value"), + pytest.param(0, False, id="zero_value"), + ], +) +def test_contract_creation_tx( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, + tx_value: int, + expect_log: bool, +) -> None: + """Test that contract creation transactions emit logs based on value.""" + initcode = Op.RETURN(0, 0) + created_address = compute_create_address(address=sender, nonce=0) + + expected_logs = ( + [transfer_log(sender, created_address, tx_value)] if expect_log else [] + ) + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + tx = Transaction( + sender=sender, + to=None, + value=tx_value, + gas_limit=gas_limit, + data=bytes(initcode), + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + post = {created_address: Account(balance=tx_value)} if tx_value > 0 else {} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "collision_nonce,collision_code", + [ + pytest.param(0, b"\x00", id="non_empty_code"), + pytest.param(1, b"", id="non_empty_nonce"), + ], +) +@pytest.mark.pre_alloc_mutable +def test_contract_creation_tx_collision( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + collision_nonce: int, + collision_code: bytes, +) -> None: + """ + Test that a contract-creating transaction with an address collision + emits no log. + + Per EIP-7610, contract creation aborts when the target address already + has non-empty code or nonce. The collision check happens before any + value transfer, so EIP-7708 emits no Transfer log. + """ + sender = pre.fund_eoa() + tx = Transaction( + sender=sender, + to=None, + value=1000, + gas_limit=200_000, + data=bytes(Op.RETURN(0, 0)), + expected_receipt=TransactionReceipt(logs=[]), + ) + + collision_address = tx.created_contract + pre[collision_address] = Account( + nonce=collision_nonce, + code=collision_code, + ) + + post = { + collision_address: Account( + nonce=collision_nonce, + code=collision_code, + ), + } + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.with_all_call_opcodes +def test_call_opcodes_transfer_log_behavior( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + call_opcode: Op, +) -> None: + """ + Test ETH transfer log behavior across all call opcode contexts. + + - CALL with value: emits log (caller -> callee) + - CALLCODE with value: emits log (caller -> caller) as self-transfer + - DELEGATECALL: no value parameter, no transfer log + - STATICCALL: no value parameter, no transfer log + """ + callee = pre.deploy_contract(Op.STOP) + + # Build the call based on opcode type + if call_opcode in [Op.CALL, Op.CALLCODE]: + # These opcodes have a value parameter + call_code = call_opcode(gas=100_000, address=callee, value=1) + else: + # DELEGATECALL and STATICCALL don't have value parameter + call_code = call_opcode(gas=100_000, address=callee) + + contract = pre.deploy_contract(call_code, balance=1) + + # Determine expected logs based on opcode behavior + expected_logs = [transfer_log(sender, contract, 1)] + + if call_opcode == Op.CALL: + # CALL transfers value from contract to callee + expected_logs.append(transfer_log(contract, callee, 1)) + post = {callee: Account(balance=1)} + elif call_opcode == Op.CALLCODE: + # CALLCODE transfers value but stays in caller's context. + # This is a self-transfer (contract -> contract), so no transfer + # log per EIP-7708 ("CALL to a different account"). + post = {} + else: + # DELEGATECALL and STATICCALL: no value transfer, no additional log + post = {} + + tx = Transaction( + sender=sender, + to=contract, + value=1, + gas_limit=200_000, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.with_all_call_opcodes( + selector=lambda call_opcode: call_opcode in (Op.CALL, Op.CALLCODE) +) +def test_call_opcodes_insufficient_balance_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + call_opcode: Op, +) -> None: + """ + Test CALL/CALLCODE with value exceeding caller balance. + + The opcode returns 0 (does not revert), transfers nothing, and emits + no transfer log. + + Note CALLCODE never emits a transfer log regardless + of balance — it's a self-transfer exempted by EIP-7708 — so for that + opcode the meaningful assertion is that the return value is 0. + """ + caller_balance = 1 + attempted_value = 100 + callee = pre.deploy_contract(Op.STOP) + + contract_code = Op.SSTORE( + 0, call_opcode(gas=100_000, address=callee, value=attempted_value) + ) + contract = pre.deploy_contract(contract_code, balance=caller_balance) + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=200_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + post = { + contract: Account(storage={0: 0}, balance=caller_balance), + callee: Account(balance=0), + } + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_delegatecall_inner_call_with_value( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test DELEGATECALL to code that performs CALL with value. + + Scenario: A DELEGATECALLs B, B does CALL with value to C. + The CALL from B executes in A's context, so log shows A as sender. + """ + recipient = pre.deploy_contract(Op.STOP) + + # B: code that CALLs recipient with value + code_b = Op.CALL(gas=50_000, address=recipient, value=1) + contract_b = pre.deploy_contract(code_b) + + # A: DELEGATECALLs to B (executes B's code in A's context) + code_a = Op.DELEGATECALL(gas=100_000, address=contract_b) + contract_a = pre.deploy_contract(code_a, balance=1) + + tx = Transaction( + sender=sender, + to=contract_a, + value=0, + gas_limit=200_000, + expected_receipt=TransactionReceipt( + logs=[ + # CALL from B executes in A's context, so A is the sender + transfer_log(contract_a, recipient, 1), + ] + ), + ) + + post = {recipient: Account(balance=1)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "create_value", + [ + pytest.param(1, id="with_value"), + pytest.param(0, id="zero_value"), + ], +) +@pytest.mark.with_all_create_opcodes +def test_create_opcode_emits_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, + create_opcode: Op, + create_value: int, +) -> None: + """Test that CREATE/CREATE2 opcodes emit logs based on value.""" + initcode = Op.RETURN(0, 0) + initcode_len = len(initcode) + + contract_code = Op.MSTORE( + 0, Op.PUSH32(bytes(initcode).rjust(32, b"\x00")) + ) + Op.SSTORE( + 0, + create_opcode( + value=create_value, offset=32 - initcode_len, size=initcode_len + ), + ) + contract = pre.deploy_contract(contract_code, balance=create_value) + created_address = compute_create_address( + address=contract, + nonce=1, + salt=0, + initcode=bytes(initcode), + opcode=create_opcode, + ) + + expected_logs = [transfer_log(sender, contract, 1)] + if create_value > 0: + expected_logs.append( + transfer_log(contract, created_address, create_value) + ) + + gas_limit = 200_000 + if fork.is_eip_enabled(8037): + gas_limit = 1_000_000 + + tx = Transaction( + sender=sender, + to=contract, + value=1, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + post = {created_address: Account(balance=create_value)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.with_all_create_opcodes +def test_initcode_calls_with_value( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + create_opcode: Op, +) -> None: + """ + Test that CALL with value during initcode emits correct log. + + Initcode performs CALL with value before returning deployed code. + Log should show the being-created contract as sender. + """ + recipient = pre.deploy_contract(Op.STOP) + + # Initcode: CALL recipient with value, then RETURN empty code + initcode = Op.CALL(gas=50_000, address=recipient, value=1) + Op.RETURN( + 0, 0 + ) + initcode_bytes = bytes(initcode) + + # Use Initcode helper or direct memory setup for longer initcode + if create_opcode == Op.CREATE: + # Store initcode in memory using code copy approach + factory_code = ( + Op.CODECOPY( + 0, + Op.SUB(Op.CODESIZE, len(initcode_bytes)), + len(initcode_bytes), + ) + + Op.CREATE(value=1, offset=0, size=len(initcode_bytes)) + + Op.STOP + ) + initcode + else: + factory_code = ( + Op.CODECOPY( + 0, + Op.SUB(Op.CODESIZE, len(initcode_bytes)), + len(initcode_bytes), + ) + + Op.CREATE2(value=1, offset=0, size=len(initcode_bytes), salt=0) + + Op.STOP + ) + initcode + + factory = pre.deploy_contract(factory_code, balance=2) + + # Compute created address + if create_opcode == Op.CREATE: + created_address = compute_create_address(address=factory, nonce=1) + else: + created_address = compute_create2_address( + address=factory, salt=0, initcode=initcode_bytes + ) + + tx = Transaction( + sender=sender, + to=factory, + value=0, + gas_limit=300_000, + expected_receipt=TransactionReceipt( + logs=[ + # CREATE transfers value to new contract + transfer_log(factory, created_address, 1), + # Initcode CALLs recipient with value + transfer_log(created_address, recipient, 1), + ] + ), + ) + + post = {recipient: Account(balance=1)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_create_initcode_stop_emits_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test that CREATE with initcode using STOP (no RETURN) emits transfer log. + + When initcode runs STOP instead of RETURN, the contract is created with + empty code. This is a successful CREATE, so transfer log should be emitted. + """ + contract_code = Op.MSTORE( + 0, Op.PUSH32(bytes(Op.STOP).rjust(32, b"\x00")) + ) + Op.CREATE(value=1, offset=31, size=1) + contract = pre.deploy_contract(contract_code, balance=1) + + created_address = compute_create_address(address=contract, nonce=1) + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=500_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(contract, created_address, 1)] + ), + ) + + post = {created_address: Account(balance=1, code=b"")} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "initcode", + [ + pytest.param(Op.REVERT(0, 0), id="initcode_reverts"), + pytest.param(Op.INVALID, id="initcode_invalid"), + ], +) +def test_failed_create_with_value_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + initcode: Bytecode, +) -> None: + """ + Test that failed CREATE with value does NOT emit transfer log. + + When initcode fails (REVERT, INVALID), the value transfer is reverted + and no log should be emitted for the CREATE. + """ + initcode_len = len(initcode) + contract_code = Op.MSTORE( + 0, Op.PUSH32(bytes(initcode).rjust(32, b"\x00")) + ) + Op.SSTORE(0, Op.CREATE(1, 32 - initcode_len, initcode_len)) + contract = pre.deploy_contract(contract_code, balance=1) + + tx = Transaction( + sender=sender, + to=contract, + value=1, + gas_limit=500_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, contract, 1)] + ), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +def test_create_insufficient_balance_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test that CREATE with insufficient balance does NOT emit transfer log. + + Contract receives 1, tries to CREATE with 1000 value - CREATE fails + (returns 0) but doesn't halt, so tx-level log remains. + """ + initcode = Op.RETURN(0, 0) + initcode_len = len(initcode) + contract_code = Op.MSTORE( + 0, Op.PUSH32(bytes(initcode).rjust(32, b"\x00")) + ) + Op.SSTORE(0, Op.CREATE(1000, 32 - initcode_len, initcode_len)) + contract = pre.deploy_contract(contract_code, balance=0) + + tx = Transaction( + sender=sender, + to=contract, + value=1, + gas_limit=500_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, contract, 1)] + ), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "initcode", + [ + pytest.param( + # OOG before return + Op.MSTORE(offset=0xFFFFFF, value=0) + Op.RETURN(0, 0), + id="create_out_of_gas_memory_expansion", + ), + pytest.param( + # Invalid opcode + Op.INVALID + Op.RETURN(0, 0), + id="invalid_opcode", + ), + pytest.param( + # OOG during code deposit payment (200 gas/byte for returned code) + # Returns 1000 bytes which costs 200,000 gas for code deposit + Op.RETURN(0, 1000), + id="create_out_of_gas_code_deposit", + ), + ], +) +def test_create_out_of_gas_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, + initcode: Bytecode, +) -> None: + """Test that CREATE running out of gas does NOT emit transfer log.""" + tx_value = 1000 + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + create_value = 500 + contract_code = Op.CALLDATACOPY( + dest_offset=0, + offset=0, + size=Op.CALLDATASIZE, + ) + Op.CREATE(value=create_value, offset=0, size=Op.CALLDATASIZE) + contract = pre.deploy_contract(contract_code) + + tx = Transaction( + sender=sender, + to=contract, + data=initcode, + value=tx_value, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, contract, tx_value)] + ), + ) + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "contract_code", + [ + pytest.param( + # CALL stack underflow: only push 6 items instead of 7 + Op.PUSH1(0) + + Op.PUSH1(0) + + Op.PUSH1(0) + + Op.PUSH1(0) + + Op.PUSH1(100) + + Op.PUSH2(0x1234) + + Op.CALL, + id="call_stack_underflow", + ), + pytest.param( + # CREATE stack underflow: only push 2 items instead of 3 + Op.PUSH1(0) + Op.PUSH1(0) + Op.CREATE, + id="create_stack_underflow", + ), + ], +) +def test_stack_underflow_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + contract_code: Bytecode, +) -> None: + """Test that stack underflow during CALL/CREATE does NOT emit log.""" + contract = pre.deploy_contract(contract_code, balance=1000) + + tx = Transaction( + sender=sender, + to=contract, + value=1000, + gas_limit=100_000, + expected_receipt=TransactionReceipt(logs=[]), # TX fails, no logs + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.pre_alloc_mutable +@pytest.mark.with_all_create_opcodes +def test_create_collision_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + create_opcode: Op, +) -> None: + """ + Test that CREATE/CREATE2 collision does not emit transfer log. + + When CREATE fails because target address already has code/nonce, + no value transfer occurs and no log should be emitted. + """ + initcode = Op.RETURN(0, 0) + initcode_bytes = bytes(initcode) + initcode_len = len(initcode_bytes) + + # Deploy factory first to compute created address + if create_opcode == Op.CREATE: + factory_code = Op.MSTORE( + 0, Op.PUSH32(initcode_bytes.rjust(32, b"\x00")) + ) + Op.CREATE(value=1, offset=32 - initcode_len, size=initcode_len) + else: + factory_code = Op.MSTORE( + 0, Op.PUSH32(initcode_bytes.rjust(32, b"\x00")) + ) + Op.CREATE2( + value=1, offset=32 - initcode_len, size=initcode_len, salt=0 + ) + + factory = pre.deploy_contract(factory_code, balance=1) + + # Compute and pre-populate the collision address + if create_opcode == Op.CREATE: + collision_address = compute_create_address(address=factory, nonce=1) + else: + collision_address = compute_create2_address( + address=factory, salt=0, initcode=initcode_bytes + ) + + # Pre-deploy contract at collision address to cause collision + pre.deploy_contract(Op.STOP, address=collision_address) + + tx = Transaction( + sender=sender, + to=factory, + value=0, + gas_limit=200_000, + expected_receipt=TransactionReceipt( + logs=[] + ), # No logs - CREATE failed + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +def test_selfdestruct_with_value_emits_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + fork: Fork, + sender: EOA, +) -> None: + """Test that SELFDESTRUCT with value emits a transfer log.""" + beneficiary = pre.nonexistent_account() + contract_balance = 2000 + + contract_code = Op.SELFDESTRUCT(beneficiary) + contract = pre.deploy_contract(contract_code, balance=contract_balance) + + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt( + logs=[transfer_log(contract, beneficiary, contract_balance)] + ), + ) + + post = {beneficiary: Account(balance=contract_balance)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_selfdestruct_to_system_address( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, +) -> None: + """ + Test SELFDESTRUCT sending ETH to the EIP-7708 system address. + + Edge case: beneficiary is the same address (0xff...fe) that emits logs. + """ + contract_code = Op.SELFDESTRUCT(Spec.SYSTEM_ADDRESS) + contract = pre.deploy_contract(contract_code, balance=1) + + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt( + logs=[transfer_log(contract, Spec.SYSTEM_ADDRESS, 1)] + ), + ) + + post = {Spec.SYSTEM_ADDRESS: Account(balance=1)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "op_type", + [ + pytest.param("call", id="call"), + pytest.param("selfdestruct", id="selfdestruct"), + ], +) +def test_zero_value_operations_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + op_type: str, +) -> None: + """Test that zero-value operations do NOT emit transfer logs.""" + target = pre.nonexistent_account() + + if op_type == "call": + contract_code = Op.CALL(gas=100_000, address=target, value=0) + else: + contract_code = Op.SELFDESTRUCT(target) + + contract = pre.deploy_contract(contract_code, balance=0) + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=100_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "call_opcode", + [ + pytest.param(Op.CALL, id="call"), + pytest.param(Op.CALLCODE, id="callcode"), + ], +) +def test_call_to_self_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + call_opcode: Op, +) -> None: + """ + Test that CALL/CALLCODE with value to self emits no transfer log. + + Uses CALLDATASIZE to detect recursion: external call has no calldata, + recursive call passes 1 byte of calldata to signal stop. + """ + # CALLDATASIZE > 0 means recursive call, jump to end + # Byte offsets: CALLDATASIZE(1) + PUSH1(2) + JUMPI(1) = 4 + # CALL with args_size=1: ~16 bytes, JUMPDEST at offset 20 + contract_code = ( + Op.CALLDATASIZE + + Op.PUSH1(20) + + Op.JUMPI + + call_opcode(gas=100_000, address=Op.ADDRESS, value=1, args_size=1) + + Op.JUMPDEST + + Op.STOP + ) + contract = pre.deploy_contract(contract_code, balance=1) + + tx = Transaction( + sender=sender, + to=contract, + value=0, + gas_limit=200_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "recipient_code,call_gas,call_value,recipient_balance,contract_balance", + [ + pytest.param(Op.REVERT(0, 0), 50_000, 500, 0, 500, id="call_reverted"), + pytest.param(Op.JUMP(0), 100, 500, 0, 500, id="call_out_of_gas"), + pytest.param( + # OOG with memory expansion - tries to access large memory offset + Op.MSTORE(0xFFFFFF, 0) + Op.STOP, + 1000, + 500, + 0, + 500, + id="call_out_of_gas_memory_expansion", + ), + pytest.param( + Op.SELFDESTRUCT(Address(0x1234)), + 100, + 0, + 2000, + 0, + id="selfdestruct_out_of_gas", + ), + pytest.param( + Op.STOP, + 50_000, + 2000, + 0, + 0, + id="call_insufficient_balance", + ), + ], +) +def test_failed_inner_operation_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + recipient_code: Bytecode, + call_gas: int, + call_value: int, + recipient_balance: int, + contract_balance: int, +) -> None: + """Test that failed inner operations do NOT emit transfer logs.""" + recipient = pre.deploy_contract(recipient_code, balance=recipient_balance) + tx_value = 1000 + + contract_code = Op.CALL( + gas=call_gas, + address=recipient, + value=call_value, + ) + contract = pre.deploy_contract(contract_code, balance=contract_balance) + + tx = Transaction( + sender=sender, + to=contract, + value=tx_value, + gas_limit=100_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, contract, tx_value)] + ), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "inner_calls", + [ + pytest.param(1, id="single_call"), + pytest.param(3, id="multiple_calls"), + ], +) +def test_inner_call_succeeds_outer_reverts_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + inner_calls: int, +) -> None: + """ + Test that logs from successful inner calls are rolled back on outer revert. + + Scenario: Contract performs N CALLs with value (all succeed), then REVERTs. + Expected: No logs remain (all transfer logs are rolled back). + """ + callee = pre.deploy_contract(Op.STOP) + + # Build contract code: N CALLs with value, then REVERT + contract_code = Op.CALL(gas=100_000, address=callee, value=1) + for _ in range(inner_calls - 1): + contract_code += Op.POP + Op.CALL(gas=100_000, address=callee, value=1) + contract_code += Op.POP + Op.REVERT(0, 0) + + contract = pre.deploy_contract(contract_code, balance=inner_calls) + + tx = Transaction( + sender=sender, + to=contract, + value=1, + gas_limit=500_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.with_all_create_opcodes +def test_inner_create_succeeds_outer_reverts_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, + create_opcode: Op, +) -> None: + """ + Test that a CREATE/CREATE2 transfer log is rolled back on outer revert. + + The factory CREATE/CREATE2s a child with value (the deployment succeeds + and a `factory -> created` log is emitted in the child frame), then the + factory itself REVERTs. Per EIP-7708 the rollback semantics mirror those + of CALL: the child log is discarded together with the rest of the + factory's frame, so the transaction receipt records no logs. + """ + create_value = 1 + initcode = Op.RETURN(0, 0) + initcode_len = len(initcode) + + factory_code = ( + Op.MSTORE(0, Op.PUSH32(bytes(initcode).rjust(32, b"\x00"))) + + Op.MSTORE( + 32, + create_opcode( + value=create_value, + offset=32 - initcode_len, + size=initcode_len, + ), + ) + + Op.REVERT(32, 32) + ) + factory = pre.deploy_contract(factory_code, balance=create_value) + + entry_storage = Storage() + expected_create_address = compute_create_address( + address=factory, + nonce=1, + salt=0, + initcode=initcode, + opcode=create_opcode, + ) + entry_code = Op.CALL( + address=factory, ret_offset=0, ret_size=32 + ) + Op.SSTORE( + entry_storage.store_next(expected_create_address), Op.MLOAD(0) + ) + entry = pre.deploy_contract(entry_code) + + gas_limit = 200_000 + if fork.is_eip_enabled(8037): + gas_limit = 1_000_000 + + tx = Transaction( + sender=sender, + to=entry, + value=0, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test( + env=env, + pre=pre, + post={entry: Account(storage=entry_storage)}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "call_depth", + [ + pytest.param(2, id="depth_2"), + pytest.param(3, id="depth_3"), + pytest.param(10, id="depth_10"), + ], +) +def test_nested_calls_log_order( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + call_depth: int, +) -> None: + """Test that nested CALLs emit transfer logs in chronological order.""" + transfer_value = 100 + tx_value = 1000 + + # Build the chain from innermost outward by prepending each new caller. + # Once finished, accounts[0] is the entry contract (the tx target) and + # accounts[-1] is the final recipient. + accounts: list[Address] = [pre.nonexistent_account()] + for _ in range(call_depth): + contract_code = Op.SSTORE( + 0, + Op.CALL(gas=500_000, address=accounts[0], value=transfer_value), + ) + accounts.insert( + 0, pre.deploy_contract(contract_code, balance=transfer_value) + ) + + entry_contract = accounts[0] + final_recipient = accounts[-1] + + expected_logs: list[TransactionLog] = [ + transfer_log(sender, entry_contract, tx_value) + ] + for i in range(call_depth): + expected_logs.append( + transfer_log(accounts[i], accounts[i + 1], transfer_value) + ) + + tx = Transaction( + sender=sender, + to=entry_contract, + value=tx_value, + gas_limit=1_000_000, + expected_receipt=TransactionReceipt(logs=expected_logs), + ) + + post: dict[Address, Account] = { + final_recipient: Account(balance=transfer_value) + } + for chain_contract in accounts[:-1]: + post[chain_contract] = Account(storage={0: 1}) + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_contract_log_and_transfer_ordering( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test log ordering between contract-emitted logs and transfer logs. + + Scenario: Contract emits LOG0, then CALLs with value. + Expected order: tx transfer log, contract LOG0, CALL transfer log. + """ + callee = pre.deploy_contract(Op.STOP) + + # Contract emits LOG0, then CALLs callee with value + contract_code = ( + Op.MSTORE(0, 0xDEADBEEF) + + Op.LOG0(offset=0, size=32) # Emit LOG0 with data + + Op.CALL(gas=50_000, address=callee, value=1) + ) + contract = pre.deploy_contract(contract_code, balance=1) + + tx = Transaction( + sender=sender, + to=contract, + value=1, + gas_limit=200_000, + expected_receipt=TransactionReceipt( + logs=[ + # 1. TX-level transfer + transfer_log(sender, contract, 1), + # 2. Contract LOG0 (emitted before CALL) + TransactionLog( + address=contract, + topics=[], + data=Bytes((0xDEADBEEF).to_bytes(32, "big")), + ), + # 3. CALL transfer (emitted during CALL) + transfer_log(contract, callee, 1), + ] + ), + ) + + post = {callee: Account(balance=1)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "reverting_code", + [ + pytest.param(Op.REVERT(0, 0), id="revert"), + pytest.param(Op.INVALID, id="invalid_opcode"), + pytest.param(Op.ADD, id="stack_underflow"), + pytest.param(Op.MSTORE(2**256 - 1, 0), id="out_of_gas"), + ], +) +def test_reverted_transaction_no_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + reverting_code: Bytecode, +) -> None: + """Test that a failed transaction does NOT emit a transfer log.""" + contract = pre.deploy_contract(reverting_code) + + tx = Transaction( + sender=sender, + to=contract, + value=1000, + gas_limit=100_000, + expected_receipt=TransactionReceipt(logs=[]), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) + + +@pytest.mark.parametrize( + "address_type", + [ + pytest.param("ecrecover", id="precompile_ecrecover"), + pytest.param("sha256", id="precompile_sha256"), + pytest.param("system", id="system_address"), + pytest.param("coinbase", id="coinbase_address"), + ], +) +def test_transfer_to_special_address( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + address_type: str, +) -> None: + """Test that transfers to special addresses emit transfer logs.""" + transfer_amount = 1000 + + # Resolve target address based on type + # Note: blake2f (0x09) excluded as it requires specific input format + address_map = { + "ecrecover": Address(0x01), + "sha256": Address(0x02), + "system": Spec.SYSTEM_ADDRESS, + } + + if address_type == "coinbase": + target = env.fee_recipient + # Don't check exact balance - coinbase also receives gas fees + post = {} + else: + target = address_map[address_type] + post = {target: Account(balance=transfer_amount)} + + tx = Transaction( + sender=sender, + to=target, + value=transfer_amount, + gas_limit=100_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, target, transfer_amount)] + ), + ) + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.with_all_typed_transactions +def test_transfer_with_all_tx_types( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + typed_transaction: Transaction, +) -> None: + """Test that ETH transfers emit logs for all transaction types.""" + recipient = pre.nonexistent_account() + transfer_amount = 1000 + + tx = typed_transaction.copy( + to=recipient, + value=transfer_amount, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient, transfer_amount)] + ), + ) + + post = {recipient: Account(balance=transfer_amount)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +def test_multiple_transfers_same_block( + blockchain_test: BlockchainTestFiller, pre: Alloc +) -> None: + """ + Test that multiple transfers in the same block have independent logs. + + Each transaction should have its own transfer log in its receipt, + verifying logs don't bleed across transactions. + """ + sender = pre.fund_eoa() + recipient1 = pre.nonexistent_account() + recipient2 = pre.nonexistent_account() + + blocks = [ + Block( + txs=[ + Transaction( + to=recipient1, + sender=sender, + nonce=0, + value=100, + gas_limit=21_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient1, 100)] + ), + ), + Transaction( + to=recipient2, + sender=sender, + nonce=1, + value=200, + gas_limit=21_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(sender, recipient2, 200)] + ), + ), + ], + ), + ] + + blockchain_test( + pre=pre, + blocks=blocks, + post={ + recipient1: Account(balance=100), + recipient2: Account(balance=200), + }, + ) + + +def test_selfdestruct_then_transfer_same_block( + blockchain_test: BlockchainTestFiller, pre: Alloc, fork: Fork +) -> None: + """ + Test transfer to address that selfdestructed earlier in the same block. + + Tx1: Contract selfdestructs, sending balance to beneficiary. + Tx2: Transfer to the contract triggers SELFDESTRUCT again (code not deleted + per EIP-6780), sending the received value to beneficiary. + + Expected logs: + - Tx1: contract -> beneficiary (500) + - Tx2: sender -> contract (100) + contract -> beneficiary (100) + """ + sender = pre.fund_eoa() + beneficiary = pre.nonexistent_account() + + contract_code = Op.SELFDESTRUCT(beneficiary) + contract = pre.deploy_contract(contract_code, balance=500) + + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + + blocks = [ + Block( + txs=[ + Transaction( + to=contract, + sender=sender, + nonce=0, + value=0, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt( + logs=[transfer_log(contract, beneficiary, 500)] + ), + ), + Transaction( + to=contract, + sender=sender, + nonce=1, + value=100, + gas_limit=gas_limit, + expected_receipt=TransactionReceipt( + logs=[ + transfer_log(sender, contract, 100), + transfer_log(contract, beneficiary, 100), + ] + ), + ), + ], + ), + ] + + blockchain_test( + pre=pre, + blocks=blocks, + post={ + beneficiary: Account(balance=600), + contract: Account(balance=0), + }, + ) + + +def test_selfdestruct_to_self_cross_tx_no_log( + blockchain_test: BlockchainTestFiller, pre: Alloc +) -> None: + """ + Test that selfdestruct-to-self in a cross-tx context emits no log. + + A contract created in Tx1 is not in created_accounts during Tx2. + Selfdestruct-to-self in Tx2 emits no log per EIP-7708: no Burn + log (not same-tx) and no Transfer log (not a different account). + + Tx1: Contract creation tx (to=None) deploying SELFDESTRUCT(ADDRESS), + value=2000. Logs: [transfer_log(sender, created, 2000)] + Tx2: Call created contract directly, value=0. Logs: [] + Post: contract keeps balance (not deleted, not in created_accounts in Tx2) + """ + contract_balance = 2000 + sender = pre.fund_eoa() + + runtime_code = Op.SELFDESTRUCT(Op.ADDRESS) + initcode = Initcode(deploy_code=runtime_code) + + # Calculate the address that will be created by the first tx + created_address = compute_create_address(address=sender, nonce=0) + + blocks = [ + Block( + txs=[ + # Tx1: Create the contract directly via contract creation tx + Transaction( + to=None, + sender=sender, + nonce=0, + value=contract_balance, + data=bytes(initcode), + gas_limit=300_000, + expected_receipt=TransactionReceipt( + logs=[ + transfer_log( + sender, created_address, contract_balance + ), + ] + ), + ), + # Tx2: Call the created contract directly (cross-tx) + Transaction( + to=created_address, + sender=sender, + nonce=1, + value=0, + gas_limit=100_000, + expected_receipt=TransactionReceipt(logs=[]), + ), + ], + ), + ] + + blockchain_test( + pre=pre, + blocks=blocks, + post={ + # Contract keeps balance: not deleted since not in + # created_accounts during Tx2 + created_address: Account(balance=contract_balance), + }, + ) + + +def test_call_to_delegated_account_with_value( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, +) -> None: + """ + Test CALL opcode to 7702 delegated account with value. + + Unlike simple tx transfer, CALL to delegated account executes the + delegated code. The transfer log should show the EOA as recipient. + """ + delegation_target = pre.deploy_contract(code=Op.STOP) + delegated_eoa = pre.fund_eoa(amount=0, delegation=delegation_target) + + caller_code = Op.CALL(gas=50_000, address=delegated_eoa, value=100) + caller = pre.deploy_contract(caller_code, balance=100) + + tx = Transaction( + sender=sender, + to=caller, + value=0, + gas_limit=200_000, + expected_receipt=TransactionReceipt( + logs=[transfer_log(caller, delegated_eoa, 100)] + ), + ) + + post = {delegated_eoa: Account(balance=100)} + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.execute(pytest.mark.skip("Requires specific base fee")) +def test_call_with_value_to_coinbase_no_priority_fee_log( + state_test: StateTestFiller, + env: Environment, + pre: Alloc, + sender: EOA, + fork: Fork, +) -> None: + """ + Verify no Transfer log is emitted for the coinbase priority fee. + + A contract executes CALL with nonzero value to the coinbase address, + and the transaction pays a nonzero priority fee to that same + coinbase. Only the CALL-with-value must produce a Transfer log; the + priority fee crediting happens outside the EVM as a protocol-level + balance change and must not emit a log. + + An implementation that hooks all balance additions (instead of only + CALL / SELFDESTRUCT / tx-level value transfers) would emit an extra + Transfer log for the fee and fail the exact-log assertion. + """ + coinbase = env.fee_recipient + call_value = 1 + + caller_code = Op.CALL(gas=Op.GAS, address=coinbase, value=call_value) + caller = pre.deploy_contract(caller_code, balance=call_value) + env.base_fee_per_gas = ZeroPaddedHexNumber(7) + max_fee_per_gas = int(env.base_fee_per_gas) * 2 + tx = Transaction( + sender=sender, + to=caller, + value=0, + gas_limit=fork.transaction_gas_limit_cap(), + max_fee_per_gas=max_fee_per_gas, + max_priority_fee_per_gas=max_fee_per_gas, + expected_receipt=TransactionReceipt( + logs=[transfer_log(caller, coinbase, call_value)] + ), + ) + + state_test(env=env, pre=pre, post={}, tx=tx) diff --git a/tests/cancun/eip6780_selfdestruct/test_journal_revert.py b/tests/cancun/eip6780_selfdestruct/test_journal_revert.py index 9168e1e6408..1ed5f267e5a 100644 --- a/tests/cancun/eip6780_selfdestruct/test_journal_revert.py +++ b/tests/cancun/eip6780_selfdestruct/test_journal_revert.py @@ -7,10 +7,12 @@ Account, Alloc, Environment, + Fork, Op, StateTestFiller, Storage, Transaction, + TransactionReceipt, ) REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6780.md" @@ -22,6 +24,7 @@ def test_selfdestruct_balance_transfer_reverted( state_test: StateTestFiller, env: Environment, pre: Alloc, + fork: Fork, ) -> None: """ Test that SELFDESTRUCT balance transfer is reverted on sub-call revert. @@ -64,6 +67,13 @@ def test_selfdestruct_balance_transfer_reverted( sender = pre.fund_eoa() + # Under EIP-7708 the SELFDESTRUCT-triggered Transfer log is emitted inside + # the reverted sub-call, so it must be discarded together with the rest of + # the reverted state. + expected_receipt = ( + TransactionReceipt(logs=[]) if fork.is_eip_enabled(7708) else None + ) + state_test( env=env, pre=pre, @@ -78,5 +88,6 @@ def test_selfdestruct_balance_transfer_reverted( sender=sender, to=outer, gas_limit=1_000_000, + expected_receipt=expected_receipt, ), ) diff --git a/tests/cancun/eip6780_selfdestruct/test_reentrancy_selfdestruct_revert.py b/tests/cancun/eip6780_selfdestruct/test_reentrancy_selfdestruct_revert.py index 7848ea91ac6..6179045a240 100644 --- a/tests/cancun/eip6780_selfdestruct/test_reentrancy_selfdestruct_revert.py +++ b/tests/cancun/eip6780_selfdestruct/test_reentrancy_selfdestruct_revert.py @@ -1,4 +1,7 @@ -"""Suicide scenario requested test https://github.com/ethereum/tests/issues/1325.""" +""" +Self-destruct scenario requested test +https://github.com/ethereum/tests/issues/1325. +""" from typing import SupportsBytes @@ -14,9 +17,12 @@ Op, StateTestFiller, Transaction, + TransactionReceipt, ) from execution_testing.forks import Cancun +from tests.amsterdam.eip7708_eth_transfer_logs.spec import transfer_log + REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6780.md" REFERENCE_SPEC_VERSION = "1b6a0e94cc47e859b9866e570391cf37dc55059a" @@ -49,7 +55,7 @@ def selfdestruct_contract_address( @pytest.fixture def executor_contract_bytecode( - first_suicide: Op, + first_selfdestruct: Op, revert_contract_address: Address, selfdestruct_contract_address: Address, ) -> Bytecode: @@ -58,9 +64,11 @@ def executor_contract_bytecode( Op.SSTORE( 1, ( - first_suicide(address=selfdestruct_contract_address, value=0) - if first_suicide in [Op.CALL, Op.CALLCODE] - else first_suicide(address=selfdestruct_contract_address) + first_selfdestruct( + address=selfdestruct_contract_address, value=0 + ) + if first_selfdestruct in [Op.CALL, Op.CALLCODE] + else first_selfdestruct(address=selfdestruct_contract_address) ), ) + Op.SSTORE(2, Op.CALL(address=revert_contract_address)) @@ -100,14 +108,14 @@ def executor_contract_address( @pytest.fixture def revert_contract_bytecode( - second_suicide: Op, + second_selfdestruct: Op, selfdestruct_contract_address: Address, ) -> Bytecode: """Contract code that performs a call and then reverts.""" call_op = ( - second_suicide(address=selfdestruct_contract_address, value=100) - if second_suicide in [Op.CALL, Op.CALLCODE] - else second_suicide(address=selfdestruct_contract_address) + second_selfdestruct(address=selfdestruct_contract_address, value=100) + if second_selfdestruct in [Op.CALL, Op.CALLCODE] + else second_selfdestruct(address=selfdestruct_contract_address) ) return Op.MSTORE(0, Op.ADD(15, call_op)) + Op.REVERT(0, 32) @@ -131,18 +139,18 @@ def revert_contract_address( @pytest.mark.valid_from("Paris") @pytest.mark.parametrize( - "first_suicide", [Op.CALL, Op.CALLCODE, Op.DELEGATECALL] + "first_selfdestruct", [Op.CALL, Op.CALLCODE, Op.DELEGATECALL] ) @pytest.mark.parametrize( - "second_suicide", [Op.CALL, Op.CALLCODE, Op.DELEGATECALL] + "second_selfdestruct", [Op.CALL, Op.CALLCODE, Op.DELEGATECALL] ) def test_reentrancy_selfdestruct_revert( pre: Alloc, env: Environment, sender: EOA, fork: Fork, - first_suicide: Op, - second_suicide: Op, + first_selfdestruct: Op, + second_selfdestruct: Op, state_test: StateTestFiller, selfdestruct_contract_bytecode: Bytecode, selfdestruct_contract_address: Address, @@ -171,23 +179,24 @@ def test_reentrancy_selfdestruct_revert( ), } - if first_suicide in [Op.CALLCODE, Op.DELEGATECALL]: + if first_selfdestruct in [Op.CALLCODE, Op.DELEGATECALL]: if fork >= Cancun: # On Cancun even callcode/delegatecall does not remove the account, # so the value remain post[executor_contract_address] = Account( storage={ - 0x01: 0x01, # First call to contract S->suicide success - 0x02: 0x00, # Second call to contract S->suicide reverted + 0x01: 0x01, # 1st call to contract S->selfdestruct success + 0x02: 0x00, # 2nd call to contract S->selfdestruct revert 0x03: 16, # Reverted value to check that revert really # worked }, ) else: - # Callcode executed first suicide from sender. sender is deleted + # Callcode executed first selfdestruct from sender. + # Sender is deleted. post[executor_contract_address] = Account.NONEXISTENT # type: ignore - # Original suicide account remains in state + # Original selfdestruct account remains in state post[selfdestruct_contract_address] = Account( balance=selfdestruct_contract_init_balance, storage={} ) @@ -196,19 +205,19 @@ def test_reentrancy_selfdestruct_revert( balance=executor_contract_init_balance, ) - # On Cancun suicide no longer destroys the account from state, just cleans - # the balance - if first_suicide in [Op.CALL]: + # On Cancun selfdestruct no longer destroys the account from state, just + # cleans the balance + if first_selfdestruct in [Op.CALL]: post[executor_contract_address] = Account( storage={ - 0x01: 0x01, # First call to contract S->suicide success - 0x02: 0x00, # Second call to contract S->suicide reverted + 0x01: 0x01, # First call to contract S->selfdestruct success + 0x02: 0x00, # Second call to contract S->selfdestruct reverted 0x03: 16, # Reverted value to check that revert really worked }, ) if fork >= Cancun: - # On Cancun suicide does not remove the account, just sends the - # balance + # On Cancun selfdestruct does not remove the account, just sends + # the balance post[selfdestruct_contract_address] = Account( balance=0, code=selfdestruct_contract_bytecode, storage={} ) @@ -220,11 +229,41 @@ def test_reentrancy_selfdestruct_revert( balance=selfdestruct_contract_init_balance, ) + # Under EIP-7708 the first SELFDESTRUCT emits a Transfer log to the + # recipient; the second SELFDESTRUCT happens inside the reverted frame so + # its logs are discarded. For CALL the transfer is from S; for + # CALLCODE/DELEGATECALL the code runs in executor's context, so the + # transfer is from executor. + expected_receipt = None + if fork.is_eip_enabled(7708): + if first_selfdestruct == Op.CALL: + expected_logs = [ + transfer_log( + selfdestruct_contract_address, + selfdestruct_recipient_address, + selfdestruct_contract_init_balance, + ) + ] + elif first_selfdestruct in [Op.CALLCODE, Op.DELEGATECALL]: + expected_logs = [ + transfer_log( + executor_contract_address, + selfdestruct_recipient_address, + executor_contract_init_balance, + ) + ] + else: + raise RuntimeError( + f"Unexpected opcode for test: {first_selfdestruct}" + ) + expected_receipt = TransactionReceipt(logs=expected_logs) + tx = Transaction( sender=sender, to=executor_contract_address, gas_limit=500_000, value=0, + expected_receipt=expected_receipt, ) state_test(env=env, pre=pre, post=post, tx=tx) diff --git a/tests/cancun/eip6780_selfdestruct/test_selfdestruct.py b/tests/cancun/eip6780_selfdestruct/test_selfdestruct.py index 37b589fd3f3..07a42652b2d 100644 --- a/tests/cancun/eip6780_selfdestruct/test_selfdestruct.py +++ b/tests/cancun/eip6780_selfdestruct/test_selfdestruct.py @@ -24,10 +24,16 @@ StateTestFiller, Storage, Transaction, + TransactionReceipt, compute_create_address, ) from execution_testing.forks import Cancun +from tests.amsterdam.eip7708_eth_transfer_logs.spec import ( + burn_log, + transfer_log, +) + REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6780.md" REFERENCE_SPEC_VERSION = "1b6a0e94cc47e859b9866e570391cf37dc55059a" @@ -197,6 +203,7 @@ def test_create_selfdestruct_same_tx( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_code: Bytecode, sendall_recipient_addresses: List[Address], create_opcode: Op, @@ -231,8 +238,8 @@ def test_create_selfdestruct_same_tx( initcode=selfdestruct_contract_initcode, opcode=create_opcode, ) - for i in range(len(sendall_recipient_addresses)): - if sendall_recipient_addresses[i] == SELF_ADDRESS: + for i, addr in enumerate(sendall_recipient_addresses): + if addr == SELF_ADDRESS: sendall_recipient_addresses[i] = selfdestruct_contract_address if selfdestruct_contract_initial_balance > 0: pre.fund_address( @@ -281,8 +288,13 @@ def test_create_selfdestruct_same_tx( Op.EXTCODEHASH(selfdestruct_contract_address), ) + # Precompute entry_code_address (for Transfer log sender attribution) + entry_code_address = compute_create_address(address=sender, nonce=0) + # Call the self-destructing contract multiple times as required, increasing - # the wei sent each time + # the wei sent each time. Also track the sequence of EIP-7708 logs so they + # can be asserted as expected receipt logs. + expected_logs_after_tx_value: list = [] entry_code_balance = 0 for i, sendall_recipient in zip( range(call_times), cycle(sendall_recipient_addresses) @@ -303,6 +315,33 @@ def test_create_selfdestruct_same_tx( entry_code_balance += i selfdestruct_contract_current_balance += i + # CALL with value > 0 emits a Transfer log (entry_code -> contract) + if i > 0: + expected_logs_after_tx_value.append( + transfer_log( + entry_code_address, selfdestruct_contract_address, i + ) + ) + + # SELFDESTRUCT emits a Transfer log to a different address, or a Burn + # log when sending to self (contract was created in this tx). + if selfdestruct_contract_current_balance > 0: + if sendall_recipient == selfdestruct_contract_address: + expected_logs_after_tx_value.append( + burn_log( + selfdestruct_contract_address, + selfdestruct_contract_current_balance, + ) + ) + else: + expected_logs_after_tx_value.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient, + selfdestruct_contract_current_balance, + ) + ) + # Balance is always sent to other contracts if sendall_recipient != selfdestruct_contract_address: sendall_final_balances[sendall_recipient] += ( @@ -342,7 +381,7 @@ def test_create_selfdestruct_same_tx( gas_limit=500_000, ) - entry_code_address = tx.created_contract + assert tx.created_contract == entry_code_address post: Dict[Address, Account] = { entry_code_address: Account( @@ -356,11 +395,21 @@ def test_create_selfdestruct_same_tx( post[selfdestruct_contract_address] = Account.NONEXISTENT # type: ignore + if fork.is_eip_enabled(7708): + expected_logs = [] + if entry_code_balance > 0: + # tx value transfer: sender -> entry_code_address + expected_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + expected_logs.extend(expected_logs_after_tx_value) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @pytest.mark.parametrize("create_opcode", [Op.CREATE, Op.CREATE2]) -@pytest.mark.parametrize("call_times", [0, 1]) +@pytest.mark.parametrize("call_times", [0, 1, 2]) @pytest.mark.parametrize( "selfdestruct_contract_initial_balance", [0, 100_000], @@ -370,6 +419,7 @@ def test_self_destructing_initcode( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_code: Bytecode, sendall_recipient_addresses: List[Address], create_opcode: Op, @@ -452,7 +502,7 @@ def test_self_destructing_initcode( entry_code_balance += i entry_code += Op.SSTORE( - entry_code_storage.store_next(0), + entry_code_storage.store_next(entry_code_balance), Op.BALANCE(selfdestruct_contract_address), ) @@ -489,6 +539,38 @@ def test_self_destructing_initcode( ), } + if fork.is_eip_enabled(7708): + expected_logs = [] + # tx value transfer: sender -> entry_code_address (created contract) + if entry_code_balance > 0: + expected_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + # Initcode SELFDESTRUCT sends pre-existing balance to the recipient. + if selfdestruct_contract_initial_balance > 0: + expected_logs.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient_addresses[0], + selfdestruct_contract_initial_balance, + ) + ) + # CALLs to the destroyed contract transfer ETH to it. + for i in range(call_times): + if i > 0: + expected_logs.append( + transfer_log( + entry_code_address, selfdestruct_contract_address, i + ) + ) + # At finalization the (destroyed) contract has the accumulated + # post-SELFDESTRUCT balance, which is burned. + if entry_code_balance > 0: + expected_logs.append( + burn_log(selfdestruct_contract_address, entry_code_balance) + ) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -502,6 +584,7 @@ def test_self_destructing_initcode_create_tx( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, tx_value: int, selfdestruct_code: Bytecode, sendall_recipient_addresses: List[Address], @@ -541,6 +624,22 @@ def test_self_destructing_initcode_create_tx( ), } + if fork.is_eip_enabled(7708): + expected_logs = [] + if tx_value > 0: + expected_logs.append( + transfer_log(sender, selfdestruct_contract_address, tx_value) + ) + if sendall_amount > 0: + expected_logs.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient_addresses[0], + sendall_amount, + ) + ) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -571,6 +670,7 @@ def test_recreate_self_destructed_contract_different_txs( blockchain_test: BlockchainTestFiller, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_code: Bytecode, selfdestruct_contract_initial_balance: int, sendall_recipient_addresses: List[Address], @@ -597,7 +697,7 @@ def test_recreate_self_destructed_contract_different_txs( entry_code_storage = Storage() sendall_amount = selfdestruct_contract_initial_balance - # Bytecode used to create the contract + # Validate bytecode used to create the contract assert create_opcode != Op.CREATE, ( "cannot recreate contract using CREATE opcode" ) @@ -645,18 +745,46 @@ def test_recreate_self_destructed_contract_different_txs( selfdestruct_contract_address, selfdestruct_contract_initial_balance, ) - for i in range(len(sendall_recipient_addresses)): - if sendall_recipient_addresses[i] == SELF_ADDRESS: + for i, addr in enumerate(sendall_recipient_addresses): + if addr == SELF_ADDRESS: sendall_recipient_addresses[i] = selfdestruct_contract_address txs: List[Transaction] = [] for i in range(recreate_times + 1): + expected_receipt = None + if fork.is_eip_enabled(7708): + # First tx: contract is recreated at the pre-funded address, then + # SELFDESTRUCTs transferring initial_balance to the recipient + # (or emitting a Burn log when SD to self). Subsequent txs see + # address with 0 balance (destroyed+cleared), so no log. + tx_logs: list = [] + if i == 0 and selfdestruct_contract_initial_balance > 0: + if ( + sendall_recipient_addresses[0] + == selfdestruct_contract_address + ): + tx_logs.append( + burn_log( + selfdestruct_contract_address, + selfdestruct_contract_initial_balance, + ) + ) + else: + tx_logs.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient_addresses[0], + selfdestruct_contract_initial_balance, + ) + ) + expected_receipt = TransactionReceipt(logs=tx_logs) txs.append( Transaction( data=Hash(i), sender=sender, to=entry_code_address, gas_limit=500_000, + expected_receipt=expected_receipt, ) ) entry_code_storage[i] = selfdestruct_contract_address @@ -737,6 +865,7 @@ def test_selfdestruct_pre_existing( eip_enabled: bool, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_code: Bytecode, selfdestruct_contract_initial_balance: int, sendall_recipient_addresses: List[Address], @@ -760,8 +889,8 @@ def test_selfdestruct_pre_existing( ) entry_code_storage = Storage() - for i in range(len(sendall_recipient_addresses)): - if sendall_recipient_addresses[i] == SELF_ADDRESS: + for i, addr in enumerate(sendall_recipient_addresses): + if addr == SELF_ADDRESS: sendall_recipient_addresses[i] = selfdestruct_contract_address # Create a dict to record the expected final balances @@ -780,8 +909,12 @@ def test_selfdestruct_pre_existing( # destructing contract, as many times as required entry_code = Bytecode() + # Pre-compute the entry_code_address to use for Transfer log attribution. + entry_code_address = compute_create_address(address=sender, nonce=0) + # Call the self-destructing contract multiple times as required, increasing # the wei sent each time + expected_logs_after_tx_value: list = [] entry_code_balance = 0 for i, sendall_recipient in zip( range(call_times), cycle(sendall_recipient_addresses) @@ -802,6 +935,31 @@ def test_selfdestruct_pre_existing( entry_code_balance += i selfdestruct_contract_current_balance += i + # CALL with nonzero value emits Transfer(entry_code -> contract). + if i > 0: + expected_logs_after_tx_value.append( + transfer_log( + entry_code_address, selfdestruct_contract_address, i + ) + ) + + # SELFDESTRUCT emits Transfer to a different recipient; for a + # pre-existing contract sending to itself, no log is emitted (balance + # stays). Pre-Cancun, SD also burns on self, but EIP-7708 is + # Amsterdam+, long after EIP-6780 is enabled, so the self-keep path + # applies here. + if ( + sendall_recipient != selfdestruct_contract_address + and selfdestruct_contract_current_balance > 0 + ): + expected_logs_after_tx_value.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient, + selfdestruct_contract_current_balance, + ) + ) + # Balance is always sent to other contracts if sendall_recipient != selfdestruct_contract_address: sendall_final_balances[sendall_recipient] += ( @@ -847,7 +1005,7 @@ def test_selfdestruct_pre_existing( gas_limit=500_000, ) - entry_code_address = tx.created_contract + assert tx.created_contract == entry_code_address post: Dict[Address, Account] = { entry_code_address: Account( @@ -869,6 +1027,15 @@ def test_selfdestruct_pre_existing( else: post[selfdestruct_contract_address] = Account.NONEXISTENT # type: ignore + if fork.is_eip_enabled(7708): + expected_logs = [] + if entry_code_balance > 0: + expected_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + expected_logs.extend(expected_logs_after_tx_value) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -880,6 +1047,7 @@ def test_selfdestruct_created_same_block_different_tx( eip_enabled: bool, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_contract_initial_balance: int, sendall_recipient_addresses: List[Address], call_times: int, @@ -959,6 +1127,45 @@ def test_selfdestruct_created_same_block_different_tx( else: post[selfdestruct_contract_address] = Account.NONEXISTENT # type: ignore + tx1_receipt = None + tx2_receipt = None + if fork.is_eip_enabled(7708): + tx1_logs = [] + if selfdestruct_contract_initial_balance > 0: + tx1_logs.append( + transfer_log( + sender, + selfdestruct_contract_address, + selfdestruct_contract_initial_balance, + ) + ) + tx1_receipt = TransactionReceipt(logs=tx1_logs) + + tx2_logs = [] + if entry_code_balance > 0: + tx2_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + running_balance = selfdestruct_contract_initial_balance + for i in range(call_times): + if i > 0: + tx2_logs.append( + transfer_log( + entry_code_address, selfdestruct_contract_address, i + ) + ) + running_balance += i + if running_balance > 0: + tx2_logs.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient_addresses[0], + running_balance, + ) + ) + running_balance = 0 + tx2_receipt = TransactionReceipt(logs=tx2_logs) + txs = [ Transaction( value=selfdestruct_contract_initial_balance, @@ -966,6 +1173,7 @@ def test_selfdestruct_created_same_block_different_tx( sender=sender, to=None, gas_limit=500_000, + expected_receipt=tx1_receipt, ), Transaction( value=entry_code_balance, @@ -973,6 +1181,7 @@ def test_selfdestruct_created_same_block_different_tx( sender=sender, to=None, gas_limit=500_000, + expected_receipt=tx2_receipt, ), ] @@ -988,6 +1197,7 @@ def test_calling_from_new_contract_to_pre_existing_contract( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, sendall_recipient_addresses: List[Address], create_opcode: Op, call_opcode: Op, @@ -1121,6 +1331,35 @@ def test_calling_from_new_contract_to_pre_existing_contract( gas_limit=500_000, ) + if fork.is_eip_enabled(7708): + # The new contract's body is a DELEGATECALL/CALLCODE to the pre- + # existing selfdestruct code, so SELFDESTRUCT runs in the NEW + # contract's context and transfers its balance to the recipient. + expected_logs = [] + if entry_code_balance > 0: + expected_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + running_balance = selfdestruct_contract_initial_balance + for i in range(call_times): + if i > 0: + expected_logs.append( + transfer_log( + entry_code_address, selfdestruct_contract_address, i + ) + ) + running_balance += i + if running_balance > 0: + expected_logs.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient_addresses[0], + running_balance, + ) + ) + running_balance = 0 + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -1135,6 +1374,7 @@ def test_calling_from_pre_existing_contract_to_new_contract( eip_enabled: bool, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_code: Bytecode, sendall_recipient_addresses: List[Address], call_opcode: Op, @@ -1277,6 +1517,42 @@ def test_calling_from_pre_existing_contract_to_new_contract( else: post[caller_address] = Account.NONEXISTENT # type: ignore + if fork.is_eip_enabled(7708): + # SELFDESTRUCT runs in the caller (pre-existing) contract's context + # via DELEGATECALL/CALLCODE, so the Transfer log attributes the + # balance flow from the caller to the recipient. + expected_logs = [] + if entry_code_balance > 0: + expected_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + if selfdestruct_contract_initial_balance > 0: + # CREATE with value: entry_code -> new selfdestruct_contract + expected_logs.append( + transfer_log( + entry_code_address, + selfdestruct_contract_address, + selfdestruct_contract_initial_balance, + ) + ) + caller_running_balance = pre_existing_contract_initial_balance + for i in range(call_times): + if i > 0: + expected_logs.append( + transfer_log(entry_code_address, caller_address, i) + ) + caller_running_balance += i + if caller_running_balance > 0: + expected_logs.append( + transfer_log( + caller_address, + sendall_recipient_addresses[0], + caller_running_balance, + ) + ) + caller_running_balance = 0 + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -1297,6 +1573,7 @@ def test_create_selfdestruct_same_tx_increased_nonce( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_code: Bytecode, sendall_recipient_addresses: List[Address], create_opcode: Op, @@ -1377,8 +1654,11 @@ def test_create_selfdestruct_same_tx_increased_nonce( Op.EXTCODEHASH(selfdestruct_contract_address), ) + entry_code_address = compute_create_address(address=sender, nonce=0) + # Call the self-destructing contract multiple times as required, increasing # the wei sent each time + expected_logs_after_tx_value: list = [] entry_code_balance = 0 for i, sendall_recipient in zip( range(call_times), cycle(sendall_recipient_addresses) @@ -1399,6 +1679,28 @@ def test_create_selfdestruct_same_tx_increased_nonce( entry_code_balance += i selfdestruct_contract_current_balance += i + # CALL with value > 0 emits a Transfer log (entry_code -> contract). + # The inner CREATE(value=0) prepended to selfdestruct_code does not + # emit a log (zero value). + if i > 0: + expected_logs_after_tx_value.append( + transfer_log( + entry_code_address, selfdestruct_contract_address, i + ) + ) + + # SELFDESTRUCT always sends to a pre-deployed recipient in this test + # (SELF_ADDRESS is not parametrized here), so a Transfer log is + # emitted whenever the contract has a nonzero balance. + if selfdestruct_contract_current_balance > 0: + expected_logs_after_tx_value.append( + transfer_log( + selfdestruct_contract_address, + sendall_recipient, + selfdestruct_contract_current_balance, + ) + ) + # Balance is always sent to other contracts if sendall_recipient != selfdestruct_contract_address: sendall_final_balances[sendall_recipient] += ( @@ -1438,7 +1740,7 @@ def test_create_selfdestruct_same_tx_increased_nonce( gas_limit=1_000_000, ) - entry_code_address = tx.created_contract + assert tx.created_contract == entry_code_address post: Dict[Address, Account] = { entry_code_address: Account( @@ -1468,6 +1770,15 @@ def test_create_selfdestruct_same_tx_increased_nonce( post[selfdestruct_contract_address] = Account.NONEXISTENT # type: ignore + if fork.is_eip_enabled(7708): + expected_logs = [] + if entry_code_balance > 0: + expected_logs.append( + transfer_log(sender, entry_code_address, entry_code_balance) + ) + expected_logs.extend(expected_logs_after_tx_value) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -1478,6 +1789,7 @@ def test_create_and_destroy_multiple_contracts_same_tx( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, num_contracts: int, selfdestruct_contract_initial_balance: int, ) -> None: @@ -1583,6 +1895,23 @@ def test_create_and_destroy_multiple_contracts_same_tx( for addr in contract_addresses: post[addr] = Account.NONEXISTENT # type: ignore + if fork.is_eip_enabled(7708): + # Each contract SELFDESTRUCTs to a shared recipient after being created + # in the same tx. CREATE2 uses value=0 and CALLs use value=0, so the + # only Transfer logs are emitted when each contract's pre-funded + # balance is sent to the recipient via SELFDESTRUCT. + expected_logs = [] + if selfdestruct_contract_initial_balance > 0: + for addr in contract_addresses: + expected_logs.append( + transfer_log( + addr, + sendall_recipient, + selfdestruct_contract_initial_balance, + ) + ) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -1593,6 +1922,7 @@ def test_create_multiple_contracts_destroy_one_then_destroy_other_next_tx( eip_enabled: bool, pre: Alloc, sender: EOA, + fork: Fork, selfdestruct_contract_initial_balance: int, ) -> None: """ @@ -1694,16 +2024,48 @@ def test_create_multiple_contracts_destroy_one_then_destroy_other_next_tx( + Op.STOP ) + tx1_receipt = None + tx2_receipt = None + if fork.is_eip_enabled(7708): + # Tx1: only A SELFDESTRUCTs (flag=1), transferring its pre-funded + # balance to the shared recipient. B gets called with flag=0 and + # returns without emitting any log. + tx1_logs = [] + if selfdestruct_contract_initial_balance > 0: + tx1_logs.append( + transfer_log( + contract_a_address, + sendall_recipient, + selfdestruct_contract_initial_balance, + ) + ) + tx1_receipt = TransactionReceipt(logs=tx1_logs) + + # Tx2: B (now pre-existing) SELFDESTRUCTs transferring its + # pre-funded balance to the recipient. + tx2_logs = [] + if selfdestruct_contract_initial_balance > 0: + tx2_logs.append( + transfer_log( + contract_b_address, + sendall_recipient, + selfdestruct_contract_initial_balance, + ) + ) + tx2_receipt = TransactionReceipt(logs=tx2_logs) + txs = [ Transaction( sender=sender, to=entry_code_address, gas_limit=1_000_000, + expected_receipt=tx1_receipt, ), Transaction( sender=sender, to=tx2_caller, gas_limit=500_000, + expected_receipt=tx2_receipt, ), ] @@ -1742,6 +2104,7 @@ def test_parent_creates_child_selfdestruct_one( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, destroy_parent: bool, selfdestruct_contract_initial_balance: int, ) -> None: @@ -1857,6 +2220,22 @@ def test_parent_creates_child_selfdestruct_one( storage={0: 1}, ) + if fork.is_eip_enabled(7708): + # Only the SELFDESTRUCT that actually runs emits a log. Both parent + # and child are pre-funded via pre.fund_address, so whichever + # SELFDESTRUCTs to the shared recipient transfers its initial_balance. + expected_logs = [] + if selfdestruct_contract_initial_balance > 0: + source = parent_address if destroy_parent else child_address + expected_logs.append( + transfer_log( + source, + sendall_recipient, + selfdestruct_contract_initial_balance, + ) + ) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) @@ -1868,6 +2247,7 @@ def test_recursive_contract_creation_and_selfdestruct( state_test: StateTestFiller, pre: Alloc, sender: EOA, + fork: Fork, recursion_depth: int, selfdestruct_on_unwind: bool, selfdestruct_contract_initial_balance: int, @@ -2022,4 +2402,25 @@ def test_recursive_contract_creation_and_selfdestruct( storage={0: 1}, ) + if fork.is_eip_enabled(7708): + # CREATE/CALL all use value=0, so the only Transfer logs come from + # each SELFDESTRUCT that runs. On unwind every contract SDs, starting + # from the deepest; otherwise only the deepest SDs. + expected_logs = [] + if selfdestruct_contract_initial_balance > 0: + sd_sources = ( + list(reversed(contract_addresses)) + if selfdestruct_on_unwind + else [contract_addresses[-1]] + ) + for addr in sd_sources: + expected_logs.append( + transfer_log( + addr, + sendall_recipient, + selfdestruct_contract_initial_balance, + ) + ) + tx.expected_receipt = TransactionReceipt(logs=expected_logs) + state_test(pre=pre, post=post, tx=tx) From cd8c9815985f40e4a3486f388d764357d33b5c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E4=BD=B3=E8=AA=A0=20Louis=20Tsai?= <72684086+LouisTsai-Csie@users.noreply.github.com> Date: Wed, 13 May 2026 22:25:51 +0200 Subject: [PATCH 074/186] feat(spec-specs, spec-tests): add EIP-7778 block gas accounting without refunds (#2840) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(spec-specs): Implement EIP-7778 Block Gas Accounting without Refunds (#1401) * feat(specs): add eip-7778 implementation * fix(specs) spliting receipt gas from block gas * revert receipt_gas_used * make sure that the calldata floor cost overwrites the tx gas before refund * receipt gas used after refunds * clarify variable naming @gurukamath * revert to using gas used after refunds for cumulative gas in receipt and add gasSpent to receipt * spec(amsterdam): fix code formatting --------- Co-authored-by: Guruprasad Kamath * fix(tests): fix legacy tests to run with eip-7778 (#2048) * fix(tests): fix legacy tests to run with eip-7778 * fix(tests): check gas_spent and gas_used after Amsterdam * feat(spec-tests): add basic eip7778 test (#2045) * feat(spec-tests): add eip-7778 tests for calldata checks (#2060) * feat(spec-tests): add eip-7778 for calldata checks * feat(spec-tests): post review - use code gas_cost function Co-authored-by: Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com> * Apply suggestions from code review --------- Co-authored-by: Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com> Co-authored-by: Mario Vega * fix(tests): Fix gas used/spent in EIP-7702 tests (#2068) * feat(spec-specs): use post refund gas in receipts in EIP-7778 (#2073) * fix(test): Update refspec for EIP-7778 to match latest revision (#2093) * feat(test-forks): Add EIP-7778 * refactor(tests): Condition EIP-7778 tests to EIP inclusion * fix(test): use deterministic iteration order for refund types The set iteration in `build_refund_tx` is non-deterministic due to Python's hash randomization, causing fixture output to vary between runs. Sort by enum value to ensure reproducible fixtures. * doc: remove changelog md * fix: broken auth tx benchmark * doc: add eip checklist * fix: typo * Update tests/benchmark/compute/scenario/test_transaction_types.py * Apply suggestions from code review Co-authored-by: Mario Vega --------- Co-authored-by: Toni Wahrstätter <51536394+nerolation@users.noreply.github.com> Co-authored-by: Guruprasad Kamath Co-authored-by: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Co-authored-by: Mario Vega Co-authored-by: felipe Co-authored-by: spencer-tb --- docs/writing_tests/test_markers.md | 24 + .../testing/src/execution_testing/__init__.py | 3 +- .../pytest_commands/plugins/forks/forks.py | 9 + .../src/execution_testing/forks/__init__.py | 2 + .../src/execution_testing/forks/base_fork.py | 17 + .../forks/forks/eips/amsterdam/eip_7778.py | 16 + .../forks/forks/eips/prague/eip_7702.py | 10 + .../execution_testing/forks/forks/forks.py | 8 + .../src/execution_testing/specs/blockchain.py | 10 + src/ethereum/forks/amsterdam/blocks.py | 1 + src/ethereum/forks/amsterdam/fork.py | 19 +- src/ethereum/forks/amsterdam/vm/__init__.py | 1 + .../__init__.py | 1 + .../eip_checklist_external_coverage.txt | 2 + .../eip_checklist_not_applicable.txt | 17 + .../test_gas_accounting.py | 530 ++++++++++++++++++ .../scenario/test_transaction_types.py | 9 +- 17 files changed, 670 insertions(+), 9 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7778.py create mode 100644 tests/amsterdam/eip7778_block_gas_accounting_without_refunds/__init__.py create mode 100644 tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_external_coverage.txt create mode 100644 tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_not_applicable.txt create mode 100644 tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py diff --git a/docs/writing_tests/test_markers.md b/docs/writing_tests/test_markers.md index 25fce189257..22c613ab498 100644 --- a/docs/writing_tests/test_markers.md +++ b/docs/writing_tests/test_markers.md @@ -203,6 +203,30 @@ def test_something_with_all_system_contracts( In this example, the test will be parameterized for parameter `system_contract` with value `[0x000F3DF6D732807EF1319FB7B8BB8522D0BEAC02]` for fork Cancun. +### `@pytest.mark.with_all_refund_types` + +This marker is used to automatically parameterize a test with all types of refunds that are valid for the fork being tested. + +Useful to mark tests to fail if a new refund type is introduced by a future fork and the test needs to be kept up to date and maintained. + +```python +import pytest + +from execution_testing import Address, Alloc, RefundTypes, StateTestFiller + +@pytest.mark.with_all_refund_types +@pytest.mark.valid_from("Prague") +def test_something_with_all_refund_types( + state_test: StateTestFiller, + pre: Alloc, + refund_type: RefundTypes, +): + pass + +``` + +In this example, the test will be parameterized for parameter `refund_type` with value `[RefundTypes.STORAGE_CLEAR, RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY]` for fork Prague. + ### Covariant Marker Keyword Arguments All fork covariant markers accept the following keyword arguments: diff --git a/packages/testing/src/execution_testing/__init__.py b/packages/testing/src/execution_testing/__init__.py index ae04d86a2e0..e8a5b2e3211 100644 --- a/packages/testing/src/execution_testing/__init__.py +++ b/packages/testing/src/execution_testing/__init__.py @@ -30,7 +30,7 @@ TransactionException, ) from .fixtures import BaseFixture, FixtureCollector -from .forks import Fork, GasCosts, TransitionFork +from .forks import Fork, GasCosts, RefundTypes, TransitionFork from .specs import ( BaseTest, BenchmarkTest, @@ -185,6 +185,7 @@ "ParameterSet", "ReferenceSpec", "ReferenceSpecTypes", + "RefundTypes", "Removable", "Requests", "SequentialAddressLayout", diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py index 2dc7336f6e8..b10bc17c5ec 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py @@ -453,6 +453,15 @@ def covariant_decorator( fork_attribute_name="system_contracts", argnames=["system_contract"], ), + covariant_decorator( + marker_name="with_all_refund_types", + description=( + "marks a test to be parametrized for all refund types at " + "parameter named refund_type" + ), + fork_attribute_name="refund_types", + argnames=["refund_type"], + ), ] diff --git a/packages/testing/src/execution_testing/forks/__init__.py b/packages/testing/src/execution_testing/forks/__init__.py index 9dd5f0d4334..cd333c559e8 100644 --- a/packages/testing/src/execution_testing/forks/__init__.py +++ b/packages/testing/src/execution_testing/forks/__init__.py @@ -1,5 +1,6 @@ """Ethereum test fork definitions.""" +from .base_fork import RefundTypes from .forks.forks import ( BPO1, BPO2, @@ -87,6 +88,7 @@ "TransitionFork", "TransitionForkAdapter", "TransitionForkOrNoneAdapter", + "RefundTypes", "Amsterdam", "ArrowGlacier", "Berlin", diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index c074c3da840..419b27a915b 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -2,6 +2,7 @@ import re from abc import ABCMeta, abstractmethod +from enum import Enum, auto from typing import ( TYPE_CHECKING, Callable, @@ -168,6 +169,13 @@ def __call__( pass +class RefundTypes(Enum): + """Enum used to describe all refund types a fork can have.""" + + STORAGE_CLEAR = auto() + AUTHORIZATION_EXISTING_AUTHORITY = auto() + + class BaseForkMeta(ABCMeta): """Metaclass for BaseFork.""" @@ -979,6 +987,15 @@ def max_request_type(cls) -> int: """Return max request type supported by the fork.""" pass + @classmethod + @abstractmethod + def refund_types(cls) -> List[RefundTypes]: + """ + Return the list of refund types that are possible given current + fork logic. + """ + pass + # Meta information about the fork @classmethod def name(cls) -> str: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7778.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7778.py new file mode 100644 index 00000000000..e7153a7fc8a --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7778.py @@ -0,0 +1,16 @@ +""" +EIP-7778: Block Gas Accounting without Refunds. + +Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas +Accounting. + +https://eips.ethereum.org/EIPS/eip-7778 +""" + +from ....base_fork import BaseFork + + +class EIP7778(BaseFork): + """EIP-7778 class.""" + + pass diff --git a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py index d19fd6009c1..424c4ab2dab 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7702.py @@ -15,6 +15,7 @@ from ....base_fork import ( BaseFork, + RefundTypes, TransactionIntrinsicCostCalculator, ) from ....gas_costs import GasCosts @@ -95,3 +96,12 @@ def fn( return intrinsic_cost return fn + + @classmethod + def refund_types(cls) -> List[RefundTypes]: + """ + At Prague, existing authorization refund is introduced. + """ + refunds = super(EIP7702, cls).refund_types() + refunds.append(RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY) + return refunds diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index d1d6cd06143..454f3d8cabd 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -29,6 +29,7 @@ CalldataGasCalculator, ExcessBlobGasCalculator, MemoryExpansionGasCalculator, + RefundTypes, TransactionDataFloorCostCalculator, TransactionIntrinsicCostCalculator, ) @@ -1199,6 +1200,13 @@ def max_request_type(cls) -> int: """At genesis, no request type is supported, signaled by -1.""" return -1 + @classmethod + def refund_types(cls) -> List[RefundTypes]: + """ + At genesis, storage clearing refund is introduced. + """ + return [RefundTypes.STORAGE_CLEAR] + @classmethod def pre_allocation(cls) -> Mapping: """ diff --git a/packages/testing/src/execution_testing/specs/blockchain.py b/packages/testing/src/execution_testing/specs/blockchain.py index 61ab40360fd..3313e8795f3 100644 --- a/packages/testing/src/execution_testing/specs/blockchain.py +++ b/packages/testing/src/execution_testing/specs/blockchain.py @@ -303,6 +303,8 @@ class Block(Header): """Post state for verification after block execution in BlockchainTest""" block_access_list: Bytes | None = Field(None) """EIP-7928: Block-level access lists (serialized).""" + expected_gas_used: int | None = None + """Expected gas used for the block.""" def set_environment(self, env: Environment) -> Environment: """ @@ -695,6 +697,14 @@ def generate_block_data( f"Verification of block {int(env.number)} failed" ) from e + if block.expected_gas_used is not None: + gas_used = int(transition_tool_output.result.gas_used) + assert gas_used == block.expected_gas_used, ( + f"gas_used ({gas_used}) does not match expected_gas_used " + f"({block.expected_gas_used})" + f", difference: {gas_used - block.expected_gas_used}" + ) + requests_list: List[Bytes] | None = None if fork.header_requests_required(): assert transition_tool_output.result.requests is not None, ( diff --git a/src/ethereum/forks/amsterdam/blocks.py b/src/ethereum/forks/amsterdam/blocks.py index f67d52adfc2..5a4e1b410f0 100644 --- a/src/ethereum/forks/amsterdam/blocks.py +++ b/src/ethereum/forks/amsterdam/blocks.py @@ -360,6 +360,7 @@ class Receipt: cumulative_gas_used: Uint """ Total gas used in the block up to and including this transaction. + This is the gas used after refunds, paid by the user. """ bloom: Bloom diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index bbb1d832193..0af84822dc8 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -654,7 +654,7 @@ def make_receipt( Error in the top level frame of the transaction, if any. cumulative_gas_used : The total gas used so far in the block after the transaction was - executed. + executed. This is the gas used after refunds. logs : The logs produced by the transaction. @@ -1039,16 +1039,17 @@ def process_transaction( # Transactions with less execution_gas_used than the floor pay at the # floor cost. - tx_gas_used_after_refund = max( - tx_gas_used_after_refund, calldata_floor_gas_cost + tx_gas_used = max(tx_gas_used_after_refund, calldata_floor_gas_cost) + block_gas_used_in_tx = max( + tx_gas_used_before_refund, calldata_floor_gas_cost ) - tx_gas_left = tx.gas - tx_gas_used_after_refund + tx_gas_left = tx.gas - tx_gas_used gas_refund_amount = tx_gas_left * effective_gas_price # For non-1559 transactions effective_gas_price == tx.gas_price priority_fee_per_gas = effective_gas_price - block_env.base_fee_per_gas - transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas + transaction_fee = tx_gas_used * priority_fee_per_gas # refund gas sender_balance_after_refund = get_account(tx_state, sender).balance + U256( @@ -1090,11 +1091,15 @@ def process_transaction( ): destroy_account(tx_state, block_env.coinbase) - block_output.block_gas_used += tx_gas_used_after_refund + block_output.cumulative_gas_used += tx_gas_used + block_output.block_gas_used += block_gas_used_in_tx block_output.blob_gas_used += tx_blob_gas_used receipt = make_receipt( - tx, tx_output.error, block_output.block_gas_used, all_logs + tx, + tx_output.error, + block_output.cumulative_gas_used, + all_logs, ) receipt_key = rlp.encode(Uint(index)) diff --git a/src/ethereum/forks/amsterdam/vm/__init__.py b/src/ethereum/forks/amsterdam/vm/__init__.py index 2ae8d4c984c..ff523e2c33c 100644 --- a/src/ethereum/forks/amsterdam/vm/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/__init__.py @@ -88,6 +88,7 @@ class BlockOutput: """ block_gas_used: Uint = Uint(0) + cumulative_gas_used: Uint = Uint(0) transactions_trie: Trie[Bytes, Optional[Bytes | LegacyTransaction]] = ( field(default_factory=lambda: Trie(secured=False, default=None)) ) diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/__init__.py b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/__init__.py new file mode 100644 index 00000000000..fcecd89390c --- /dev/null +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/__init__.py @@ -0,0 +1 @@ +"""Tests for [EIP-7778: Block Gas Accounting without Refunds](https://eips.ethereum.org/EIPS/eip-7778).""" diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_external_coverage.txt b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_external_coverage.txt new file mode 100644 index 00000000000..eafb5d812a7 --- /dev/null +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_external_coverage.txt @@ -0,0 +1,2 @@ +general/code_coverage/eels = Please check https://app.codecov.io/gh/ethereum/execution-specs/pull/2840 for relevant test coverage +general/code_coverage/test_coverage = Please run the test with `--cov` flag for final coverage diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_not_applicable.txt b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_not_applicable.txt new file mode 100644 index 00000000000..54926eee1f9 --- /dev/null +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/eip_checklist_not_applicable.txt @@ -0,0 +1,17 @@ +opcode = EIP does not introduce a new opcode +precompile = EIP does not introduce a new precompile +removed_precompile = EIP does not remove a precompile +system_contract = EIP does not introduce a new system contract +transaction_type = EIP does not introduce a new transaction type +block_header_field = EIP does not add any new block header fields +block_body_field = EIP does not add any new block body fields +gas_cost_changes = EIP does not modify per-operation gas costs +gas_refunds_changes/test/refund_calculation/over = EIP does not change refund calculation, only block-level accounting +gas_refunds_changes/test/refund_calculation/exact = EIP does not change refund calculation, only block-level accounting +gas_refunds_changes/test/refund_calculation/under = EIP does not change refund calculation, only block-level accounting +gas_refunds_changes/test/exceptional_abort/revertable = EIP does not change refund behavior on revertable aborts +gas_refunds_changes/test/exceptional_abort/non_revertable = EIP does not change refund behavior on non-revertable aborts +blob_count_changes = EIP does not introduce any blob count changes +execution_layer_request = EIP does not introduce an execution layer request +new_transaction_validity_constraint = EIP does not introduce a new transaction validity constraint +modified_transaction_validity_constraint = EIP does not introduce a modified transaction validity constraint \ No newline at end of file diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py new file mode 100644 index 00000000000..27f373a1409 --- /dev/null +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py @@ -0,0 +1,530 @@ +""" +Test cases for +[EIP-7778 Block Gas Accounting without Refunds](https://eips.ethereum.org/EIPS/eip-7778). +""" + +from enum import Enum +from typing import Set, Tuple + +import pytest +from execution_testing import ( + Account, + Alloc, + AuthorizationTuple, + Block, + BlockchainTestFiller, + BlockException, + Bytecode, + Environment, + Fork, + RefundTypes, + Transaction, + TransactionException, +) +from execution_testing.base_types import HashInt +from execution_testing.vm import Op + +REFERENCE_SPEC_GIT_PATH = "EIPS/eip-7778.md" +REFERENCE_SPEC_VERSION = "ce17d00b8341032a946301944124c4a6013032d6" + + +def build_refund_tx( + fork: Fork, + pre: Alloc, + post: Alloc, + refund_types: Set[RefundTypes], + refunds_count: int = 1, + refund_tx_reverts: bool = False, + call_data: bytes = b"", + refund_tx_has_extra_gas_limit: bool = False, + exceed_block_gas_limit: bool = False, +) -> Tuple[int, int, int, Transaction]: + """Build a transaction that has different refund types from a fork.""" + # All essential calc functions + intrinsic_cost_calc = fork.transaction_intrinsic_cost_calculator() + max_refund_quotient = fork.max_refund_quotient() + gsc = fork.gas_costs() + data_floor_calc = fork.transaction_data_floor_cost_calculator() + + # Initial account pre loading + initial_fund = 10**18 + refund_tx_sender = pre.fund_eoa(initial_fund) + + # Initialize other aspects of pre-alloc + code = Bytecode() + authorization_list = None + refund_counter = 0 + storage_slots = list(range(HashInt(refunds_count))) + + empty_storage_on_success = False + refund_tx_extra_gas = 1 if refund_tx_has_extra_gas_limit else 0 + + for refund_type in sorted(refund_types, key=lambda r: r.value): + match refund_type: + case RefundTypes.STORAGE_CLEAR: + for slot in storage_slots: + code += Op.SSTORE( + slot, + Op.PUSH0, + # Gas accounting + original_value=1, + new_value=0, + ) + empty_storage_on_success = True + + case RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY: + code += Op.PUSH0 + delegated_contract = pre.deploy_contract(code=Bytecode()) + authorization_list = [ + AuthorizationTuple( + address=delegated_contract, + nonce=0, + signer=pre.fund_eoa(amount=1), + ) + for _ in range(refunds_count) + ] + refund_counter += ( + gsc.REFUND_AUTH_PER_EXISTING_ACCOUNT * refunds_count + ) + case _: + raise ValueError( + f"Unknown refund type: {refund_type} (Test needs update)" + ) + + if refund_tx_reverts: + code += Op.REVERT(0, 0) + + contract_address = pre.deploy_contract( + code=code, + storage=dict.fromkeys(storage_slots, 1), + ) + + gas_used_pre_refund = intrinsic_cost_calc( + calldata=call_data, + return_cost_deducted_prior_execution=True, + authorization_list_or_count=authorization_list, + ) + code.gas_cost(fork) + + # Calculate refund (still applied to user's balance) + if not refund_tx_reverts: + refund_counter += code.refund(fork) + + effective_refund = min( + refund_counter, gas_used_pre_refund // max_refund_quotient + ) + gas_used_post_refund = gas_used_pre_refund - effective_refund + call_data_floor_cost = data_floor_calc(data=call_data) + + refund_tx_block_gas_used = max(call_data_floor_cost, gas_used_pre_refund) + refund_tx_gas_used = max(call_data_floor_cost, gas_used_post_refund) + + # Build refund transaction + refund_tx = Transaction( + to=contract_address, + data=call_data, + gas_limit=refund_tx_block_gas_used + refund_tx_extra_gas, + sender=refund_tx_sender, + authorization_list=authorization_list, + expected_receipt={ + "gas_used": refund_tx_gas_used, + }, + ) + refund_tx_gas_price = ( + refund_tx.gas_price + if refund_tx.gas_price + else refund_tx.max_fee_per_gas + ) + + if ( + refund_tx_reverts + or exceed_block_gas_limit + or not empty_storage_on_success + ): + post[contract_address] = Account( + storage=dict.fromkeys(storage_slots, 1), + ) + else: + post[contract_address] = Account( + storage=dict.fromkeys(storage_slots, 0), + ) + + assert refund_tx_gas_price is not None, ( + "refund_tx_gas_price should not be None" + ) + expected_balance = initial_fund - ( + refund_tx_gas_used * refund_tx_gas_price + ) + + if not exceed_block_gas_limit: + post[refund_tx_sender] = Account(balance=expected_balance) + + return ( + gas_used_post_refund, + gas_used_pre_refund, + call_data_floor_cost, + refund_tx, + ) + + +@pytest.mark.parametrize( + "refund_tx_reverts", + [ + pytest.param(True, id="refund_tx_reverts"), + pytest.param(False, id=""), + ], +) +@pytest.mark.with_all_refund_types() +@pytest.mark.execute(pytest.mark.skip(reason="Requires specific gas price")) +@pytest.mark.valid_from("EIP7778") +def test_simple_gas_accounting( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, + refund_type: RefundTypes, + refund_tx_reverts: bool, +) -> None: + """Test gas accounting for all refund types available in the given fork.""" + refunds_count = 10 + + post = Alloc() + + (_, gas_used_pre_refund, call_data_floor_cost, refund_tx) = ( + build_refund_tx( + fork=fork, + pre=pre, + post=post, + refund_types={refund_type}, + refunds_count=refunds_count, + refund_tx_reverts=refund_tx_reverts, + ) + ) + + refund_tx_block_gas_used = max(gas_used_pre_refund, call_data_floor_cost) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[refund_tx], + expected_gas_used=refund_tx_block_gas_used, + ) + ], + post=post, + ) + + +@pytest.mark.parametrize( + "refund_tx_reverts", + [ + pytest.param(True, id="refund_tx_reverts"), + pytest.param(False, id=""), + ], +) +@pytest.mark.parametrize( + "refund_tx_has_extra_gas_limit", + [ + pytest.param(True, id="refund_tx_has_extra_gas"), + pytest.param(False, id=""), + ], +) +@pytest.mark.parametrize( + "extra_tx_data_floor", + [ + pytest.param(True, id=""), + pytest.param(False, id="extra_tx_hits_data_floor"), + ], +) +@pytest.mark.parametrize( + "exceed_block_gas_limit", + [ + pytest.param(True, marks=pytest.mark.exception_test), + False, + ], +) +@pytest.mark.with_all_refund_types() +@pytest.mark.execute(pytest.mark.skip(reason="Requires specific gas price")) +@pytest.mark.valid_from("EIP7778") +def test_multi_transaction_gas_accounting( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, + refund_type: RefundTypes, + refund_tx_has_extra_gas_limit: bool, + exceed_block_gas_limit: bool, + extra_tx_data_floor: bool, + refund_tx_reverts: bool, +) -> None: + """ + Test block gas accounting with refunds per EIP-7778. + + When exceed_block_gas_limit=True, we create a scenario where: + - Pre-refund gas (gas_used) > block_gas_limit - intrinsic_cost + (no room for another tx with correct EIP-7778 accounting) + - Post-refund gas (gas_spent) <= block_gas_limit - intrinsic_cost + (appears to have room with old refund-based accounting) + + This tests that clients correctly use pre-refund gas for block accounting. + """ + intrinsic_cost_calc = fork.transaction_intrinsic_cost_calculator() + + refunds_count = 10 + stop_bytecode = Op.STOP + stop_address = pre.deterministic_deploy_contract(deploy_code=stop_bytecode) + + post = Alloc() + ( + gas_used_post_refund, + gas_used_pre_refund, + call_data_floor_cost, + refund_tx, + ) = build_refund_tx( + fork=fork, + pre=pre, + post=post, + refund_types={refund_type}, + refunds_count=refunds_count, + refund_tx_reverts=refund_tx_reverts, + call_data=b"", + refund_tx_has_extra_gas_limit=refund_tx_has_extra_gas_limit, + exceed_block_gas_limit=exceed_block_gas_limit, + ) + refund_tx_gas_used = max(gas_used_post_refund, call_data_floor_cost) + refund_tx_block_gas_used = max(gas_used_pre_refund, call_data_floor_cost) + + extra_tx_sender = pre.fund_eoa() + extra_tx_calldata = b"\xff" if extra_tx_data_floor else b"" + extra_tx_intrinsic_gas_cost = intrinsic_cost_calc( + calldata=extra_tx_calldata + ) + + extra_tx = Transaction( + to=stop_address, + data=extra_tx_calldata, + gas_limit=extra_tx_intrinsic_gas_cost, + sender=extra_tx_sender, + expected_receipt={ + "gas_used": refund_tx_gas_used + extra_tx_intrinsic_gas_cost, + }, + error=TransactionException.GAS_ALLOWANCE_EXCEEDED + if exceed_block_gas_limit + else None, + ) + + total_block_gas_used = ( + refund_tx_block_gas_used + extra_tx_intrinsic_gas_cost + ) + if exceed_block_gas_limit: + environment_gas_limit = total_block_gas_used - 1 + else: + environment_gas_limit = total_block_gas_used + + txs = [refund_tx, extra_tx] + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=txs, + exception=BlockException.GAS_USED_OVERFLOW + if exceed_block_gas_limit + else None, + expected_gas_used=total_block_gas_used + if not exceed_block_gas_limit + else None, + gas_limit=environment_gas_limit, + ) + ], + post=post, + genesis_environment=Environment(gas_limit=environment_gas_limit), + ) + + +class CallDataTestType(Enum): + """Refund test type.""" + + DATA_FLOOR_LT_TX_GAS_AFTER_REFUND = -1 + """ + calldata_floor < tx_gas_after_refund. + """ + DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER = 0 + """ + tx_gas_after_refund < calldata_floor < tx_gas_before_refund. + """ + DATA_FLOOR_GT_TX_GAS_BEFORE_REFUND = 1 + """calldata_floor > tx_gas_before_refund.""" + + +@pytest.mark.parametrize( + "refund_tx_reverts", + [ + pytest.param(True, id="refund_tx_reverts"), + pytest.param(False, id=""), + ], +) +@pytest.mark.parametrize( + "calldata_test_type", + [ + CallDataTestType.DATA_FLOOR_LT_TX_GAS_AFTER_REFUND, + CallDataTestType.DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER, + CallDataTestType.DATA_FLOOR_GT_TX_GAS_BEFORE_REFUND, + ], +) +@pytest.mark.with_all_refund_types() +@pytest.mark.valid_from("EIP7778") +def test_varying_calldata_costs( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, + refund_type: RefundTypes, + refund_tx_reverts: bool, + calldata_test_type: CallDataTestType, +) -> None: + """ + Test by varying the calldata_floor_cost. + + Performs tests for the following 3 scenarios. + + 1. calldata_floor < tx_gas_after_refund + 2. tx_gas_after_refund < calldata_floor < tx_gas_before_refund + 3. calldata_floor > tx_gas_before_refund + """ + if refund_type == RefundTypes.STORAGE_CLEAR: + if ( + refund_tx_reverts + and calldata_test_type + == CallDataTestType.DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER + ): + pytest.skip( + "calldata_cost cannot be between pre and post refund gas" + "since refund is zero when execution reverts" + ) + + match refund_type: + case RefundTypes.STORAGE_CLEAR: + bytes_to_add_per_iteration = b"00" * 2 + case RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY: + bytes_to_add_per_iteration = b"00" * 10 + case _: + raise ValueError( + f"Unknown refund type: {refund_type} (Test needs update)" + ) + + data = b"" + + # Time to start searching for appropriate call data for each scenario + num_iterations = 200 + # Currently in EIP-7778, the optimal call data is found in about + # 30 iterations for CallDataTestType.DATA_FLOOR_GT_TX_GAS_BEFORE_REFUND. + # Setting this higher just to make it + # a bit more future proof if the gas calc logic changes + found_call_data = False + for _ in range(num_iterations): + post = Alloc() + + ( + gas_used_post_refund, + gas_used_pre_refund, + call_data_floor_cost, + refund_tx, + ) = build_refund_tx( + fork=fork, + pre=pre, + post=post, + refund_types={refund_type}, + refund_tx_reverts=refund_tx_reverts, + call_data=data, + ) + + if ( + calldata_test_type + == CallDataTestType.DATA_FLOOR_LT_TX_GAS_AFTER_REFUND + ): + if call_data_floor_cost < gas_used_post_refund: + found_call_data = True + break + elif ( + calldata_test_type + == CallDataTestType.DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER + ): + if ( + gas_used_post_refund + < call_data_floor_cost + < gas_used_pre_refund + ): + found_call_data = True + break + elif ( + calldata_test_type + == CallDataTestType.DATA_FLOOR_GT_TX_GAS_BEFORE_REFUND + ): + if gas_used_pre_refund < call_data_floor_cost: + found_call_data = True + break + else: + raise ValueError("Invalid calldata test type") + + data += bytes_to_add_per_iteration + + if not found_call_data: + raise ValueError( + f"Could not find the call_data with {num_iterations} iterations." + ) + + refund_tx_block_gas_used = max(call_data_floor_cost, gas_used_pre_refund) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[refund_tx], + expected_gas_used=refund_tx_block_gas_used, + ) + ], + post=post, + ) + + +@pytest.mark.parametrize( + "refund_tx_reverts", + [ + pytest.param(True, id="refund_tx_reverts"), + pytest.param(False, id=""), + ], +) +@pytest.mark.execute(pytest.mark.skip(reason="Requires specific gas price")) +@pytest.mark.valid_from("Amsterdam") +def test_multiple_refund_types_in_one_tx( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, + refund_tx_reverts: bool, +) -> None: + """Test gas accounting for all refund types available in the given fork.""" + refunds_count = 10 + + post = Alloc() + refund_types = set(fork.refund_types()) + + (_, gas_used_pre_refund, call_data_floor_cost, refund_tx) = ( + build_refund_tx( + fork=fork, + pre=pre, + post=post, + refund_types=refund_types, + refunds_count=refunds_count, + refund_tx_reverts=refund_tx_reverts, + ) + ) + + refund_tx_block_gas_used = max(gas_used_pre_refund, call_data_floor_cost) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[refund_tx], + expected_gas_used=refund_tx_block_gas_used, + ) + ], + post=post, + ) diff --git a/tests/benchmark/compute/scenario/test_transaction_types.py b/tests/benchmark/compute/scenario/test_transaction_types.py index b23d3180d22..5d4c3d1b002 100644 --- a/tests/benchmark/compute/scenario/test_transaction_types.py +++ b/tests/benchmark/compute/scenario/test_transaction_types.py @@ -612,11 +612,18 @@ def test_auth_transaction( ) ) + # EIP-7778: refunds no longer reduce block-level gas accounting + expected_gas_usage = ( + total_gas_used + if fork.is_eip_enabled(7778) + else total_gas_used - total_refund + ) + benchmark_test( pre=pre, post={}, blocks=[Block(txs=txs)], - expected_benchmark_gas_used=total_gas_used - total_refund, + expected_benchmark_gas_used=expected_gas_usage, ) From b087114c2610616ebe72aa5e0ea446e5c7a3e852 Mon Sep 17 00:00:00 2001 From: Edgar Date: Wed, 13 May 2026 22:43:47 +0200 Subject: [PATCH 075/186] fix(consume): add ethereum/execution-specs to SUPPORTED_REPOS (#2849) `FixtureDownloader.get_cache_path` versions the on-disk cache directory by release tag only when the release URL's owner/repo appears in `SUPPORTED_REPOS`. Otherwise it falls through to the unversioned `cache_folder / "other" / ` path. When the BAL fixture release was moved from `ethereum/execution-spec-tests` to `ethereum/execution-specs` for `tests-bal@v7.1.0`, the new URL stopped being recognized as a release URL. A v7.0.0 download from a prior session, cached at `other/fixtures_bal/`, kept satisfying every subsequent request, including ones for v7.1.0. Consumers got stale fixtures with no warning. Add `ethereum/execution-specs` to `SUPPORTED_REPOS` so its release URLs hit the versioned cache path. Add regression tests covering `is_release_url` against every supported repo and asserting the new entry is present. Discovered while validating ethrex against tests-bal@v7.1.0: 76 SD-related ef-tests appeared to fail due to a spec mismatch, but the client was actually executing v7.1.0 semantics against v7.0.0 fixtures served by the stale cache. After clearing `~/.cache/ethereum-execution-spec-tests/cached_downloads/` all 2145 amsterdam tests pass. --- .../plugins/consume/releases.py | 1 + .../plugins/consume/tests/test_releases.py | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/releases.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/releases.py index 159d7d467d1..556fa7fe2c3 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/releases.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/releases.py @@ -20,6 +20,7 @@ SUPPORTED_REPOS = [ "ethereum/execution-spec-tests", + "ethereum/execution-specs", "ethereum/tests", "ethereum/legacytests", ] diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/test_releases.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/test_releases.py index f34479b1dff..0b36da6228b 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/test_releases.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/tests/test_releases.py @@ -7,8 +7,10 @@ import pytest from ..releases import ( + SUPPORTED_REPOS, ReleaseInformation, get_release_url_from_release_information, + is_release_url, parse_release_information_from_file, ) @@ -61,3 +63,62 @@ def test_release_parsing( ) == get_release_url_from_release_information( release_name, release_information ) + + +@pytest.mark.parametrize( + "url,expected", + [ + # All currently supported release-hosting repos must be recognized so + # `FixtureDownloader.get_cache_path` versions the cache directory by + # release tag. A repo missing from `SUPPORTED_REPOS` falls through to + # the unversioned `cache_folder / "other" / archive_name` path, which + # silently shadows newer releases with the same archive filename. + ( + "https://github.com/ethereum/execution-spec-tests/releases/download/v3.0.0/fixtures_stable.tar.gz", + True, + ), + ( + "https://github.com/ethereum/execution-specs/releases/download/tests-bal%40v7.1.0/fixtures_bal.tar.gz", + True, + ), + ( + "https://github.com/ethereum/tests/releases/download/v14.0/some.tar.gz", + True, + ), + ( + "https://github.com/ethereum/legacytests/releases/download/v1.0/some.tar.gz", + True, + ), + ( + # Not a recognized repo; must NOT match. + "https://github.com/some-fork/execution-spec-tests/releases/download/v1/foo.tar.gz", + False, + ), + ( + # Local path, not a URL. + "./fixtures", + False, + ), + ], +) +def test_is_release_url_covers_supported_repos( + url: str, expected: bool +) -> None: + """ + All entries in `SUPPORTED_REPOS` must be matched by `is_release_url`. + + Regression test for bal-devnet-7: when the BAL fixture URL moved from + `execution-spec-tests` to `execution-specs`, the new URL stopped being + recognized as a release URL, so the cache key dropped the version tag and + a `tests-bal@v7.0.0` download from a prior session silently shadowed + `tests-bal@v7.1.0`. + """ + assert is_release_url(url) is expected + + +def test_supported_repos_contains_execution_specs() -> None: + """ + `ethereum/execution-specs` hosts the BAL fixture releases (from + `tests-bal@v7.1.0` onward) and must be in `SUPPORTED_REPOS`. + """ + assert "ethereum/execution-specs" in SUPPORTED_REPOS From cc8022a2340a55a825f44b8db9105785a4cbb83f Mon Sep 17 00:00:00 2001 From: danceratopz Date: Wed, 13 May 2026 23:01:58 +0200 Subject: [PATCH 076/186] refactor(tests): Use `filter_combinations` marker to drop infeasible cell in `test_varying_calldata_costs` (#2852) `STORAGE_CLEAR` refund is zero on revert, so `gas_used_pre_refund == gas_used_post_refund` and the `(post, pre)` interval that `DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER` requires is empty. Replace the runtime `pytest.skip()` with the `filter_combinations` marker introduced in #2543, which runs in `pytest_collection_modifyitems` and can express predicates across covariant-marker-injected and inline parametrize axes uniformly. Keeps `with_all_refund_types()` so new refund types added to the fork in future automatically participate, preserves the original three-decorator parametrize stack, and produces byte-identical fixture IDs and content vs the pre-refactor branch (verified via `diff` on `varying_calldata_costs.json` keys and bodies). The two infeasible items per fork are now deselected at collection time rather than skipped at runtime. --- .../test_gas_accounting.py | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py index 27f373a1409..1b6a6be1d81 100644 --- a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py @@ -370,6 +370,18 @@ class CallDataTestType(Enum): ], ) @pytest.mark.with_all_refund_types() +@pytest.mark.filter_combinations( + lambda refund_type, refund_tx_reverts, calldata_test_type, **_: not ( + refund_type == RefundTypes.STORAGE_CLEAR + and refund_tx_reverts + and calldata_test_type + == CallDataTestType.DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER + ), + reason=( + "STORAGE_CLEAR refund is zero on revert, so the (post, pre) " + "interval that DATA_FLOOR_BETWEEN needs is empty" + ), +) @pytest.mark.valid_from("EIP7778") def test_varying_calldata_costs( blockchain_test: BlockchainTestFiller, @@ -388,17 +400,6 @@ def test_varying_calldata_costs( 2. tx_gas_after_refund < calldata_floor < tx_gas_before_refund 3. calldata_floor > tx_gas_before_refund """ - if refund_type == RefundTypes.STORAGE_CLEAR: - if ( - refund_tx_reverts - and calldata_test_type - == CallDataTestType.DATA_FLOOR_BETWEEN_TX_GAS_BEFORE_AND_AFTER - ): - pytest.skip( - "calldata_cost cannot be between pre and post refund gas" - "since refund is zero when execution reverts" - ) - match refund_type: case RefundTypes.STORAGE_CLEAR: bytes_to_add_per_iteration = b"00" * 2 From d61f7ac51d5fb058186e9d75013d763fe5aabdb6 Mon Sep 17 00:00:00 2001 From: felipe Date: Wed, 13 May 2026 16:41:24 -0600 Subject: [PATCH 077/186] feat(test-cli): Add support for testing block building via simulator (#2679) * feat(test-cli): Add support for testing block building via simulator - Test build building via ``testing_buildBlockV1``, validating the built block, and re-consuming against the client * chore: pretty diff BALs on errors * refactor(test): cleanup based on comments on PR #2679 * chore: cleanup from comments on PR #2679 * chore: initial docs for build-block * chore: e2e run for block-building tests; tighten up docs --- .github/workflows/hive-consume.yaml | 25 +- docs/running_tests/consume/simulators.md | 4 + docs/running_tests/running.md | 23 ++ packages/testing/pyproject.toml | 1 + .../cli/pytest_commands/build_block.py | 43 +++ .../plugins/consume/simulators/base.py | 1 + .../simulators/build_block/__init__.py | 1 + .../simulators/build_block/conftest.py | 66 ++++ .../simulator_logic/test_via_build.py | 333 ++++++++++++++++++ .../cli/pytest_commands/processors.py | 32 +- .../execution_testing/fixtures/blockchain.py | 24 ++ .../testing/src/execution_testing/rpc/rpc.py | 12 +- 12 files changed, 534 insertions(+), 31 deletions(-) create mode 100644 packages/testing/src/execution_testing/cli/pytest_commands/build_block.py create mode 100644 packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/__init__.py create mode 100644 packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/conftest.py create mode 100644 packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/simulator_logic/test_via_build.py diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index b3f439789cf..3d726814465 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -20,6 +20,7 @@ on: - ".github/actions/load-docker-images/**" - ".github/configs/hive/**" - "packages/testing/src/execution_testing/cli/pytest_commands/consume.py" + - "packages/testing/src/execution_testing/cli/pytest_commands/build_block.py" - "packages/testing/src/execution_testing/cli/pytest_commands/pytest_ini_files/pytest-consume.ini" - "packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/**" - "packages/testing/src/execution_testing/cli/pytest_commands/plugins/pytest_hive/**" @@ -106,15 +107,27 @@ jobs: mode: simulator simulator: ethereum/eels/consume-sync sim_limit: ".*test_block_at_rlp_limit_with_logs.*Osaka.*" - - name: Dev Mode + - name: Dev Mode Consume Engine mode: dev - consume_command: engine + cli_command: consume engine test_filter: "Osaka and test_block_at_rlp_limit_with_logs" # TODO: Enable once we have a release with the pre-alloc builder format cf #2140 - # - name: dev-mode-enginex + # - name: Dev Mode Consume EngineX # mode: dev - # consume_command: enginex + # cli_command: consume enginex # test_filter: "(fork_shanghai or fork_cancun) and push0" + # NOTE: build-block uses testing_buildBlockV1 on the HTTP RPC port + # (8545), which has a smaller body cap than the Engine API port + # (8551); avoid filters that target near-block-size-limit tests. + - name: Dev Mode Build Block + mode: dev + cli_command: build-block + test_filter: "Osaka and test_clz_stack_underflow" + # TODO: Enable once eels/build-block simulator is added to Hive + # - name: Build Block + # mode: simulator + # simulator: ethereum/eels/build-block + # sim_limit: ".*test_block_at_rlp_limit_with_logs.*Osaka.*" steps: - name: Checkout execution-specs uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -186,14 +199,14 @@ jobs: hive-path: hive timeout: "30" - - name: Run consume in dev mode + - name: Run dev mode command if: matrix.mode == 'dev' working-directory: execution-specs env: HIVE_SIMULATOR: ${{ steps.start-hive.outputs.hive-url }} run: | uv sync --all-extras - uv run consume ${{ matrix.consume_command }} --input ${{ env.FIXTURES_URL }} -k "${{ matrix.test_filter }}" + uv run ${{ matrix.cli_command }} --input ${{ env.FIXTURES_URL }} -k "${{ matrix.test_filter }}" - name: Upload Hive logs if: always() diff --git a/docs/running_tests/consume/simulators.md b/docs/running_tests/consume/simulators.md index f8b88306785..f38fbe476c8 100644 --- a/docs/running_tests/consume/simulators.md +++ b/docs/running_tests/consume/simulators.md @@ -14,3 +14,7 @@ uv run consume [OPTIONS] - Help [setting up](../hive/index.md) and [starting Hive in dev mode](../hive/dev_mode.md). - For an explanation of how the `consume` simulators work, see the [Engine](../running.md#engine) and [RLP](../running.md#rlp) sections in [Running Tests](../running.md). - Help for relevant options can be found in [Consume Cache and Fixture Inputs](./cache.md) and [Useful Pytest Options](../useful_pytest_options.md). + +## Related: Block Building + +A separate hive simulator [`build-block`](../running.md#block-building) is also fixture-driven but tests the client's **producer-side** path via the `testing_buildBlockV1` engine-API testing-namespace endpoint, rather than the consumer-side import path that the simulators above exercise. diff --git a/docs/running_tests/running.md b/docs/running_tests/running.md index d09a1b3003c..d5278726ca4 100644 --- a/docs/running_tests/running.md +++ b/docs/running_tests/running.md @@ -17,6 +17,7 @@ Both `consume` and `execute` provide sub-commands which correspond to different | [`consume enginex`](#enginex) | Client imports blocks via Engine API in Hive, optimized by client reuse | EVM, block processing, Engine API | Staging, Hive | System test | | [`consume sync`](#sync) | Client syncs from another client using Engine API in Hive | EVM, block processing, Engine API, P2P sync | Staging, Hive | System test | | [`consume rlp`](#rlp) | Client imports RLP-encoded blocks upon start-up in Hive | EVM, block processing, RLP import (sync\*) | Staging, Hive | System test | +| [`build-block`](#block-building) | Client builds blocks via `testing_buildBlockV1` in Hive, validated against fixture | EVM, block production, Engine API (testing namespace) | Staging, Hive | System test | | [`execute hive`](./execute/hive.md) | Tests executed against a client via JSON RPC `eth_sendRawTransaction` in Hive | EVM, JSON RPC, mempool | Staging, Hive | System test | | [`execute remote`](./execute/remote.md) | Tests executed against a client via JSON RPC `eth_sendRawTransaction` on a live network | EVM, JSON RPC, mempool, EL-EL/EL-CL interaction (indirectly) | Production | System Test | @@ -144,6 +145,28 @@ The `consume sync` command: 5. **Monitors sync progress** and validates that the sync client reaches the same state. 6. **Verifies final state** matches between both clients. +## Block Building + +| Nomenclature | | +| -------------- | ------------------------ | +| Command | `build-block` | +| Simulator | `eels/build-block` | +| Fixture format | `blockchain_test_engine` | + +The block-building method tests the **producer-side** of an execution client: rather than asking the client to validate and import a pre-built block, it asks the client to build a block from inputs (parent, payload attributes, transactions) and then validates the resulting block field-by-field against the fixture's expected block. This exercises tx ordering, gas accounting, payload assembly, and (for fork ≥ Prague) `executionRequests` derivation. + +The endpoint used is `testing_buildBlockV1`, an engine-API testing-namespace method exposed by `ethpandaops/:master` (and similar performance builds). It is not part of the standard Engine API — the testing namespace is opt-in and intended for fixture-driven block-building verification. + +The `build-block` command, for each valid payload in the fixture: + +1. **Builds the block** via `testing_buildBlockV1(parent_hash, payload_attributes, transactions, extra_data)`. The client returns its own constructed `ExecutionPayload`. +2. **Validates execution-dependent fields** of the built payload against the fixture's expected payload (everything except `gas_limit` and `block_hash`, which depend on client-side EIP-1559 elasticity and are validated via a range check separately). +3. **Validates `executionRequests`** for fork ≥ Prague (`engine_newPayloadV4+`). +4. **Imports the fixture block** (not the client-built one) via `engine_newPayloadVX` so the chain advances with the fixture's expected gas limit and block hash. +5. **Advances the chain** via `engine_forkchoiceUpdatedVX`. + +This complements `consume engine`: where `consume engine` tests the client's payload-validation path, `build-block` tests its payload-production path against the same fixtures. + ## Engine vs RLP Simulator The RLP Simulator (`eels/consume-rlp`) and the Engine Simulator (`eels/consume-engine`) should be seen as complimentary to one another. Although they execute the same underlying EVM test cases, the block validation logic is executed via different client code paths (using different [fixture formats](./test_formats/index.md)). Therefore, ideally, **both simulators should be executed for full coverage**. diff --git a/packages/testing/pyproject.toml b/packages/testing/pyproject.toml index 28a07929f12..f50ec6d049a 100644 --- a/packages/testing/pyproject.toml +++ b/packages/testing/pyproject.toml @@ -84,6 +84,7 @@ checkfixtures = "execution_testing.cli.check_fixtures:check_fixtures" check_eip_versions = "execution_testing.cli.pytest_commands.check_eip_versions:check_eip_versions" consume = "execution_testing.cli.pytest_commands.consume:consume" protec = "execution_testing.cli.pytest_commands.consume:consume" +build-block = "execution_testing.cli.pytest_commands.build_block:build_block" checklist = "execution_testing.cli.pytest_commands.checklist:checklist" generate_checklist_stubs = "execution_testing.cli.generate_checklist_stubs:generate_checklist_stubs" genindex = "execution_testing.cli.gen_index:generate_fixtures_index_cli" diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/build_block.py b/packages/testing/src/execution_testing/cli/pytest_commands/build_block.py new file mode 100644 index 00000000000..102436ffacf --- /dev/null +++ b/packages/testing/src/execution_testing/cli/pytest_commands/build_block.py @@ -0,0 +1,43 @@ +"""CLI entry point for the `build-block` pytest-based command.""" + +from pathlib import Path +from typing import Any, List + +import click + +from .base import PytestCommand, common_pytest_options +from .processors import ( + ConsumeCommandProcessor, + HelpFlagsProcessor, + HiveEnvironmentProcessor, +) + + +def create_build_block_command() -> PytestCommand: + """Initialize the build-block command with paths and processors.""" + base_path = Path("cli/pytest_commands/plugins/consume") + command_logic_test_paths = [ + base_path / "simulators" / "simulator_logic" / "test_via_build.py" + ] + return PytestCommand( + config_file="pytest-consume.ini", + argument_processors=[ + HelpFlagsProcessor("consume"), + HiveEnvironmentProcessor(command_name="build_block"), + ConsumeCommandProcessor(is_hive=True), + ], + command_logic_test_paths=command_logic_test_paths, + ) + + +@click.command( + name="build-block", + context_settings={"ignore_unknown_options": True}, +) +@common_pytest_options +def build_block(pytest_args: List[str], **kwargs: Any) -> None: + """Test block building via testing_buildBlockV1.""" + del kwargs + + cmd = create_build_block_command() + cmd.execute(list(pytest_args)) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/base.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/base.py index 5780353cf68..969a7a06e67 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/base.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/base.py @@ -34,6 +34,7 @@ def check_live_port(test_suite_name: str) -> Literal[8545, 8551]: "eels/consume-engine", "eels/consume-enginex", "eels/consume-sync", + "eels/build-block", }: return 8551 raise ValueError( diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/__init__.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/__init__.py new file mode 100644 index 00000000000..91f13d8b15f --- /dev/null +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/__init__.py @@ -0,0 +1 @@ +"""Pytest configuration for the build-block simulator.""" diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/conftest.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/conftest.py new file mode 100644 index 00000000000..e23b5d03563 --- /dev/null +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/build_block/conftest.py @@ -0,0 +1,66 @@ +""" +Pytest fixtures for the `build-block` simulator. + +Configures the hive back-end & EL clients for block building correctness +testing via the ``testing_buildBlockV1`` endpoint. +""" + +import io +from typing import Mapping + +import pytest +from hive.client import Client + +from execution_testing.fixtures import BlockchainEngineFixture +from execution_testing.fixtures.blockchain import FixtureHeader +from execution_testing.rpc import TestingRPC + +pytest_plugins = ( + "execution_testing.cli.pytest_commands.plugins.pytest_hive.pytest_hive", + "execution_testing.cli.pytest_commands.plugins.consume.simulators.base", + "execution_testing.cli.pytest_commands.plugins.consume.simulators.single_test_client", + "execution_testing.cli.pytest_commands.plugins.consume.simulators.test_case_description", + "execution_testing.cli.pytest_commands.plugins.consume.simulators.timing_data", + "execution_testing.cli.pytest_commands.plugins.consume.simulators.exceptions", + "execution_testing.cli.pytest_commands.plugins.consume.simulators.engine_api", +) + + +def pytest_configure(config: pytest.Config) -> None: + """Set the supported fixture formats for the build-block simulator.""" + config.supported_fixture_formats = [BlockchainEngineFixture] # type: ignore[attr-defined] + + +@pytest.fixture(scope="module") +def test_suite_name() -> str: + """The name of the hive test suite used in this simulator.""" + return "eels/build-block" + + +@pytest.fixture(scope="module") +def test_suite_description() -> str: + """The description of the hive test suite used in this simulator.""" + return ( + "Test block building correctness via the " + "testing_buildBlockV1 endpoint." + ) + + +@pytest.fixture(scope="function") +def client_files( + buffered_genesis: io.BufferedReader, +) -> Mapping[str, io.BufferedReader]: + """Define the files that hive will start the client with.""" + return {"/genesis.json": buffered_genesis} + + +@pytest.fixture(scope="function") +def genesis_header(fixture: BlockchainEngineFixture) -> FixtureHeader: + """Provide the genesis header from the fixture.""" + return fixture.genesis + + +@pytest.fixture(scope="function") +def testing_rpc(client: Client) -> TestingRPC: + """Initialize Testing RPC client for the execution client under test.""" + return TestingRPC(f"http://{client.ip}:8545") diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/simulator_logic/test_via_build.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/simulator_logic/test_via_build.py new file mode 100644 index 00000000000..00350737c1a --- /dev/null +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/simulator_logic/test_via_build.py @@ -0,0 +1,333 @@ +""" +A hive based simulator that tests block building correctness via the +``testing_buildBlockV1`` endpoint. + +For each valid payload in a fixture, transactions and block attributes +are sent to the block building endpoint. The resulting block is validated +field-by-field against the fixture's expected block, then imported back +into the client via ``engine_newPayloadVX`` and +``engine_forkchoiceUpdatedVX`` to advance the chain. +""" + +import json +from difflib import unified_diff +from typing import List + +from execution_testing.base_types import Bytes +from execution_testing.fixtures import BlockchainEngineFixture +from execution_testing.fixtures.blockchain import ( + FixtureEngineNewPayload, + FixtureExecutionPayload, + FixtureHeader, +) +from execution_testing.logging import get_logger +from execution_testing.rpc import ( + EngineRPC, + EthRPC, + ForkchoiceUpdateTimeoutError, + TestingRPC, +) +from execution_testing.rpc.rpc_types import ( + ForkchoiceState, + PayloadStatusEnum, +) +from execution_testing.test_types.block_access_list import BlockAccessList + +from ..helpers.exceptions import ( + GenesisBlockMismatchExceptionError, + LoggedError, +) +from ..helpers.timing import TimingData + +logger = get_logger(__name__) + + +def _format_block_access_list_diff( + expected_rlp: bytes | None, + built_rlp: bytes | None, +) -> str: + """Return a readable diff for a BAL mismatch.""" + if expected_rlp is None or built_rlp is None: + return f"expected {expected_rlp!r}, got {built_rlp!r}" + + try: + expected_bal = BlockAccessList.from_rlp(Bytes(expected_rlp)) + built_bal = BlockAccessList.from_rlp(Bytes(built_rlp)) + except Exception as exc: + return ( + f"expected {expected_rlp!r}, got {built_rlp!r} " + f"(BAL decode failed: {exc})" + ) + + expected_json = json.dumps( + expected_bal.model_dump(mode="json"), + indent=2, + sort_keys=True, + ) + built_json = json.dumps( + built_bal.model_dump(mode="json"), + indent=2, + sort_keys=True, + ) + diff = "\n".join( + unified_diff( + expected_json.splitlines(), + built_json.splitlines(), + fromfile="expected_bal", + tofile="client_built_bal", + lineterm="", + ) + ) + return ( + f"expected {expected_rlp!r}, got {built_rlp!r}\n" + "decoded BAL diff relative to expected BAL:\n" + " '-' lines are present in the expected BAL but missing from the " + "client-built BAL.\n" + " '+' lines are extra or changed in the client-built BAL compared " + "to the expected BAL.\n" + f"{diff}" + ) + + +def _validate_gas_limit( + built: FixtureExecutionPayload, + parent_gas_limit: int, +) -> None: + """Validate the built block's gas limit is within EIP-1559 range.""" + built_gas_limit = int(built.gas_limit) + max_delta = parent_gas_limit // 1024 + + if abs(built_gas_limit - parent_gas_limit) >= max_delta: + raise LoggedError( + f"Gas limit for block {built.number} outside " + f"EIP-1559 range: parent={parent_gas_limit} " + f"(±{max_delta}), got {built.gas_limit}" + ) + + +def _validate_built_block( + built: FixtureExecutionPayload, + expected: FixtureExecutionPayload, + parent_gas_limit: int, +) -> None: + """ + Validate the built block against the fixture's expected block. + + Check all execution-dependent fields for exact match and verify + the gas limit is within the valid EIP-1559 range. + """ + _validate_gas_limit(built, parent_gas_limit) + + mismatches: List[str] = [] + + # All FixtureExecutionPayload fields are validated except: + # - gas_limit: testing_buildBlockV1 doesn't accept it; the client + # picks its own via EIP-1559 (validated separately by range check). + # - block_hash: depends on gas_limit, so it will differ too. + validated_fields = tuple( + name + for name in FixtureExecutionPayload.model_fields + if name not in {"gas_limit", "block_hash"} + ) + for field in validated_fields: + built_val = getattr(built, field) + expected_val = getattr(expected, field) + if built_val != expected_val: + if field == "block_access_list": + mismatches.append( + " block_access_list:\n" + + _format_block_access_list_diff(expected_val, built_val) + ) + continue + mismatches.append( + f" {field}: expected {expected_val}, got {built_val}" + ) + + if mismatches: + detail = "\n".join(mismatches) + raise LoggedError( + f"Block validation failed for block {expected.number}:\n{detail}" + ) + + logger.info(f"Block validated for block {expected.number}.") + + +def _bootstrap_engine_at_genesis( + engine_rpc: EngineRPC, + eth_rpc: EthRPC, + fixture: BlockchainEngineFixture, + genesis_header: FixtureHeader, + timing_data: TimingData, +) -> None: + """Send initial FCU to genesis and verify the client's genesis hash.""" + with timing_data.time("Initial forkchoice update"): + logger.info("Sending initial forkchoice update to genesis block...") + try: + response = engine_rpc.forkchoice_updated_with_retry( + forkchoice_state=ForkchoiceState( + head_block_hash=fixture.genesis.block_hash, + ), + forkchoice_version=fixture.payloads[ + 0 + ].forkchoice_updated_version, + ) + if response.payload_status.status != PayloadStatusEnum.VALID: + raise LoggedError( + "Unexpected status on forkchoice updated to " + f"genesis: {response.payload_status.status}" + ) + except ForkchoiceUpdateTimeoutError as e: + raise LoggedError( + f"Timed out waiting for forkchoice update to genesis: {e}" + ) from None + + with timing_data.time("Get genesis block"): + logger.info("Calling getBlockByNumber to get genesis block...") + genesis_block = eth_rpc.get_block_by_number(0) + assert genesis_block is not None, "genesis_block is None" + if genesis_block["hash"] != str(genesis_header.block_hash): + raise GenesisBlockMismatchExceptionError( + expected_header=genesis_header, + got_genesis_block=genesis_block, + ) + + +def _build_validate_and_advance( + testing_rpc: TestingRPC, + engine_rpc: EngineRPC, + payload: FixtureEngineNewPayload, + parent_gas_limit: int, + block_index: int, + total_blocks: int, + total_build_timing: TimingData, +) -> int: + """ + Build, validate, import, and advance the chain for one payload. + + Returns the new ``parent_gas_limit`` to use for the next block (taken + from the fixture's expected payload, not the client-built one, since + we import the fixture block to advance the chain). + """ + expected_payload = payload.params[0] + logger.info( + f"Building block {block_index + 1}/{total_blocks} " + f"(number {expected_payload.number})..." + ) + with total_build_timing.time(f"Block {block_index + 1}") as block_timing: + # 1. Build the block + with block_timing.time("testing_buildBlockV1"): + build_response = testing_rpc.build_block( + parent_block_hash=expected_payload.parent_hash, + payload_attributes=payload.get_payload_attributes(), + transactions=expected_payload.transactions, + extra_data=expected_payload.extra_data, + ) + + # 2. Validate fields + gas limit range + _validate_built_block( + built=build_response.execution_payload, + expected=expected_payload, + parent_gas_limit=parent_gas_limit, + ) + + # 3. Validate execution_requests (V4+) + if payload.new_payload_version >= 4: + expected_requests = ( + payload.params[3] if len(payload.params) >= 4 else None + ) + if build_response.execution_requests != expected_requests: + raise LoggedError( + f"execution_requests mismatch for block " + f"{expected_payload.number}: expected " + f"{expected_requests}, got " + f"{build_response.execution_requests}" + ) + + # 4. Import the fixture block (not the built block) so the chain + # advances with the expected gas limit and block hash. + with block_timing.time( + f"engine_newPayloadV{payload.new_payload_version}" + ): + logger.info( + "Importing block via " + f"engine_newPayloadV{payload.new_payload_version}..." + ) + import_response = engine_rpc.new_payload( + *payload.params, + version=payload.new_payload_version, + ) + if import_response.status != PayloadStatusEnum.VALID: + raise LoggedError( + "Unexpected status importing " + f"block: {import_response.status}" + ) + + # 5. Advance the chain via forkchoice update + v = payload.forkchoice_updated_version + with block_timing.time(f"engine_forkchoiceUpdatedV{v}"): + logger.info(f"Sending engine_forkchoiceUpdatedV{v}...") + fcu_response = engine_rpc.forkchoice_updated( + forkchoice_state=ForkchoiceState( + head_block_hash=expected_payload.block_hash, + ), + payload_attributes=None, + version=v, + ) + fcu_status = fcu_response.payload_status.status + if fcu_status != PayloadStatusEnum.VALID: + raise LoggedError( + "Unexpected status on forkchoice update: " + f"want {PayloadStatusEnum.VALID}, got {fcu_status}" + ) + + # Use the fixture's gas limit since we import the fixture block, + # not the built one. + return int(expected_payload.gas_limit) + + +def test_blockchain_via_build( + timing_data: TimingData, + eth_rpc: EthRPC, + engine_rpc: EngineRPC, + testing_rpc: TestingRPC, + fixture: BlockchainEngineFixture, + genesis_header: FixtureHeader, +) -> None: + """ + Test block building correctness against a client. + + For each valid payload in the fixture: + 1. Build a block via ``testing_buildBlockV1`` + 2. Validate execution-dependent fields + gas limit range + 3. Validate execution_requests for fork >= Prague (V4+) + 4. Import the fixture block via ``engine_newPayloadVX`` + 5. Advance the chain via ``engine_forkchoiceUpdatedVX`` + """ + _bootstrap_engine_at_genesis( + engine_rpc=engine_rpc, + eth_rpc=eth_rpc, + fixture=fixture, + genesis_header=genesis_header, + timing_data=timing_data, + ) + + with timing_data.time("Block building") as total_build_timing: + valid_payloads = [p for p in fixture.payloads if p.valid()] + logger.info( + f"Starting block building for {len(valid_payloads)} " + f"valid payload(s) " + f"(of {len(fixture.payloads)} total)..." + ) + parent_gas_limit = int(genesis_header.gas_limit) + for i, payload in enumerate(valid_payloads): + parent_gas_limit = _build_validate_and_advance( + testing_rpc=testing_rpc, + engine_rpc=engine_rpc, + payload=payload, + parent_gas_limit=parent_gas_limit, + block_index=i, + total_blocks=len(valid_payloads), + total_build_timing=total_build_timing, + ) + + logger.info("All blocks built and verified successfully.") diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/processors.py b/packages/testing/src/execution_testing/cli/pytest_commands/processors.py index 7862140380e..d23174fc34e 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/processors.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/processors.py @@ -122,32 +122,18 @@ def process_args(self, args: List[str]) -> List[str]: if os.getenv("HIVE_LOGLEVEL") is not None: warnings.warn("HIVE_LOG_LEVEL is not yet supported.", stacklevel=2) - if self.command_name == "engine": + simulator_commands = { + "engine", + "enginex", + "sync", + "rlp", + "build_block", + } + if self.command_name in simulator_commands: modified_args.extend( [ "-p", - "execution_testing.cli.pytest_commands.plugins.consume.simulators.engine.conftest", - ] - ) - elif self.command_name == "enginex": - modified_args.extend( - [ - "-p", - "execution_testing.cli.pytest_commands.plugins.consume.simulators.enginex.conftest", - ] - ) - elif self.command_name == "sync": - modified_args.extend( - [ - "-p", - "execution_testing.cli.pytest_commands.plugins.consume.simulators.sync.conftest", - ] - ) - elif self.command_name == "rlp": - modified_args.extend( - [ - "-p", - "execution_testing.cli.pytest_commands.plugins.consume.simulators.rlp.conftest", + f"execution_testing.cli.pytest_commands.plugins.consume.simulators.{self.command_name}.conftest", ] ) else: diff --git a/packages/testing/src/execution_testing/fixtures/blockchain.py b/packages/testing/src/execution_testing/fixtures/blockchain.py index 26209fc1b07..92ab859f612 100644 --- a/packages/testing/src/execution_testing/fixtures/blockchain.py +++ b/packages/testing/src/execution_testing/fixtures/blockchain.py @@ -2,6 +2,7 @@ from functools import cached_property from typing import ( + TYPE_CHECKING, Annotated, Any, ClassVar, @@ -69,6 +70,9 @@ FixtureTransactionReceipt, ) +if TYPE_CHECKING: + from execution_testing.rpc.rpc_types import PayloadAttributes + def post_state_validator( alternate_field: str | None = None, mode: str = "after" @@ -472,6 +476,26 @@ def valid(self) -> bool: """Return whether the payload is valid.""" return self.validation_error is None + def get_payload_attributes(self) -> "PayloadAttributes": + """Return the ``PayloadAttributes`` corresponding to this payload.""" + from execution_testing.rpc.rpc_types import PayloadAttributes + + execution_payload = self.params[0] + # parent_beacon_block_root exists from V3 onwards. The length check + # is for mypy narrowing; the version check captures the actual rule. + parent_beacon_block_root = ( + self.params[2] + if self.forkchoice_updated_version >= 3 and len(self.params) >= 3 + else None + ) + return PayloadAttributes( + timestamp=execution_payload.timestamp, + prev_randao=execution_payload.prev_randao, + suggested_fee_recipient=execution_payload.fee_recipient, + withdrawals=execution_payload.withdrawals, + parent_beacon_block_root=parent_beacon_block_root, + ) + @classmethod def from_fixture_header( cls, diff --git a/packages/testing/src/execution_testing/rpc/rpc.py b/packages/testing/src/execution_testing/rpc/rpc.py index e7f75aabe7f..22490da2547 100644 --- a/packages/testing/src/execution_testing/rpc/rpc.py +++ b/packages/testing/src/execution_testing/rpc/rpc.py @@ -1418,7 +1418,7 @@ def build_block( self, parent_block_hash: Hash, payload_attributes: PayloadAttributes, - transactions: Sequence[TransactionProtocol] | None, + transactions: Sequence[TransactionProtocol | Bytes] | None, extra_data: Bytes | None = None, *, version: int = 1, @@ -1428,6 +1428,9 @@ def build_block( provided *payload_attributes* and *transactions*. Calls ``testing_buildBlockVX``. + + Transactions can be either ``TransactionProtocol`` objects (with + an ``rlp()`` method) or raw ``Bytes`` (already RLP-encoded). """ method = f"buildBlockV{version}" params: List[Any] = [ @@ -1435,7 +1438,12 @@ def build_block( to_json(payload_attributes), ] if transactions is not None: - params.append([tx.rlp().hex() for tx in transactions]) + params.append( + [ + tx.hex() if isinstance(tx, bytes) else tx.rlp().hex() + for tx in transactions + ] + ) else: params.append(None) if extra_data is not None: From c8117f22bf61da4f163f349d97a9833389dd62b9 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Thu, 14 May 2026 10:20:39 +0200 Subject: [PATCH 078/186] feat(test-benchmark): add eth transfer cases for repricing (#2837) * (Claude): add eth transfer cases for repricing * refactor: split test based on pre-alloc * refactor: bump execution cost for contract ether reception * chore: remove unnecessary parametrization * refactor: move new benchmark under stateful folder * fix: apply suggested changes * feat: add receipt check * (Claude): add distinct senders * (Claude): do not limit distinct senders * (Claude): add uniq jumpdest contract test * refactor unique contract code receiver case --------- Co-authored-by: LouisTsai --- .../bloatnet/test_transaction_types.py | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 tests/benchmark/stateful/bloatnet/test_transaction_types.py diff --git a/tests/benchmark/stateful/bloatnet/test_transaction_types.py b/tests/benchmark/stateful/bloatnet/test_transaction_types.py new file mode 100644 index 00000000000..875c69fecdf --- /dev/null +++ b/tests/benchmark/stateful/bloatnet/test_transaction_types.py @@ -0,0 +1,207 @@ +"""Benchmark ether transfers to receivers that exist on-chain.""" + +import itertools +from typing import Generator + +import pytest +from execution_testing import ( + DETERMINISTIC_FACTORY_ADDRESS, + EOA, + Address, + Alloc, + BenchmarkTestFiller, + Block, + Fork, + Op, + Transaction, + compute_create2_address, + compute_create_address, +) + +# Deterministic sender pool of 15K accounts. +# Funded via system contract withdrawals (funding.txt) in payload generation. +# Placed outside pre-allocation to ensure accounts remain uncached. +SENDER_BASE_KEY = ( + 0x1111111111111111111111111111111111111111111111111111111111111111 +) + + +def yield_distinct_sender() -> Generator[EOA, None, None]: + """Yield deterministic sender EOAs pre-funded on-chain.""" + for i in itertools.count(0): + yield EOA(key=SENDER_BASE_KEY + i) + + +def build_unique_contract_initcode() -> bytes: + """ + Deployed runtime contract layout. + + offset size contents + ------ ---- -------------------------------- + 0x0000 4 PUSH2 0x5FFF; JUMP <- entry + 0x0004 28 JUMPDEST padding + 0x0020 12 JUMPDEST padding + 0x002C 20 contract ADDRESS <- unique + 0x0040 24512 JUMPDEST <- 0x5FFF lands here + 0x6000 STOP + + Embedded ADDRESS makes runtime unique per contract; + initcode and its CREATE2 hash is shared across all salts. + """ + max_code_size = 0x6000 # EIP-170 contract code size limit + + # MCOPY fills MEM[0:0x8000] with JUMPDEST. + # Runtime only uses MEM[0:0x6000]. + code = Op.MSTORE(0, bytes(Op.JUMPDEST * 32)) + for size in (1 << s for s in range(5, 15)): + code += Op.MCOPY(size, 0, size) + + # Runtime entry: JUMP to final JUMPDEST, then STOP. + entry = Op.JUMP(max_code_size - 1) + entry += Op.JUMPDEST * (32 - len(entry)) # Padding + + code += Op.MSTORE(0, bytes(entry)) + + # Mask ADDRESS into a JUMPDEST template via OR: + # bytes 0..12 bytes 12..32 + # ----------- ------------ + # ADDRESS 00 .. 00 <20-byte address> + # addr_slot 5b .. 5b 00 .. 00 + # OR result 5b .. 5b <20-byte address> + addr_slot = Op.JUMPDEST * 12 + Op.STOP * 20 + code += Op.MSTORE(0x20, Op.OR(Op.ADDRESS, bytes(addr_slot))) + + code += Op.RETURN(0, max_code_size) + + return bytes(code) + + +JOCHEMNET_UNIQUE_CONTRACT_INITCODE = build_unique_contract_initcode() + + +def yield_distinct_unique_code_jumpdest_receiver() -> Generator[ + Address, None, None +]: + """ + Yield contract addresses deployed by the deterministic CREATE2 factory. + """ + for salt in itertools.count(0): + yield compute_create2_address( + address=DETERMINISTIC_FACTORY_ADDRESS, + salt=salt, + initcode=JOCHEMNET_UNIQUE_CONTRACT_INITCODE, + ) + + +# Bittrex controller mainnet address +# Creates 1.5M contracts with deterministic address via CREATE +# It is guaranteed no contract is destructed +# Used for existing contract targets in benchmark +BITTREX_CONTROLLER_ADDRESS = Address( + 0xA3C1E324CA1CE40DB73ED6026C4A177F099B5770 +) + + +def yield_distinct_contract_receiver() -> Generator[Address, None, None]: + """Yield contract account created by Bittrex controller via CREATE.""" + for nonce in itertools.count(2): + yield compute_create_address( + address=BITTREX_CONTROLLER_ADDRESS, nonce=nonce + ) + + +def yield_distinct_existent_receiver() -> Generator[Address, None, None]: + """ + Yield existing balance-only EOA on bloatnet. pre-funded by Spamoor + (https://github.com/CPerezz/spamoor/pull/12). + """ + for address in itertools.count(0x1000): + yield Address(address) + + +def yield_distinct_nonexistent_receiver() -> Generator[Address, None, None]: + """Yield non-existent accounts starting from keccak256('random').""" + for address in itertools.count(0xF3CF193BB4AF1022AF7D2089F37D8BAE7157B85F): + yield Address(address) + + +@pytest.mark.repricing +@pytest.mark.parametrize( + "case_id", + [ + "diff_to_nonexistent", + "diff_to_existent", + "diff_to_contract", + "diff_to_unique_code_jumpdest_contract", + ], +) +@pytest.mark.parametrize("transfer_amount", [0, 1]) +def test_ether_transfers_onchain_receivers( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + case_id: str, + transfer_amount: int, + fork: Fork, + gas_benchmark_value: int, +) -> None: + """ + Ether transfers to receivers that exist on-chain at run time. + + Scenarios: + - diff_to_nonexistent: distinct nonexistent receivers + (matches AccountMode.NON_EXISTING_ACCOUNT) + - diff_to_existent: distinct existent EOA receivers + (matches AccountMode.EXISTING_EOA) + - diff_to_contract: distinct contract receivers + (matches AccountMode.EXISTING_CONTRACT) + - diff_to_unique_code_jumpdest_contract: distinct CREATE2 contract + receivers each holding unique deployed code + """ + senders = yield_distinct_sender() + receiver_execution_gas = 0 + if case_id == "diff_to_nonexistent": + receivers = yield_distinct_nonexistent_receiver() + elif case_id == "diff_to_existent": + receivers = yield_distinct_existent_receiver() + elif case_id == "diff_to_contract": + receivers = yield_distinct_contract_receiver() + # Runtime code is the same across all the receivers + # Example contract: https://etherscan.io/address/0xa888df3ef62286dde06a79395760b9bce6c83c83#code + runtime = ( + Op.MSTORE(0x40, 0x60, new_memory_size=0x60) + + Op.JUMPI(Op.PUSH2(0x49), Op.ISZERO(Op.CALLDATASIZE)) + + Op.JUMPDEST * 3 + + Op.JUMP(Op.PUSH2(0x50)) + + Op.JUMPDEST + ) + receiver_execution_gas = runtime.gas_cost(fork) + elif case_id == "diff_to_unique_code_jumpdest_contract": + receivers = yield_distinct_unique_code_jumpdest_receiver() + # Runtime code aligns entry code path. + runtime = Op.JUMP(Op.PUSH2(0x5FFF)) + Op.JUMPDEST + receiver_execution_gas = runtime.gas_cost(fork) + else: + raise ValueError(f"Unknown case: {case_id}") + + iteration_cost = ( + fork.transaction_intrinsic_cost_calculator()() + receiver_execution_gas + ) + iteration_count = gas_benchmark_value // iteration_cost + + txs = [ + Transaction( + to=next(receivers), + value=transfer_amount, + gas_limit=iteration_cost, + sender=next(senders), + ) + for _ in range(iteration_count) + ] + + benchmark_test( + pre=pre, + post={}, + blocks=[Block(txs=txs)], + expected_benchmark_gas_used=iteration_count * iteration_cost, + expected_receipt_status=1, + ) From 267a2bd335ca47698636d33168f27282ba8f1958 Mon Sep 17 00:00:00 2001 From: felipe Date: Thu, 14 May 2026 09:56:32 -0600 Subject: [PATCH 079/186] test(tests): inter-dependent tx tests for BAL parallelization (#2851) * feat(test): inter-dependent tx tests for BAL parallelization * chore: move 7702 test to 7702 BAL test file * feat(test): extend test cases based on comments on PR #2851 --- .../test_block_access_lists.py | 517 ++++++++++++++++++ .../test_block_access_lists_eip7702.py | 98 ++++ .../test_cases.md | 5 + 3 files changed, 620 insertions(+) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 13851dc6d02..8dce480a1e2 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -20,12 +20,15 @@ BlockAccessListExpectation, BlockchainTestFiller, BlockException, + Conditional, Environment, Fork, Hash, Header, + Initcode, Op, Transaction, + TransactionException, add_kzg_version, compute_create_address, ) @@ -2188,6 +2191,520 @@ def test_bal_cross_tx_storage_revert_to_zero( ) +def test_bal_cross_tx_storage_chain( + pre: Alloc, + blockchain_test: BlockchainTestFiller, +) -> None: + """ + Verify clients apply BAL state changes from prior transactions before + executing later transactions in the same block. + + Each Tx i seeds slots 0 and 1 with `1`, then computes a + Fibonacci-style sum into slot i: `slot[i] = SLOAD(i-1) + SLOAD(i-2)`. + Every Tx i>=2 depends on the two immediately preceding writes, so + any parallelization that fails to apply a prior Tx's BAL storage + change cascades into a wrong slot value and a different state root. + """ + chain_length = 8 + # i<2 seeds slot i with 1; i>=2 computes the Fibonacci sum. + contract = pre.deploy_contract( + code=Conditional( + condition=Op.LT(Op.CALLDATALOAD(0), 2), + if_true=Op.SSTORE(Op.CALLDATALOAD(0), 1), + if_false=Op.SSTORE( + Op.CALLDATALOAD(0), + Op.ADD( + Op.SLOAD(Op.SUB(Op.CALLDATALOAD(0), 1)), + Op.SLOAD(Op.SUB(Op.CALLDATALOAD(0), 2)), + ), + ), + ), + ) + + fib = [1, 1] + for i in range(2, chain_length): + fib.append(fib[i - 1] + fib[i - 2]) + + txs = [] + senders = [] + for i in range(chain_length): + sender = pre.fund_eoa() + senders.append(sender) + txs.append( + Transaction( + sender=sender, + to=contract, + data=Hash(i), + gas_limit=100_000, + ) + ) + + account_expectations: dict = { + sender: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=i + 1, post_nonce=1) + ], + ) + for i, sender in enumerate(senders) + } + account_expectations[contract] = BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=i, + slot_changes=[ + BalStorageChange( + block_access_index=i + 1, post_value=fib[i] + ), + ], + ) + for i in range(chain_length) + ], + nonce_changes=[], + balance_changes=[], + code_changes=[], + storage_reads=[], + ) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=txs, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations + ), + ) + ], + post={ + contract: Account( + storage={i: fib[i] for i in range(chain_length)} + ), + }, + ) + + +@pytest.mark.with_all_create_opcodes +def test_bal_cross_tx_deploy_then_call( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + create_opcode: Op, +) -> None: + """ + Verify clients apply Tx1's CREATE to their state view before + executing Tx2's CALL in the same block. Tx1 deploys a contract at a + deterministic address whose runtime code writes a sentinel to slot 0. + Tx2 CALLs that address. A client that parallelizes Tx2 without + applying Tx1's `code_changes` would hit an empty account, the CALL + would no-op, and slot 0 would remain 0. + """ + sentinel = 0x42 + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + runtime = Op.SSTORE(0, sentinel) + Op.STOP + initcode = Initcode(deploy_code=runtime) + initcode_bytes = bytes(initcode) + + salt = 0 + is_create2 = create_opcode == Op.CREATE2 + if is_create2: + deploy_op = Op.CREATE2( + value=0, offset=0, size=Op.CALLDATASIZE, salt=salt + ) + else: + deploy_op = Op.CREATE(value=0, offset=0, size=Op.CALLDATASIZE) + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE(0, deploy_op) + + Op.STOP + ) + factory = pre.deploy_contract(code=factory_code) + target = compute_create_address( + address=factory, + nonce=1, + salt=salt, + initcode=initcode_bytes, + opcode=create_opcode, + ) + + tx_deploy = Transaction( + sender=alice, + to=factory, + data=initcode_bytes, + gas_limit=500_000, + ) + tx_call = Transaction( + sender=bob, + to=target, + gas_limit=100_000, + ) + + account_expectations = { + target: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + code_changes=[ + BalCodeChange(block_access_index=1, new_code=bytes(runtime)) + ], + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange( + block_access_index=2, post_value=sentinel + ), + ], + ), + ], + ), + } + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx_deploy, tx_call], + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations + ), + ) + ], + post={ + target: Account( + nonce=1, code=bytes(runtime), storage={0: sentinel} + ), + factory: Account(nonce=2, storage={0: target}), + }, + ) + + +@pytest.mark.parametrize( + "funding_method", + ["direct_call", "selfdestruct"], +) +def test_bal_cross_tx_balance_dependency( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + funding_method: str, +) -> None: + """ + Verify clients apply Tx1's balance change before executing Tx2 in + the same block. Tx1 routes value into a contract; Tx2 invokes the + contract which records its `SELFBALANCE` to storage. A client that + parallelizes Tx2 without applying Tx1's `balance_changes` would + record the pre-block balance, yielding a different state root. The + `selfdestruct` variant routes the funds via SELFDESTRUCT from a + pre-funded killer contract so the recipient's bytecode never runs + in Tx1 — catching any client optimization that ties balance + tracking to code execution. + """ + transferred = 1 + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + # Any non-empty calldata triggers the SELFBALANCE record path; + # empty calldata is the value-receiver path. + contract = pre.deploy_contract( + code=Conditional( + condition=Op.ISZERO(Op.CALLDATASIZE), + if_true=Op.STOP, + if_false=Op.SSTORE(0, Op.SELFBALANCE), + ), + ) + + if funding_method == "direct_call": + tx_send = Transaction( + sender=alice, + to=contract, + value=transferred, + gas_limit=100_000, + ) + send_expectations: dict = {} + elif funding_method == "selfdestruct": + killer = pre.deploy_contract( + code=Op.SELFDESTRUCT(contract), + balance=transferred, + ) + tx_send = Transaction( + sender=alice, + to=killer, + gas_limit=100_000, + ) + send_expectations = { + killer: BalAccountExpectation( + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0), + ], + ), + } + else: + raise ValueError(f"unknown funding_method: {funding_method}") + + tx_read = Transaction( + sender=bob, + to=contract, + data=b"\x01", + gas_limit=100_000, + ) + + account_expectations = { + contract: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=transferred + ), + ], + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange( + block_access_index=2, post_value=transferred + ), + ], + ), + ], + ), + **send_expectations, + } + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx_send, tx_read], + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations + ), + ) + ], + post={ + contract: Account(balance=transferred, storage={0: transferred}), + }, + ) + + +@pytest.mark.parametrize( + "eunice_outcome", + [ + pytest.param("success", id="success"), + pytest.param("oog_minus_1", id="oog_minus_1"), + pytest.param( + "insufficient_funds", + id="insufficient_funds", + marks=pytest.mark.exception_test, + ), + ], +) +def test_bal_cross_tx_funding_chain( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + fork: Fork, + eunice_outcome: str, +) -> None: + """ + Funding chain: alice → bob → charlie → dan → eunice → target. Each + intermediate starts empty and must receive the prior tx's forwarded + value to afford its own upfront gas + outgoing transfer. A client + that parallelizes any later tx against pre-block state would see a + zero balance on its sender and wrongly reject the block. The + `oog_minus_1` variant funds eunice with exactly `gas_limit - 1` + worth of gas so her SSTORE OOGs at the boundary (target's BAL flips + from `storage_changes` to `storage_reads`). The `insufficient_funds` + variant has dan forward one wei short of eunice's `gas_limit * + gas_price`, so eunice's tx is rejected pre-execution and the entire + block MUST be rejected with `INSUFFICIENT_ACCOUNT_FUNDS` — a sanity + check on the off-by-one boundary of the upfront balance check. + """ + gas_price = 0xA + + target_code = Op.SSTORE( + 0, 0xC0FFEE, key_warm=False, original_value=0, new_value=0xC0FFEE + ) + target = pre.deploy_contract(code=target_code) + + intrinsic_calc = fork.transaction_intrinsic_cost_calculator() + intrinsic_gas = intrinsic_calc() + eunice_exact_gas = intrinsic_gas + target_code.gas_cost(fork) + eunice_gas_limit = ( + eunice_exact_gas - 1 + if eunice_outcome == "oog_minus_1" + else eunice_exact_gas + ) + eunice_upfront = eunice_gas_limit * gas_price + transfer_cost = intrinsic_gas * gas_price + + # Each sender (including alice) starts with or receives exactly what + # the next forward + its own gas demands; everyone ends at zero in + # the success/oog variants. `insufficient_funds` shorts eunice by + # one wei via dan, leaving her unable to cover upfront gas. + dan_value = ( + eunice_upfront - 1 + if eunice_outcome == "insufficient_funds" + else eunice_upfront + ) + charlie_value = transfer_cost + dan_value + bob_value = transfer_cost + charlie_value + alice_value = transfer_cost + bob_value + alice_pre_balance = transfer_cost + alice_value + + alice = pre.fund_eoa(amount=alice_pre_balance) + bob = pre.fund_eoa(amount=0) + charlie = pre.fund_eoa(amount=0) + dan = pre.fund_eoa(amount=0) + eunice = pre.fund_eoa(amount=0) + + eunice_error = ( + TransactionException.INSUFFICIENT_ACCOUNT_FUNDS + if eunice_outcome == "insufficient_funds" + else None + ) + + txs = [ + Transaction( + sender=alice, + to=bob, + value=alice_value, + gas_limit=intrinsic_gas, + gas_price=gas_price, + ), + Transaction( + sender=bob, + to=charlie, + value=bob_value, + gas_limit=intrinsic_gas, + gas_price=gas_price, + ), + Transaction( + sender=charlie, + to=dan, + value=charlie_value, + gas_limit=intrinsic_gas, + gas_price=gas_price, + ), + Transaction( + sender=dan, + to=eunice, + value=dan_value, + gas_limit=intrinsic_gas, + gas_price=gas_price, + ), + Transaction( + sender=eunice, + to=target, + gas_limit=eunice_gas_limit, + gas_price=gas_price, + error=eunice_error, + ), + ] + + if eunice_outcome == "insufficient_funds": + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=txs, + exception=( + TransactionException.INSUFFICIENT_ACCOUNT_FUNDS + ), + ) + ], + post={}, + ) + return + + if eunice_outcome == "oog_minus_1": + target_bal = BalAccountExpectation( + storage_reads=[0], + nonce_changes=[], + balance_changes=[], + code_changes=[], + storage_changes=[], + ) + target_post = Account(storage={}) + elif eunice_outcome == "success": + target_bal = BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange( + block_access_index=5, post_value=0xC0FFEE + ), + ], + ), + ], + nonce_changes=[], + balance_changes=[], + code_changes=[], + storage_reads=[], + ) + target_post = Account(storage={0: 0xC0FFEE}) + else: + raise ValueError(f"unknown eunice_outcome: {eunice_outcome}") + + account_expectations = { + alice: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0), + ], + ), + bob: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=2, post_nonce=1)], + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=alice_value + ), + BalBalanceChange(block_access_index=2, post_balance=0), + ], + ), + charlie: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=3, post_nonce=1)], + balance_changes=[ + BalBalanceChange(block_access_index=2, post_balance=bob_value), + BalBalanceChange(block_access_index=3, post_balance=0), + ], + ), + dan: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=4, post_nonce=1)], + balance_changes=[ + BalBalanceChange( + block_access_index=3, post_balance=charlie_value + ), + BalBalanceChange(block_access_index=4, post_balance=0), + ], + ), + eunice: BalAccountExpectation( + nonce_changes=[BalNonceChange(block_access_index=5, post_nonce=1)], + balance_changes=[ + BalBalanceChange(block_access_index=4, post_balance=dan_value), + BalBalanceChange(block_access_index=5, post_balance=0), + ], + ), + target: target_bal, + } + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=txs, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations, + ), + ) + ], + post={ + alice: Account(nonce=1, balance=0), + bob: Account(nonce=1, balance=0), + charlie: Account(nonce=1, balance=0), + dan: Account(nonce=1, balance=0), + eunice: Account(nonce=1, balance=0), + target: target_post, + }, + ) + + def test_bal_cross_block_ripemd160_state_leak( pre: Alloc, blockchain_test: BlockchainTestFiller, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py index 8824b61b97b..9a776f797ff 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py @@ -827,6 +827,104 @@ def test_bal_7702_multi_hop_delegation_chain( ) +def test_bal_7702_cross_tx_delegation_then_call( + pre: Alloc, + blockchain_test: BlockchainTestFiller, +) -> None: + """ + Verify clients apply Tx1's EIP-7702 delegation before later txs CALL + the now-delegated EOA. Tx1 installs a delegation designator on `alice` + pointing to a contract that increments slot 0. Tx2 and Tx3 CALL alice, + so each later tx must observe both the installed code (Tx1) and the + prior increment (the immediately preceding tx) for the final slot 0 + to read 2. A client that parallelizes any tx against pre-block state + would see no code or a stale counter, yielding a different state root. + """ + alice = pre.fund_eoa() + bob = pre.fund_eoa() + charlie = pre.fund_eoa() + relayer = pre.fund_eoa() + + # Delegation target: increments slot 0 each time it's invoked. + counter = pre.deploy_contract( + code=Op.SSTORE(0, Op.ADD(Op.SLOAD(0), 1)), + ) + + tx_delegate = Transaction( + sender=relayer, + to=bob, + value=0, + gas_limit=1_000_000, + gas_price=0xA, + authorization_list=[ + AuthorizationTuple( + address=counter, + nonce=0, + signer=alice, + ) + ], + ) + tx_call_1 = Transaction( + sender=bob, + to=alice, + gas_limit=200_000, + gas_price=0xA, + ) + tx_call_2 = Transaction( + sender=charlie, + to=alice, + gas_limit=200_000, + gas_price=0xA, + ) + + block = Block( + txs=[tx_delegate, tx_call_1, tx_call_2], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1), + ], + code_changes=[ + BalCodeChange( + block_access_index=1, + new_code=Spec7702.delegation_designation(counter), + ) + ], + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange( + block_access_index=2, post_value=1 + ), + BalStorageChange( + block_access_index=3, post_value=2 + ), + ], + ), + ], + ), + # Delegation target: loaded as execution target on each + # CALL to alice, but mutations land in alice's storage. + counter: BalAccountExpectation.empty(), + }, + ), + ) + + blockchain_test( + pre=pre, + blocks=[block], + post={ + alice: Account( + nonce=1, + code=Spec7702.delegation_designation(counter), + storage={0: 2}, + ), + }, + ) + + def test_bal_7702_null_address_delegation_no_code_change( pre: Alloc, blockchain_test: BlockchainTestFiller, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 73eaebe3c36..7d8faf64484 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -75,6 +75,11 @@ | `test_bal_multiple_storage_writes_same_slot` | Ensure BAL tracks multiple writes to same storage slot across transactions | Alice calls contract 3 times in same block. Contract increments slot 1 on each call: 0 → 1 → 2 → 3 | BAL **MUST** include contract with slot 1 having three `slot_changes`: txIndex=1 (value 1), txIndex=2 (value 2), txIndex=3 (value 3). Each transaction's write must be recorded separately. | ✅ Completed | | `test_bal_nested_delegatecall_storage_writes_net_zero` | Ensure BAL correctly filters net-zero storage changes across nested DELEGATECALL frames | Parametrized by nesting depth (1-3). Root contract has slot 0 = 1. Each frame writes a different intermediate value via DELEGATECALL chain, deepest frame writes back to original value (1). Example depth=2: 1 → 2 → 3 → 1 | BAL **MUST** include root contract with `storage_reads` for slot 0 but **MUST NOT** include `storage_changes` (net-zero). All delegate contracts **MUST** have empty changes. Tests that frame merging correctly removes parent's intermediate writes when child reverts to pre-tx value. | ✅ Completed | | `test_bal_cross_tx_storage_revert_to_zero` | Ensure BAL captures storage changes when tx2 reverts slot back to original value (blobhash regression test) | Alice sends tx1 writing slot 0=0xABCD (from 0x0), then tx2 writing slot 0=0x0 (back to original) | BAL **MUST** include contract with slot 0 having two `slot_changes`: txIndex=1 (0xABCD) and txIndex=2 (0x0). Cross-transaction net-zero **MUST NOT** be filtered. | ✅ Completed | +| `test_bal_cross_tx_storage_chain` | Verify clients apply BAL state changes from prior transactions before executing later transactions in the same block. Each later Tx depends on the two preceding writes (Fibonacci-style), so any tx skipped or run against pre-block state cascades into a wrong slot value and a different state root. | Fixed `chain_length=8`. Single branching contract: Tx i with `i<2` seeds slot i with `1`; Tx i with `i>=2` writes `slot[i] = SLOAD(i-1) + SLOAD(i-2)`. | BAL **MUST** include the contract with `storage_changes` for each slot i (post=`fib(i)` at `block_access_index=i+1`). Post-state: slots 0-7 equal `[1, 1, 2, 3, 5, 8, 13, 21]`. | ✅ Completed | +| `test_bal_cross_tx_deploy_then_call` | Verify clients apply Tx1's CREATE to their state view before executing Tx2's CALL in the same block. A client that parallelizes Tx2 without applying Tx1's `code_changes` would hit an empty account, the CALL would no-op, and slot 0 would remain 0. Parametrized over `@pytest.mark.with_all_create_opcodes` (CREATE and CREATE2). | Tx1 (Alice) calls a factory which CREATE/CREATE2s a contract whose runtime is `SSTORE(0, 0x42) + STOP` at a deterministic address. Tx2 (Bob) CALLs that address directly. | BAL **MUST** include the target contract with `nonce_changes` and `code_changes` at `block_access_index=1` (the deployment) and `storage_changes` for slot 0 (post=`0x42`) at `block_access_index=2` (Tx2's CALL through the deployed runtime). Post-state: target contract has runtime code and `slot[0] == 0x42`. | ✅ Completed | +| `test_bal_cross_tx_balance_dependency` | Verify clients apply Tx1's balance change before executing Tx2 in the same block. A client that parallelizes Tx2 without applying Tx1's `balance_changes` would record the pre-block balance via `SELFBALANCE`, yielding a different state root. Parametrized over `direct_call` and `selfdestruct` funding paths so a client can't tie balance tracking to recipient-code execution. | Tx1 (Alice) routes `1` wei into a branching contract (empty calldata → STOP). In `direct_call`, alice sends value directly; in `selfdestruct`, alice calls a pre-funded killer contract that `SELFDESTRUCT`s to the recipient (recipient bytecode never runs in Tx1). Tx2 (Bob) calls the contract with non-empty calldata, taking the `SSTORE(0, SELFBALANCE)` path. | BAL **MUST** include the contract with `balance_changes` at `block_access_index=1` (post=`1`) and `storage_changes` for slot 0 (post=`1`) at `block_access_index=2`. In `selfdestruct`, BAL also includes the killer with `balance_changes` (post=`0`) at index 1. Post-state: `contract.balance == contract.storage[0] == 1` proves Tx2 observed Tx1's balance change. | ✅ Completed | +| `test_bal_7702_cross_tx_delegation_then_call` | Verify clients apply Tx1's EIP-7702 delegation before later txs CALL the now-delegated EOA. Three-tx chain forces clients to apply both the code-install and each intermediate storage increment for the final value to be correct. | Tx1 (Relayer): sponsors an EIP-7702 auth that delegates Alice to a `SSTORE(0, SLOAD(0) + 1)` counter contract. Tx2 (Bob) and Tx3 (Charlie): both CALL Alice, which dispatches to the counter and increments her slot 0. | BAL **MUST** include Alice with `code_changes` at `block_access_index=1` (delegation designator), `nonce_changes` at index 1, and two `storage_changes` for slot 0 (post=1 at index 2, post=2 at index 3). Post-state: Alice has the delegation code and `slot[0] == 2`. | ✅ Completed | +| `test_bal_cross_tx_funding_chain` | Verify clients apply each tx's BAL `balance_changes` to the next sender's funds check. Five-tx chain across distinct senders, each intermediate starts empty and depends on the prior tx to be solvent. A parallelizing client validating any later tx against pre-block state would see zero balance on its sender and wrongly reject the block. Parametrized over `success`, `oog_minus_1` (eunice's tx OOGs at exact gas minus one), and `insufficient_funds` (dan forwards one wei short so eunice's upfront balance check fails, block rejected with `INSUFFICIENT_ACCOUNT_FUNDS`). | Tx1 alice→bob, Tx2 bob→charlie, Tx3 charlie→dan, Tx4 dan→eunice. Each forwards exactly the next sender's upfront cost. Tx5 eunice→target with runtime `SSTORE(0, 0xC0FFEE)`. | For `success`/`oog_minus_1`: BAL **MUST** include nonce/balance changes for each EOA at its tx's `block_access_index`, plus target's `storage_changes` at index 5 (`success`) or `storage_reads=[0]` (`oog_minus_1`). Post-state: all five EOAs end with `balance=0`; target has `slot[0]==0xC0FFEE` in `success` and empty storage in `oog_minus_1`. For `insufficient_funds`: block **MUST** be rejected with `TransactionException.INSUFFICIENT_ACCOUNT_FUNDS`. | ✅ Completed | | `test_bal_intra_tx_multiple_sstores_same_slot` | Ensure BAL coalesces consecutive SSTOREs to the same slot within one tx into a single storage change with the final post-value | Contract executes `SSTORE(0x01, 0xAA) + SSTORE(0x01, 0xBB) + SSTORE(0x01, 0xCC)` in one tx. Parametrized by `pre_value`: `slot_starts_empty` (0x00), `slot_starts_nonzero` (0x11), `intermediate_equals_pre` (0xBB, where the second write transiently matches the pre-state). | BAL **MUST** include contract with slot `0x01` having exactly one `slot_changes` entry: `txIndex=1, post_value=0xCC`. Intermediate values `0xAA` and `0xBB` **MUST NOT** appear as separate entries (enforced via `absent_values`). | ✅ Completed | | `test_bal_intra_tx_sstores_same_slot_net_zero` | Ensure BAL filters net-zero result when multiple SSTOREs to the same slot occur within one tx | Parametrized: `nonzero_pre_returns_to_pre` (pre=0xCC, writes 0xAA→0xBB→0xCC) and `empty_pre_ephemeral_writes` (pre=0x00, writes 0xAA→0xBB→0x00). Final value equals pre-state in both cases. | BAL **MUST** include contract with slot `0x01` in `storage_reads` (slot was accessed) and **MUST NOT** include slot `0x01` in `storage_changes` (net-zero). | ✅ Completed | | `test_bal_create_contract_init_revert` | Ensure BAL correctly handles CREATE when parent call reverts | Caller calls factory, factory executes CREATE (succeeds), then factory REVERTs rolling back the CREATE | BAL **MUST** include Alice with `nonce_changes`. Caller and factory with no changes (reverted). Created contract address appears in BAL but **MUST NOT** have `nonce_changes` or `code_changes` (CREATE was rolled back). Contract address **MUST NOT** exist in post-state. | ✅ Completed | From b3f5df5d854a8ff4de34d961644e3c53757d700a Mon Sep 17 00:00:00 2001 From: kclowes Date: Thu, 14 May 2026 11:15:22 -0600 Subject: [PATCH 080/186] feat(spec-specs, spec-tests): add EIP-7843 SLOTNUM opcode (#2853) * feat(src): Initial EIP-7843 (SLOTNUM) Implementation (#2007) * feat(amsterdam): Implement EIP-7843 SLOTNUM opcode * mario feedback * fix(tests): minor fixes and updates for eip7843 (#2057) * fix(tests): minor updates to eip-7843 following #2007 * fix: account for slotnum in genesis creation * fix: append slot_number in fixture_loader.py * execution-api 7843 pr 731 implemented (#2101) * src(fix): framework bug fix for slotnum (#2108) * refactor(tests): Condition EIP-7843 tests to EIP inclusion * fix(specs): align EIP-7843 SLOTNUM gas references with renamed constants Replace stale GAS_BASE reference with GasCosts.OPCODE_SLOTNUM (= BASE) to match the opcode gas naming convention used across block instructions on forks/amsterdam. Also update the test-fork mixin to use gas_costs.BASE instead of the retired gas_costs.GAS_BASE. * Remove stray header_bal_hash_required checks * Remove unneeded eip7843 spec.py --------- Co-authored-by: felix Co-authored-by: felipe Co-authored-by: marioevz Co-authored-by: spencer-tb --- .../consume/simulators/single_test_client.py | 3 + .../execute/rpc/chain_builder_eth_rpc.py | 3 + .../execution_testing/fixtures/blockchain.py | 8 +- .../src/execution_testing/forks/base_fork.py | 14 ++ .../forks/forks/eips/amsterdam/eip_7843.py | 54 ++++++++ .../execution_testing/forks/forks/forks.py | 12 ++ .../src/execution_testing/rpc/rpc_types.py | 1 + .../src/execution_testing/specs/blockchain.py | 26 +++- .../src/execution_testing/specs/state.py | 1 + .../specs/static_state/environment.py | 3 + .../test_types/block_types.py | 4 + .../src/execution_testing/vm/opcodes.py | 30 +++++ src/ethereum/forks/amsterdam/blocks.py | 10 +- src/ethereum/forks/amsterdam/fork.py | 1 + src/ethereum/forks/amsterdam/vm/__init__.py | 1 + src/ethereum/forks/amsterdam/vm/gas.py | 1 + .../amsterdam/vm/instructions/__init__.py | 2 + .../forks/amsterdam/vm/instructions/block.py | 33 +++++ src/ethereum/genesis.py | 3 + .../evm_tools/loaders/fixture_loader.py | 4 + .../evm_tools/loaders/fork_loader.py | 9 ++ .../evm_tools/t8n/__init__.py | 2 + src/ethereum_spec_tools/evm_tools/t8n/env.py | 15 +++ tests/amsterdam/eip7843_slotnum/__init__.py | 1 + .../amsterdam/eip7843_slotnum/test_slotnum.py | 126 ++++++++++++++++++ whitelist.txt | 1 + 26 files changed, 361 insertions(+), 7 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7843.py create mode 100644 tests/amsterdam/eip7843_slotnum/__init__.py create mode 100644 tests/amsterdam/eip7843_slotnum/test_slotnum.py diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/single_test_client.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/single_test_client.py index 2d22fbb2e80..67984186bd2 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/single_test_client.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/single_test_client.py @@ -34,6 +34,9 @@ def client_genesis(fixture: BlockchainFixtureCommon) -> dict: alloc = to_json(fixture.pre) # NOTE: nethermind requires account keys without '0x' prefix genesis["alloc"] = {k.replace("0x", ""): v for k, v in alloc.items()} + # NOTE: geth expects slotNumber as plain integer, not hex string + if "slotNumber" in genesis: + genesis["slotNumber"] = int(genesis["slotNumber"], 16) return genesis diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/chain_builder_eth_rpc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/chain_builder_eth_rpc.py index 11373581f8c..890e35cd09f 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/chain_builder_eth_rpc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/chain_builder_eth_rpc.py @@ -156,6 +156,9 @@ def _payload_attributes( if next_fork.engine_payload_attribute_max_blobs_per_block() else None ), + slot_number=( + 0 if next_fork.engine_payload_attribute_slot_number() else None + ), ) def _finalize_payload( diff --git a/packages/testing/src/execution_testing/fixtures/blockchain.py b/packages/testing/src/execution_testing/fixtures/blockchain.py index 92ab859f612..f8bf1e5a2dc 100644 --- a/packages/testing/src/execution_testing/fixtures/blockchain.py +++ b/packages/testing/src/execution_testing/fixtures/blockchain.py @@ -215,6 +215,10 @@ class FixtureHeader(CamelModel): block_access_list_hash: ( Annotated[Hash, HeaderForkRequirement("bal_hash")] | None ) = Field(None, alias="blockAccessListHash") + slot_number: ( + Annotated[ZeroPaddedHexNumber, HeaderForkRequirement("slot_number")] + | None + ) = Field(None) fork: Fork | None = Field(None, exclude=True) @@ -353,7 +357,7 @@ def get_default_from_annotation( def genesis(cls, fork: Fork, env: Environment, state_root: Hash) -> Self: """Get the genesis header for the given fork.""" environment_values = env.model_dump( - exclude_none=True, exclude={"withdrawals"} + exclude_none=True, exclude={"withdrawals", "slot_number"} ) if env.withdrawals is not None: environment_values["withdrawals_root"] = Withdrawal.list_root( @@ -370,6 +374,7 @@ def genesis(cls, fork: Fork, env: Environment, state_root: Hash) -> Self: if fork.header_bal_hash_required() else None ), + "slot_number": 0 if fork.header_slot_number_required() else None, "fork": fork, } return cls(**environment_values, **extras) @@ -410,6 +415,7 @@ class FixtureExecutionPayload(CamelModel): block_access_list: Bytes | None = Field( None, description="RLP-serialized EIP-7928 Block Access List" ) + slot_number: HexNumber | None = Field(None) @classmethod def from_fixture_header( diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index 419b27a915b..03059aff283 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -436,6 +436,12 @@ def empty_block_bal_item_count(cls) -> int: """ pass + @classmethod + @abstractmethod + def header_slot_number_required(cls) -> bool: + """Return true if the header must contain slot number (EIP-7843).""" + pass + # Gas related abstract methods @classmethod @@ -881,6 +887,14 @@ def engine_payload_attribute_max_blobs_per_block(cls) -> bool: """ pass + @classmethod + @abstractmethod + def engine_payload_attribute_slot_number(cls) -> bool: + """ + Return true if the payload attributes include the slot number. + """ + pass + # Engine API method versions @classmethod def engine_new_payload_version(cls) -> Optional[int]: diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7843.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7843.py new file mode 100644 index 00000000000..d701bef1cc5 --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7843.py @@ -0,0 +1,54 @@ +""" +EIP-7843: SLOTNUM opcode. + +Opcode to get the current slot number. + +https://eips.ethereum.org/EIPS/eip-7843 +""" + +from typing import Callable, Dict, List + +from execution_testing.vm import ( + OpcodeBase, + Opcodes, +) + +from ....base_fork import BaseFork + + +class EIP7843( + BaseFork, + # Engine API method version bumps + # New field `slotNumber` in ExecutionPayload + engine_new_payload_version_bump=True, + engine_get_payload_version_bump=True, + engine_forkchoice_updated_version_bump=True, +): + """EIP-7843 class.""" + + @classmethod + def header_slot_number_required(cls) -> bool: + """Slot number in header required.""" + return True + + @classmethod + def engine_payload_attribute_slot_number(cls) -> bool: + """Payload attributes include the slot number.""" + return True + + @classmethod + def opcode_gas_map( + cls, + ) -> Dict[OpcodeBase, int | Callable[[OpcodeBase], int]]: + """Add SLOTNUM opcode gas cost.""" + gas_costs = cls.gas_costs() + base_map = super(EIP7843, cls).opcode_gas_map() + return { + **base_map, + Opcodes.SLOTNUM: gas_costs.BASE, + } + + @classmethod + def valid_opcodes(cls) -> List[Opcodes]: + """Add SLOTNUM opcode.""" + return [Opcodes.SLOTNUM] + super(EIP7843, cls).valid_opcodes() diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 454f3d8cabd..41dc660309e 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -925,6 +925,11 @@ def header_beacon_root_required(cls) -> bool: """At genesis, header must not contain parent beacon block root.""" return False + @classmethod + def header_slot_number_required(cls) -> bool: + """At genesis, header must not contain slot number (EIP-7843).""" + return False + @classmethod def engine_new_payload_blob_hashes(cls) -> bool: """At genesis, payloads do not have blob hashes.""" @@ -965,6 +970,13 @@ def engine_payload_attribute_max_blobs_per_block(cls) -> bool: """ return False + @classmethod + def engine_payload_attribute_slot_number(cls) -> bool: + """ + At genesis, payload attributes do not include the slot number. + """ + return False + @classmethod def get_reward(cls) -> int: """ diff --git a/packages/testing/src/execution_testing/rpc/rpc_types.py b/packages/testing/src/execution_testing/rpc/rpc_types.py index b0668583f0d..7aab1ecf51d 100644 --- a/packages/testing/src/execution_testing/rpc/rpc_types.py +++ b/packages/testing/src/execution_testing/rpc/rpc_types.py @@ -212,6 +212,7 @@ class PayloadAttributes(CamelModel): parent_beacon_block_root: Hash | None = None target_blobs_per_block: HexNumber | None = None max_blobs_per_block: HexNumber | None = None + slot_number: HexNumber | None = None class BlobsBundle(CamelModel): diff --git a/packages/testing/src/execution_testing/specs/blockchain.py b/packages/testing/src/execution_testing/specs/blockchain.py index 3313e8795f3..f0b1530f57c 100644 --- a/packages/testing/src/execution_testing/specs/blockchain.py +++ b/packages/testing/src/execution_testing/specs/blockchain.py @@ -30,6 +30,7 @@ HeaderNonce, HexNumber, Number, + ZeroPaddedHexNumber, ) from execution_testing.client_clis import ( BlockExceptionWithMessage, @@ -165,6 +166,7 @@ class Header(CamelModel): parent_beacon_block_root: Removable | Hash | None = None requests_hash: Removable | Hash | None = None block_access_list_hash: Removable | Hash | None = None + slot_number: Removable | HexNumber | None = None REMOVE_FIELD: ClassVar[Removable] = Removable() """ @@ -351,6 +353,8 @@ def set_environment(self, env: Environment) -> Environment: and self.block_access_list is not None ): new_env_values["block_access_list"] = self.block_access_list + if not isinstance(self.slot_number, Removable): + new_env_values["slot_number"] = self.slot_number """ These values are required, but they depend on the previous environment, so they can be calculated here. @@ -672,19 +676,30 @@ def generate_block_data( if (blob_gas_per_blob := fork.blob_gas_per_blob()) > 0: blob_gas_used = blob_gas_per_blob * count_blobs(txs) + # Prepare slot_number for header initialization + slot_number_value: ZeroPaddedHexNumber | None = None + if fork.header_slot_number_required(): + slot_number_value = ZeroPaddedHexNumber( + int(env.slot_number) if env.slot_number is not None else 0 + ) + header = FixtureHeader( **( transition_tool_output.result.model_dump( exclude_none=True, exclude={"blob_gas_used", "transactions_trie"}, ) - | env.model_dump(exclude_none=True, exclude={"blob_gas_used"}) + | env.model_dump( + exclude_none=True, + exclude={"blob_gas_used", "slot_number"}, + ) ), blob_gas_used=blob_gas_used, transactions_trie=Transaction.list_root(txs), - extra_data=block.extra_data - if block.extra_data is not None - else b"", + extra_data=( + block.extra_data if block.extra_data is not None else b"" + ), + slot_number=slot_number_value, fork=fork, ) @@ -777,7 +792,8 @@ def generate_block_data( t8n_bal ) if bal != t8n_bal: - # If the BAL was modified, update the header hash + # If the BAL was modified and the fork requires it, update the + # header hash header.block_access_list_hash = Hash(bal.rlp.keccak256()) built_block = BuiltBlock( diff --git a/packages/testing/src/execution_testing/specs/state.py b/packages/testing/src/execution_testing/specs/state.py index bead9b2a932..b0c456a3590 100644 --- a/packages/testing/src/execution_testing/specs/state.py +++ b/packages/testing/src/execution_testing/specs/state.py @@ -318,6 +318,7 @@ def _generate_blockchain_blocks(self) -> List[Block]: "extra_data": self.env.extra_data, "withdrawals": self.env.withdrawals, "parent_beacon_block_root": self.env.parent_beacon_block_root, + "slot_number": self.env.slot_number, "txs": [self.tx], "ommers": [], "header_verify": self.blockchain_test_header_verify, diff --git a/packages/testing/src/execution_testing/specs/static_state/environment.py b/packages/testing/src/execution_testing/specs/static_state/environment.py index 32cd3b4e6db..89b42cbe45b 100644 --- a/packages/testing/src/execution_testing/specs/static_state/environment.py +++ b/packages/testing/src/execution_testing/specs/static_state/environment.py @@ -33,6 +33,7 @@ class EnvironmentInStateTestFiller(BaseModel): current_excess_blob_gas: ValueInFiller | None = Field( None, alias="currentExcessBlobGas" ) + current_slot_number: ValueInFiller | None = Field(None, alias="slotNumber") model_config = ConfigDict(extra="forbid") @@ -72,4 +73,6 @@ def get_environment(self, tags: TagDict) -> Environment: kwargs["base_fee_per_gas"] = self.current_base_fee if self.current_excess_blob_gas is not None: kwargs["excess_blob_gas"] = self.current_excess_blob_gas + if self.current_slot_number is not None: + kwargs["slot_number"] = self.current_slot_number return Environment(**kwargs) diff --git a/packages/testing/src/execution_testing/test_types/block_types.py b/packages/testing/src/execution_testing/test_types/block_types.py index 4d95a4e43f7..56d367e2e68 100644 --- a/packages/testing/src/execution_testing/test_types/block_types.py +++ b/packages/testing/src/execution_testing/test_types/block_types.py @@ -101,6 +101,7 @@ class EnvironmentGeneric(CamelModel, Generic[NumberBoundTypeVar]): excess_blob_gas: NumberBoundTypeVar | None = Field( None, alias="currentExcessBlobGas" ) + slot_number: NumberBoundTypeVar | None = Field(None, alias="slotNumber") parent_difficulty: NumberBoundTypeVar | None = Field(None) parent_timestamp: NumberBoundTypeVar | None = Field(None) @@ -200,6 +201,9 @@ def set_fork_requirements(self, fork: Fork) -> "Environment": ): updated_values["parent_beacon_block_root"] = 0 + if fork.header_slot_number_required() and self.slot_number is None: + updated_values["slot_number"] = 0 + return self.copy(**updated_values) def __hash__(self) -> int: diff --git a/packages/testing/src/execution_testing/vm/opcodes.py b/packages/testing/src/execution_testing/vm/opcodes.py index 1ad001cb1c6..96fcd6599a3 100644 --- a/packages/testing/src/execution_testing/vm/opcodes.py +++ b/packages/testing/src/execution_testing/vm/opcodes.py @@ -2225,6 +2225,36 @@ class Opcodes(Opcode, Enum): Source: [EIP-7516](https://eips.ethereum.org/EIPS/eip-7516) """ + SLOTNUM = Opcode(0x4B, popped_stack_items=0, pushed_stack_items=1) + """ + SLOTNUM() = slotNumber + ---- + + Description + ---- + Returns the current slot number as provided by the consensus layer. + The slot number is passed from the consensus layer to the execution + layer through the engine API. + + Inputs + ---- + - None + + Outputs + ---- + - slotNumber: current slot number (uint64) + + Fork + ---- + Amsterdam + + Gas + ---- + 2 + + Source: [EIP-7843](https://eips.ethereum.org/EIPS/eip-7843) + """ + POP = Opcode(0x50, popped_stack_items=1) """ POP() diff --git a/src/ethereum/forks/amsterdam/blocks.py b/src/ethereum/forks/amsterdam/blocks.py index 5a4e1b410f0..302533da837 100644 --- a/src/ethereum/forks/amsterdam/blocks.py +++ b/src/ethereum/forks/amsterdam/blocks.py @@ -114,7 +114,7 @@ class Header: [`keccak256`]: ref:ethereum.crypto.hash.keccak256 [changes]: ref:ethereum.state.State.compute_state_root_and_trie_changes [Trie]: ref:ethereum.merkle_patricia_trie.Trie - """ # noqa: E501 + """ transactions_root: Root """ @@ -258,6 +258,14 @@ class Header: [cbalh]: ref:ethereum.forks.amsterdam.block_access_lists.hash_block_access_list """ # noqa: E501 + slot_number: U64 + """ + The slot number of this block as provided by the consensus layer. + Introduced in [EIP-7843]. + + [EIP-7843]: https://eips.ethereum.org/EIPS/eip-7843 + """ + @slotted_freezable @dataclass diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index 0af84822dc8..531c086a9f7 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -314,6 +314,7 @@ def execute_block( excess_blob_gas=block.header.excess_blob_gas, parent_beacon_block_root=block.header.parent_beacon_block_root, block_access_list_builder=BlockAccessListBuilder(), + slot_number=block.header.slot_number, ) block_output = apply_body( diff --git a/src/ethereum/forks/amsterdam/vm/__init__.py b/src/ethereum/forks/amsterdam/vm/__init__.py index ff523e2c33c..11cb126ee4f 100644 --- a/src/ethereum/forks/amsterdam/vm/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/__init__.py @@ -57,6 +57,7 @@ class BlockEnvironment: excess_blob_gas: U64 parent_beacon_block_root: Hash32 block_access_list_builder: BlockAccessListBuilder + slot_number: U64 @dataclass diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index f831e7f4ce9..fc427587318 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -165,6 +165,7 @@ class GasCosts: OPCODE_CHAINID = BASE OPCODE_BASEFEE = BASE OPCODE_BLOBBASEFEE = BASE + OPCODE_SLOTNUM = BASE OPCODE_BLOBHASH = Uint(3) OPCODE_PUSH = VERY_LOW OPCODE_PUSH0 = BASE diff --git a/src/ethereum/forks/amsterdam/vm/instructions/__init__.py b/src/ethereum/forks/amsterdam/vm/instructions/__init__.py index 0da72c8ea5c..d858b5053f0 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/__init__.py @@ -99,6 +99,7 @@ class Ops(enum.Enum): BASEFEE = 0x48 BLOBHASH = 0x49 BLOBBASEFEE = 0x4A + SLOTNUM = 0x4B # Control Flow Ops STOP = 0x00 @@ -251,6 +252,7 @@ class Ops(enum.Enum): Ops.PREVRANDAO: block_instructions.prev_randao, Ops.GASLIMIT: block_instructions.gas_limit, Ops.CHAINID: block_instructions.chain_id, + Ops.SLOTNUM: block_instructions.slot_number, Ops.MLOAD: memory_instructions.mload, Ops.MSTORE: memory_instructions.mstore, Ops.MSTORE8: memory_instructions.mstore8, diff --git a/src/ethereum/forks/amsterdam/vm/instructions/block.py b/src/ethereum/forks/amsterdam/vm/instructions/block.py index 8c93840b384..24c524673eb 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/block.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/block.py @@ -259,3 +259,36 @@ def chain_id(evm: Evm) -> None: # PROGRAM COUNTER evm.pc += Uint(1) + + +def slot_number(evm: Evm) -> None: + """ + Push the current slot number onto the stack. + + The slot number is provided by the consensus layer and passed to the + execution layer through the engine API. + + Parameters + ---------- + evm : + The current EVM frame. + + Raises + ------ + :py:class:`~ethereum.forks.amsterdam.vm.exceptions.StackOverflowError` + If `len(stack)` is equal to `1024`. + :py:class:`~ethereum.forks.amsterdam.vm.exceptions.OutOfGasError` + If `evm.gas_left` is less than `2`. + + """ + # STACK + pass + + # GAS + charge_gas(evm, GasCosts.OPCODE_SLOTNUM) + + # OPERATION + push(evm.stack, U256(evm.message.block_env.slot_number)) + + # PROGRAM COUNTER + evm.pc += Uint(1) diff --git a/src/ethereum/genesis.py b/src/ethereum/genesis.py index aa15805521b..55eed6aa4d9 100644 --- a/src/ethereum/genesis.py +++ b/src/ethereum/genesis.py @@ -265,6 +265,9 @@ def add_genesis_block( if has_field(hardfork.Header, "block_access_list_hash"): fields["block_access_list_hash"] = keccak256(rlp.encode([])) + if has_field(hardfork.Header, "slot_number"): + fields["slot_number"] = U64(0) + genesis_header = hardfork.Header(**fields) block_fields = { diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py index 2ca816dbbf0..3a93f850fbd 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py @@ -197,4 +197,8 @@ def json_to_header(self, raw: Any) -> Any: bal_hash = hex_to_bytes32(raw.get("blockAccessListHash")) parameters.append(bal_hash) + if "slotNumber" in raw: + slot_number = hex_to_u64(raw.get("slotNumber")) + parameters.append(slot_number) + return self.fork.Header(*parameters) diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py index 7953f97db4f..f9ec92d6ded 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fork_loader.py @@ -302,6 +302,15 @@ def has_withdrawal(self) -> bool: """Check if the fork has a `Withdrawal` class.""" return hasattr(self._module("blocks"), "Withdrawal") + @property + def has_slot_number(self) -> bool: + """Check if the fork supports the SLOTNUM opcode (EIP-7843).""" + try: + block_env = self._module("vm").BlockEnvironment + return "slot_number" in block_env.__dataclass_fields__ + except (ModuleNotFoundError, AttributeError): + return False + @property def decode_transaction(self) -> Any: """decode_transaction function of the fork.""" diff --git a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py index e17cde49005..c5fc7cde359 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py @@ -400,6 +400,8 @@ def block_environment(self) -> Any: kw_arguments["block_access_list_builder"] = ( self.fork.BlockAccessListBuilder() ) + if self.fork.has_slot_number: + kw_arguments["slot_number"] = self.env.slot_number return block_environment(**kw_arguments) diff --git a/src/ethereum_spec_tools/evm_tools/t8n/env.py b/src/ethereum_spec_tools/evm_tools/t8n/env.py index f76c0caaf57..edf3763d573 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/env.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/env.py @@ -53,6 +53,7 @@ class Env: parent_excess_blob_gas: Optional[U64] parent_blob_gas_used: Optional[U64] excess_blob_gas: Optional[U64] + slot_number: Optional[U64] requests: Any def __init__(self, t8n: "T8N", stdin: Optional[Dict] = None): @@ -86,6 +87,8 @@ def __init__(self, t8n: "T8N", stdin: Optional[Dict] = None): ) self.read_excess_blob_gas(data, t8n) + self.read_slot_number(data, t8n) + def read_excess_blob_gas(self, data: Any, t8n: "T8N") -> None: """ Read the excess_blob_gas from the data. If the excess blob gas is @@ -147,6 +150,8 @@ def read_excess_blob_gas(self, data: Any, t8n: "T8N") -> None: if t8n.fork.has_hash_block_access_list: arguments["block_access_list_hash"] = Hash32(b"\0" * 32) + if t8n.fork.has_slot_number: + arguments["slot_number"] = U64(0) parent_header = t8n.fork.Header(**arguments) @@ -222,6 +227,16 @@ def read_randao(self, data: Any, t8n: "T8N") -> None: left_pad_zero_bytes(hex_to_bytes(current_random), 32) ) + def read_slot_number(self, data: Any, t8n: "T8N") -> None: + """ + Read the slot number from the data. + The slot number is provided by the consensus layer. + """ + self.slot_number = None + if t8n.fork.has_slot_number: + if "slotNumber" in data: + self.slot_number = parse_hex_or_int(data["slotNumber"], U64) + def read_withdrawals(self, data: Any, t8n: "T8N") -> None: """ Read the withdrawals from the data. diff --git a/tests/amsterdam/eip7843_slotnum/__init__.py b/tests/amsterdam/eip7843_slotnum/__init__.py new file mode 100644 index 00000000000..540001d5d95 --- /dev/null +++ b/tests/amsterdam/eip7843_slotnum/__init__.py @@ -0,0 +1 @@ +"""Tests for [EIP-7843: SLOTNUM](https://eips.ethereum.org/EIPS/eip-7843).""" diff --git a/tests/amsterdam/eip7843_slotnum/test_slotnum.py b/tests/amsterdam/eip7843_slotnum/test_slotnum.py new file mode 100644 index 00000000000..65358ebb31c --- /dev/null +++ b/tests/amsterdam/eip7843_slotnum/test_slotnum.py @@ -0,0 +1,126 @@ +"""Tests for EIP-7843 (SLOTNUM).""" + +from dataclasses import dataclass + +import pytest +from execution_testing import ( + Account, + Alloc, + Environment, + Fork, + Op, + StateTestFiller, + Transaction, +) + + +@dataclass(frozen=True) +class ReferenceSpec: + """Reference specification.""" + + git_path: str + version: str + + +ref_spec_7843 = ReferenceSpec( + git_path="EIPS/eip-7843.md", + version="6bc5d6b7acbc016a79fa573f98975093b5c2ca52", +) + +REFERENCE_SPEC_GIT_PATH = ref_spec_7843.git_path +REFERENCE_SPEC_VERSION = ref_spec_7843.version + +pytestmark = pytest.mark.valid_from("EIP7843") + + +@pytest.mark.parametrize( + "slot_number", + [ + pytest.param(0, id="slot_zero"), + pytest.param(1, id="slot_one"), + pytest.param(0x1000, id="slot_4096"), + pytest.param(2**32, id="slot_large"), + pytest.param(2**64 - 1, id="slot_max_u64"), + ], +) +def test_slotnum_value( + state_test: StateTestFiller, + pre: Alloc, + slot_number: int, +) -> None: + """ + Test that SLOTNUM opcode returns the correct slot number. + + The slot number is provided by the consensus layer and should be + accessible via the SLOTNUM opcode (0x4B). + """ + # Store SLOTNUM result at storage key 0 + code = Op.SSTORE(0, Op.SLOTNUM) + code_address = pre.deploy_contract(code) + + tx = Transaction( + sender=pre.fund_eoa(), + gas_limit=100_000, + to=code_address, + ) + + post = { + code_address: Account( + storage={0: slot_number}, + ), + } + + state_test( + env=Environment(slot_number=slot_number), + pre=pre, + tx=tx, + post=post, + ) + + +@pytest.mark.parametrize( + "gas_delta,call_succeeds", + [ + pytest.param(0, True, id="enough_gas"), + pytest.param(-1, False, id="out_of_gas"), + ], +) +def test_slotnum_gas_cost( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + gas_delta: int, + call_succeeds: bool, +) -> None: + """ + Test that SLOTNUM opcode costs exactly 2 gas (G_BASE). + """ + slotnum_gas = Op.SLOTNUM.gas_cost(fork) + call_gas = slotnum_gas + gas_delta + + # Callee just executes SLOTNUM + callee_code = Op.SLOTNUM + Op.STOP + callee_address = pre.deterministic_deploy_contract(deploy_code=callee_code) + + # Caller calls the callee with limited gas and stores result + caller_code = Op.SSTORE(0, Op.CALL(gas=call_gas, address=callee_address)) + caller_address = pre.deploy_contract(caller_code) + + tx = Transaction( + sender=pre.fund_eoa(), + gas_limit=100_000, + to=caller_address, + ) + + post = { + caller_address: Account( + storage={0: 1 if call_succeeds else 0}, + ), + } + + state_test( + env=Environment(slot_number=12345), + pre=pre, + tx=tx, + post=post, + ) diff --git a/whitelist.txt b/whitelist.txt index 0c73495052e..fbad9e66265 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -1109,6 +1109,7 @@ simlimit sload slot1 slot2 +SLOTNUM slt smod socketserver From ea3552f023bd410aff5b9b76f17cc1780a80ddf0 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Fri, 15 May 2026 01:42:30 +0100 Subject: [PATCH 081/186] refactor(spec-specs,test-types): replace `pycryptodome` with `hashlib` for keccak (#2370) * use hashlib * test(crypto): cover keccak backend dispatch in `ethereum.crypto.hash` Add tests that verify the active backend matches published Keccak-256 and Keccak-512 vectors, both backends produce byte-identical output, and the pycryptodome fallback engages cleanly when `hashlib.new("keccak-256")` is patched to raise. Also covers EEST `Bytes.keccak256` and `trie.keccak256` routing. Without the fallback dispatch these tests fail (or, on Pythons whose hashlib lacks Keccak entirely, the test session aborts at collection), so the suite drives the fix that follows. * fix(crypto): fall back to pycryptodome when hashlib lacks Keccak OpenSSL only gained default-provider Keccak in 3.2.0 (Nov 2023). LTS 3.0.x and 3.1.x, still shipped by Debian 12 and RHEL 9, do not provide it, so `hashlib.new("keccak-256", ...)` raises `ValueError` there and every call to `keccak256` crashes. At module import time, probe with `hashlib.new("keccak-256", b"")`. On `ValueError`, rebind the digest helpers to pycryptodome's bundled implementation. The probe is more reliable than checking `hashlib.algorithms_available`, which omits some OpenSSL-provider digests on python-build-standalone builds. Route the EEST keccak helpers in `base_types.Bytes.keccak256` and `test_types.trie.keccak256` through `ethereum.crypto.hash`, so the dispatch lives in one place. Widen `keccak256` and `keccak512` parameter types from `Bytes | bytearray` to `bytes | bytearray` so the EEST `Bytes` subclass passes through without coercion. * fix(crypto): define keccak digest helpers unconditionally for docc The previous `try/except` block defined `_keccak256_digest` and `_keccak512_digest` inside its branches. `docc`'s static analyzer does not traverse `try/except` at module scope when discovering module-level names, so it could not resolve the references from `keccak256` and `keccak512`, breaking the `Build Documentation` job with: docc.plugins.references.ReferenceError: in `src/ethereum/crypto/hash.py`, undefined identifier: `ethereum.crypto.hash._keccak256_digest` Define the helpers unconditionally at module scope and branch on a module-level `_USE_HASHLIB` flag inside their bodies. The probe runs once at import; the runtime branch adds about 20ns per call, dwarfed by the hash itself. `pycryptodome` is now imported unconditionally, which is free since it is already a hard dep via `elliptic_curve.py`. Update the dispatch tests to assert on `_USE_HASHLIB` instead of the presence of `_pycryptodome_keccak` (now always imported). * Fix keccak-256 initialization in test function * code review feedback * update docc --------- Co-authored-by: danceratopz Co-authored-by: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Co-authored-by: Sam Wilson --- .../base_types/base_types.py | 5 +- .../base_types/tests/test_keccak_dispatch.py | 174 ++++++++++++++++++ .../src/execution_testing/test_types/trie.py | 8 +- pyproject.toml | 2 +- src/ethereum/crypto/hash.py | 55 +++++- uv.lock | 10 +- 6 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 packages/testing/src/execution_testing/base_types/tests/test_keccak_dispatch.py diff --git a/packages/testing/src/execution_testing/base_types/base_types.py b/packages/testing/src/execution_testing/base_types/base_types.py index 0bb63e69eca..b42fb315485 100644 --- a/packages/testing/src/execution_testing/base_types/base_types.py +++ b/packages/testing/src/execution_testing/base_types/base_types.py @@ -13,7 +13,7 @@ TypeVar, ) -from Crypto.Hash import keccak +from ethereum.crypto.hash import keccak256 as _keccak256 from pydantic import GetCoreSchemaHandler, StringConstraints from pydantic_core.core_schema import ( PlainValidatorFunctionSchema, @@ -201,8 +201,7 @@ def hex(self, *args: Any, **kwargs: Any) -> str: def keccak256(self) -> "Hash": """Return the keccak256 hash of the opcode byte representation.""" - k = keccak.new(digest_bits=256) - return Hash(k.update(bytes(self)).digest()) + return Hash(_keccak256(self)) def sha256(self) -> "Hash": """Return the sha256 hash of the opcode byte representation.""" diff --git a/packages/testing/src/execution_testing/base_types/tests/test_keccak_dispatch.py b/packages/testing/src/execution_testing/base_types/tests/test_keccak_dispatch.py new file mode 100644 index 00000000000..95bd341ba6d --- /dev/null +++ b/packages/testing/src/execution_testing/base_types/tests/test_keccak_dispatch.py @@ -0,0 +1,174 @@ +""" +Tests for the Keccak backend dispatch in `ethereum.crypto.hash`. + +The module decides at import time whether to use hashlib (linked OpenSSL) +or pycryptodome, depending on whether `hashlib.new("keccak-256", ...)` +succeeds. These tests verify: + +* both backends produce byte-identical output (cross-backend equivalence); +* the fallback engages cleanly when hashlib raises, simulated via + monkeypatch so we can exercise the path on a Python whose OpenSSL does + expose Keccak; +* on a Python where hashlib supports Keccak, the fast path is selected + (guards against a regression where `algorithms_available` lies and the + module silently forces every user onto pycryptodome). +""" + +import hashlib +import importlib +from collections.abc import Iterator +from typing import Any +from unittest.mock import patch + +import pytest + +# Pre-NIST Keccak vectors. Empty-input digests are widely published; the +# `hashme` vector was confirmed against a working hashlib build during +# PR #2370 review. +KECCAK256_VECTORS: list[tuple[bytes, str]] = [ + ( + b"", + "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + ), + ( + b"abc", + "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", + ), + ( + b"hashme", + "7f98885dc9cf152c0bb08eaf056668f99c47cabd8fe01b1276f9a305b1389646", + ), +] + +KECCAK512_VECTORS: list[tuple[bytes, str]] = [ + ( + b"", + "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304" + "c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", + ), +] + + +def _hashlib_has_keccak() -> bool: + """Return True if `hashlib.new("keccak-256", ...)` succeeds here.""" + try: + hashlib.new("keccak-256") + except ValueError: + return False + return True + + +def _clean_reimport_hash() -> Any: + """Drop and reimport `ethereum.crypto.hash` for a fresh dispatch run.""" + mod = importlib.import_module("ethereum.crypto.hash") + return importlib.reload(mod) + + +@pytest.fixture +def restore_hash_module() -> Iterator[None]: + """Restore the natural-state `ethereum.crypto.hash` after each test.""" + yield + _clean_reimport_hash() + + +@pytest.mark.parametrize("buffer, expected_hex", KECCAK256_VECTORS) +def test_keccak256_known_vectors(buffer: bytes, expected_hex: str) -> None: + """Active backend produces published Keccak-256 digests.""" + from ethereum.crypto.hash import keccak256 + + assert keccak256(buffer).hex() == expected_hex + + +@pytest.mark.parametrize("buffer, expected_hex", KECCAK512_VECTORS) +def test_keccak512_known_vectors(buffer: bytes, expected_hex: str) -> None: + """Active backend produces published Keccak-512 digests.""" + from ethereum.crypto.hash import keccak512 + + assert keccak512(buffer).hex() == expected_hex + + +def test_both_backends_agree() -> None: + """Hashlib and pycryptodome produce byte-identical Keccak-256 output.""" + if not _hashlib_has_keccak(): + pytest.skip("hashlib lacks keccak-256 on this OpenSSL build") + + from Crypto.Hash import keccak as pyc_keccak + + inputs = [ + b"", + b"x", + b"\x00" * 64, + bytes(range(256)), + b"a" * 4096, + b"\xff" * 65536, + ] + for buf in inputs: + hl = hashlib.new("keccak-256", buf).digest() + pc = pyc_keccak.new(digest_bits=256).update(buf).digest() + assert hl == pc, f"backends disagree on input of length {len(buf)}" + + +def test_fallback_engages_when_hashlib_lacks_keccak( + restore_hash_module: None, +) -> None: + """If hashlib raises for Keccak, the module uses pycryptodome instead.""" + del restore_hash_module + real_new = hashlib.new + + def mocked_new(name: str, *args: Any, **kwargs: Any) -> Any: + if name in ("keccak-256", "keccak-512"): + raise ValueError(f"unsupported hash type {name}") + return real_new(name, *args, **kwargs) + + with patch.object(hashlib, "new", side_effect=mocked_new): + h = _clean_reimport_hash() + + assert h._USE_HASHLIB is False, ( + "module did not engage pycryptodome fallback" + ) + for buffer, expected_hex in KECCAK256_VECTORS: + assert h.keccak256(buffer).hex() == expected_hex + for buffer, expected_hex in KECCAK512_VECTORS: + assert h.keccak512(buffer).hex() == expected_hex + + +def test_native_path_used_when_hashlib_has_keccak( + restore_hash_module: None, +) -> None: + """ + Verify hashlib path is selected when keccak-256 is supported. + + Guards against a regression where a bogus availability check (e.g. + one that relied on `hashlib.algorithms_available`) would silently + force every user onto the slower pycryptodome path. + """ + del restore_hash_module + if not _hashlib_has_keccak(): + pytest.skip("hashlib lacks keccak-256 on this OpenSSL build") + + h = _clean_reimport_hash() + assert h._USE_HASHLIB is True, ( + "module engaged pycryptodome fallback despite hashlib having keccak" + ) + + +def test_eest_bytes_keccak256_matches_eels() -> None: + """`Bytes.keccak256()` returns the same digest as EELS `keccak256`.""" + from ethereum.crypto.hash import keccak256 + + from ..base_types import Bytes + + for buffer in (b"", b"hashme", bytes(range(256))): + from_eest = bytes(Bytes(buffer).keccak256()) + from_eels = bytes(keccak256(buffer)) + assert from_eest == from_eels + + +def test_eest_trie_keccak256_matches_eels() -> None: + """`trie.keccak256` and EELS `keccak256` return identical digests.""" + from ethereum.crypto.hash import keccak256 as eels + + from ...test_types.trie import keccak256 as trie + + for buffer in (b"", b"hashme", bytes(range(256))): + assert bytes(trie(buffer)) == bytes(eels(buffer)) diff --git a/packages/testing/src/execution_testing/test_types/trie.py b/packages/testing/src/execution_testing/test_types/trie.py index 4eb9d4288b2..16fd4d5709d 100644 --- a/packages/testing/src/execution_testing/test_types/trie.py +++ b/packages/testing/src/execution_testing/test_types/trie.py @@ -18,7 +18,7 @@ cast, ) -from Crypto.Hash import keccak +from ethereum.crypto.hash import keccak256 from ethereum_rlp import Extended, rlp from ethereum_types.bytes import Bytes, Bytes20, Bytes32 from ethereum_types.frozen import slotted_freezable @@ -36,12 +36,6 @@ class FrontierAccount: code: Bytes -def keccak256(buffer: Bytes) -> Bytes32: - """Compute the keccak256 hash of the input `buffer`.""" - k = keccak.new(digest_bits=256) - return Bytes32(k.update(buffer).digest()) - - def encode_account( raw_account_data: FrontierAccount, storage_root: Bytes ) -> Bytes: diff --git a/pyproject.toml b/pyproject.toml index b89580d7ac0..40fd1eef299 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -225,7 +225,7 @@ actionlint = [ "shellcheck-py>=0.10", ] doc = [ - "docc>=0.6.0,<0.7.0", + "docc>=0.6.1,<0.7.0", "fladrif>=0.2.0,<0.3.0", "mistletoe>=1.5.0,<2", ] diff --git a/src/ethereum/crypto/hash.py b/src/ethereum/crypto/hash.py index 67b9053f3a0..9439522a7ce 100644 --- a/src/ethereum/crypto/hash.py +++ b/src/ethereum/crypto/hash.py @@ -11,14 +11,55 @@ Cryptographic hashing functions. """ -from Crypto.Hash import keccak -from ethereum_types.bytes import Bytes, Bytes32, Bytes64 +import hashlib + +from Crypto.Hash import keccak as _pycryptodome_keccak +from ethereum_types.bytes import Bytes32, Bytes64 Hash32 = Bytes32 Hash64 = Bytes64 -def keccak256(buffer: Bytes | bytearray) -> Hash32: +def _hashlib_has_keccak() -> bool: + """Return `True` if `hashlib` can compute pre-NIST Keccak digests.""" + try: + hashlib.new("keccak-256", b"") + except ValueError: + return False + return True + + +# Decide once at import time whether to dispatch to hashlib (linked OpenSSL) +# or to pycryptodome's bundled implementation. OpenSSL only gained +# default-provider Keccak in 3.2.0 (Nov 2023); LTS 3.0.x and 3.1.x (still +# shipped by Debian 12, RHEL 9, etc.) do not provide it. We probe with +# `hashlib.new()` because `hashlib.algorithms_available` omits some +# OpenSSL-provider digests on common builds (e.g. python-build-standalone / +# uv-managed CPython on OpenSSL 3.5.x), yielding false negatives. +_USE_HASHLIB = _hashlib_has_keccak() + + +if _USE_HASHLIB: + + def _keccak256_digest(buffer: bytes | bytearray) -> bytes: + return hashlib.new("keccak-256", buffer).digest() + + def _keccak512_digest(buffer: bytes | bytearray) -> bytes: + return hashlib.new("keccak-512", buffer).digest() +else: + + def _keccak256_digest(buffer: bytes | bytearray) -> bytes: + return ( + _pycryptodome_keccak.new(digest_bits=256).update(buffer).digest() + ) + + def _keccak512_digest(buffer: bytes | bytearray) -> bytes: + return ( + _pycryptodome_keccak.new(digest_bits=512).update(buffer).digest() + ) + + +def keccak256(buffer: bytes | bytearray) -> Hash32: """ Computes the keccak256 hash of the input `buffer`. @@ -33,11 +74,10 @@ def keccak256(buffer: Bytes | bytearray) -> Hash32: Output of the hash function. """ - k = keccak.new(digest_bits=256) - return Hash32(k.update(buffer).digest()) + return Hash32(_keccak256_digest(buffer)) -def keccak512(buffer: Bytes | bytearray) -> Hash64: +def keccak512(buffer: bytes | bytearray) -> Hash64: """ Computes the keccak512 hash of the input `buffer`. @@ -52,5 +92,4 @@ def keccak512(buffer: Bytes | bytearray) -> Hash64: Output of the hash function. """ - k = keccak.new(digest_bits=512) - return Hash64(k.update(buffer).digest()) + return Hash64(_keccak512_digest(buffer)) diff --git a/uv.lock b/uv.lock index 9c6ba50bf78..65ccb609d2f 100644 --- a/uv.lock +++ b/uv.lock @@ -737,7 +737,7 @@ wheels = [ [[package]] name = "docc" -version = "0.6.0" +version = "0.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-resources" }, @@ -749,9 +749,9 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/37/cd2e718c92e26da0e1129700467f62efd8bd1f53dc1dae59b3e0e0402574/docc-0.6.0.tar.gz", hash = "sha256:d335be8f509884fefb507e75a184a3c9824e50e511dd5464be9089d1ad744912", size = 72398, upload-time = "2026-04-29T02:02:30.202Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/e2/47252138c9978ca2ab7a3637bba1464f8da2d1f34e1886babaef0459c1b6/docc-0.6.1.tar.gz", hash = "sha256:c4cc94f542afa76e2d9b10ce5e43ec4cdddc87897dde52a2a0f07a1db0af9499", size = 74268, upload-time = "2026-05-14T23:51:53.862Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/66/b81c58e0514531a26201f3d6b437b24375b996db5a8105d3e21420ccfc08/docc-0.6.0-py3-none-any.whl", hash = "sha256:bb4ed18f23926f1cea649a407c67d6794a92361826593e6ba374e80892fe98d1", size = 99176, upload-time = "2026-04-29T02:02:28.829Z" }, + { url = "https://files.pythonhosted.org/packages/89/0b/56f73ba7767f53796d43e86e2a3e77d04211b214f09b8fc96cbb5fb110c5/docc-0.6.1-py3-none-any.whl", hash = "sha256:c058a8207603270d437d4f1887eb850ddfc2519f336627d4f373d87d296a0198", size = 100269, upload-time = "2026-05-14T23:51:52.256Z" }, ] [[package]] @@ -965,7 +965,7 @@ dev = [ { name = "cairosvg", specifier = ">=2.7.0,<3" }, { name = "codespell", specifier = "==2.4.1" }, { name = "codespell", specifier = ">=2.4.1,<3" }, - { name = "docc", specifier = ">=0.6.0,<0.7.0" }, + { name = "docc", specifier = ">=0.6.1,<0.7.0" }, { name = "ethereum-execution", extras = ["optimized"] }, { name = "ethereum-execution-testing", editable = "packages/testing" }, { name = "filelock", specifier = ">=3.15.1,<4" }, @@ -1003,7 +1003,7 @@ dev = [ { name = "vulture", specifier = "==2.14.0" }, ] doc = [ - { name = "docc", specifier = ">=0.6.0,<0.7.0" }, + { name = "docc", specifier = ">=0.6.1,<0.7.0" }, { name = "fladrif", specifier = ">=0.2.0,<0.3.0" }, { name = "mistletoe", specifier = ">=1.5.0,<2" }, ] From c198ebf00ab3897f66ed49bc28cc4c50aa61a858 Mon Sep 17 00:00:00 2001 From: Carson Date: Thu, 14 May 2026 22:41:18 -0400 Subject: [PATCH 082/186] feat(spec-specs, tests): add EIP-7954 Increase Maximum Contract Size (#2850) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat(specs,tests): Implement EIP-7954 (#2276) * ✨ feat: Tests for new contract size * ✨ feat: Gas metering of initcode * ✨ feat: Transition, Mainnet tests * 🧹 chore: Names * fix: use gas constant instead of hard-coded number * fix: remove references to old_max that are not in tests * fix: align with other forks; use 2*code_size for initcode size * chore: fix lint * refactor: simplify gas calculation with gas cost API; add post check * refactor: use opcode metadata for gas calc * feat(test): add max_code with max_init_code in same test * refactor: simplify calls to compute_create_address; no conditional necessary * 🧹 chore: Simplify docstring * 🧹 chore: Simplify opcode based testing * 🧹 chore: Better names * 🧹 chore: types * version Co-authored-by: felipe * feat(test): use deterministic deploy for similar contracts * refactor: use same max-size self-checking contract for tests - DRY max size contract for mainnet by including the superset in one and removing subset tests --------- Co-authored-by: raxhvl Co-authored-by: fselmo * fix(tests): Failing initcode test (#2355) * refactor(tests): remove gas metering test moved to EIP-8037 The 2D gas metering test for max initcode size via CREATE is an EIP-8037 concern and now lives in the 8037 test suite. The 7954 max initcode enforcement is covered by test_max_initcode_size_via_create. * fix(tests): Merge issues * refactor(tests): Condition EIP-7954 to EIP Inclusion * refactor(tests): gate pre-EIP-7954 code size tests before EIP7954 These ported_static tests hardcode sizes around the pre-EIP-7954 24 KiB MAX_CODE_SIZE / 48 KiB MAX_INITCODE_SIZE limits, so paths that previously failed now succeed on Amsterdam and break their Account.NONEXISTENT expectations. I marked them valid_before(EIP7954). The remaining 22 params still cover EIP-2929 warming on Amsterdam. Equivalent Amsterdam-side coverage is provided by eip7954_increase_max_contract_size/test_max_code_size.py and test_max_initcode_size.py, which size against fork.max_code_size() / fork.max_initcode_size() and follow the same creation-tx, CREATE, and CREATE2 paths with the new limits. * fix(tests): cover warm-after-failed-create over max code size --------- Co-authored-by: raxhvl <10168946+raxhvl@users.noreply.github.com> Co-authored-by: raxhvl Co-authored-by: fselmo Co-authored-by: Mario Vega Co-authored-by: spencer-tb --- .../forks/forks/eips/amsterdam/eip_7954.py | 24 + src/ethereum/forks/amsterdam/__init__.py | 2 + .../forks/amsterdam/vm/interpreter.py | 2 +- .../__init__.py | 1 + .../conftest.py | 28 ++ .../spec.py | 17 + .../test_cases.md | 23 + .../test_eip_mainnet.py | 119 +++++ .../test_fork_transition.py | 410 ++++++++++++++++++ .../test_max_code_size.py | 354 +++++++++++++++ .../test_max_initcode_size.py | 187 ++++++++ .../test_codesize_oog_invalid_size.py | 1 + .../test_create2_code_size_limit.py | 1 + .../test_create_code_size_limit.py | 1 + .../test_create_address_warm_after_fail.py | 4 + .../test_create2_init_code_size_limit.py | 1 + .../test_create_init_code_size_limit.py | 1 + .../test_creation_tx_init_code_size_limit.py | 1 + .../eip3860_initcode/test_initcode.py | 2 +- 19 files changed, 1177 insertions(+), 2 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7954.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/__init__.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/conftest.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/spec.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/test_cases.md create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/test_eip_mainnet.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/test_fork_transition.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py create mode 100644 tests/amsterdam/eip7954_increase_max_contract_size/test_max_initcode_size.py diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7954.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7954.py new file mode 100644 index 00000000000..b5c23ce2752 --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7954.py @@ -0,0 +1,24 @@ +""" +EIP-7954: Increase Maximum Contract Size. + +Raise the maximum contract code size from 24KiB to 32KiB and initcode size from +48KiB to 64KiB. + +https://eips.ethereum.org/EIPS/eip-7954 +""" + +from ....base_fork import BaseFork + + +class EIP7954(BaseFork): + """EIP-7954 class.""" + + @classmethod + def max_code_size(cls) -> int: + """Max contract code size is 32 KiB.""" + return 32 * 1024 + + @classmethod + def max_initcode_size(cls) -> int: + """Max initcode size is 64 KiB.""" + return 64 * 1024 diff --git a/src/ethereum/forks/amsterdam/__init__.py b/src/ethereum/forks/amsterdam/__init__.py index e6f3e9476a0..e47bb43c1a3 100644 --- a/src/ethereum/forks/amsterdam/__init__.py +++ b/src/ethereum/forks/amsterdam/__init__.py @@ -4,11 +4,13 @@ ### Changes - [EIP-7928: Block-Level Access Lists][EIP-7928] +- [EIP-7954: Increase Maximum Contract Size][EIP-7954] ### Releases [EIP-7773]: https://eips.ethereum.org/EIPS/eip-7773 [EIP-7928]: https://eips.ethereum.org/EIPS/eip-7928 +[EIP-7954]: https://eips.ethereum.org/EIPS/eip-7954 """ from ethereum.fork_criteria import ForkCriteria, Unscheduled diff --git a/src/ethereum/forks/amsterdam/vm/interpreter.py b/src/ethereum/forks/amsterdam/vm/interpreter.py index 522411b5018..6ab6f66bafb 100644 --- a/src/ethereum/forks/amsterdam/vm/interpreter.py +++ b/src/ethereum/forks/amsterdam/vm/interpreter.py @@ -62,7 +62,7 @@ from .runtime import get_valid_jump_destinations STACK_DEPTH_LIMIT = Uint(1024) -MAX_CODE_SIZE = 0x6000 +MAX_CODE_SIZE = 0x8000 MAX_INIT_CODE_SIZE = 2 * MAX_CODE_SIZE diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/__init__.py b/tests/amsterdam/eip7954_increase_max_contract_size/__init__.py new file mode 100644 index 00000000000..7ea8f8276b3 --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/__init__.py @@ -0,0 +1 @@ +"""Tests for [EIP-7954: Increase Maximum Contract Size](https://eips.ethereum.org/EIPS/eip-7954).""" diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/conftest.py b/tests/amsterdam/eip7954_increase_max_contract_size/conftest.py new file mode 100644 index 00000000000..78cb66ed14d --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/conftest.py @@ -0,0 +1,28 @@ +"""Fixtures for the EIP-7954 max contract size tests.""" + +import pytest +from execution_testing import Address, Alloc, Bytecode, Fork, Op + + +@pytest.fixture +def max_code_size_contract( + pre: Alloc, + fork: Fork, +) -> tuple[Address, Bytecode]: + """ + Deploy a max-size self-checking contract deterministically. + + The contract uses its own ADDRESS to query EXTCODESIZE, EXTCODEHASH, + and EXTCODECOPY on itself, storing results in storage slots 0-2. + Padded with JUMPDESTs to reach the fork's max code size. + """ + logic = ( + Op.SSTORE(0, Op.EXTCODESIZE(Op.ADDRESS)) + + Op.SSTORE(1, Op.EXTCODEHASH(Op.ADDRESS)) + + Op.EXTCODECOPY(Op.ADDRESS, 0, 0, Op.EXTCODESIZE(Op.ADDRESS)) + + Op.SSTORE(2, Op.SHA3(0, Op.EXTCODESIZE(Op.ADDRESS))) + + Op.STOP + ) + target_code = logic + Op.JUMPDEST * (fork.max_code_size() - len(logic)) + target = pre.deterministic_deploy_contract(deploy_code=target_code) + return target, target_code diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/spec.py b/tests/amsterdam/eip7954_increase_max_contract_size/spec.py new file mode 100644 index 00000000000..7dac2d83625 --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/spec.py @@ -0,0 +1,17 @@ +"""Reference spec for [EIP-7954: Increase Maximum Contract Size](https://eips.ethereum.org/EIPS/eip-7954).""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ReferenceSpec: + """Reference specification.""" + + git_path: str + version: str + + +ref_spec_7954 = ReferenceSpec( + git_path="EIPS/eip-7954.md", + version="b1f5bf8f70ba9306400f5e13313f781c35acc860", +) diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/test_cases.md b/tests/amsterdam/eip7954_increase_max_contract_size/test_cases.md new file mode 100644 index 00000000000..68d665d0c82 --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/test_cases.md @@ -0,0 +1,23 @@ +# EIP-7954 Increase Maximum Contract Size Test Cases + +| Function Name | Goal | Setup | Expectation | Status | +|---------------|------|-------|-------------|--------| +| `test_max_code_size` | Enforce new `MAX_CODE_SIZE` boundary for contract creation transactions | Alice deploys contracts with runtime code at the new max and one byte over. | New max: contract deployed. Over max: deployment fails. | ✅ Completed | +| `test_max_code_size_via_create` | Enforce new `MAX_CODE_SIZE` boundary via CREATE/CREATE2 opcodes | Same as above but deployment is done through a factory contract using CREATE and CREATE2. | New max: child contract deployed. Over max: child contract does not exist. | ✅ Completed | +| `test_max_initcode_size` | Enforce new `MAX_INITCODE_SIZE` boundary for contract creation transactions | Alice sends creation transactions with initcode at the new max and one byte over. | New max: transaction accepted, contract deployed. Over max: transaction rejected. | ✅ Completed | +| `test_max_initcode_size_via_create` | Enforce new `MAX_INITCODE_SIZE` boundary via CREATE/CREATE2 opcodes | Same as above but initcode is passed through a factory contract using CREATE and CREATE2. | New max: child contract deployed. Over max: CREATE returns 0, child contract does not exist. | ✅ Completed | +| `test_max_initcode_size_gas_metering` | Verify initcode gas metering at the new max (transaction level) | Alice sends a creation transaction with max-size initcode. Gas limit set to exact intrinsic cost, then one short. | Exact gas: contract deployed. One short: transaction rejected. | ✅ Completed | +| `test_max_initcode_size_gas_metering_via_create` | Verify initcode gas metering at the new max (opcode level) | Caller forwards computed exact gas to a factory that runs CREATE with max-size initcode. Tested with exact gas and one short. | Exact gas: CREATE succeeds, contract deployed. One short: factory runs out of gas. | ✅ Completed | +| `test_max_code_size_deposit_gas` | Verify code deposit gas is charged correctly at the new max | Alice deploys a contract with exactly `MAX_CODE_SIZE` bytes. Gas set to exact deposit cost, then one short. | Exact gas: contract deployed. One short: deployment fails (out of gas during code deposit). | ✅ Completed | +| `test_max_code_size_external_opcodes` | Verify external code opcodes work with max-size contracts | Deterministically pre-deploy a max-size self-checking contract. Call it to run EXTCODESIZE, EXTCODEHASH, and EXTCODECOPY on itself via ADDRESS. | Each opcode returns the correct value for the max-size contract. | ✅ Completed | +| `test_max_code_size_self_opcodes` | Verify self code opcodes work with max-size contracts | Pre-deploy a max-size contract with CODESIZE and CODECOPY checker logic. Call via DELEGATECALL so opcodes operate on the large contract's own code. | CODESIZE returns the correct length, CODECOPY produces the correct hash. | ✅ Completed | +| `test_max_code_size_with_max_initcode` | Deploy max-size code when initcode is also at max size | Alice deploys a contract with `MAX_CODE_SIZE` bytes of runtime code using initcode padded to `MAX_INITCODE_SIZE`. | Contract deployed with the full max-size runtime code. | ✅ Completed | +| `test_max_code_size_fork_transition` | New `MAX_CODE_SIZE` activates exactly at the fork boundary | Before the fork, deploy a contract with the new `MAX_CODE_SIZE` bytes of runtime code. After the fork, attempt the same deployment. | Pre-fork: deployment fails (exceeds old limit). Post-fork: deployment succeeds. | ✅ Completed | +| `test_max_code_size_via_create_fork_transition` | New `MAX_CODE_SIZE` activates at the fork boundary via CREATE/CREATE2 opcodes | Same as above but deployment is done through a factory contract using CREATE and CREATE2. | Pre-fork: child contract does not exist. Post-fork: child contract deployed. | ✅ Completed | +| `test_max_initcode_size_fork_transition` | New `MAX_INITCODE_SIZE` activates exactly at the fork boundary for transactions | Before the fork, send a creation transaction with the new `MAX_INITCODE_SIZE` bytes of initcode. After the fork, send the same transaction. | Pre-fork: block rejected (initcode exceeds old limit). Post-fork: transaction accepted, contract deployed. | ✅ Completed | +| `test_max_initcode_size_via_create_fork_transition` | New `MAX_INITCODE_SIZE` activates at the fork boundary via CREATE/CREATE2 opcodes | Same as above but initcode is passed through a factory contract using CREATE and CREATE2. | Pre-fork: CREATE fails (initcode exceeds old limit). Post-fork: child contract deployed. | ✅ Completed | +| `test_max_code_size_with_max_initcode_fork_transition` | Both new limits activate together at the fork boundary | Before the fork, deploy max code with max initcode. After the fork, attempt the same deployment. | Pre-fork: block rejected (initcode exceeds old limit). Post-fork: contract deployed with max-size runtime code. | ✅ Completed | +| `test_parent_max_code_size_across_fork` | Old `MAX_CODE_SIZE` still works on both sides of the transition | Before and after the fork, deploy a contract with the old `MAX_CODE_SIZE` bytes of runtime code. | Both deployments succeed. The old limit remains valid after the fork. | ✅ Completed | +| `test_over_max_code_size_mainnet` | Deploying above the new limit fails on mainnet | Alice deploys a contract with `MAX_CODE_SIZE + 1` bytes of runtime code. | Contract does not exist (deployment fails during code deposit). | ✅ Completed | +| `test_over_max_initcode_size_mainnet` | Oversized initcode creation is rejected on mainnet | Alice sends a creation transaction with `MAX_INITCODE_SIZE + 1` bytes of initcode. | Transaction rejected. No contract deployed. | ✅ Completed | +| `test_max_code_size_with_max_initcode_mainnet` | Verify opcodes on a max-size contract on mainnet | Call the deterministic max-size self-checking contract. It queries EXTCODESIZE, EXTCODEHASH, and EXTCODECOPY on itself via ADDRESS. | Each opcode returns the correct value for the max-size contract. | ✅ Completed | diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/test_eip_mainnet.py b/tests/amsterdam/eip7954_increase_max_contract_size/test_eip_mainnet.py new file mode 100644 index 00000000000..7d0ff0e0a36 --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/test_eip_mainnet.py @@ -0,0 +1,119 @@ +""" +Mainnet tests for +[EIP-7954: Increase Maximum Contract Size](https://eips.ethereum.org/EIPS/eip-7954). +""" + +from typing import Any + +import pytest +from execution_testing import ( + Account, + Alloc, + Fork, + Initcode, + Op, + StateTestFiller, + Transaction, + TransactionException, + compute_create_address, + keccak256, +) + +from .spec import ref_spec_7954 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7954.git_path +REFERENCE_SPEC_VERSION = ref_spec_7954.version + +pytestmark = [pytest.mark.valid_at("EIP7954"), pytest.mark.mainnet] + + +def test_over_max_code_size_mainnet( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """Verify deployment above the new limit is rejected on mainnet.""" + deploy_code = Op.JUMPDEST * (fork.max_code_size() + 1) + initcode = Initcode(deploy_code=deploy_code) + + alice = pre.fund_eoa() + create_address = compute_create_address(address=alice, nonce=0) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post: dict[Any, Account | None] = { + create_address: Account.NONEXISTENT, + } + + state_test(pre=pre, tx=tx, post=post) + + +@pytest.mark.exception_test +def test_over_max_initcode_size_mainnet( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """Verify a CREATE transaction over the new initcode limit is rejected.""" + initcode = Initcode( + deploy_code=Op.STOP, + initcode_length=fork.max_initcode_size() + 1, + ) + + alice = pre.fund_eoa() + create_address = compute_create_address(address=alice, nonce=0) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transaction_gas_limit_cap(), + error=TransactionException.INITCODE_SIZE_EXCEEDED, + ) + + post: dict[Any, Account | None] = { + create_address: Account.NONEXISTENT, + } + + state_test(pre=pre, tx=tx, post=post) + + +def test_max_code_size_with_max_initcode_mainnet( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + max_code_size_contract: tuple, +) -> None: + """ + Verify max-size contract works on mainnet. + + Calls the deterministic max-size contract which checks EXTCODESIZE, + EXTCODEHASH, and EXTCODECOPY on itself. The contract bytecode is + the same used for deployment tests, padded to max code size. + """ + target, target_code = max_code_size_contract + + alice = pre.fund_eoa() + + tx = Transaction( + sender=alice, + to=target, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post = { + target: Account( + storage={ + 0: len(target_code), + 1: keccak256(bytes(target_code)), + 2: keccak256(bytes(target_code)), + } + ) + } + + state_test(pre=pre, tx=tx, post=post) diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/test_fork_transition.py b/tests/amsterdam/eip7954_increase_max_contract_size/test_fork_transition.py new file mode 100644 index 00000000000..4000ed7df4a --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/test_fork_transition.py @@ -0,0 +1,410 @@ +""" +Fork transition tests for +[EIP-7954: Increase Maximum Contract Size](https://eips.ethereum.org/EIPS/eip-7954). + +Tests that the new max code size and initcode size limits activate +exactly at the EIP7954 fork boundary (timestamp 15,000). +""" + +from typing import Any + +import pytest +from execution_testing import ( + Account, + Alloc, + Block, + BlockchainTestFiller, + Initcode, + Op, + Transaction, + TransactionException, + TransitionFork, + compute_create_address, +) + +from .spec import ref_spec_7954 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7954.git_path +REFERENCE_SPEC_VERSION = ref_spec_7954.version + +pytestmark = pytest.mark.valid_at_transition_to("EIP7954") + +CREATE2_SALT = 0xC0FFEE + + +def test_max_code_size_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, +) -> None: + """Ensure the new max code size limit activates at the fork boundary.""" + code_size = fork.transitions_to().max_code_size() + deploy_code = Op.JUMPDEST * code_size + initcode = Initcode(deploy_code=deploy_code) + + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + create_address_pre = compute_create_address(address=alice, nonce=0) + create_address_post = compute_create_address(address=bob, nonce=0) + + blocks = [ + Block( + timestamp=14_999, + txs=[ + Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transitions_from().transaction_gas_limit_cap(), + ) + ], + ), + Block( + timestamp=15_000, + txs=[ + Transaction( + sender=bob, + to=None, + data=initcode, + gas_limit=fork.transitions_to().transaction_gas_limit_cap(), + ) + ], + ), + ] + + post: dict[Any, Account | None] = { + create_address_pre: Account.NONEXISTENT, + create_address_post: Account(code=deploy_code), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) + + +@pytest.mark.parametrize("create_opcode", [Op.CREATE, Op.CREATE2]) +def test_max_code_size_via_create_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, + create_opcode: Op, +) -> None: + """Ensure the new max code size limit activates at the fork via opcodes.""" + code_size = fork.transitions_to().max_code_size() + deploy_code = Op.JUMPDEST * code_size + initcode = Initcode(deploy_code=deploy_code) + initcode_bytes = bytes(initcode) + + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + create_call = ( + create_opcode( + value=0, offset=0, size=Op.CALLDATASIZE, salt=CREATE2_SALT + ) + if create_opcode == Op.CREATE2 + else create_opcode(value=0, offset=0, size=Op.CALLDATASIZE) + ) + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE(0, create_call) + + Op.STOP + ) + + factory_pre = pre.deploy_contract(factory_code) + factory_post = pre.deploy_contract(factory_code) + + create_address_pre = compute_create_address( + address=factory_pre, + nonce=1, + salt=CREATE2_SALT, + initcode=initcode, + opcode=create_opcode, + ) + create_address_post = compute_create_address( + address=factory_post, + nonce=1, + salt=CREATE2_SALT, + initcode=initcode, + opcode=create_opcode, + ) + + blocks = [ + Block( + timestamp=14_999, + txs=[ + Transaction( + sender=alice, + to=factory_pre, + data=initcode_bytes, + gas_limit=fork.transitions_from().transaction_gas_limit_cap(), + ) + ], + ), + Block( + timestamp=15_000, + txs=[ + Transaction( + sender=bob, + to=factory_post, + data=initcode_bytes, + gas_limit=fork.transitions_to().transaction_gas_limit_cap(), + ) + ], + ), + ] + + post: dict[Any, Account | None] = { + create_address_pre: Account.NONEXISTENT, + create_address_post: Account(code=deploy_code), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) + + +@pytest.mark.exception_test +def test_max_initcode_size_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, +) -> None: + """Ensure the new max initcode size limit activates exactly at the fork.""" + initcode = Initcode( + deploy_code=Op.STOP, + initcode_length=fork.transitions_to().max_initcode_size(), + ) + + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + create_address_post = compute_create_address(address=bob, nonce=0) + + initcode_too_large = TransactionException.INITCODE_SIZE_EXCEEDED + + blocks = [ + # Pre-fork: initcode at the new max exceeds the parent fork's limit, + # so the tx is rejected and the block is invalid. + Block( + timestamp=14_999, + txs=[ + Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transitions_from().transaction_gas_limit_cap(), + error=initcode_too_large, + ) + ], + exception=initcode_too_large, + ), + # Post-fork: the new limit is in effect, tx succeeds. + Block( + timestamp=15_000, + txs=[ + Transaction( + sender=bob, + to=None, + data=initcode, + gas_limit=fork.transitions_to().transaction_gas_limit_cap(), + ) + ], + ), + ] + + post: dict[Any, Account | None] = { + create_address_post: Account(code=Op.STOP), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) + + +@pytest.mark.parametrize("create_opcode", [Op.CREATE, Op.CREATE2]) +def test_max_initcode_size_via_create_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, + create_opcode: Op, +) -> None: + """Ensure the new max initcode size limit activates at fork via opcodes.""" + initcode = Initcode( + deploy_code=Op.STOP, + initcode_length=fork.transitions_to().max_initcode_size(), + ) + initcode_bytes = bytes(initcode) + + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + create_call = ( + create_opcode( + value=0, offset=0, size=Op.CALLDATASIZE, salt=CREATE2_SALT + ) + if create_opcode == Op.CREATE2 + else create_opcode(value=0, offset=0, size=Op.CALLDATASIZE) + ) + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE(0, create_call) + + Op.STOP + ) + + factory_pre = pre.deploy_contract(factory_code) + factory_post = pre.deploy_contract(factory_code) + + create_address_pre = compute_create_address( + address=factory_pre, + nonce=1, + salt=CREATE2_SALT, + initcode=initcode, + opcode=create_opcode, + ) + create_address_post = compute_create_address( + address=factory_post, + nonce=1, + salt=CREATE2_SALT, + initcode=initcode, + opcode=create_opcode, + ) + + blocks = [ + Block( + timestamp=14_999, + txs=[ + Transaction( + sender=alice, + to=factory_pre, + data=initcode_bytes, + gas_limit=fork.transitions_from().transaction_gas_limit_cap(), + ) + ], + ), + Block( + timestamp=15_000, + txs=[ + Transaction( + sender=bob, + to=factory_post, + data=initcode_bytes, + gas_limit=fork.transitions_to().transaction_gas_limit_cap(), + ) + ], + ), + ] + + # Pre-fork: CREATE returns 0 (initcode exceeds parent fork limit) + # Post-fork: CREATE succeeds + post: dict[Any, Account | None] = { + factory_pre: Account(storage={0: 0}), + create_address_pre: Account.NONEXISTENT, + factory_post: Account(storage={0: create_address_post}), + create_address_post: Account(code=Op.STOP), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) + + +@pytest.mark.exception_test +def test_max_code_size_with_max_initcode_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, +) -> None: + """Ensure max code + max initcode activates at the fork boundary.""" + deploy_code = Op.JUMPDEST * fork.transitions_to().max_code_size() + initcode = Initcode( + deploy_code=deploy_code, + initcode_length=fork.transitions_to().max_initcode_size(), + ) + + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + create_address_post = compute_create_address(address=bob, nonce=0) + + initcode_too_large = TransactionException.INITCODE_SIZE_EXCEEDED + + blocks = [ + Block( + timestamp=14_999, + txs=[ + Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transitions_from().transaction_gas_limit_cap(), + error=initcode_too_large, + ) + ], + exception=initcode_too_large, + ), + Block( + timestamp=15_000, + txs=[ + Transaction( + sender=bob, + to=None, + data=initcode, + gas_limit=fork.transitions_to().transaction_gas_limit_cap(), + ) + ], + ), + ] + + post: dict[Any, Account | None] = { + create_address_post: Account(code=deploy_code), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) + + +def test_parent_max_code_size_across_fork( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, +) -> None: + """Ensure previous max code size works after transition.""" + parent = fork.transitions_from() + assert parent is not None, "Parent fork must be defined for this test" + + code_size = parent.max_code_size() + deploy_code = Op.JUMPDEST * code_size + initcode = Initcode(deploy_code=deploy_code) + + alice = pre.fund_eoa() + bob = pre.fund_eoa() + + create_address_pre = compute_create_address(address=alice, nonce=0) + create_address_post = compute_create_address(address=bob, nonce=0) + + blocks = [ + Block( + timestamp=14_999, + txs=[ + Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transitions_from().transaction_gas_limit_cap(), + ) + ], + ), + Block( + timestamp=15_000, + txs=[ + Transaction( + sender=bob, + to=None, + data=initcode, + gas_limit=fork.transitions_to().transaction_gas_limit_cap(), + ) + ], + ), + ] + + post: dict[Any, Account | None] = { + create_address_pre: Account(code=deploy_code), + create_address_post: Account(code=deploy_code), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py b/tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py new file mode 100644 index 00000000000..85ed98451c9 --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/test_max_code_size.py @@ -0,0 +1,354 @@ +""" +Test [EIP-7954: Increase Maximum Contract Size](https://eips.ethereum.org/EIPS/eip-7954). +""" + +from typing import Any, Callable + +import pytest +from execution_testing import ( + Account, + Alloc, + CodeGasMeasure, + Fork, + Initcode, + Op, + StateTestFiller, + Transaction, + compute_create_address, + keccak256, +) + +from .spec import ref_spec_7954 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7954.git_path +REFERENCE_SPEC_VERSION = ref_spec_7954.version + +pytestmark = pytest.mark.valid_from("EIP7954") + +CREATE2_SALT = 0xC0FFEE + +DEPLOY_CODE_SIZE_PARAMS = [ + pytest.param(lambda f: f.max_code_size(), id="at_max"), + pytest.param(lambda f: f.max_code_size() + 1, id="over_max"), +] + + +@pytest.mark.parametrize("deploy_code_size", DEPLOY_CODE_SIZE_PARAMS) +def test_max_code_size( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + deploy_code_size: Callable[[Fork], int], +) -> None: + """Ensure the new max code size boundary is enforced.""" + code_size = deploy_code_size(fork) + deploy_code = Op.JUMPDEST * code_size + + alice = pre.fund_eoa() + initcode = Initcode(deploy_code=deploy_code) + create_address = compute_create_address(address=alice, nonce=0) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post: dict[Any, Account | None] = {} + if code_size <= fork.max_code_size(): + post[create_address] = Account(code=deploy_code) + else: + post[create_address] = Account.NONEXISTENT + + state_test(pre=pre, tx=tx, post=post) + + +@pytest.mark.parametrize("deploy_code_size", DEPLOY_CODE_SIZE_PARAMS) +@pytest.mark.with_all_create_opcodes() +def test_max_code_size_via_create( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + deploy_code_size: Callable[[Fork], int], + create_opcode: Op, +) -> None: + """Ensure the new max code size boundary is enforced via create opcodes.""" + code_size = deploy_code_size(fork) + deploy_code = Op.JUMPDEST * code_size + initcode = Initcode(deploy_code=deploy_code) + initcode_bytes = bytes(initcode) + + alice = pre.fund_eoa() + + create_call = ( + create_opcode( + value=0, offset=0, size=Op.CALLDATASIZE, salt=CREATE2_SALT + ) + if create_opcode == Op.CREATE2 + else create_opcode(value=0, offset=0, size=Op.CALLDATASIZE) + ) + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE(0, create_call) + + Op.STOP + ) + + factory = pre.deploy_contract(factory_code) + + create_address = compute_create_address( + address=factory, + nonce=1, + salt=CREATE2_SALT, + initcode=initcode, + opcode=create_opcode, + ) + + tx = Transaction( + sender=alice, + to=factory, + data=initcode_bytes, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + created = code_size <= fork.max_code_size() + post: dict[Any, Account | None] = { + factory: Account(storage={0: create_address if created else 0}), + } + if created: + post[create_address] = Account(code=deploy_code) + else: + post[create_address] = Account.NONEXISTENT + + state_test(pre=pre, tx=tx, post=post) + + +@pytest.mark.parametrize( + "gas_shortfall", + [ + pytest.param(0, id="exact_gas"), + pytest.param(1, id="short_one_gas"), + ], +) +def test_max_code_size_deposit_gas( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + gas_shortfall: int, +) -> None: + """Ensure code deposit gas is charged correctly at the new max.""" + deploy_code = Op.JUMPDEST * fork.max_code_size() + initcode = Initcode(deploy_code=deploy_code) + + alice = pre.fund_eoa() + create_address = compute_create_address(address=alice, nonce=0) + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=initcode, + contract_creation=True, + return_cost_deducted_prior_execution=True, + ) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=( + intrinsic_gas + + initcode.execution_gas(fork) + + initcode.deployment_gas(fork) + - gas_shortfall + ), + ) + # With shortfall, code deposit OOGs: tx succeeds but + # contract is not deployed + post = { + create_address: Account(code=deploy_code) + if not gas_shortfall + else Account.NONEXISTENT, + } + + state_test(pre=pre, tx=tx, post=post) + + +def test_max_code_size_with_max_initcode( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """Ensure max-size code deploys when initcode is also at max size.""" + deploy_code = Op.JUMPDEST * fork.max_code_size() + initcode = Initcode( + deploy_code=deploy_code, + initcode_length=fork.max_initcode_size(), + ) + + alice = pre.fund_eoa() + create_address = compute_create_address(address=alice, nonce=0) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post = {create_address: Account(code=deploy_code)} + + state_test(pre=pre, tx=tx, post=post) + + +def test_max_code_size_external_opcodes( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + max_code_size_contract: tuple, +) -> None: + """Ensure external code opcodes work with the new max contract size.""" + target, target_code = max_code_size_contract + + alice = pre.fund_eoa() + + tx = Transaction( + sender=alice, + to=target, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post = { + target: Account( + storage={ + 0: len(target_code), + 1: keccak256(bytes(target_code)), + 2: keccak256(bytes(target_code)), + } + ) + } + + state_test(pre=pre, tx=tx, post=post) + + +def test_max_code_size_self_opcodes( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """ + Ensure self code opcodes work with the new max contract size. + + Tested via DELEGATECALL so opcodes operate on the large + contract's own code while writing results to the caller's + storage. + """ + logic = ( + Op.SSTORE(0, Op.CODESIZE) + + Op.CODECOPY(0, 0, Op.CODESIZE) + + Op.SSTORE(1, Op.SHA3(0, Op.CODESIZE)) + + Op.STOP + ) + target_code = logic + Op.JUMPDEST * (fork.max_code_size() - len(logic)) + target = pre.deterministic_deploy_contract(deploy_code=target_code) + + alice = pre.fund_eoa() + oracle = pre.deploy_contract( + code=Op.DELEGATECALL(gas=Op.GAS, address=target) + ) + + tx = Transaction( + sender=alice, + to=oracle, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post = { + oracle: Account( + storage={ + 0: len(target_code), + 1: keccak256(bytes(target_code)), + } + ) + } + + state_test(pre=pre, tx=tx, post=post) + + +@pytest.mark.parametrize( + "create_opcode", + [ + pytest.param(Op.CREATE, id="CREATE"), + pytest.param(Op.CREATE2, id="CREATE2"), + ], +) +def test_warm_after_failed_create_over_max_code_size( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + create_opcode: Op, +) -> None: + """ + Verify the would-be contract address is warm after a CREATE that fails + because the returned deploy code exceeds max_code_size. + + Unlike pre-validation aborts (insufficient balance, nonce overflow), the + address is added to the access list during initcode execution, so the + post-RETURN size check rejecting deployment must leave the address warm. + """ + initcode = Op.RETURN(offset=0, size=fork.max_code_size() + 1) + initcode_bytes = bytes(initcode) + if create_opcode == Op.CREATE2: + salt = CREATE2_SALT + create_call = create_opcode( + value=0, + offset=0, + size=len(initcode_bytes), + salt=salt, + ) + else: + salt = 0 + create_call = create_opcode( + value=0, offset=0, size=len(initcode_bytes) + ) + + creator_code = Op.MSTORE( + 0, Op.PUSH32(initcode_bytes.ljust(32, b"\0")) + ) + Op.SSTORE(0, create_call) + + creator_address = pre.deploy_contract(creator_code, storage={0: 1}) + + contract_address = compute_create_address( + address=creator_address, + nonce=1, + salt=salt, + initcode=initcode_bytes, + opcode=create_opcode, + ) + + warm_balance = Op.BALANCE(contract_address, address_warm=True) + checker_address = pre.deploy_contract( + CodeGasMeasure( + code=warm_balance, + extra_stack_items=1, + sstore_key=1, + ) + ) + + entry_address = pre.deploy_contract( + Op.CALL(gas=Op.GAS, address=creator_address) + + Op.CALL(gas=Op.GAS, address=checker_address) + + Op.STOP + ) + + tx = Transaction( + to=entry_address, + gas_limit=fork.transaction_gas_limit_cap(), + sender=pre.fund_eoa(), + ) + + post = { + creator_address: Account(storage={0: 0}), + checker_address: Account(storage={1: warm_balance.gas_cost(fork)}), + contract_address: Account.NONEXISTENT, + } + + state_test(pre=pre, tx=tx, post=post) diff --git a/tests/amsterdam/eip7954_increase_max_contract_size/test_max_initcode_size.py b/tests/amsterdam/eip7954_increase_max_contract_size/test_max_initcode_size.py new file mode 100644 index 00000000000..f3a469c43a5 --- /dev/null +++ b/tests/amsterdam/eip7954_increase_max_contract_size/test_max_initcode_size.py @@ -0,0 +1,187 @@ +""" +Test [EIP-7954: Increase Maximum Contract Size](https://eips.ethereum.org/EIPS/eip-7954). + +Tests for the increased maximum initcode size (64 KiB). +""" + +from typing import Any, Callable + +import pytest +from execution_testing import ( + Account, + Alloc, + Fork, + Initcode, + Op, + StateTestFiller, + Transaction, + TransactionException, + compute_create_address, +) + +from .spec import ref_spec_7954 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7954.git_path +REFERENCE_SPEC_VERSION = ref_spec_7954.version + +pytestmark = pytest.mark.valid_from("EIP7954") + +CREATE2_SALT = 0xC0FFEE + +INITCODE_SIZE_PARAMS = [ + pytest.param(lambda f: f.max_initcode_size(), id="at_max"), + pytest.param(lambda f: f.max_initcode_size() + 1, id="over_max"), +] + +TX_INITCODE_SIZE_PARAMS = [ + pytest.param(lambda f: f.max_initcode_size(), id="at_max"), + pytest.param( + lambda f: f.max_initcode_size() + 1, + id="over_max", + marks=pytest.mark.exception_test, + ), +] + + +@pytest.mark.parametrize("initcode_size", TX_INITCODE_SIZE_PARAMS) +def test_max_initcode_size( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + initcode_size: Callable[[Fork], int], +) -> None: + """Ensure the new max initcode size is enforced for transactions.""" + size = initcode_size(fork) + initcode = Initcode( + deploy_code=Op.STOP, + initcode_length=size, + ) + + alice = pre.fund_eoa() + create_address = compute_create_address(address=alice, nonce=0) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + post: dict[Any, Account | None] = {} + if size <= fork.max_initcode_size(): + post[create_address] = Account(code=Op.STOP) + else: + tx.error = TransactionException.INITCODE_SIZE_EXCEEDED + post[create_address] = Account.NONEXISTENT + + state_test(pre=pre, tx=tx, post=post) + + +@pytest.mark.parametrize("initcode_size", INITCODE_SIZE_PARAMS) +@pytest.mark.with_all_create_opcodes() +def test_max_initcode_size_via_create( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + initcode_size: Callable[[Fork], int], + create_opcode: Op, +) -> None: + """Ensure the new max initcode size is enforced via create opcodes.""" + size = initcode_size(fork) + initcode = Initcode( + deploy_code=Op.STOP, + initcode_length=size, + ) + initcode_bytes = bytes(initcode) + + alice = pre.fund_eoa() + + create_call = ( + create_opcode( + value=0, offset=0, size=Op.CALLDATASIZE, salt=CREATE2_SALT + ) + if create_opcode == Op.CREATE2 + else create_opcode(value=0, offset=0, size=Op.CALLDATASIZE) + ) + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.SSTORE(0, create_call) + + Op.STOP + ) + + factory = pre.deploy_contract(factory_code) + + create_address = compute_create_address( + address=factory, + nonce=1, + salt=CREATE2_SALT, + initcode=initcode, + opcode=create_opcode, + ) + + tx = Transaction( + sender=alice, + to=factory, + data=initcode_bytes, + gas_limit=fork.transaction_gas_limit_cap(), + ) + + # Opcode-level: oversized initcode causes OutOfGasError + # (tx succeeds, CREATE returns 0) + created = size <= fork.max_initcode_size() + post: dict[Any, Account | None] = { + factory: Account(storage={0: create_address if created else 0}), + } + if created: + post[create_address] = Account(code=Op.STOP) + else: + post[create_address] = Account.NONEXISTENT + + state_test(pre=pre, tx=tx, post=post) + + +@pytest.mark.parametrize( + "gas_shortfall", + [ + pytest.param(0, id="exact_gas"), + pytest.param( + 1, + id="short_one_gas", + marks=pytest.mark.exception_test, + ), + ], +) +def test_max_initcode_size_gas_metering( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + gas_shortfall: int, +) -> None: + """Verify initcode gas metering at the new max initcode size.""" + initcode = Initcode( + deploy_code=Op.STOP, initcode_length=fork.max_initcode_size() + ) + alice = pre.fund_eoa() + + intrinsic_gas = fork.transaction_intrinsic_cost_calculator()( + calldata=initcode, contract_creation=True + ) + + tx = Transaction( + sender=alice, + to=None, + data=initcode, + gas_limit=intrinsic_gas - gas_shortfall, + error=TransactionException.INTRINSIC_GAS_TOO_LOW + if gas_shortfall + else None, + ) + + post = { + compute_create_address(address=alice, nonce=0): Account.NONEXISTENT + if gas_shortfall + else Account(code=Op.STOP), + } + + state_test(pre=pre, tx=tx, post=post) diff --git a/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py b/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py index 1ee550de908..f7781ee3d97 100644 --- a/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py +++ b/tests/ported_static/stCodeSizeLimit/test_codesize_oog_invalid_size.py @@ -26,6 +26,7 @@ ["state_tests/stCodeSizeLimit/codesizeOOGInvalidSizeFiller.json"], ) @pytest.mark.valid_from("Cancun") +@pytest.mark.valid_before("EIP7954") @pytest.mark.parametrize( "d, g, v", [ diff --git a/tests/ported_static/stCodeSizeLimit/test_create2_code_size_limit.py b/tests/ported_static/stCodeSizeLimit/test_create2_code_size_limit.py index 5d29703f019..b3bf7840879 100644 --- a/tests/ported_static/stCodeSizeLimit/test_create2_code_size_limit.py +++ b/tests/ported_static/stCodeSizeLimit/test_create2_code_size_limit.py @@ -30,6 +30,7 @@ ["state_tests/stCodeSizeLimit/create2CodeSizeLimitFiller.yml"], ) @pytest.mark.valid_from("Cancun") +@pytest.mark.valid_before("EIP7954") @pytest.mark.parametrize( "d, g, v", [ diff --git a/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py b/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py index da4d856ee9b..84ab61dc09c 100644 --- a/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py +++ b/tests/ported_static/stCodeSizeLimit/test_create_code_size_limit.py @@ -30,6 +30,7 @@ ["state_tests/stCodeSizeLimit/createCodeSizeLimitFiller.yml"], ) @pytest.mark.valid_from("Cancun") +@pytest.mark.valid_before("EIP7954") @pytest.mark.parametrize( "d, g, v", [ diff --git a/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py b/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py index 56b4a02b6c9..fc6321be024 100644 --- a/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py +++ b/tests/ported_static/stCreateTest/test_create_address_warm_after_fail.py @@ -70,24 +70,28 @@ 0, 0, id="create-code-too-big-v0", + marks=pytest.mark.valid_before("EIP7954"), ), pytest.param( 2, 0, 1, id="create-code-too-big-v1", + marks=pytest.mark.valid_before("EIP7954"), ), pytest.param( 3, 0, 0, id="create2-code-too-big-v0", + marks=pytest.mark.valid_before("EIP7954"), ), pytest.param( 3, 0, 1, id="create2-code-too-big-v1", + marks=pytest.mark.valid_before("EIP7954"), ), pytest.param( 4, diff --git a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py index 02b8f8dd203..006e46e0616 100644 --- a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py +++ b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create2_init_code_size_limit.py @@ -32,6 +32,7 @@ ], ) @pytest.mark.valid_from("Cancun") +@pytest.mark.valid_before("EIP7954") @pytest.mark.parametrize( "d, g, v", [ diff --git a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py index dc9500e9b45..dd3acfc9717 100644 --- a/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py +++ b/tests/ported_static/stEIP3860_limitmeterinitcode/test_create_init_code_size_limit.py @@ -33,6 +33,7 @@ ], ) @pytest.mark.valid_from("Cancun") +@pytest.mark.valid_before("EIP7954") @pytest.mark.parametrize( "d, g, v", [ diff --git a/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py b/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py index ff9a504ca81..8a935525416 100644 --- a/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py +++ b/tests/ported_static/stEIP3860_limitmeterinitcode/test_creation_tx_init_code_size_limit.py @@ -33,6 +33,7 @@ ], ) @pytest.mark.valid_from("Cancun") +@pytest.mark.valid_before("EIP7954") @pytest.mark.parametrize( "d, g, v", [ diff --git a/tests/shanghai/eip3860_initcode/test_initcode.py b/tests/shanghai/eip3860_initcode/test_initcode.py index f76bca44c2a..bc19611f6d6 100644 --- a/tests/shanghai/eip3860_initcode/test_initcode.py +++ b/tests/shanghai/eip3860_initcode/test_initcode.py @@ -238,7 +238,7 @@ def tx_access_list(self) -> List[AccessList]: """ return [ AccessList(address=Address(i), storage_keys=[]) - for i in range(1, 478) + for i in range(1, 642) ] @pytest.fixture From 78a79eec7051d85de662a0e128c8a58f0bbf5cbb Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 15 May 2026 03:29:49 -0600 Subject: [PATCH 083/186] bugfix(ci): bump hive start up timeout in CI (#2857) --- .github/workflows/hive-execute.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-execute.yaml b/.github/workflows/hive-execute.yaml index b4508a5423e..b00a5c0571f 100644 --- a/.github/workflows/hive-execute.yaml +++ b/.github/workflows/hive-execute.yaml @@ -81,7 +81,7 @@ jobs: clients: go-ethereum client-file: execution-specs/.github/configs/hive/latest.yaml hive-path: hive - timeout: "120" + timeout: "180" - name: Run execute remote E2E tests working-directory: execution-specs From ff1434585dea218730761908ed34731194dd507d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 15 May 2026 16:46:24 +0000 Subject: [PATCH 084/186] fix(tests): drop gas_price from EIP-7702 txs in BAL 7702 tests (#2862) * fix(tests): drop gas_price from EIP-7702 txs in BAL 7702 tests EIP-7702 (type-4) transactions don't have a gas_price field; remove the stray gas_price=0xA from txs that include an authorization_list. * fix(test-types): prevent tx type > 2 from defining ``gas_price`` in tests --------- Co-authored-by: fselmo --- .../test_types/transaction_types.py | 4 ++++ .../test_block_access_lists_eip7702.py | 14 -------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/testing/src/execution_testing/test_types/transaction_types.py b/packages/testing/src/execution_testing/test_types/transaction_types.py index 7153faab6b1..bc3d0794f3f 100644 --- a/packages/testing/src/execution_testing/test_types/transaction_types.py +++ b/packages/testing/src/execution_testing/test_types/transaction_types.py @@ -428,6 +428,10 @@ def model_post_init(self, __context: Any) -> None: if self.ty <= 1 and self.gas_price is None: self.gas_price = HexNumber(TransactionDefaults.gas_price) self.model_fields_set.remove("gas_price") + if self.ty >= 2: + assert self.gas_price is None, ( + f"gas_price not supported for tx type {int(self.ty)}" + ) if self.ty >= 1 and self.access_list is None: self.access_list = [] if self.ty < 1: diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py index 9a776f797ff..434c432c2cf 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py @@ -67,7 +67,6 @@ def test_bal_7702_delegation_create( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle, @@ -166,7 +165,6 @@ def test_bal_7702_delegation_update( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle1, @@ -182,7 +180,6 @@ def test_bal_7702_delegation_update( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle2, @@ -295,7 +292,6 @@ def test_bal_7702_delegation_clear( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle, @@ -311,7 +307,6 @@ def test_bal_7702_delegation_clear( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=abyss, @@ -473,7 +468,6 @@ def test_bal_7702_invalid_nonce_authorization( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle, @@ -540,7 +534,6 @@ def test_bal_7702_invalid_authority_has_code_authorization( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle, @@ -600,7 +593,6 @@ def test_bal_7702_invalid_chain_id_authorization( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( chain_id=999, # Wrong chain id @@ -744,7 +736,6 @@ def test_bal_7702_multi_hop_delegation_chain( sender=alice, to=entry_address, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=auth_b, @@ -855,7 +846,6 @@ def test_bal_7702_cross_tx_delegation_then_call( to=bob, value=0, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=counter, @@ -1022,7 +1012,6 @@ def test_bal_7702_double_auth_reset( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=contract_a, @@ -1111,7 +1100,6 @@ def test_bal_7702_double_auth_swap( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=contract_a, @@ -1213,7 +1201,6 @@ def test_bal_selfdestruct_to_7702_delegation( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle, @@ -1346,7 +1333,6 @@ def test_bal_withdrawal_to_7702_delegation( to=bob, value=10, gas_limit=1_000_000, - gas_price=0xA, authorization_list=[ AuthorizationTuple( address=oracle, From 892e6d1e10e408c848c68b4fabb3853375f62505 Mon Sep 17 00:00:00 2001 From: felipe Date: Fri, 15 May 2026 16:16:52 -0600 Subject: [PATCH 085/186] feat(tests): eip7928 checklist v1 (#2859) * feat(tests): complete EIP-7928 testing checklist * feat(tests): transition tests for EIP-7928 (BALs) * fix(test-types,test-fixtures): pass through rlp to engine modifier; rename as future issue --- .../execution_testing/fixtures/blockchain.py | 66 +++++- .../fixtures/tests/test_blockchain.py | 153 ++++++++++++- .../src/execution_testing/specs/blockchain.py | 40 ++++ .../specs/tests/test_types.py | 75 +++++- .../eip_checklist_external_coverage.txt | 3 + .../eip_checklist_not_applicable.txt | 14 ++ .../test_block_access_lists.py | 6 + .../test_block_access_lists_eip4895.py | 2 + .../test_block_access_lists_invalid.py | 2 + .../test_cases.md | 4 + .../test_fork_transition.py | 215 ++++++++++++++++++ 11 files changed, 576 insertions(+), 4 deletions(-) create mode 100644 tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_external_coverage.txt create mode 100644 tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_not_applicable.txt create mode 100644 tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py diff --git a/packages/testing/src/execution_testing/fixtures/blockchain.py b/packages/testing/src/execution_testing/fixtures/blockchain.py index f8bf1e5a2dc..6290eebb657 100644 --- a/packages/testing/src/execution_testing/fixtures/blockchain.py +++ b/packages/testing/src/execution_testing/fixtures/blockchain.py @@ -6,6 +6,7 @@ Annotated, Any, ClassVar, + Dict, List, Literal, Self, @@ -23,9 +24,11 @@ from ethereum_types.numeric import Uint from pydantic import ( AliasChoices, + ConfigDict, Field, PlainSerializer, computed_field, + model_serializer, model_validator, ) from pydantic_core import PydanticUndefined @@ -53,6 +56,7 @@ from execution_testing.test_types import ( BlockAccessList, Environment, + Removable, Requests, Transaction, Withdrawal, @@ -437,6 +441,49 @@ def from_fixture_header( ) +class FixtureExecutionPayloadModifier(CamelModel): + """ + Modifier for ``FixtureExecutionPayload`` fields, used to construct + intentionally invalid ``engine_newPayload`` requests in negative tests. + + Each field defaults to ``None`` (no override). Set a field to a concrete + value to override it on the payload, or to ``REMOVE_FIELD`` (sentinel) to + omit it from the payload entirely. This mirrors ``Header``'s mechanism + but targets ``FixtureExecutionPayload`` instead of ``FixtureHeader``. + """ + + model_config = ConfigDict( + **CamelModel.model_config, + arbitrary_types_allowed=True, + ) + + block_access_list: Removable | Bytes | None = None + + REMOVE_FIELD: ClassVar[Removable] = Removable() + """Sentinel to specify that a payload field should be removed.""" + + @model_serializer(mode="wrap", when_used="json") + def _serialize_model(self, serializer: Any, info: Any) -> Dict[str, Any]: + """Exclude Removable fields from serialization.""" + del info + data = serializer(self) + return {k: v for k, v in data.items() if not isinstance(v, Removable)} + + def apply( + self, target: "FixtureExecutionPayload" + ) -> "FixtureExecutionPayload": + """Return a copy of ``target`` with this modifier's overrides.""" + overrides: Dict[str, Any] = {} + for field_name in self.__class__.model_fields: + value = getattr(self, field_name) + if value is None: + continue + overrides[field_name] = ( + None if isinstance(value, Removable) else value + ) + return target.model_copy(update=overrides) + + EngineNewPayloadV1Parameters = Tuple[FixtureExecutionPayload] EngineNewPayloadV3Parameters = Tuple[FixtureExecutionPayload, List[Hash], Hash] EngineNewPayloadV4Parameters = Tuple[ @@ -511,6 +558,9 @@ def from_fixture_header( withdrawals: List[Withdrawal] | None, requests: List[Bytes] | None, block_access_list: Bytes | None = None, + execution_payload_modifier: ( + "FixtureExecutionPayloadModifier | None" + ) = None, **kwargs: Any, ) -> Self: """Create `FixtureEngineNewPayload` from a `FixtureHeader`.""" @@ -521,7 +571,17 @@ def from_fixture_header( "Invalid header for engine_newPayload" ) - if fork.engine_execution_payload_block_access_list(): + # An ``execution_payload_modifier`` that touches ``block_access_list`` + # (either overriding or removing it) replaces the fork's default body, + # so the fork-required check is skipped in that case. + modifier_overrides_bal = ( + execution_payload_modifier is not None + and execution_payload_modifier.block_access_list is not None + ) + if ( + fork.engine_execution_payload_block_access_list() + and not modifier_overrides_bal + ): if block_access_list is None: raise ValueError( "`block_access_list` is required in engine " @@ -534,6 +594,10 @@ def from_fixture_header( withdrawals=withdrawals, block_access_list=block_access_list, ) + if execution_payload_modifier is not None: + execution_payload = execution_payload_modifier.apply( + execution_payload + ) params: List[Any] = [execution_payload] if fork.engine_new_payload_blob_hashes(): diff --git a/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py b/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py index f444607188a..bc7b9552325 100644 --- a/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py +++ b/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py @@ -23,7 +23,7 @@ EngineAPIError, TransactionException, ) -from execution_testing.forks import Prague +from execution_testing.forks import Amsterdam, Prague from execution_testing.test_types import ( EOA, AuthorizationTuple, @@ -42,6 +42,7 @@ FixtureConfig, FixtureEngineNewPayload, FixtureExecutionPayload, + FixtureExecutionPayloadModifier, FixtureHeader, FixtureTransaction, InvalidFixtureBlock, @@ -1568,3 +1569,153 @@ def test_json_deserialization( if not can_be_deserialized: pytest.skip(reason="Model instance cannot be deserialized") assert adapter.validate_python(json_repr) == type_instance + + +def _amsterdam_payload_header() -> FixtureHeader: + """Build a fully-populated header suitable for an Amsterdam V5 payload.""" + return FixtureHeader( + parent_hash=Hash(0), + ommers_hash=Hash(1), + fee_recipient=Address(2), + state_root=Hash(3), + transactions_trie=Hash(4), + receipts_root=Hash(5), + logs_bloom=Bloom(6), + difficulty=7, + number=1, + gas_limit=9, + gas_used=10, + timestamp=11, + extra_data=Bytes([12]), + prev_randao=Hash(13), + nonce=HeaderNonce(14), + base_fee_per_gas=15, + withdrawals_root=Hash(16), + blob_gas_used=17, + excess_blob_gas=18, + parent_beacon_block_root=19, + requests_hash=20, + block_access_list_hash=Hash(21), + slot_number=22, + ) + + +class TestFixtureExecutionPayloadModifier: + """Verify the internal modifier helper used to mutate engine payloads.""" + + def test_apply_no_fields_is_noop(self) -> None: + """A modifier with no fields set must not change the payload.""" + payload = FixtureExecutionPayload.from_fixture_header( + header=_amsterdam_payload_header(), + transactions=[], + withdrawals=[], + block_access_list=Bytes(b"\xaa\xbb"), + ) + result = FixtureExecutionPayloadModifier().apply(payload) + assert result == payload + + def test_apply_overrides_block_access_list_value(self) -> None: + """Setting block_access_list overrides the body on the payload.""" + payload = FixtureExecutionPayload.from_fixture_header( + header=_amsterdam_payload_header(), + transactions=[], + withdrawals=[], + block_access_list=Bytes(b"\xaa\xbb"), + ) + result = FixtureExecutionPayloadModifier( + block_access_list=Bytes(b"\xcc\xdd"), + ).apply(payload) + assert result.block_access_list == Bytes(b"\xcc\xdd") + + def test_apply_remove_field_clears_block_access_list(self) -> None: + """REMOVE_FIELD removes block_access_list so it's excluded on dump.""" + payload = FixtureExecutionPayload.from_fixture_header( + header=_amsterdam_payload_header(), + transactions=[], + withdrawals=[], + block_access_list=Bytes(b"\xaa\xbb"), + ) + result = FixtureExecutionPayloadModifier( + block_access_list=FixtureExecutionPayloadModifier.REMOVE_FIELD, + ).apply(payload) + assert result.block_access_list is None + assert "blockAccessList" not in to_json(result) + + def test_from_fixture_header_injects_body_on_pre_bal_fork(self) -> None: + """Modifier can inject a BAL body into a fork that doesn't carry it.""" + payload = FixtureEngineNewPayload.from_fixture_header( + fork=Prague, + header=FixtureHeader( + parent_hash=Hash(0), + ommers_hash=Hash(1), + fee_recipient=Address(2), + state_root=Hash(3), + transactions_trie=Hash(4), + receipts_root=Hash(5), + logs_bloom=Bloom(6), + difficulty=7, + number=1, + gas_limit=9, + gas_used=10, + timestamp=11, + extra_data=Bytes([12]), + prev_randao=Hash(13), + nonce=HeaderNonce(14), + base_fee_per_gas=15, + withdrawals_root=Hash(16), + blob_gas_used=17, + excess_blob_gas=18, + parent_beacon_block_root=19, + requests_hash=20, + ), + transactions=[], + withdrawals=[], + requests=[], + execution_payload_modifier=FixtureExecutionPayloadModifier( + block_access_list=Bytes(b""), + ), + ) + assert payload.params[0].block_access_list == Bytes(b"") + assert "blockAccessList" in to_json(payload.params[0]) + + def test_from_fixture_header_removes_body_on_post_bal_fork(self) -> None: + """REMOVE_FIELD bypasses the fork-required check and omits the body.""" + payload = FixtureEngineNewPayload.from_fixture_header( + fork=Amsterdam, + header=_amsterdam_payload_header(), + transactions=[], + withdrawals=[], + requests=[], + block_access_list=None, + execution_payload_modifier=FixtureExecutionPayloadModifier( + block_access_list=( + FixtureExecutionPayloadModifier.REMOVE_FIELD + ), + ), + ) + assert payload.params[0].block_access_list is None + assert "blockAccessList" not in to_json(payload.params[0]) + + def test_from_fixture_header_requires_bal_on_post_bal_fork(self) -> None: + """Without a modifier override, Amsterdam still requires a BAL body.""" + with pytest.raises(ValueError, match="block_access_list"): + FixtureEngineNewPayload.from_fixture_header( + fork=Amsterdam, + header=_amsterdam_payload_header(), + transactions=[], + withdrawals=[], + requests=[], + block_access_list=None, + ) + + def test_from_fixture_header_passthrough_without_modifier(self) -> None: + """No modifier leaves the payload's BAL body unchanged.""" + payload = FixtureEngineNewPayload.from_fixture_header( + fork=Amsterdam, + header=_amsterdam_payload_header(), + transactions=[], + withdrawals=[], + requests=[], + block_access_list=Bytes(b"\xaa\xbb"), + ) + assert payload.params[0].block_access_list == Bytes(b"\xaa\xbb") diff --git a/packages/testing/src/execution_testing/specs/blockchain.py b/packages/testing/src/execution_testing/specs/blockchain.py index f0b1530f57c..39fc641c3fb 100644 --- a/packages/testing/src/execution_testing/specs/blockchain.py +++ b/packages/testing/src/execution_testing/specs/blockchain.py @@ -66,6 +66,7 @@ FixtureBlockBase, FixtureConfig, FixtureEngineNewPayload, + FixtureExecutionPayloadModifier, FixtureHeader, FixtureTransaction, FixtureWithdrawal, @@ -395,6 +396,7 @@ class BuiltBlock(CamelModel): result: Result expected_exception: BLOCK_EXCEPTION_TYPE = None engine_api_error_code: EngineAPIError | None = None + rlp_modifier: Header | None = None fork: Fork block_access_list: BlockAccessList | None @@ -447,6 +449,40 @@ def get_block_rlp(self) -> Bytes: """Get the RLP of the block.""" return self.get_fixture_block().rlp + @staticmethod + def derive_engine_payload_modifier( + rlp_modifier: Header | None, + block_access_list: BlockAccessList | None, + ) -> "FixtureExecutionPayloadModifier | None": + """ + Propagate ``rlp_modifier``'s header changes to the engine payload. + + The engine ``ExecutionPayload`` schema does not carry + ``block_access_list_hash`` directly; the equivalent payload field is + the ``block_access_list`` body. So a header modifier that touches the + BAL hash needs to drive a matching change on the payload body. + """ + if rlp_modifier is None: + return None + bal_hash_override = rlp_modifier.block_access_list_hash + if bal_hash_override is None: + return None + if bal_hash_override is Header.REMOVE_FIELD: + return FixtureExecutionPayloadModifier( + block_access_list=( + FixtureExecutionPayloadModifier.REMOVE_FIELD + ), + ) + # The user injected a header BAL hash; mirror that on the engine + # payload by forcing a body to be present. Its exact value is + # irrelevant for negative tests — a non-``None`` value is enough to + # make a payload-version mismatch detectable. + if block_access_list is None: + return FixtureExecutionPayloadModifier( + block_access_list=Bytes(b""), + ) + return None + def get_fixture_engine_new_payload(self) -> FixtureEngineNewPayload: """Get a FixtureEngineNewPayload from the built block.""" return FixtureEngineNewPayload.from_fixture_header( @@ -458,6 +494,9 @@ def get_fixture_engine_new_payload(self) -> FixtureEngineNewPayload: block_access_list=self.block_access_list.rlp if self.block_access_list else None, + execution_payload_modifier=self.derive_engine_payload_modifier( + self.rlp_modifier, self.block_access_list + ), validation_error=self.expected_exception, error_code=self.engine_api_error_code, ) @@ -808,6 +847,7 @@ def generate_block_data( result=transition_tool_output.result, expected_exception=block.exception, engine_api_error_code=block.engine_api_error_code, + rlp_modifier=block.rlp_modifier, fork=fork, block_access_list=bal, ) diff --git a/packages/testing/src/execution_testing/specs/tests/test_types.py b/packages/testing/src/execution_testing/specs/tests/test_types.py index 4d52085b6ec..f5c43cb5fe9 100644 --- a/packages/testing/src/execution_testing/specs/tests/test_types.py +++ b/packages/testing/src/execution_testing/specs/tests/test_types.py @@ -9,9 +9,13 @@ Hash, HeaderNonce, ) -from execution_testing.fixtures.blockchain import FixtureHeader +from execution_testing.fixtures.blockchain import ( + FixtureExecutionPayloadModifier, + FixtureHeader, +) +from execution_testing.test_types.block_access_list import BlockAccessList -from ..blockchain import Header +from ..blockchain import BuiltBlock, Header fixture_header_ones = FixtureHeader( parent_hash=Hash(1), @@ -139,3 +143,70 @@ def test_fixture_header_join( ) -> None: """Test that the join method works as expected.""" assert modifier.apply(fixture_header) == fixture_header_expected + + +class TestDeriveEnginePayloadModifier: + """ + Verify the auto-propagation from ``rlp_modifier``'s header-only changes + to the engine payload body. Test authors set ``rlp_modifier`` once on a + ``Block``; the framework must reflect that change on both the RLP block + and the ``engine_newPayload`` fixture. + """ + + def test_no_rlp_modifier_returns_none(self) -> None: + """No modifier → no engine payload override.""" + assert ( + BuiltBlock.derive_engine_payload_modifier( + rlp_modifier=None, + block_access_list=None, + ) + is None + ) + + def test_rlp_modifier_unrelated_field_returns_none(self) -> None: + """A modifier that doesn't touch BAL hash leaves the payload alone.""" + assert ( + BuiltBlock.derive_engine_payload_modifier( + rlp_modifier=Header(state_root=Hash(100)), + block_access_list=None, + ) + is None + ) + + def test_remove_bal_hash_removes_body_from_payload(self) -> None: + """Removing the header's BAL hash also removes the payload body.""" + modifier = BuiltBlock.derive_engine_payload_modifier( + rlp_modifier=Header(block_access_list_hash=Header.REMOVE_FIELD), + block_access_list=BlockAccessList(), + ) + assert isinstance(modifier, FixtureExecutionPayloadModifier) + assert modifier.block_access_list is ( + FixtureExecutionPayloadModifier.REMOVE_FIELD + ) + + def test_inject_bal_hash_on_pre_fork_adds_body(self) -> None: + """ + Injecting a header BAL hash on a block that has no body (pre-fork) + triggers a body to be added to the engine payload, so a payload- + version mismatch is detectable. + """ + modifier = BuiltBlock.derive_engine_payload_modifier( + rlp_modifier=Header(block_access_list_hash=Hash(0)), + block_access_list=None, + ) + assert isinstance(modifier, FixtureExecutionPayloadModifier) + assert modifier.block_access_list == Bytes(b"") + + def test_inject_bal_hash_on_post_fork_leaves_body_alone(self) -> None: + """ + Setting a BAL hash on a block that already has a body (post-fork) + does not override the body — the resulting block-hash mismatch is + what triggers the client rejection in that scenario. + """ + assert ( + BuiltBlock.derive_engine_payload_modifier( + rlp_modifier=Header(block_access_list_hash=Hash(0)), + block_access_list=BlockAccessList(), + ) + is None + ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_external_coverage.txt b/tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_external_coverage.txt new file mode 100644 index 00000000000..b0596291a7e --- /dev/null +++ b/tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_external_coverage.txt @@ -0,0 +1,3 @@ +general/code_coverage/eels = Run produced tests against EELS and verify line coverage of new BAL code (block_access_list/, modifiers, builder) is at the expected level +general/code_coverage/test_coverage = Run tests with `uv run fill --cov tests/amsterdam/eip7928_block_level_access_lists` to verify test code coverage +general/code_coverage/second_client = Cross-client coverage tracked separately via the multi-client BAL conformance effort diff --git a/tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_not_applicable.txt b/tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_not_applicable.txt new file mode 100644 index 00000000000..3b42a3a248c --- /dev/null +++ b/tests/amsterdam/eip7928_block_level_access_lists/eip_checklist_not_applicable.txt @@ -0,0 +1,14 @@ +opcode = EIP-7928 does not introduce a new opcode +precompile = EIP-7928 does not introduce a new precompile +removed_precompile = EIP-7928 does not remove a precompile +system_contract = EIP-7928 does not introduce a new system contract +transaction_type = EIP-7928 does not introduce a new transaction type +block_body_field = EIP-7928 does not introduce a new block body field (the block_access_list is transmitted via the Engine API payload, committed only via its hash in the header) +gas_cost_changes = EIP-7928 does not modify existing gas costs (the BAL gas budget constraint is covered under block_level_constraint) +gas_refunds_changes = EIP-7928 does not modify gas refunds +blob_count_changes = EIP-7928 does not modify blob count parameters +execution_layer_request = EIP-7928 does not introduce an execution layer request +new_transaction_validity_constraint = EIP-7928 introduces a block-level constraint, not a transaction-level one +modified_transaction_validity_constraint = EIP-7928 does not modify any existing transaction validity constraint +block_level_constraint/test/content/logs = BAL size constraint depends only on (accounts + storage_keys) counts; transaction logs do not affect bal_items and therefore cannot change constraint behavior +block_level_constraint/test/content/receipts = BAL is not part of the receipts trie; varying receipt sizes do not contribute to bal_items and therefore cannot change constraint behavior diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 8dce480a1e2..e7d99ad0935 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -21,6 +21,7 @@ BlockchainTestFiller, BlockException, Conditional, + EIPChecklist, Environment, Fork, Hash, @@ -41,6 +42,7 @@ pytestmark = pytest.mark.valid_from("Amsterdam") +@EIPChecklist.BlockHeaderField.Test.ValueBehavior.Accept() def test_bal_nonce_changes( pre: Alloc, blockchain_test: BlockchainTestFiller, @@ -2805,6 +2807,7 @@ def test_bal_cross_block_ripemd160_state_leak( ) +@EIPChecklist.BlockLevelConstraint.Test.Content.TransactionTypes() def test_bal_all_transaction_types( pre: Alloc, blockchain_test: BlockchainTestFiller, @@ -3164,6 +3167,9 @@ def test_bal_lexicographic_address_ordering( ) +@EIPChecklist.BlockLevelConstraint.Test.Boundary.Under() +@EIPChecklist.BlockLevelConstraint.Test.Boundary.Exact() +@EIPChecklist.BlockLevelConstraint.Test.Boundary.Over() @pytest.mark.parametrize( "boundary_offset", [ diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py index c423012f387..d72f262c240 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py @@ -15,6 +15,7 @@ Block, BlockAccessListExpectation, BlockchainTestFiller, + EIPChecklist, Environment, Fork, Header, @@ -80,6 +81,7 @@ def test_bal_withdrawal_empty_block( ) +@EIPChecklist.BlockLevelConstraint.Test.Content.Withdrawals() def test_bal_withdrawal_and_transaction( pre: Alloc, blockchain_test: BlockchainTestFiller, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index 72175a18c11..52d366019d8 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -21,6 +21,7 @@ BlockAccessListExpectation, BlockchainTestFiller, BlockException, + EIPChecklist, Environment, Fork, Hash, @@ -1181,6 +1182,7 @@ def test_bal_invalid_duplicate_entries( ) +@EIPChecklist.BlockHeaderField.Test.ValueBehavior.Reject() @pytest.mark.valid_from("Amsterdam") @pytest.mark.exception_test def test_bal_invalid_hash_mismatch( diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 7d8faf64484..c67ca1eaf3e 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -170,4 +170,8 @@ | `test_bal_call_opcode_succeeds_in_static_context` | All call opcodes (no value) succeed in static context | Parametrized: `@pytest.mark.with_all_call_opcodes`. Caller invokes `call_opcode(target)` inside STATICCALL. | `target` **MUST** appear in BAL. Ensures clients don't over-restrict beyond EIP-214. | ✅ Completed | | `test_bal_callcode_with_value_in_static_context` | CALLCODE with nonzero value succeeds in static context | EIP-214 explicitly excludes CALLCODE from write-protection. Caller invokes `CALLCODE(value=1, target)` inside STATICCALL. | `target` **MUST** appear in BAL. Ensures clients don't apply CALL-with-value restriction to CALLCODE. | ✅ Completed | | `test_bal_create_and_oog` | CREATE/CREATE2 OOG boundary test at three gas levels | Parametrized: `@pytest.mark.with_all_create_opcodes`, `OutOfGasBoundary` (OOG_BEFORE_TARGET_ACCESS, OOG_AFTER_TARGET_ACCESS, SUCCESS). BEFORE and AFTER differ by 1 gas, proving the static cost boundary. | OOG_BEFORE: created address **MUST NOT** appear in BAL. OOG_AFTER: created address IS in BAL as `empty()` (accessed, state reverted). SUCCESS: created address in BAL with `nonce_changes`/`code_changes`. | ✅ Completed | +| `test_bal_fork_transition_happy_path` | Verify a BAL is produced at the Amsterdam activation block and absent before it. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. Uses `@pytest.mark.valid_at_transition_to("Amsterdam")` to run across the `BPO2 -> Amsterdam` boundary. | Two blocks: pre-fork (`timestamp=14_999`) with a simple Alice→Bob transfer, then activation block (`timestamp=15_000`) with the same kind of transfer. | Pre-fork block header **MUST NOT** carry `block_access_list_hash`. Activation block **MUST** include `block_access_list_hash` correctly derived from the BAL body, and the BAL body **MUST** record Alice's `nonce_changes` and Bob's `balance_changes` at `block_access_index=1`. | ✅ Completed | +| `test_invalid_pre_fork_block_with_bal_hash_field` | Verify clients reject a pre-Amsterdam block whose header carries `block_access_list_hash`. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. | Single block at `timestamp=14_999` with a regular transfer, mutated via `rlp_modifier=Header(block_access_list_hash=Hash(0))` to inject the field into the pre-fork header schema. | Block **MUST** be rejected with `BlockException.INCORRECT_BLOCK_FORMAT` / `EngineAPIError.InvalidParams`. The new header / body field must not be accepted before activation. | ✅ Completed | +| `test_invalid_post_fork_block_without_bal_hash_field` | Verify clients reject an Amsterdam activation block whose header is missing `block_access_list_hash`. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. | Single block at `timestamp=15_000` with a regular transfer, mutated via `rlp_modifier=Header(block_access_list_hash=Header.REMOVE_FIELD)` so the field is dropped from the header. | Block **MUST** be rejected with `BlockException.INCORRECT_BLOCK_FORMAT` / `EngineAPIError.InvalidParams`. The new header field becomes mandatory from the activation block onward. | ✅ Completed | +| `test_fork_transition_bal_size_constraint` | Verify the BAL size constraint (`bal_items <= gas_limit // BLOCK_ACCESS_LIST_ITEM`) applies only on/after Amsterdam. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. Parametrized over `exceeds_limit_at_fork`: `at_fork_within_budget` (`gas_limit == empty_block_bal_item_count() * BLOCK_ACCESS_LIST_ITEM`) and `at_fork_over_budget` (`gas_limit` one wei below that). | Two empty blocks: pre-fork (`timestamp=14_999`) and activation block (`timestamp=15_000`). The same low `gas_limit` is used for both via `genesis_environment=Environment(gas_limit=...)`. | Pre-fork block **MUST** be accepted under both budgets (constraint not yet enforced). Activation block **MUST** be accepted at the exact budget and **MUST** be rejected with `BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED` one item over the budget. | ✅ Completed | diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py b/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py new file mode 100644 index 00000000000..8e524c8e68e --- /dev/null +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py @@ -0,0 +1,215 @@ +"""Fork-transition tests for EIP-7928 (Block-level Access Lists).""" + +import pytest +from execution_testing import ( + Account, + Alloc, + BalAccountExpectation, + BalBalanceChange, + BalNonceChange, + Block, + BlockAccessListExpectation, + BlockchainTestFiller, + BlockException, + EIPChecklist, + EngineAPIError, + Environment, + Hash, + Header, + Transaction, + TransitionFork, +) + +from .spec import ref_spec_7928 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7928.git_path +REFERENCE_SPEC_VERSION = ref_spec_7928.version + +FORK_TIMESTAMP = 15_000 + + +@EIPChecklist.BlockHeaderField.Test.ForkTransition.Initial() +@pytest.mark.valid_at_transition_to("Amsterdam") +def test_bal_fork_transition_happy_path( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Verify that a BAL is produced at the Amsterdam activation block. + + - Pre-fork block (timestamp < 15_000): no BAL hash, no BAL body. + - Activation block (timestamp == 15_000): BAL hash and body are present + and match the actual access activity in the block. + """ + alice = pre.fund_eoa() + bob = pre.fund_eoa(amount=0) + + pre_fork_tx = Transaction(sender=alice, to=bob, value=100, gas_price=10) + post_fork_tx = Transaction(sender=alice, to=bob, value=100, gas_price=10) + + blocks = [ + Block( + timestamp=FORK_TIMESTAMP - 1, + txs=[pre_fork_tx], + header_verify=Header( + block_access_list_hash=Header.EMPTY_FIELD, + ), + ), + Block( + timestamp=FORK_TIMESTAMP, + txs=[post_fork_tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=2) + ], + ), + bob: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=200 + ), + ], + ), + } + ), + ), + ] + + blockchain_test( + pre=pre, + blocks=blocks, + post={bob: Account(balance=200)}, + ) + + +@EIPChecklist.BlockHeaderField.Test.ForkTransition.Before() +@pytest.mark.valid_at_transition_to("Amsterdam") +@pytest.mark.exception_test +def test_invalid_pre_fork_block_with_bal_hash_field( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Reject a pre-Amsterdam block whose header carries + `block_access_list_hash`. + + The field is not part of the pre-fork header schema; injecting it via the + Engine API must fail with `INCORRECT_BLOCK_FORMAT` / `InvalidParams`. + """ + sender = pre.fund_eoa() + receiver = pre.fund_eoa(amount=0) + + tx = Transaction(sender=sender, to=receiver, value=100, gas_price=10) + + blockchain_test( + pre=pre, + post={}, + blocks=[ + Block( + timestamp=FORK_TIMESTAMP - 1, + txs=[tx], + rlp_modifier=Header(block_access_list_hash=Hash(0)), + exception=BlockException.INCORRECT_BLOCK_FORMAT, + engine_api_error_code=EngineAPIError.InvalidParams, + ), + ], + ) + + +@EIPChecklist.BlockHeaderField.Test.ForkTransition.After() +@pytest.mark.valid_at_transition_to("Amsterdam") +@pytest.mark.exception_test +def test_invalid_post_fork_block_without_bal_hash_field( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Reject an Amsterdam activation block whose header is missing + `block_access_list_hash`. + """ + sender = pre.fund_eoa() + receiver = pre.fund_eoa(amount=0) + + tx = Transaction(sender=sender, to=receiver, value=100, gas_price=10) + + blockchain_test( + pre=pre, + post={}, + blocks=[ + Block( + timestamp=FORK_TIMESTAMP, + txs=[tx], + rlp_modifier=Header( + block_access_list_hash=Header.REMOVE_FIELD, + ), + exception=BlockException.INCORRECT_BLOCK_FORMAT, + engine_api_error_code=EngineAPIError.InvalidParams, + ), + ], + ) + + +@EIPChecklist.BlockLevelConstraint.Test.ForkTransition.AcceptedBeforeFork() +@EIPChecklist.BlockLevelConstraint.Test.ForkTransition.AcceptedAfterFork() +@EIPChecklist.BlockLevelConstraint.Test.ForkTransition.RejectedAfterFork() +@pytest.mark.valid_at_transition_to("Amsterdam") +@pytest.mark.parametrize( + "exceeds_limit_at_fork", + [ + pytest.param(False, id="at_fork_within_budget"), + pytest.param( + True, + marks=pytest.mark.exception_test, + id="at_fork_over_budget", + ), + ], +) +def test_fork_transition_bal_size_constraint( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: TransitionFork, + exceeds_limit_at_fork: bool, +) -> None: + """ + Verify the BAL size constraint applies only on/after Amsterdam. + + - Pre-fork block at a `gas_limit` that *would* fail the post-fork + constraint is accepted (the constraint is not yet enforced). + - Activation block at the exact budget is accepted. + - Activation block one item over the budget is rejected with + `BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED`. + """ + amsterdam = fork.transitions_to() + min_gas_limit = ( + amsterdam.empty_block_bal_item_count() + * amsterdam.gas_costs().BLOCK_ACCESS_LIST_ITEM + ) + over_budget_gas_limit = min_gas_limit - 1 + + pre_fork_block = Block( + timestamp=FORK_TIMESTAMP - 1, + txs=[], + ) + + if exceeds_limit_at_fork: + at_fork_block = Block( + timestamp=FORK_TIMESTAMP, + txs=[], + exception=BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED, + ) + block_gas_limit = over_budget_gas_limit + else: + at_fork_block = Block( + timestamp=FORK_TIMESTAMP, + txs=[], + ) + block_gas_limit = min_gas_limit + + blockchain_test( + pre=pre, + post={}, + blocks=[pre_fork_block, at_fork_block], + genesis_environment=Environment(gas_limit=block_gas_limit), + ) From c6b7f1704db7c2e224ecaefabbef2973f0c75acb Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Mon, 18 May 2026 11:50:13 +0530 Subject: [PATCH 086/186] chore(test-client-clis): update NethermindExceptionMapper strings for type-4 transactions (#2867) --- .../src/execution_testing/client_clis/clis/nethermind.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py index a833759b36b..929fc139cbb 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py +++ b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py @@ -347,10 +347,10 @@ class NethermindExceptionMapper(ExceptionMapper): "blob transaction of type create" ), TransactionException.TYPE_4_EMPTY_AUTHORIZATION_LIST: ( - "MissingAuthorizationList: Must be set" + "EIP-7702 transaction with empty auth list" ), TransactionException.TYPE_4_TX_CONTRACT_CREATION: ( - "NotAllowedCreateTransaction: To must be set" + "EIP-7702 transaction cannot be used to create contract" ), TransactionException.TYPE_4_TX_PRE_FORK: ( "InvalidTxType: Transaction type in Custom is not supported" From c2a9d0e6e357d0505cf6b7b0fe654bfa73e63828 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 18 May 2026 20:08:51 +0530 Subject: [PATCH 087/186] Revert "Merge remote-tracking branch 'upstream/forks/amsterdam' into sync-upstream" This reverts commit 60d949ee3583cf73bf4f77b24184ff81a7647ff0, reversing changes made to cbdaee9cf1ad6d833173e1cf3d2c42c23f3345aa. --- .github/workflows/docs-build.yaml | 11 +- Justfile | 5 + docs/CHANGELOG.md | 1130 +++++++++++++++++ docs/changelog_section_template.md | 19 + docs/dev/docs.md | 1 + packages/testing/pyproject.toml | 2 + .../testing/src/execution_testing/__init__.py | 2 - .../src/execution_testing/cli/ci_helpers.py | 52 +- .../plugins/execute/execute.py | 7 +- .../pytest_commands/plugins/filler/filler.py | 8 +- .../filler/gen_test_doc/gen_test_doc.py | 2 +- .../plugins/filler/static_filler.py | 2 +- .../pytest_commands/plugins/forks/forks.py | 16 +- .../tests/test_fork_parametrizer_types.py | 23 +- .../plugins/shared/benchmarking.py | 18 +- .../plugins/shared/execute_fill.py | 64 +- .../src/execution_testing/forks/base_fork.py | 63 +- .../forks/tests/test_forks.py | 52 + .../forks/transition_base_fork.py | 45 +- .../execution_testing/test_types/__init__.py | 2 - .../tools/utility/generators.py | 29 +- .../test_block_access_lists.py | 156 --- .../test_cases.md | 2 - .../compute/precompile/test_alt_bn128.py | 29 - .../test_tstorage_create_contexts.py | 8 +- tests/frontier/opcodes/test_all_opcodes.py | 4 +- .../eip3860_initcode/test_initcode.py | 5 +- tox.ini | 5 + 28 files changed, 1500 insertions(+), 262 deletions(-) create mode 100644 docs/CHANGELOG.md create mode 100644 docs/changelog_section_template.md diff --git a/.github/workflows/docs-build.yaml b/.github/workflows/docs-build.yaml index 477d159119b..a9617549142 100644 --- a/.github/workflows/docs-build.yaml +++ b/.github/workflows/docs-build.yaml @@ -71,10 +71,19 @@ jobs: docs/**/*.md *.md + changelog: + name: "Validate Changelog Entries" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: ./.github/actions/setup-uv + - name: Run changelog validation + run: just changelog + check-should-publish: name: "Check Should Publish" runs-on: ubuntu-latest - needs: [lint-md] + needs: [lint-md, changelog] outputs: should_publish: ${{ steps.check.outputs.should_publish }} branch: ${{ steps.check.outputs.branch }} diff --git a/Justfile b/Justfile index 76725ba624f..2d1562c9f8a 100644 --- a/Justfile +++ b/Justfile @@ -304,6 +304,11 @@ docs-serve *args: docs-serve-fast *args: FAST_DOCS=True uv run mkdocs serve "$@" +# Validate docs/CHANGELOG.md entries +[group('docs')] +changelog: + uv run validate_changelog + # Lint markdown files (markdownlint) [group('docs')] lint-md: diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 00000000000..4286cf29063 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,1130 @@ +# Changelog + +Test fixtures for use by clients are available for each release on the [Github releases page](https://github.com/ethereum/execution-spec-tests/releases). + +**Key:** ✨ = New, 🐞 = Fixed, 🔀 = Changed. 💥 = Breaking + +## 🔜 [Unreleased] + +### 💥 Breaking Change + +### 🛠️ Framework + +- 🐞 Remove `Op.CLZ` from `UndefinedOpcodes` list ([#1970](https://github.com/ethereum/execution-specs/pull/1970)). +- 🐞 Make `TransactionTraces` `CamelModel` less lestrictive ([#2081](https://github.com/ethereum/execution-specs/pull/2081)). + +#### `fill` + +- ✨ Allow command to customize `--chain-id` used for filling ([#2016](https://github.com/ethereum/execution-specs/pull/2016)). + +#### `consume` + +- ✨ Add Besu `evmtool` support for `consume direct` via `state-test` and `block-test` subcommands ([#2219](https://github.com/ethereum/execution-specs/pull/2219)). + +#### `execute` + +- ✨ Add transaction batching to avoid RPC overload when executing tests with many transactions. Transactions are now sent in configurable batches (default: 750) with progress logging. Use `--max-tx-per-batch` to configure the batch size ([#1907](https://github.com/ethereum/execution-specs/pull/1907)). +- ✨ `execute hive` and `execute remote` now defer funding of accounts until the minimum amount required to send the test transactions is calculated, in order to optimize the amount of Eth used to execute the tests ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). +- ✨ Dynamically fetch gas prices from the network and update all transactions to use 1.5x the current values ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). +- ✨ New `--dry-run` flag to calculate the amount of Eth that will be spent executing a test given the current network gas prices ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). +- 🔀 Load balancing mode of `execute` for xdist was updated from `loadscope` to `load` ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). +- 💥 `--eoa-fund-amount-default` has been deprecated since the command now automatically calculates the funding amount ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). +- 💥 `--sender-key-initial-balance` flag of `execute hive` has been renamed to `--seed-key-initial-balance` ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). +- 🔀 Flags --default-gas-price, --default-max-fee-per-gas and --default-max-priority-fee-per-gas now default to None and ideally should be omitted because, when unset, the command now defaults to fetch the value from the network, which is a more reliable behavior ([#1822](https://github.com/ethereum/execution-specs/pull/1822)). + +### 📋 Misc + +- ✨ Implement EIP-7928 Block-Level Access Lists ([#1719](https://github.com/ethereum/execution-specs/pull/1719)). + +### 🧪 Test Cases + +- ✨ Add missing fuzzy-compute benchmark configurations for `KECCAK256`, `CODECOPY`, `CALLDATACOPY`, `RETURNDATACOPY`, `MLOAD`, `MSTORE`, `MSTORE8`, `MCOPY`, `LOG*`, `CALLDATASIZE`, `CALLDATALOAD`, and `RETURNDATASIZE` opcodes ([#1956](https://github.com/ethereum/execution-specs/pull/1956)). +- ✨ Add precompile benchmark configurations for `ecPairing`, `blake2f`, `BLS12_G1_MSM`, `BLS12_G2_MSM` and `BLS12_PAIRING` to unblock repricing analysis ([#2003](https://github.com/ethereum/execution-specs/pull/2003)). +- 🔀 Relabel `@pytest.mark.repricing` markers in benchmark tests to reflect configurations requested for gas repricing analysis ([#1971](https://github.com/ethereum/execution-specs/pull/1971)). +- ✨ New EIP-7702 test cases added ([#1974](https://github.com/ethereum/execution-specs/pull/1974)). +- ✨ Add missing benchmark configurations / opcode to benchmark tests for repricing analysis([#2006](https://github.com/ethereum/execution-specs/pull/2006)). +- ✨ Port STATICCALL to CALL tests with zero and non-zero value transfer from `tests/static`, extending coverage with `pytest.mark.with_all_precompiles` ([#1960](https://github.com/ethereum/execution-specs/pull/1960)). +- ✨ Add BAL tests that dequeue EIP-7251 consolidation requests. ([#2076](https://github.com/ethereum/execution-specs/pull/2076)). +- ✨ Add BAL tests for handling 7702 delegation reset and delegated create. ([#2097](https://github.com/ethereum/execution-specs/pull/2097)). +- ✨ Add benchmark scenarios for ether transfers to precompiles, warm access list transfers, and max-size contract creation transactions ([#2171](https://github.com/ethereum/execution-specs/pull/2171)). + +## [v5.4.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.4.0) - 2025-12-07 + +### 🛠️ Framework + +#### General + +- 🔀 Updated default block gas limit from 45M to 60M to align with [EIP-7935](https://eips.ethereum.org/EIPS/eip-7935) for the Osaka fork. + +#### `fill` + +- 🐞 Allow `evmone` to fill Prague and Osaka blockchain tests (mainly modified deposit contract tests) ([#1689](https://github.com/ethereum/execution-specs/pull/1689)). +- 🐞 Turn off Block-Level Access List related checks when filling tests for Amsterdam ([#1737](https://github.com/ethereum/execution-specs/pull/1737)). + +#### `consume` + +- 🐞 Fix a bug with `consume sync` tests where some clients don't have JSON-RPC immediately available after syncing and can't yet serve the synced block ([#1670](https://github.com/ethereum/execution-specs/pull/1670)). + +### 📋 Misc + +- 🐞 WELDed the EEST tox environments relevant to producing documentation into EELS, and added a tool to cleanly add codespell whitelist entries. ([#1695](https://github.com/ethereum/execution-specs/pull/1659)). +- 🐞 Fix duplicate storage write issues for block access lists EIP-7928 implementation ([#1743](https://github.com/ethereum/execution-specs/pull/1743)). + +### 🧪 Test Cases + +- 🐞 Fix BALs opcode OOG test vectors by updating the Amsterdam commit hash in specs and validating appropriately on the testing side ([#2293](https://github.com/ethereum/execution-spec-tests/pull/2293)). +- ✨ Fix test vector for BALs SSTORE with OOG by pointing to updated specs; add new boundary conditions cases for SSTORE w/ OOG ([#2297](https://github.com/ethereum/execution-spec-tests/pull/2297)). +- ✨ Expand EIP-6110 modified contract tests, where the extra event log has no topics at all ([#1693](https://github.com/ethereum/execution-specs/pull/1693)). +- ✨ Add a CREATE/2 test cases for when it runs OOG on code deposit ([#1705](https://github.com/ethereum/execution-specs/pull/1705)). +- ✨ Expand cases to test *CALL opcodes causing OOG ([#1703](https://github.com/ethereum/execution-specs/pull/1703)). +- ✨ Add a test case for base fee in block check after London ([#1702](https://github.com/ethereum/execution-specs/pull/1702)). +- ✨ Add tests for `modexp` and `ripemd` precompiled contracts ([#1691](https://github.com/ethereum/execution-specs/pull/1691), [#1781](https://github.com/ethereum/execution-specs/pull/1781)). +- ✨ Add `ecrecover` precompile tests originating form `evmone` unittests ([#1685](https://github.com/ethereum/execution-specs/pull/1685)). +- ✨ Add test to validate withdarawls root ([#1746](https://github.com/ethereum/execution-specs/pull/1746)). +- ✨ Add test for old behavior of zero gasprice txs ([#1736](https://github.com/ethereum/execution-specs/pull/1736)). +- ✨ Add stack overflow tests and expand `BLOCKHASH` tests ([#1728](https://github.com/ethereum/execution-specs/pull/1728)). +- ✨ Ported tests for `ripemd` precompile going OOG for all forks ([#1732](https://github.com/ethereum/execution-specs/pull/1732)). +- ✨ Add tests for ecadd/ecmul/ecpairing constant gas repricing ([#1738](https://github.com/ethereum/execution-specs/pull/1738)). +- ✨ Add tests that EIP-1559 and EIP-2930 typed txs are invalid and void before their fork ([#1754](https://github.com/ethereum/execution-specs/pull/1754)). +- ✨ Add tests for an old validation rule for gas limit above 5000 ([#1731](https://github.com/ethereum/execution-specs/pull/1731)). +- ✨ Add tests for OOG in EXP, LOG and others ([#1686](https://github.com/ethereum/execution-specs/pull/1686)). +- ✨ Make EIP-7934 tests more dynamic and able to handle new header fields added in future forks ([#2022](https://github.com/ethereum/execution-specs/pull/2022)). + +## [v5.3.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.3.0) - 2025-10-09 + +## 🇯🇵 Summary + +EEST v5.3.0 is a follow-up from our main v5.0.0 [release](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.0.0), with updated BPO1 and BPO2 values aligning with the testnet parameters. + +This release additionally includes fixes for tests in hive, as well as new test cases for EIP-7883, EIP-7934 and critical cases for EIP-7951 (added to EEST by @chfast following a coverage review of the test suite). + +## 🔑 Key Changes + +### 🛠️ Framework + +- ✨ Add benchmark-specific test wrapper (`benchmark_test`) that supports **EIP-7825** and create a benchmark code generator for common test pattern ([#1945](https://github.com/ethereum/execution-spec-tests/pull/1945)). + +#### `fill` + +- ✨ Added `--optimize-gas`, `--optimize-gas-output` and `--optimize-gas-post-processing` flags that allow to binary search the minimum gas limit value for a transaction in a test that still yields the same test result ([#1979](https://github.com/ethereum/execution-spec-tests/pull/1979)). +- ✨ Added `--watch` flag that monitors test files for changes and automatically re-runs the fill command when developing tests ([#2173](https://github.com/ethereum/execution-spec-tests/pull/2173)). +- 🔀 Upgraded ckzg version to 2.1.3 or newer for correct handling of points at infinity ([#2171](https://github.com/ethereum/execution-spec-tests/pull/2171)). +- 🔀 Move pytest marker registration for `fill` and `execute-*` from their respective ini files to the shared `pytest_plugins.shared.execute_fill` pytest plugin ([#2110](https://github.com/ethereum/execution-spec-tests/pull/2110)). +- ✨ Added an `--input.blobParams` CLI argument to the transition tool (`t8n`) invocation ([#2264](https://github.com/ethereum/execution-spec-tests/pull/2264)). + +#### `consume` + +- ✨ Add retry logic to RPC requests to fix flaky connection issues in Hive ([#2205](https://github.com/ethereum/execution-spec-tests/pull/2205)). +- 🛠️ Mark `consume sync` tests as `flaky` with 3 retires due to client sync inconsistencies ([#2252](https://github.com/ethereum/execution-spec-tests/pull/2252)). +- ✨ Add `consume direct` using `evmone-statetest` and `evmone-blockchaintest` ([#2243](https://github.com/ethereum/execution-spec-tests/pull/2243)). + +### 📋 Misc + +- ✨ Add tighter validation for EIP-7928 model coming from t8n when filling ([#2138](https://github.com/ethereum/execution-spec-tests/pull/2138)). +- ✨ Add flexible API for absence checks for EIP-7928 (BAL) tests ([#2124](https://github.com/ethereum/execution-spec-tests/pull/2124)). +- 🐞 Use `engine_newPayloadV5` for `>=Amsterdam` forks in `consume engine` ([#2170](https://github.com/ethereum/execution-spec-tests/pull/2170)). +- 🔀 Refactor EIP-7928 (BAL) absence checks into a friendlier class-based DevEx ([#2175](https://github.com/ethereum/execution-spec-tests/pull/2175)). +- 🐞 Tighten up validation for empty lists on Block-Level Access List tests ([#2118](https://github.com/ethereum/execution-spec-tests/pull/2118)). +- ✨ Added the `MemoryVariable` EVM abstraction to generate more readable bytecode when there's heavy use of variables that are stored in memory ([#1609](https://github.com/ethereum/execution-spec-tests/pull/1609)). +- 🐞 Fix an issue with `test_bal_block_rewards` where the block base fee was wrongfully overridden ([#2262](https://github.com/ethereum/execution-spec-tests/pull/2262)). +- ✨ Complete EIP checklist for EIP-7934 and update the checklist template to include block-level constraint checks ([#2282](https://github.com/ethereum/execution-spec-tests/pull/2282)). + +### 🧪 Test Cases + +- ✨ Add safe EIP-6110 workaround to allow Geth/Reth to pass invalid deposit request tests even thought they are out of spec ([#2177](https://github.com/ethereum/execution-spec-tests/pull/2177), [#2233](https://github.com/ethereum/execution-spec-tests/pull/2233)). +- ✨ Add an EIP-7928 test case targeting the `SELFDESTRUCT` opcode. ([#2159](https://github.com/ethereum/execution-spec-tests/pull/2159)). +- ✨ Add essential tests for coverage gaps in EIP-7951 (`p256verify` precompile) ([#2179](https://github.com/ethereum/execution-spec-tests/pull/2159), [#2203](https://github.com/ethereum/execution-spec-tests/pull/2203), [#2215](https://github.com/ethereum/execution-spec-tests/pull/2215), [#2216](https://github.com/ethereum/execution-spec-tests/pull/2216), [#2217](https://github.com/ethereum/execution-spec-tests/pull/2217), [#2218](https://github.com/ethereum/execution-spec-tests/pull/2218), [#2221](https://github.com/ethereum/execution-spec-tests/pull/2221), [#2229](https://github.com/ethereum/execution-spec-tests/pull/2229), [#2230](https://github.com/ethereum/execution-spec-tests/pull/2230), [#2237](https://github.com/ethereum/execution-spec-tests/pull/2237), [#2238](https://github.com/ethereum/execution-spec-tests/pull/2238)). +- ✨ Add EIP-7928 successful and OOG single-opcode tests ([#2118](https://github.com/ethereum/execution-spec-tests/pull/2118)). +- ✨ Add EIP-7928 tests for EIP-2930 interactions ([#2167](https://github.com/ethereum/execution-spec-tests/pull/2167)). +- ✨ Add EIP-7928 tests for NOOP operations ([#2178](https://github.com/ethereum/execution-spec-tests/pull/2178)). +- ✨ Add EIP-7928 tests for net-zero balance transfers ([#2280](https://github.com/ethereum/execution-spec-tests/pull/2280)). +- ✨ Add fork transition test cases for EIP-7934 ([#2282](https://github.com/ethereum/execution-spec-tests/pull/2282)). + +## [v5.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.0.0) - 2025-09-05 + +## 🇯🇵 Summary + +EEST Fujisan is our first full release for Osaka, the first full release since Pectra! + +In addition to the latest Osaka specific test cases, it includes re-filled `GeneralStateTests` from `ethereum/tests` (now fully maintained within EEST under `tests/static`) for Osaka adhering to the transaction gas limit cap from [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825). Further framework changes include new simulators, test formats and test types. + +## ⚔️ Future Weld with EELS + +EEST will merge with [EELS](https://github.com/ethereum/execution-specs) during **Q4 2025**, after which EEST becomes read-only for external contributors. + +**What this means?** + +- All EEST code moves to the EELS repository. +- New EEST framework location: `execution-specs/src/ethereum_spec_tests/`. +- New EEST tests location: `execution-specs/tests/eest/`. +- Future PRs go to EELS instead of EEST. + +**Important Notes:** + +- All PRs for tests and framework changes should still be directed at EEST until further notice. +- There will be a brief freeze on EEST contributions during Q4 "The Switch", after which contributors can continue as before, but in EELS. +- Test releases will continue from EEST as normal before, during, and after this transition. + +More information will be communicated accordingly through the normal communication channels. + +## ❗Current Status Quo + +### Test Fixtures Overview + +- `fixtures_static.tar.gz` has been deprecated. +- `fixtures_stable.tar.gz` & `fixtures_develop.tar.gz` now both contain re-filled static tests, `GeneralStateTests` from `ethereum/tests`, filled **from Cancun**. +- `fixtures_stable.tar.gz` contains tests filled for forks until Prague. +- `fixtures_develop.tar.gz` contains tests filled for forks until Osaka. +- `fixtures_benchmark.tar.gz` contains benchmark tests filled for only Prague. + +### EL Client Test Requirements + +**Prague Coverage (Mainnet):** + +- Run all `state_test`'s & `blockchain_test`'s from `fixtures_stable.tar.gz`. +- Run only `BlockchainTests` from the latest `ethereum/tests` [release](https://github.com/ethereum/tests/releases/tag/v17.2), filled **until Prague**. + +**Fusaka Coverage (Including Mainnet):** + +- Run all `state_test`'s & `blockchain_test`'s from `fixtures_develop.tar.gz`. +- Run only `BlockchainTests` from the latest `ethereum/tests` [release](https://github.com/ethereum/tests/releases/tag/v17.2), filled **until Prague**. + +**Note**: If you require `GeneralStateTests` from `ethereum/tests` **filled for forks before Cancun** then you must get these from the latest `ethereum/tests` [release](https://github.com/ethereum/tests/releases/tag/v17.2). + +### Benchmark Tests + +For the most up-to-date benchmark tests, use `fixtures_benchmark.tar.gz`. + +> **Note**: Benchmark tests for Osaka (compliant with EIP-7825 transaction gas limit cap) will be added in a future feature release. + +### Test Fixture Formats + +This release includes 2 new test formats designed primarily for [Hive](https://github.com/ethereum/hive) simulators: + +- [**`blockchain_tests_engine_x`**](https://eest.ethereum.org/v5.0.0/running_tests/test_formats/blockchain_test_engine_x/?h=#blockchain-engine-x-tests): An optimized version of `blockchain_tests_engine` where multiple tests share the same genesis state, allowing multiple tests to run on a single client instantiation within Hive's `consume-engine`. The standard format requires a fresh client startup for each test. Due its combined genesis state, this is additionally the primary format used by the Nethermind team for benchmarking. + +- [**`blockchain_tests_sync`**](https://eest.ethereum.org/main/running_tests/test_formats/blockchain_test_sync/?h=sync#blockchain-engine-sync-tests): A new format adjacent to the existing `blockchain_tests_engine` format. Used specifically for the upcoming `consume-sync` simulator, which delivers engine payloads from test fixtures to the client under test, then sync's a separate client to it. This test fixture is only marked to be filled for the [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934) block RLP limit tests in Osaka. + +### Tooling & Simulators + +Improved tooling and new Hive simulators are additionally included in this release: + +- [**`execute remote`**](https://eest.ethereum.org/main/running_tests/execute/remote/#running-test-on-a-live-remote-network): this command now supports optional [Engine RPC endpoints](https://eest.ethereum.org/main/running_tests/execute/remote/#engine-rpc-endpoint-optional) (`--engine-endpoint`) with JWT authentication #2070. + - This allows manual control over block creation and transaction inclusion for more deterministic test execution on live networks. Previously, `execute remote` could only submit transactions and rely on the network's automatic block production, but now it can actively drive chain progression by creating blocks on-demand via the Engine API. +- [**`consume sync`**](https://eest.ethereum.org/main/running_tests/running/#sync): Adjacent to `consume-engine`, designed to work with the `blockchain_tests_sync` format for testing client sync scenarios. +- [**`execute blobs`**](https://eest.ethereum.org/main/running_tests/execute/hive/#the-eestexecute-blobs-simulator): A new Hive specific simulator that uses the EEST execute pytest plugin. Sends blob transactions to the client under test and verifies its `engine_getBlobsVX` endpoint. Requires tests to be written with a new python test format `blob_transaction_test`. Primarily used to test PeerDAS from the EL perspective. +- [**`execute eth config`**](https://eest.ethereum.org/main/running_tests/execute/eth_config/): A command used to test the `eth_config` endpoint from [EIP-7910](https://eips.ethereum.org/EIPS/eip-7910). Can be ran [remotely](https://github.com/ethereum/execution-spec-tests/issues/2049) or within Hive. + +### Filling For Stateless Clients + +A `witness-filler` extension is included in this release, allowing for tests to be filled that include an `executionWitness` for each fixture #2066. This essentially calls an external executable written in rust, and hence must be installed for usage within `fill` using the `--witness` flag. The current approach is below: + +```sh +cargo install --git https://github.com/kevaundray/reth.git --branch jsign-witness-filler witness-filler +uv run fill ... --output=fixtures-witness --witness --clean +``` + +> **Note**: The `witness-filler` executable is not maintained by EEST so we cannot help with any issues. + +## 💥 Breaking Changes + +### Important changes for EEST superusers + +- EEST now requires `uv>=0.7.0` ([#1904](https://github.com/ethereum/execution-spec-tests/pull/1904)). If your version of `uv` is too old. +- When filling fixtures transition forks are included within there respective "to" fork, where `--fork Osaka` will now include `PragueToOsakaAtTime15k`. Previously transitions fork would only be included when filling with `--from Prague --until Osaka` flags. +- Python 3.10 support was removed in this release ([#1808](https://github.com/ethereum/execution-spec-tests/pull/1808)). +- EEST no longer allows usage of Yul code in Python tests. From now on, please make use of our opcode wrapper. Yul code is now only allowed in the "static tests" located in `./tests/static/` (these are test cases defined by JSON and YAML files instead of Python test functions that were originally maintained in [ethereum/tests](https://github.com/ethereum/tests)). +- In order to fill the static tests (which is not the case by default), please ensure that `solc` is located in your `PATH`. +- The output behavior of `fill` has changed ([#1608](https://github.com/ethereum/execution-spec-tests/pull/1608)): + - Before: `fill` wrote fixtures into the directory specified by the `--output` flag (default: `fixtures`). This could have many unintended consequences, including unexpected errors if old or invalid fixtures existed in the directory (for details see [#1030](https://github.com/ethereum/execution-spec-tests/issues/1030)). + - Now: `fill` will exit without filling any tests if the specified directory exists and is not-empty. This may be overridden by adding the `--clean` flag, which will first remove the specified directory. +- Writing debugging information to the EVM "dump directory" by default has been disabled. To obtain debug output, the `--evm-dump-dir` flag must now be explicitly set. As a consequence, the now redundant `--skip-evm-dump` option was removed ([#1874](https://github.com/ethereum/execution-spec-tests/pull/1874)). This undoes functionality originally introduced in [#999](https://github.com/ethereum/execution-spec-tests/pull/999) and [#1150](https://github.com/ethereum/execution-spec-tests/pull/1150). + +### Feature `zkevm` updated to `benchmark` + +Due to the crossover between `zkevm` and `benchmark` tests, all instances of the former have been replaced with the latter nomenclature. Repository PR labels and titles are additionally updated to reflect this change. + +This update renames the `zkevm` feature release to `benchmark` and further expands the latter for 1M, 10M, 30M, 45M, 60M, 90M, and 120M block gas limits in `fixtures_benchmark.tar.gz`. + +To select a test for a given gas limit, the IDs of the tests have been expanded to contain `benchmark-gas-value_XM`, where `X` can be any of the aforementioned values. + +The benchmark release also now includes BlockchainEngineX format that combines most of the tests into a minimal amount of genesis files. For more info see [Blockchain Engine X Tests](https://eest.ethereum.org/main/running_tests/test_formats/blockchain_test_engine_x/) in the EEST documentation. + +Users can select any of the artifacts depending on their benchmarking or testing needs for their provers. + +## 🔑 Other Key Changes + +### 🛠️ Framework + +#### 🔀 Refactoring + +- 🔀 Move `TransactionType` enum from test file to proper module location in `ethereum_test_types.transaction_types` for better code organization and reusability. +- ✨ Opcode classes now validate keyword arguments and raise `ValueError` with clear error messages. +- 🔀 This PR removes the `solc` requirement to fill Python test cases. Regular test contributors no longer need to concern themselves with `solc` and, as such, the `solc-select` dependency has been removed. The remaining tests that used Yul have been ported to the EEST opcode wrapper mini-lang and the use of Yul in Python tests is no longer supported. Maintainers only: To fill the "static" JSON and YAML tests (`./tests/static/`) locally, `solc` (ideally v0.8.24) must be available in your PATH. +- 🔀 Updated default block gas limit from 36M to 45M to match mainnet environment. +- 🔀 Refactor fork logic to include transition forks within there "to" fork ([#2051](https://github.com/ethereum/execution-spec-tests/pull/2051)). + +#### `fill` + +- ✨ Add the `ported_from` test marker to track Python test cases that were converted from static fillers in [ethereum/tests](https://github.com/ethereum/tests) repository ([#1590](https://github.com/ethereum/execution-spec-tests/pull/1590)). +- ✨ Add a new pytest plugin, `ported_tests`, that lists the static fillers and PRs from `ported_from` markers for use in the coverage Github Workflow ([#1634](https://github.com/ethereum/execution-spec-tests/pull/1634)). +- ✨ Enable two-phase filling of fixtures with pre-allocation groups and add a `BlockchainEngineXFixture` format ([#1706](https://github.com/ethereum/execution-spec-tests/pull/1706), [#1760](https://github.com/ethereum/execution-spec-tests/pull/1760)). +- ✨ Add `--generate-all-formats` flag to enable generation of all fixture formats including `BlockchainEngineXFixture` in a single command; enable `--generate-all-formats` automatically for tarball output, `--output=fixtures.tar.gz`, [#1855](https://github.com/ethereum/execution-spec-tests/pull/1855). +- 🔀 Refactor: Encapsulate `fill`'s fixture output options (`--output`, `--flat-output`, `--single-fixture-per-file`) into a `FixtureOutput` class ([#1471](https://github.com/ethereum/execution-spec-tests/pull/1471),[#1612](https://github.com/ethereum/execution-spec-tests/pull/1612)). +- ✨ Don't warn about a "high Transaction gas_limit" for `zkevm` tests ([#1598](https://github.com/ethereum/execution-spec-tests/pull/1598)). +- 🐞 `fill` no longer writes generated fixtures into an existing, non-empty output directory; it must now be empty or `--clean` must be used to delete it first ([#1608](https://github.com/ethereum/execution-spec-tests/pull/1608)). +- 🐞 `zkevm` marked tests have been removed from `tests-deployed` tox environment into its own separate workflow `tests-deployed-zkevm` and are filled by `evmone-t8n` ([#1617](https://github.com/ethereum/execution-spec-tests/pull/1617)). +- ✨ Field `postStateHash` is now added to all `blockchain_test` and `blockchain_test_engine` tests that use `exclude_full_post_state_in_output` in place of `postState`. Fixes `evmone-blockchaintest` test consumption and indirectly fixes coverage runs for these tests ([#1667](https://github.com/ethereum/execution-spec-tests/pull/1667)). +- 🔀 Changed INVALID_DEPOSIT_EVENT_LAYOUT to a BlockException instead of a TransactionException ([#1773](https://github.com/ethereum/execution-spec-tests/pull/1773)). +- 🔀 Disabled writing debugging information to the EVM "dump directory" to improve performance. To obtain debug output, the `--evm-dump-dir` flag must now be explicitly set. As a consequence, the now redundant `--skip-evm-dump` option was removed ([#1874](https://github.com/ethereum/execution-spec-tests/pull/1874)). +- ✨ Generate unique addresses with Python for compatible static tests, instead of using hard-coded addresses from legacy static test fillers ([#1781](https://github.com/ethereum/execution-spec-tests/pull/1781)). +- ✨ Added support for the `--benchmark-gas-values` flag in the `fill` command, allowing a single genesis file to be used across different gas limit settings when generating fixtures. ([#1895](https://github.com/ethereum/execution-spec-tests/pull/1895)). +- ✨ Static tests can now specify a maximum fork where they should be filled for ([#1977](https://github.com/ethereum/execution-spec-tests/pull/1977)). +- ✨ Static tests can now be filled in every format using `--generate-all-formats` ([#2006](https://github.com/ethereum/execution-spec-tests/pull/2006)). +- 💥 Flag `--flat-output` has been removed due to having been unneeded for an extended period of time ([#2018](https://github.com/ethereum/execution-spec-tests/pull/2018)). +- ✨ Add support for `BlockchainEngineSyncFixture` format for tests marked with `pytest.mark.verify_sync` to enable client synchronization testing via `consume sync` command ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)). +- ✨ Framework is updated to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) fork markers to enable the filling of BPO tests ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)). +- ✨ Generate and include execution witness data in blockchain fixtures if `--witness` is specified ([#2066](https://github.com/ethereum/execution-spec-tests/pull/2066)). + +#### `consume` + +- ✨ Add `--extract-to` parameter to `consume cache` command for direct fixture extraction to specified directory, replacing the need for separate download scripts. ([#1861](https://github.com/ethereum/execution-spec-tests/pull/1861)). +- 🐞 Fix `consume cache --cache-folder` parameter being ignored, now properly caches fixtures in the specified directory instead of always using the default system cache location. +- 🐞 Fix the `consume_direct.sh` script generated by `consume` in the `--evm-dump` dir by quoting test IDs [#1987](https://github.com/ethereum/execution-spec-tests/pull/1987). +- 🔀 `consume` now automatically avoids GitHub API calls when using direct release URLs (better for CI environments), while release specifiers like `stable@latest` continue to use the API for version resolution ([#1788](https://github.com/ethereum/execution-spec-tests/pull/1788)). +- 🔀 Refactor consume simulator architecture to use explicit pytest plugin structure with forward-looking architecture ([#1801](https://github.com/ethereum/execution-spec-tests/pull/1801)). +- 🔀 Add exponential retry logic to initial fcu within consume engine ([#1815](https://github.com/ethereum/execution-spec-tests/pull/1815)). +- ✨ Add `consume sync` command to test client synchronization capabilities by having one client sync from another via Engine API and P2P networking ([#2007](https://github.com/ethereum/execution-spec-tests/pull/2007)). +- 💥 Removed the `consume hive` command, this was a convenience command that ran `consume rlp` and `consume engine` in one pytest session; the individual commands should now be used instead ([#2008](https://github.com/ethereum/execution-spec-tests/pull/2008)). +- ✨ Update the hive ruleset to include BPO ([EIP-7892](https://eips.ethereum.org/EIPS/eip-7892)) forks ([#2050](https://github.com/ethereum/execution-spec-tests/pull/2050)). + +#### `execute` + +- ✨ Added new `Blob` class which can use the ckzg library to generate valid blobs at runtime ([#1614](https://github.com/ethereum/execution-spec-tests/pull/1614)). +- ✨ Added `blob_transaction_test` execute test spec, which allows tests that send blob transactions to a running client and verifying its `engine_getBlobsVX` endpoint behavior ([#1644](https://github.com/ethereum/execution-spec-tests/pull/1644)). +- ✨ Added `execute eth-config` command to test the `eth_config` RPC endpoint of a client, and includes configurations by default for Mainnet, Sepolia, Holesky, and Hoodi ([#1863](https://github.com/ethereum/execution-spec-tests/pull/1863)). +- ✨ Command `execute remote` now allows specification of an Engine API endpoint to drive the chain via `--engine-endpoint` and either `--engine-jwt-secret` or `--engine-jwt-secret-file`. This mode is useful when there's no consensus client connected to the execution client so `execute` will automatically request blocks via the Engine API when it sends transactions ([#2070](https://github.com/ethereum/execution-spec-tests/pull/2070)). +- ✨ Added `--address-stubs` flag to the `execute` command which allows to specify a JSON-formatted string, JSON file or YAML file which contains label-to-address of specific pre-deployed contracts already existing in the network where the tests are executed ([#2073](https://github.com/ethereum/execution-spec-tests/pull/2073)). + +### 📋 Misc + +- ✨ Add pypy3.11 support ([#1854](https://github.com/ethereum/execution-spec-tests/pull/1854)). +- 🔀 Use only relative imports in `tests/` directory ([#1848](https://github.com/ethereum/execution-spec-tests/pull/1848)). +- 🔀 Convert absolute imports to relative imports in `src/` directory for better code maintainability ([#1907](https://github.com/ethereum/execution-spec-tests/pull/1907)). +- 🔀 Misc. doc updates, including a navigation footer ([#1846](https://github.com/ethereum/execution-spec-tests/pull/1846)). +- 🔀 Remove Python 3.10 support ([#1808](https://github.com/ethereum/execution-spec-tests/pull/1808)). +- 🔀 Modernize codebase with Python 3.11 language features ([#1812](https://github.com/ethereum/execution-spec-tests/pull/1812)). +- ✨ Add changelog formatting validation to CI to ensure consistent punctuation in bullet points [#1691](https://github.com/ethereum/execution-spec-tests/pull/1691). +- ✨ Added the [EIP checklist template](https://eest.ethereum.org/main/writing_tests/checklist_templates/eip_testing_checklist_template/) that serves as a reference to achieve better coverage when implementing tests for new EIPs ([#1327](https://github.com/ethereum/execution-spec-tests/pull/1327)). +- ✨ Added [Post-Mortems of Missed Test Scenarios](https://eest.ethereum.org/main/writing_tests/post_mortems/) to the documentation that serves as a reference list of all cases that were missed during the test implementation phase of a new EIP, and includes the steps taken in order to prevent similar test cases to be missed in the future ([#1327](https://github.com/ethereum/execution-spec-tests/pull/1327)). +- ✨ Add documentation "Running Tests" that explains the different methods available to run EEST tests and reference guides for running `consume` and `hive`: ([#1172](https://github.com/ethereum/execution-spec-tests/pull/1172)). +- ✨ Added a new `eest` sub-command, `eest info`, to easily print a cloned EEST repository's version and the versions of relevant tools, e.g., `python`, `uv` ([#1621](https://github.com/ethereum/execution-spec-tests/pull/1621)). +- ✨ Add `CONTRIBUTING.md` for execution-spec-tests and improve coding standards documentation ([#1604](https://github.com/ethereum/execution-spec-tests/pull/1604)). +- ✨ Add `CLAUDE.md` to help working in @ethereum/execution-spec-tests with [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) ([#1749](https://github.com/ethereum/execution-spec-tests/pull/1749)). +- ✨ Use `codespell` instead of `pyspelling` to spell-check python and markdown sources ([#1715](https://github.com/ethereum/execution-spec-tests/pull/1715)). +- 🔀 Updated from pytest 7 to [pytest 8](https://docs.pytest.org/en/stable/changelog.html#features-and-improvements), benefits include improved type hinting and hook typing, stricter mark handling, and clearer error messages for plugin and metadata development ([#1433](https://github.com/ethereum/execution-spec-tests/pull/1433)). +- 🐞 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 `extract_config` command to extract genesis files used to launch clients in hive ([#1740](https://github.com/ethereum/execution-spec-tests/pull/1740)). +- ✨ 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)). +- 🔀 Add macOS hive development mode workaround to the docs [#1786](https://github.com/ethereum/execution-spec-tests/pull/1786). +- 🔀 Refactor and clean up of exceptions including EOF exceptions within client specific mappers [#1803](https://github.com/ethereum/execution-spec-tests/pull/1803). +- 🔀 Rename `tests/zkevm/` to `tests/benchmark/` and replace the `zkevm` pytest mark with `benchmark` [#1804](https://github.com/ethereum/execution-spec-tests/pull/1804). +- 🔀 Add fixture comparison check to optimize coverage workflow in CI ([#1833](https://github.com/ethereum/execution-spec-tests/pull/1833)). +- 🔀 Move `TransactionType` enum from test file to proper module location in `ethereum_test_types.transaction_types` for better code organization and reusability ([#1763](https://github.com/ethereum/execution-spec-tests/pull/1673)). +- ✨ Opcode classes now validate keyword arguments and raise `ValueError` with clear error messages ([#1739](https://github.com/ethereum/execution-spec-tests/pull/1739), [#1856](https://github.com/ethereum/execution-spec-tests/pull/1856)). +- ✨ All commands (`fill`, `consume`, `execute`) now work without having to clone the repository, e.g. `uv run --with git+https://github.com/ethereum/execution-spec-tests.git consume` now works from any folder ([#1863](https://github.com/ethereum/execution-spec-tests/pull/1863)). +- 🔀 Move Prague to stable and Osaka to develop ([#1573](https://github.com/ethereum/execution-spec-tests/pull/1573)). +- ✨ Add a `pytest.mark.with_all_typed_transactions` marker that creates default typed transactions for each `tx_type` supported by the current `fork` ([#1890](https://github.com/ethereum/execution-spec-tests/pull/1890)). +- ✨ Add basic support for ``Amsterdam`` fork in order to begin testing Glamsterdam ([#2069](https://github.com/ethereum/execution-spec-tests/pull/2069)). +- ✨ [EIP-7928](https://eips.ethereum.org/EIPS/eip-7928): Add initial framework support for `Block Level Access Lists (BAL)` testing for Amsterdam ([#2067](https://github.com/ethereum/execution-spec-tests/pull/2067)). + +### 🧪 Test Cases + +- ✨ [BloatNet](https://bloatnet.info)/Multidimensional Metering: Add benchmarks to be used as part of the BloatNet project and also for Multidimensional Metering. +- ✨ [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): Add additional test cases for modular comparison. +- 🔀 Refactored `BLOBHASH` opcode context tests to use the `pre_alloc` plugin in order to avoid contract and EOA address collisions ([#1637](https://github.com/ethereum/execution-spec-tests/pull/1637)). +- 🔀 Refactored `SELFDESTRUCT` opcode collision tests to use the `pre_alloc` plugin in order to avoid contract and EOA address collisions ([#1643](https://github.com/ethereum/execution-spec-tests/pull/1643)). +- ✨ EIP-7594: Sanity test cases to send blob transactions and verify `engine_getBlobsVX` using the `execute` command ([#1644](https://github.com/ethereum/execution-spec-tests/pull/1644),[#1884](https://github.com/ethereum/execution-spec-tests/pull/1884)). +- 🔀 Refactored EIP-145 static tests into python ([#1683](https://github.com/ethereum/execution-spec-tests/pull/1683)). +- ✨ EIP-7823, EIP-7883: Add test cases for ModExp precompile gas-cost updates and input limits on Osaka ([#1579](https://github.com/ethereum/execution-spec-tests/pull/1579), [#1729](https://github.com/ethereum/execution-spec-tests/pull/1729), [#1881](https://github.com/ethereum/execution-spec-tests/pull/1881)). +- ✨ [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825): Add test cases for the transaction gas limit of 2^24 gas ([#1711](https://github.com/ethereum/execution-spec-tests/pull/1711), [#1882](https://github.com/ethereum/execution-spec-tests/pull/1882)). +- ✨ [EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): add test cases for `P256VERIFY` precompile to support secp256r1 curve [#1670](https://github.com/ethereum/execution-spec-tests/pull/1670). +- ✨ Introduce blockchain tests for benchmark to cover the scenario of pure ether transfers [#1742](https://github.com/ethereum/execution-spec-tests/pull/1742). +- ✨ [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934): Add test cases for the block RLP max limit of 10MiB ([#1730](https://github.com/ethereum/execution-spec-tests/pull/1730)). +- ✨ [EIP-7939](https://eips.ethereum.org/EIPS/eip-7939): Add count leading zeros (CLZ) opcode tests for Osaka ([#1733](https://github.com/ethereum/execution-spec-tests/pull/1733)). +- ✨ [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934): Add additional test cases for block RLP max limit with all typed transactions and for a log-creating transactions ([#1890](https://github.com/ethereum/execution-spec-tests/pull/1890)). +- ✨ [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825): Pre-Osaka tests have been updated to either (1) dynamically adapt to the transaction gas limit cap, or (2) reduce overall gas consumption to fit the new limit ([#1924](https://github.com/ethereum/EIPs/pull/1924), [#1928](https://github.com/ethereum/EIPs/pull/1928), [#1980](https://github.com/ethereum/EIPs/pull/1980)). +- ✨ [EIP-7918](https://eips.ethereum.org/EIPS/eip-7918): Blob base fee bounded by execution cost test cases (initial), includes some adjustments to [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) tests ([#1685](https://github.com/ethereum/execution-spec-tests/pull/1685)). +- 🔀 Adds the max blob transaction limit to the tests including updates to [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) for Osaka ([#1884](https://github.com/ethereum/execution-spec-tests/pull/1884)). +- 🐞 Fix issues when filling block rlp size limit tests with ``--generate-pre-alloc-groups`` ([#1989](https://github.com/ethereum/execution-spec-tests/pull/1989)). +- ✨ [EIP-7928](https://eips.ethereum.org/EIPS/eip-7928): Add test cases for `Block Level Access Lists (BAL)` to Amsterdam ([#2067](https://github.com/ethereum/execution-spec-tests/pull/2067)). +- 🐞 Fix issues with `Block Level Access Lists (BAL)` tests for Amsterdam ([#2121](https://github.com/ethereum/execution-spec-tests/pull/2121)). + +## [v4.5.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.5.0) - 2025-05-14 + +### 💥 Breaking Change + +#### EOF removed from Osaka + +Following ["Interop Testing Call 34"](https://github.com/ethereum/pm/issues/1499) and the procedural EIPs [PR](https://github.com/ethereum/EIPs/pull/9703) the decision to remove EOF from Osaka was made. + +To accommodate EOF testing for the interim within EEST, its tests have migrated to a new `tests/unscheduled` folder. This folder will now contain tests for features that are not yet CFI'd in any fork. When EOF is CFI'd for a fork in the future, all tests will be moved from unscheduled to the respective future fork folder. + +A new fork `EOFv1` has additionally been created to fill and consume EOF related fixtures. Client tests fillers such as `evmone` (and client consumers) will now need to use this fork name. + +### 🛠️ Framework + +- ✨ Add an empty account function for usage within fill and execute ([#1482](https://github.com/ethereum/execution-spec-tests/pull/1482)). +- ✨ Added `TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST` exception to specifically catch the case where the intrinsic gas cost is insufficient due to the data floor gas cost ([#1582](https://github.com/ethereum/execution-spec-tests/pull/1582)). + +### 📋 Misc + +- ✨ Engine API updates for Osaka, add `get_blobs` rpc method ([#1510](https://github.com/ethereum/execution-spec-tests/pull/1510)). +- ✨ The EIP Version checker has been moved from `fill` and `execute` to it's own command-line tool `check_eip_versions` that gets ran daily as a Github Action ([#1537](https://github.com/ethereum/execution-spec-tests/pull/1537)). +- 🔀 Add new `tests/unscheduled` folder, move EOF from Osaka to unscheduled, add `EOFv1` fork name for EOF tests ([#1507](https://github.com/ethereum/execution-spec-tests/pull/1507)). +- ✨ CI features now contain an optional field to skip them from EEST full releases, `benchmark` and EOF features are now feature only ([#1596](https://github.com/ethereum/execution-spec-tests/pull/1596)). +- 🐞 Don't attempt to install `solc` via `solc-select` on ARM (official Linux ARM builds of `solc` are not available at the time of writing, cf [ethereum/solidity#11351](https://github.com/ethereum/solidity/issues/11351)) and add a version sanity check ([#1556](https://github.com/ethereum/execution-spec-tests/pull/1556)). + +### 🧪 Test Cases + +- 🔀 Automatically apply the `benchmark` marker to all tests under `./tests/benchmark/` and `./tests/prague/eip2537_bls_12_381_precompiles/` via conftest configuration ([#1534](https://github.com/ethereum/execution-spec-tests/pull/1534)). +- ✨ Port [calldataload](https://github.com/ethereum/tests/blob/ae4791077e8fcf716136e70fe8392f1a1f1495fb/src/GeneralStateTestsFiller/VMTests/vmTests/calldatacopyFiller.yml) and [calldatasize](https://github.com/ethereum/tests/blob/81862e4848585a438d64f911a19b3825f0f4cd95/src/GeneralStateTestsFiller/VMTests/vmTests/calldatasizeFiller.yml) tests ([#1236](https://github.com/ethereum/execution-spec-tests/pull/1236)). + +## [v4.4.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.4.0) - 2025-04-29 + +### 💥 Breaking Change + +#### `fixtures_static` + +A new fixture tarball has been included in this release: `fixtures_static.tar.gz`. + +This tarball contains all tests inside of [`./tests/static`](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static), which at this point only contains all tests copied from [`GeneralStateTests` in `ethereum/tests@7dc757ec132e372b6178a016b91f4c639f366c02`](https://github.com/ethereum/tests/tree/7dc757ec132e372b6178a016b91f4c639f366c02/src/GeneralStateTestsFiller). + +The tests have been filled using the new static test filler introduced in [#1336](https://github.com/ethereum/execution-spec-tests/pull/1336), and enhanced in [#1362](https://github.com/ethereum/execution-spec-tests/pull/1362) and [#1439](https://github.com/ethereum/execution-spec-tests/pull/1439). + +Users can expect that all tests currently living in [ethereum/tests](https://github.com/ethereum/tests/tree/develop/src) should eventually make its way into [`./tests/static`](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static) and can rely that these tests, filled for new forks even, will be included in `fixtures_static.tar.gz`. + +#### `fixtures_benchmark` + +Another new fixture tarball has been included in this release: `fixtures_benchmark.tar.gz`. + +Includes tests that are tailored specifically to test the execution layer proof generators. + +### 🛠️ Framework + +#### `fill` + +- 🐞 Fix the reported fixture source URLs for the case of auto-generated tests ([#1488](https://github.com/ethereum/execution-spec-tests/pull/1488)). + +#### `consume` + +- 🐞 Fix the Hive commands used to reproduce test executions that are displayed in test descriptions in the Hive UI ([#1494](https://github.com/ethereum/execution-spec-tests/pull/1494)). +- 🐞 Fix consume direct fails for geth blockchain tests ([#1502](https://github.com/ethereum/execution-spec-tests/pull/1502)). + +### 📋 Misc + +### 🧪 Test Cases + +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Test that DELEGATECALL to a 7702 target works as intended ([#1485](https://github.com/ethereum/execution-spec-tests/pull/1485)). +- ✨ [EIP-2573](https://eips.ethereum.org/EIPS/eip-2537): Includes a BLS12 point generator, alongside additional coverage many of the precompiles ([#1350](https://github.com/ethereum/execution-spec-tests/pull/1350)), ([#1505](https://github.com/ethereum/execution-spec-tests/pull/1505)). +- ✨ Add all [`GeneralStateTests` from `ethereum/tests`](https://github.com/ethereum/tests/tree/7dc757ec132e372b6178a016b91f4c639f366c02/src/GeneralStateTestsFiller) to `execution-spec-tests` located now at [tests/static/state_tests](https://github.com/ethereum/execution-spec-tests/tree/main/tests/static/state_tests) ([#1442](https://github.com/ethereum/execution-spec-tests/pull/1442)). +- ✨ [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929): Test that precompile addresses are cold/warm depending on the fork they are activated ([#1495](https://github.com/ethereum/execution-spec-tests/pull/1495)). + +## [v4.3.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.3.0) - 2025-04-18 + +### 💥 Breaking Change + +#### Consume engine strict exception checking + +`consume engine` now checks exceptions returned by the execution clients in their Engine API responses, specifically in the `validationError`field of the `engine_newPayloadVX` method. + +While not strictly a breaking change since tests will continue to run normally, failures are expected if a client modifies their exception messages. + +This feature can be disabled by using `--disable-strict-exception-matching` for specific clients or forks. + +### 🛠️ Framework + +#### `fill` + +- ✨ The `static_filler` plug-in now has support for static state tests (from [GeneralStateTests](https://github.com/ethereum/tests/tree/develop/src/GeneralStateTestsFiller)) ([#1362](https://github.com/ethereum/execution-spec-tests/pull/1362)). +- ✨ Introduce `pytest.mark.exception_test` to mark tests that contain an invalid transaction or block ([#1436](https://github.com/ethereum/execution-spec-tests/pull/1436)). +- 🐞 Fix `DeprecationWarning: Pickle, copy, and deepcopy support will be removed from itertools in Python 3.14.` by avoiding use `itertools` object in the spec `BaseTest` pydantic model ([#1414](https://github.com/ethereum/execution-spec-tests/pull/1414)). +- ✨ An optional configuration flag to override the maximum gas limit in the environment for filling or executing tests is now available. The `--block-gas-limit` flag overrides the default block gas limit during filling. The `--transaction-gas-limit` flag overrides the maximum for transactions during execution. ([#1470](https://github.com/ethereum/execution-spec-tests/pull/1470)). + +#### `consume` + +- 🐞 Fix fixture tarball downloading with regular, non-Github release URLS and with numerical versions in regular release specs, e.g., `stable@v4.2.0` ([#1437](https://github.com/ethereum/execution-spec-tests/pull/1437)). +- ✨ `consume engine` now has strict exception mapping enabled by default ([#1416](https://github.com/ethereum/execution-spec-tests/pull/1416)). + +#### Tools + +- 🔀 `generate_system_contract_deploy_test` test generator has been updated to handle system contracts that are not allowed to be absent when the fork happens ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). +- ✨ Add `generate_system_contract_error_test` to generate tests on system contracts that invalidate a block in case of error ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). + +#### Exceptions + +- ✨ `BlockException.SYSTEM_CONTRACT_EMPTY`: Raised when a required system contract was not found in the state by the time it was due to execution with a system transaction call ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). +- ✨ `BlockException.SYSTEM_CONTRACT_CALL_FAILED`: Raised when a system contract call made by a system transaction fails ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). +- ✨ `BlockException.INVALID_BLOCK_HASH`: Raised when the calculated block hash does not match the expectation (Currently only during Engine API calls) ([#1416](https://github.com/ethereum/execution-spec-tests/pull/1416)). +- ✨ `BlockException.INVALID_VERSIONED_HASHES`: Raised when a discrepancy is found between versioned hashes in the payload and the ones found in the transactions ([#1416](https://github.com/ethereum/execution-spec-tests/pull/1416)). + +### 🧪 Test Cases + +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Test precompile case in same transaction as delegation without extra gas in case of precompile code execution; parametrize all call opcodes in existing precompile test ([#1431](https://github.com/ethereum/execution-spec-tests/pull/1431)). +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Add invalid nonce authorizations tests for the case of multiple signers when the sender's nonce gets increased ([#1441](https://github.com/ethereum/execution-spec-tests/pull/1441)). +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Add a test that verifies that set code transactions are correctly rejected before Prague activation ([#1463](https://github.com/ethereum/execution-spec-tests/pull/1463)). +- ✨ [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623): Additionally parametrize transaction validity tests with the `to` set to an EOA account (previously only contracts) ([#1422](https://github.com/ethereum/execution-spec-tests/pull/1422)). +- ✨ [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Add EIP-7251 test cases for modified consolidations contract that allows more consolidations ([#1465](https://github.com/ethereum/execution-spec-tests/pull/1465)). +- ✨ [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Add extra deposit request edge cases, sending eth to the deposit contract while sending a deposit request ([#1467](https://github.com/ethereum/execution-spec-tests/pull/1467)). +- ✨ [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Add cases for deposit log layout and other topics (ERC-20) transfer ([#1371](https://github.com/ethereum/execution-spec-tests/pull/1371)). +- ✨ [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Remove pytest skips for consolidation request cases ([#1449](https://github.com/ethereum/execution-spec-tests/pull/1449)). +- ✨ [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Add cases to verify behavior of contracts missing at fork ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). +- ✨ [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Add cases to verify behavior of system contract errors invalidating a block ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). +- 🔀 Remove [EIP-7698](https://eips.ethereum.org/EIPS/eip-7698): EIP has been removed and the tests related to it have also been removed, while preserving a subset of the tests to verify that functionality is removed in clients ([#1451](https://github.com/ethereum/execution-spec-tests/pull/1451)). + +### 📋 Misc + +- 🐞 Configure `markdownlint` to expect an indent of 4 with unordered lists (otherwise HTML documentation is rendered incorrectly, [#1460](https://github.com/ethereum/execution-spec-tests/pull/1460)). +- 🔀 Update `eels_resolutions.json` to point to temporary commit `bb0eb750d643ced0ebf5dec732cdd23558d0b7f2`, which is based on `forks/prague` branch, commit `d9a7ee24db359aacecd636349b4f3ac95a4a6e71`, with PRs , and merged ([#1394](https://github.com/ethereum/execution-spec-tests/pull/1394)). + +## [v4.2.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.2.0) - 2025-04-08 + +**Note**: Although not a breaking change, `consume` users should delete the cache directory (typically located at `~/.cache/ethereum-execution-spec-tests`) used to store downloaded fixture release tarballs. This release adds support for [ethereum/tests](https://github.com/ethereum/tests) and [ethereum/legacytests](https://github.com/ethereum/legacytests) fixture release downloads and the structure of the cache directory has been updated to accommodate this change. + +To try this feature: + +```shell +consume direct --input=https://github.com/ethereum/tests/releases/download/v17.0/fixtures_blockchain_tests.tgz +``` + +To determine the cache directory location, see the `--cache-folder` entry from the command: + +```shell +consume cache --help +``` + +### 💥 Breaking Change + +### 🛠️ Framework + +#### `consume` + +- ✨ Add support for [ethereum/tests](https://github.com/ethereum/tests) and [ethereum/legacytests](https://github.com/ethereum/legacytests) release tarball download via URL to the `--input` flag of `consume` commands ([#1306](https://github.com/ethereum/execution-spec-tests/pull/1306)). +- ✨ Add support for Nethermind's `nethtest` command to `consume direct` ([#1250](https://github.com/ethereum/execution-spec-tests/pull/1250)). +- ✨ Allow filtering of test cases by fork via pytest marks (e.g., `-m "Cancun or Prague"`) ([#1304](https://github.com/ethereum/execution-spec-tests/pull/1304), [#1318](https://github.com/ethereum/execution-spec-tests/pull/1318)). +- ✨ Allow filtering of test cases by fixture format via pytest marks (e.g., `-m blockchain_test`) ([#1314](https://github.com/ethereum/execution-spec-tests/pull/1314)). +- ✨ Add top-level entries `forks` and `fixture_formats` to the index file that list all the forks and fixture formats used in the indexed fixtures ([#1318](https://github.com/ethereum/execution-spec-tests/pull/1318)). +- ✨ Enable logging from `consume` commands ([#1361](https://github.com/ethereum/execution-spec-tests/pull/1361)). +- ✨ Propagate stdout and stderr (including logs) captured during test execution to the Hive test result ([#1361](https://github.com/ethereum/execution-spec-tests/pull/1361)). +- 🐞 Don't parametrize tests for unsupported fixture formats; improve `consume` test collection ([#1315](https://github.com/ethereum/execution-spec-tests/pull/1315)). +- 🐞 Fix the the hive command printed in test reports to reproduce tests in isolation by prefixing the `--sim.limit` flag value with `id:` ([#1333](https://github.com/ethereum/execution-spec-tests/pull/1333)). +- 🐞 Improve index generation of [ethereum/tests](https://github.com/ethereum/tests) fixtures: Allow generation at any directory level and include `generatedTestHash` in the index file for the `fixture_hash` ([#1303](https://github.com/ethereum/execution-spec-tests/pull/1303)). +- 🐞 Fix loading of [ethereum/tests](https://github.com/ethereum/tests) and [ethereum/legacytests](https://github.com/ethereum/legacytests) fixtures for the case of mixed `0x0` and `0x1` transaction types in multi-index (`data`, `gas`, `value`) state test fixtures ([#1330](https://github.com/ethereum/execution-spec-tests/pull/1330)). +- ✨ Add Osaka to the hive ruleset, includes a small ruleset refactor ([#1355](https://github.com/ethereum/execution-spec-tests/pull/1355)). + +#### `fill` + +- 🐞 Fix `--fork/from/until` for transition forks when using `fill` [#1311](https://github.com/ethereum/execution-spec-tests/pull/1311). +- 🐞 Fix the node id for state tests marked by transition forks ([#1313](https://github.com/ethereum/execution-spec-tests/pull/1313)). +- ✨ Add `static_filler` plug-in which allows to fill static YAML and JSON tests (from [ethereum/tests](https://github.com/ethereum/tests)) by adding flag `--fill-static-tests` to `uv run fill` ([#1336](https://github.com/ethereum/execution-spec-tests/pull/1336)). + +#### `execute` + +- 🔀 Test IDs have changed to include the name of the test spec where the test came from (e.g. `state_test`, `blockchain_test`, etc) ([#1367](https://github.com/ethereum/execution-spec-tests/pull/1367)). +- ✨ Markers can now be used to execute only tests from a specific test spec type (e.g. `-m state_test`, `-m blockchain_test`, etc) ([#1367](https://github.com/ethereum/execution-spec-tests/pull/1367)). + +### 📋 Misc + +- 🔀 Bump the version of `execution-specs` used by the framework to the package [`ethereum-execution==1.17.0rc6.dev1`](https://pypi.org/project/ethereum-execution/1.17.0rc6.dev1/); bump the version used for test fixture generation for forks < Prague to current `execution-specs` master, [fa847a0](https://github.com/ethereum/execution-specs/commit/fa847a0e48309debee8edc510ceddb2fd5db2f2e) ([#1310](https://github.com/ethereum/execution-spec-tests/pull/1310)). +- 🐞 Init `TransitionTool` in `GethTransitionTool` ([#1276](https://github.com/ethereum/execution-spec-tests/pull/1276)). +- 🔀 Refactored RLP encoding of test objects to allow automatic generation of tests ([#1359](https://github.com/ethereum/execution-spec-tests/pull/1359)). +- ✨ Document how to manage `execution-spec-tests` package dependencies ([#1388](https://github.com/ethereum/execution-spec-tests/pull/1388)). + +#### Packaging + +- 🐞 Fix `eest make test` when `ethereum-execution-spec-tests` is installed as a package ([#1342](https://github.com/ethereum/execution-spec-tests/pull/1342)). +- 🔀 Pin `setuptools` and `wheel` in `[build-system]`, bump `trie>=3.1` and remove `setuptools` from package dependencies ([#1345](https://github.com/ethereum/execution-spec-tests/pull/1345), [#1351](https://github.com/ethereum/execution-spec-tests/pull/1351)). + +### 🧪 Test Cases + +- ✨ Add additional test coverage for EIP-152 Blake2 precompiles ([#1244](https://github.com/ethereum/execution-spec-tests/pull/1244)). Refactor to add variables for spec constants and common fixture code. ([#1395](https://github.com/ethereum/execution-spec-tests/pull/1395)), ([#1405](https://github.com/ethereum/execution-spec-tests/pull/1405)). +- ✨ Add EIP-7702 incorrect-rlp-encoding tests ([#1347](https://github.com/ethereum/execution-spec-tests/pull/1347)). +- ✨ Add EIP-2935 tests for all call opcodes ([#1379](https://github.com/ethereum/execution-spec-tests/pull/1379)). +- ✨ Add more tests for EIP-7702: max-fee-per-gas verification, delegation-designation as initcode tests ([#1372](https://github.com/ethereum/execution-spec-tests/pull/1372)). +- ✨ Add converted Identity precompile tests ([#1344](https://github.com/ethereum/execution-spec-tests/pull/1344)). + +## [v4.1.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.1.0) - 2025-03-11 + +### 💥 Breaking Changes + +The following changes may be potentially breaking (all clients were tested with these changes with the state test format, but not the blockchain test format): + +- 💥 Add a `yParity` field (that duplicates `v`) to transaction authorization tuples in fixture formats to have fields that conform to EIP-7702 spec, resolves [erigontech/erigon#14073](https://github.com/erigontech/erigon/issues/14073) ([#1286](https://github.com/ethereum/execution-spec-tests/pull/1286)). +- 💥 Rename the recently introduced `_info` field `fixture_format` to `fixture-format` for consistency [#1295](https://github.com/ethereum/execution-spec-tests/pull/1295). + +### 🛠️ Framework + +- 🔀 Make `BaseFixture` able to parse any fixture format such as `BlockchainFixture` ([#1210](https://github.com/ethereum/execution-spec-tests/pull/1210)). +- ✨ Blockchain and Blockchain-Engine tests now have a marker to specify that they were generated from a state test, which can be used with `-m blockchain_test_from_state_test` and `-m blockchain_test_engine_from_state_test` respectively ([#1220](https://github.com/ethereum/execution-spec-tests/pull/1220)). +- ✨ Blockchain and Blockchain-Engine tests that were generated from a state test now have `blockchain_test_from_state_test` or `blockchain_test_engine_from_state_test` as part of their test IDs ([#1220](https://github.com/ethereum/execution-spec-tests/pull/1220)). +- 🔀 Refactor `ethereum_test_fixtures` and `ethereum_clis` to create `FixtureConsumer` and `FixtureConsumerTool` classes which abstract away the consumption process used by `consume direct` ([#935](https://github.com/ethereum/execution-spec-tests/pull/935)). +- ✨ Allow `consume direct --collect-only` without specifying a fixture consumer binary on the command-line ([#1237](https://github.com/ethereum/execution-spec-tests/pull/1237)). +- ✨ Allow `fill --collect-only` without the need for existence of the folder `./fixtures`. +- ✨ Report the (resolved) fixture tarball URL and local fixture cache directory when `consume`'s `--input` flag is a release spec or URL ([#1239](https://github.com/ethereum/execution-spec-tests/pull/1239)). +- ✨ EOF Container validation tests (`eof_test`) now generate container deployment state tests, by wrapping the EOF container in an init-container and sending a deploy transaction ([#783](https://github.com/ethereum/execution-spec-tests/pull/783), [#1233](https://github.com/ethereum/execution-spec-tests/pull/1233)). +- ✨ Use regexes for Hive's `--sim.limit` argument and don't use xdist if `--sim.parallelism==1` in the `eest/consume-rlp` and `eest/consume-rlp` simulators ([#1220](https://github.com/ethereum/execution-spec-tests/pull/1220)). +- 🐞 Register generated test markers, e.g., `blockchain_test_from_state_test`, to prevent test session warnings ([#1238](https://github.com/ethereum/execution-spec-tests/pull/1238), [#1245](https://github.com/ethereum/execution-spec-tests/pull/1245)). +- 🐞 Zero-pad `Environment` fields passed to `t8n` tools as required by `evmone-t8n` ([#1268](https://github.com/ethereum/execution-spec-tests/pull/1268)). + +### 📋 Misc + +- ✨ Add a guide to the docs for porting tests from `ethereum/tests` to EEST ([#1165](https://github.com/ethereum/execution-spec-tests/pull/1165)). +- ✨ Improve the `uv run eest make test` interactive CLI to enable creation of new test modules within existing test sub-folders ([#1241](https://github.com/ethereum/execution-spec-tests/pull/1241)). +- ✨ Update `mypy` to latest release `>=1.15.0,<1.16` ([#1209](https://github.com/ethereum/execution-spec-tests/pull/1209)). +- 🐞 Bug fix for filling with EELS for certain Python versions due to an issue with CPython ([#1231](https://github.com/ethereum/execution-spec-tests/pull/1231)). +- 🐞 Fix HTML site deployment due to the site's index file exceeding Github's max file size limit ([#1292](https://github.com/ethereum/execution-spec-tests/pull/1292)). +- ✨ Update the build fixtures workflow to use multiple self-hosted runners, remove `pectra-devnet-6` feature build ([#1296](https://github.com/ethereum/execution-spec-tests/pull/1296)). + +### 🧪 Test Cases + +- ✨ Add gas cost of delegation access in CALL opcode ([#1208](https://github.com/ethereum/execution-spec-tests/pull/1208)). +- ✨ Add EIP-7698 failed nonce and short data tests ([#1211](https://github.com/ethereum/execution-spec-tests/pull/1211)). +- ✨ Add EIP-2537 additional pairing precompile tests cases, and then update all BLS12 test vectors ([#1275](https://github.com/ethereum/execution-spec-tests/pull/1275), [#1289](https://github.com/ethereum/execution-spec-tests/pull/1289)). +- ✨ Add EIP-7685 and EIP-7002 test cases for additional request type combinations and modified withdrawal contract that allows more withdrawals ([#1340](https://github.com/ethereum/execution-spec-tests/pull/1340)). +- ✨ Add test cases for EIP-152 Blake2 and Identity precompiles ([#1244](https://github.com/ethereum/execution-spec-tests/pull/1244)). + +## [v4.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v4.0.0) - 2025-02-14 - 💕 + +### 📁 Fixture Releases + +- 🔀 Initially we moved old fork configured tests within stable and develop fixture releases to a separate legacy release ([#788](https://github.com/ethereum/execution-spec-tests/pull/788)). +- 🔀 This was later reverted after some client teams preferred to keep them in all in the same releases ([#1053](https://github.com/ethereum/execution-spec-tests/pull/1053)). + +### 💥 Breaking Change + +- ✨ Use uv for package management replacing pip ([#777](https://github.com/ethereum/execution-spec-tests/pull/777)). +- ✨ Ruff now replaces Flake8, Isort and Black resulting in significant changes to the entire code base including its usage ([#922](https://github.com/ethereum/execution-spec-tests/pull/922)). +- 🔀 Fill test fixtures using EELS by default. EEST now uses the [`ethereum-specs-evm-resolver`](https://github.com/petertdavies/ethereum-spec-evm-resolver) with the EELS daemon ([#792](https://github.com/ethereum/execution-spec-tests/pull/792)). +- 🔀 The EOF fixture format contained in `eof_tests` may now contain multiple exceptions in the `"exception"` field in the form of a pipe (`|`) separated string ([#759](https://github.com/ethereum/execution-spec-tests/pull/759)). +- 🔀 `state_test`, `blockchain_test` and `blockchain_test_engine` fixtures now contain a `config` field, which contains an object that contains a `blobSchedule` field. On the `blockchain_test` and `blockchain_test_engine` fixtures, the object also contains a duplicate of the `network` root field. The root's `network` field will be eventually deprecated ([#1040](https://github.com/ethereum/execution-spec-tests/pull/1040)). +- 🔀 `latest-stable-release` and `latest-develop-release` keywords for the `--input` flag in consume commands have been replaced with `stable@latest` and `develop@latest` respectively ([#1044](https://github.com/ethereum/execution-spec-tests/pull/1044)). + +### 🛠️ Framework + +- ✨ Execute command added to run existing tests in live networks ([#](https://github.com/ethereum/execution-spec-tests/pull/1157)). +- 🐞 Fixed consume hive commands from spawning different hive test suites during the same test execution when using xdist ([#712](https://github.com/ethereum/execution-spec-tests/pull/712)). +- ✨ `consume hive` command is now available to run all types of hive tests ([#712](https://github.com/ethereum/execution-spec-tests/pull/712)). +- ✨ Generated fixtures now contain the test index `index.json` by default ([#716](https://github.com/ethereum/execution-spec-tests/pull/716)). +- ✨ A metadata folder `.meta/` now stores all fixture metadata files by default ([#721](https://github.com/ethereum/execution-spec-tests/pull/721)). +- 🐞 Fixed `fill` command index generation issue due to concurrency ([#725](https://github.com/ethereum/execution-spec-tests/pull/725)). +- ✨ Added `with_all_evm_code_types`, `with_all_call_opcodes` and `with_all_create_opcodes` markers, which allow automatic parametrization of tests to EOF ([#610](https://github.com/ethereum/execution-spec-tests/pull/610), [#739](https://github.com/ethereum/execution-spec-tests/pull/739)). +- ✨ Added `with_all_system_contracts` marker, which helps parametrize tests with all contracts that affect the chain on a system level ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). +- ✨ Code generators `Conditional` and `Switch` now support EOF by adding parameter `evm_code_type` ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). +- ✨ `fill` command now supports parameter `--evm-code-type` that can be (currently) set to `legacy` or `eof_v1` to force all test smart contracts to deployed in normal or in EOF containers ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). +- 🐞 Fixed fixture index generation on EOF tests ([#728](https://github.com/ethereum/execution-spec-tests/pull/728)). +- 🐞 Fixes consume genesis mismatch exception for hive based simulators ([#734](https://github.com/ethereum/execution-spec-tests/pull/734)). +- ✨ Adds reproducible consume commands to hiveview ([#717](https://github.com/ethereum/execution-spec-tests/pull/717)). +- 💥 Added multiple exceptions to the EOF fixture format ([#759](https://github.com/ethereum/execution-spec-tests/pull/759)). +- ✨ Added optional parameter to all `with_all_*` markers to specify a lambda function that filters the parametrized values ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). +- ✨ Added [`extend_with_defaults` utility function](https://eest.ethereum.org/main/writing_tests/writing_a_new_test/#ethereum_test_tools.utility.pytest.extend_with_defaults), which helps extend test case parameter sets with default values. `@pytest.mark.parametrize` ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). +- ✨ Added `Container.Init` to `ethereum_test_types.EOF.V1` package, which allows generation of an EOF init container more easily ([#739](https://github.com/ethereum/execution-spec-tests/pull/739)). +- ✨ Introduce method valid_opcodes() to the fork class ([#748](https://github.com/ethereum/execution-spec-tests/pull/748)). +- 🐞 Fixed `consume` exit code return values, ensuring that pytest's return value is correctly propagated to the shell. This allows the shell to accurately reflect the test results (e.g., failures) based on the pytest exit code ([#765](https://github.com/ethereum/execution-spec-tests/pull/765)). +- ✨ Added a new flag `--solc-version` to the `fill` command, which allows the user to specify the version of the Solidity compiler to use when compiling Yul source code; this version will now be automatically downloaded by `fill` via [`solc-select`](https://github.com/crytic/solc-select) ([#772](https://github.com/ethereum/execution-spec-tests/pull/772)). +- 🐞 Fix usage of multiple `@pytest.mark.with_all*` markers which shared parameters, such as `with_all_call_opcodes` and `with_all_create_opcodes` which shared `evm_code_type`, and now only parametrize compatible values ([#762](https://github.com/ethereum/execution-spec-tests/pull/762)). +- ✨ Added `selector` and `marks` fields to all `@pytest.mark.with_all*` markers, which allows passing lambda functions to select or mark specific parametrized values (see [documentation](https://eest.ethereum.org/main/writing_tests/test_markers/#covariant-marker-keyword-arguments) for more information) ([#762](https://github.com/ethereum/execution-spec-tests/pull/762)). +- ✨ Improves consume input flags for develop and stable fixture releases, fixes `--help` flag for consume ([#745](https://github.com/ethereum/execution-spec-tests/pull/745)). +- 🔀 Return exit-code from `consume` commands ([#766](https://github.com/ethereum/execution-spec-tests/pull/766)). +- 🔀 Remove duplicate EOF container tests, automatically check for duplicates ([#800](https://github.com/ethereum/execution-spec-tests/pull/800)). +- 🔀 Fix DATALOAD `pushed_stack_items` calculation ([#784](https://github.com/ethereum/execution-spec-tests/pull/784)). +- ✨ Add `evm_bytes` rename and print asm ([#844](https://github.com/ethereum/execution-spec-tests/pull/844)). +- 🔀 Use the `session_temp_folder` introduced in #824 ([#845](https://github.com/ethereum/execution-spec-tests/pull/845)). +- 🐞 Don't treat eels resolutions as a fixture ([#878](https://github.com/ethereum/execution-spec-tests/pull/878)). +- ✨ Emphasize that no tests were executed during a fill pytest session ([#887](https://github.com/ethereum/execution-spec-tests/pull/887)). +- 🔀 Move generic code from TransitionTool to a new generic base class EthereumCLI ([#894](https://github.com/ethereum/execution-spec-tests/pull/894)). +- 🐞 Fix erroneous fork mes- 🔀 Fix max stack height calculation ([#810](https://github.com/ethereum/execution-spec-tests/pull/810)). +- ✨ Add storage key hint in Storage class ([#917](https://github.com/ethereum/execution-spec-tests/pull/917)). +- ✨ Add system to verify exception strings ([#795](https://github.com/ethereum/execution-spec-tests/pull/795)). +- 🔀 Fix `FixedBytes` assignment rules ([#1010](https://github.com/ethereum/execution-spec-tests/pull/1010)). +- 🔀 Fix `Address` padding options ([#1113](https://github.com/ethereum/execution-spec-tests/pull/1113)). +- 🔀 Add `Container.expected_bytecode` optional parameter ([#737](https://github.com/ethereum/execution-spec-tests/pull/737)). +- ✨ Add support for `initcode_prefix` on EOF `Container.Init` ([#819](https://github.com/ethereum/execution-spec-tests/pull/819)).sage in pytest session header with development forks ([#806](https://github.com/ethereum/execution-spec-tests/pull/806)). +- 🐞 Fix `Conditional` code generator in EOF mode ([#821](https://github.com/ethereum/execution-spec-tests/pull/821)). +- 🔀 Ensure that `Block` objects keep track of their `fork`, for example, when the block's `rlp_modifier` is not `None` ([#854](https://github.com/ethereum/execution-spec-tests/pull/854)). +- 🔀 `ethereum_test_rpc` library has been created with what was previously `ethereum_test_tools.rpc` ([#822](https://github.com/ethereum/execution-spec-tests/pull/822)). +- ✨ Add `Wei` type to `ethereum_test_base_types` which allows parsing wei amounts from strings like "1 ether", "1000 wei", "10**2 gwei", etc ([#825](https://github.com/ethereum/execution-spec-tests/pull/825)). +- ✨ Pin EELS versions in `eels_resolutions.json` and include this file in fixture releases ([#872](https://github.com/ethereum/execution-spec-tests/pull/872)). +- 🔀 Replace `ethereum.base_types` with `ethereum-types` ([#850](https://github.com/ethereum/execution-spec-tests/pull/850)). +- 💥 Rename the `PragueEIP7692` fork to `Osaka` ([#869](https://github.com/ethereum/execution-spec-tests/pull/869)). +- ✨ Improve `fill` terminal output to emphasize that filling tests is not actually testing a client ([#807](https://github.com/ethereum/execution-spec-tests/pull/887)). +- ✨ Add the `BlockchainTestEngine` test spec type that only generates a fixture in the `EngineFixture` (`blockchain_test_engine`) format ([#888](https://github.com/ethereum/execution-spec-tests/pull/888)). +- 🔀 Move the `evm_transition_tool` package to `ethereum_clis` and derive the transition tool CL interfaces from a shared `EthereumCLI` class that can be reused for other sub-commands ([#894](https://github.com/ethereum/execution-spec-tests/pull/894)). +- ✨ Pass `state_test` property to T8N tools that support it (Only EELS at the time of merge) ([#943](https://github.com/ethereum/execution-spec-tests/pull/943)). +- ✨ Add the `eofwrap` cli used to wrap tests from `ethereum/tests` in an EOF container ([#896](https://github.com/ethereum/execution-spec-tests/pull/896)). +- 🔀 Improve gentest architecture with `EthereumTestBaseModel` and `EthereumTestRootModel` ([#901](https://github.com/ethereum/execution-spec-tests/pull/901)). +- 🔀 Migrate transaction test to `state_test` for `gentest` ([#903](https://github.com/ethereum/execution-spec-tests/pull/903)). +- 🔀 `ethereum_test_forks` forks now contain gas-calculating functions, which return the appropriate function to calculate the gas used by a transaction or memory function for the given fork ([#779](https://github.com/ethereum/execution-spec-tests/pull/779)). +- 🐞 Fix `Bytecode` class `__eq__` method ([#939](https://github.com/ethereum/execution-spec-tests/pull/939)). +- 🔀 Update `pydantic` from 2.8.2 to 2.9.2 ([#960](https://github.com/ethereum/execution-spec-tests/pull/960)). +- ✨ Add the `eest make test` command, an interactive CLI that helps users create a new test module and function ([#950](https://github.com/ethereum/execution-spec-tests/pull/950)). +- ✨ Add the `eest clean` command that helps delete generated files and directories from the repository ([#980](https://github.com/ethereum/execution-spec-tests/pull/980)). +- ✨ Add framework changes for EIP-7742, required for Prague devnet-5 ([#931](https://github.com/ethereum/execution-spec-tests/pull/931)). +- ✨ Add the `eest make env` command that generates a default env file (`env.yaml`)([#996](https://github.com/ethereum/execution-spec-tests/pull/996)). +- ✨ Generate Transaction Test type ([#933](https://github.com/ethereum/execution-spec-tests/pull/933)). +- ✨ Add a default location for evm logs (`--evm-dump-dir`) when filling tests ([#999](https://github.com/ethereum/execution-spec-tests/pull/999)). +- ✨ Slow tests now have greater timeout when making a request to the T8N server ([#1037](https://github.com/ethereum/execution-spec-tests/pull/1037)). +- ✨ Introduce [`pytest.mark.parametrize_by_fork`](https://eest.ethereum.org/main/writing_tests/test_markers/#pytestmarkfork_parametrize) helper marker ([#1019](https://github.com/ethereum/execution-spec-tests/pull/1019), [#1057](https://github.com/ethereum/execution-spec-tests/pull/1057)). +- 🐞 fix(consume): allow absolute paths with `--evm-bin` ([#1052](https://github.com/ethereum/execution-spec-tests/pull/1052)). +- ✨ Disable EIP-7742 framework changes for Prague ([#1023](https://github.com/ethereum/execution-spec-tests/pull/1023)). +- ✨ Allow verification of the transaction receipt on executed test transactions ([#1068](https://github.com/ethereum/execution-spec-tests/pull/1068)). +- ✨ Modify `valid_at_transition_to` marker to add keyword arguments `subsequent_transitions` and `until` to fill a test using multiple transition forks ([#1081](https://github.com/ethereum/execution-spec-tests/pull/1081)). +- 🐞 fix(consume): use `"HIVE_CHECK_LIVE_PORT"` to signal hive to wait for port 8551 (Engine API port) instead of the 8545 port when running `consume engine` ([#1095](https://github.com/ethereum/execution-spec-tests/pull/1095)). +- ✨ `state_test`, `blockchain_test` and `blockchain_test_engine` fixtures now contain the `blobSchedule` from [EIP-7840](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7840.md), only for tests filled for Cancun and Prague forks ([#1040](https://github.com/ethereum/execution-spec-tests/pull/1040)). +- 🔀 Change `--dist` flag to the default value, `load`, for better parallelism handling during test filling ([#1118](https://github.com/ethereum/execution-spec-tests/pull/1118)). +- 🔀 Refactor framework code to use the [`ethereum-rlp`](https://pypi.org/project/ethereum-rlp/) package instead of `ethereum.rlp`, previously available in ethereum/execution-specs ([#1180](https://github.com/ethereum/execution-spec-tests/pull/1180)). +- 🔀 Update EELS / execution-specs EEST dependency to [99238233](https://github.com/ethereum/execution-specs/commit/9923823367b5586228e590537d47aa9cc4c6a206) for EEST framework libraries and test case generation ([#1181](https://github.com/ethereum/execution-spec-tests/pull/1181)). +- ✨ Add the `consume cache` command to cache fixtures before running consume commands ([#1044](https://github.com/ethereum/execution-spec-tests/pull/1044)). +- ✨ The `--input` flag of the consume commands now supports parsing of tagged release names in the format `@` ([#1044](https://github.com/ethereum/execution-spec-tests/pull/1044)). +- 🐞 Fix stdout output when using the `fill` command ([#1188](https://github.com/ethereum/execution-spec-tests/pull/1188)). +- ✨ Add tests for blockchain intermediate state verification ([#1075](https://github.com/ethereum/execution-spec-tests/pull/1075)). +- ✨ Add Interactive CLI input functionality ([#947](https://github.com/ethereum/execution-spec-tests/pull/947)). +- 🔀 Rename `EOFTest.data` to `EOFTest.container` with rebase of `EOFStateTest` ([#1145](https://github.com/ethereum/execution-spec-tests/pull/1145)). +- ✨ Turn on `--traces` for EELS + `ethereum-specs-evm-resolver` ([#1174](https://github.com/ethereum/execution-spec-tests/pull/1174)). + +### 📋 Misc + +- ✨ Feature releases can now include multiple types of fixture tarball files from different releases that start with the same prefix ([#736](https://github.com/ethereum/execution-spec-tests/pull/736)). +- ✨ Releases for feature eip7692 now include both Cancun and Prague based tests in the same release, in files `fixtures_eip7692.tar.gz` and `fixtures_eip7692-prague.tar.gz` respectively ([#743](https://github.com/ethereum/execution-spec-tests/pull/743)). +✨ Re-write the test case reference doc flow as a pytest plugin and add pages for test functions with a table providing an overview of their parametrized test cases ([#801](https://github.com/ethereum/execution-spec-tests/pull/801), [#842](https://github.com/ethereum/execution-spec-tests/pull/842)). +- 🔀 Simplify Python project configuration and consolidate it into `pyproject.toml` ([#764](https://github.com/ethereum/execution-spec-tests/pull/764)). +- ✨ Add dev docs to help using nectos/act ([#776](https://github.com/ethereum/execution-spec-tests/pull/776)). +- 🔀 Update `uv.lock` for updated solc deps ([#782](https://github.com/ethereum/execution-spec-tests/pull/782)). +- ✨ Enable coverage on any test change ([#790](https://github.com/ethereum/execution-spec-tests/pull/790)). +- 🔀 Created `pytest_plugins.concurrency` plugin to sync multiple `xdist` processes without using a command flag to specify the temporary working folder ([#824](https://github.com/ethereum/execution-spec-tests/pull/824)). +- 🔀 Move pytest plugin `pytest_plugins.filler.solc` to `pytest_plugins.solc.solc` ([#823](https://github.com/ethereum/execution-spec-tests/pull/823)). +- 🔀 Remove `formats.py`, embed properties as class vars ([#826](https://github.com/ethereum/execution-spec-tests/pull/826)). +- ✨ Add `build-evm-base` to docs deploy workflows ([#829](https://github.com/ethereum/execution-spec-tests/pull/829)). +- 🔀 Add links to the online test case docs in the EOF tracker ([#838](https://github.com/ethereum/execution-spec-tests/pull/838)). +- 🔀 Fix miscellaneous improvements to troubleshooting, navigation, styling ([#840](https://github.com/ethereum/execution-spec-tests/pull/840)). +- ✨ Include all parameters in test parameter datatables ([#842](https://github.com/ethereum/execution-spec-tests/pull/842)). +- ✨ Add info about ripemd160 & update running actions locally ([#847](https://github.com/ethereum/execution-spec-tests/pull/847)). +- ✨ Add `SECURITY.md` describing how to report vulnerabilities ([#848](https://github.com/ethereum/execution-spec-tests/pull/848)). +- 🔀 Change image from ubuntu-24.04 to ubuntu-latest in CI ([#855](https://github.com/ethereum/execution-spec-tests/pull/855)). +- 🐞 Asserts that the deploy docs tags workflow is only triggered for full releases ([#857](https://github.com/ethereum/execution-spec-tests/pull/857)). +- 🐞 Fix deploy docs tags workflow trigger ([#858](https://github.com/ethereum/execution-spec-tests/pull/858)). +- ✨ A new application-wide configuration manager provides access to environment and application configurations. ([#892](https://github.com/ethereum/execution-spec-tests/pull/892)). +- 🔀 Update the developer docs navigation ([#898](https://github.com/ethereum/execution-spec-tests/pull/898)). +- 🔀 Use jinja2 templating in `gentest` ([#900](https://github.com/ethereum/execution-spec-tests/pull/900)). +- ✨ Fix/add test github actions locally page ([#909](https://github.com/ethereum/execution-spec-tests/pull/909)). +- 🐞 Fix print fill output in coverage workflow on errors ([#919](https://github.com/ethereum/execution-spec-tests/pull/919)). +- 🐞 Use a local version of ethereum/execution-specs (EELS) when running the framework tests in CI ([#997](https://github.com/ethereum/execution-spec-tests/pull/997)). +- ✨ Use self-hosted runners for fixture building in CI ([#1051](https://github.com/ethereum/execution-spec-tests/pull/1051)). +- ✨ Release tarballs now contain fixtures filled for all forks, not only the fork under active development and the fork currently deployed on mainnet ([#1053](https://github.com/ethereum/execution-spec-tests/pull/1053)). +- ✨ `StateTest` fixture format now contains `state` field in each network post result, containing the decoded post allocation that results from the transaction execution ([#1064](https://github.com/ethereum/execution-spec-tests/pull/1064)). +- ✨ Include EELS fork resolution information in filled json test fixtures ([#1123](https://github.com/ethereum/execution-spec-tests/pull/1123)). +- 🔀 Updates ruff from version 0.8.2 to 0.9.4 ([#1168](https://github.com/ethereum/execution-spec-tests/pull/1168)). +- 🔀 Update `uv.lock` to be compatible with `uv>=0.5.22` ([#1178](https://github.com/ethereum/execution-spec-tests/pull/1178)). +- 🔀 Update `mypy` from version `0.991` to `1.15` ([#1209](https://github.com/ethereum/execution-spec-tests/pull/1209)). + +### 🧪 Test Cases + +- ✨ Migrate validation tests `EIP3540/validInvalidFiller.yml` ([#598](https://github.com/ethereum/execution-spec-tests/pull/598)). +- ✨ EIP-4844 test `tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py` includes an EOF test case ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). +- ✨ Example test `tests/frontier/opcodes/test_dup.py` now includes EOF parametrization ([#610](https://github.com/ethereum/execution-spec-tests/pull/610)). +- ✨ Add EOFv1 function test - Call simple contract test ([#695](https://github.com/ethereum/execution-spec-tests/pull/695)). +- ✨ Add section size validation tests ([#705](https://github.com/ethereum/execution-spec-tests/pull/705)). +- ✨ Add deep and wide EOF subcontainers tests ([#718](https://github.com/ethereum/execution-spec-tests/pull/718)). +- ✨ Update [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) tests for Devnet-3 ([#733](https://github.com/ethereum/execution-spec-tests/pull/733)). +- ✨ Migrate "valid" EOFCREATE validation ([#738](https://github.com/ethereum/execution-spec-tests/pull/738)). +- ✨ Migrate tests for truncated sections ([#740](https://github.com/ethereum/execution-spec-tests/pull/740)). +- ✨ Add out of order container section test ([#741](https://github.com/ethereum/execution-spec-tests/pull/741)). +- ✨ Convert all opcodes validation test `tests/frontier/opcodes/test_all_opcodes.py` ([#748](https://github.com/ethereum/execution-spec-tests/pull/748)). +- 🔀 Add Test types with 128 inputs ([#749](https://github.com/ethereum/execution-spec-tests/pull/749)). +- 🔀 Use new marker to EOF-ize MCOPY test ([#754](https://github.com/ethereum/execution-spec-tests/pull/754)). +- ✨ Add EOF Tests from Fuzzing ([#756](https://github.com/ethereum/execution-spec-tests/pull/756)). +- ✨ Add embedded container tests ([#763](https://github.com/ethereum/execution-spec-tests/pull/763)). +- ✨ Validate EOF only opcodes are invalid in legacy ([#768](https://github.com/ethereum/execution-spec-tests/pull/768)). +- ✨ Update EOF tracker, add unimplemented tests ([#773](https://github.com/ethereum/execution-spec-tests/pull/773)). +- ✨ Add EIP-7620 EOFCREATE gas tests ([#785](https://github.com/ethereum/execution-spec-tests/pull/785)). +- ✨ Add more fuzzing discovered EOF tests ([#789](https://github.com/ethereum/execution-spec-tests/pull/789)). +- ✨ Add EOF tests for invalid non-returning sections ([#794](https://github.com/ethereum/execution-spec-tests/pull/794)). +- ✨ Test to ensure transient storage is cleared after transactions ([#798](https://github.com/ethereum/execution-spec-tests/pull/798)). +- ✨ Test that transient storage stays at correct address ([#799](https://github.com/ethereum/execution-spec-tests/pull/799)). +- ✨ Add EOFCREATE referencing the same subcontainer twice test ([#809](https://github.com/ethereum/execution-spec-tests/pull/809)). +- ✨ Add dangling data in subcontainer test ([#812](https://github.com/ethereum/execution-spec-tests/pull/812)). +- 🐞 Fix [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)+EOF tests due to incorrect test expectations and faulty `Conditional` test generator in EOF mode ([#821](https://github.com/ethereum/execution-spec-tests/pull/821)). +- 🐞 Fix TSTORE EOF variant test ([#831](https://github.com/ethereum/execution-spec-tests/pull/831)). +- 🔀 Unify EOF return code constants ([#834](https://github.com/ethereum/execution-spec-tests/pull/834)). +- ✨ Add RJUMP* vs CALLF tests ([#833](https://github.com/ethereum/execution-spec-tests/pull/833)). +- ✨ Add tests to clarify "non-returning instruction" ([#837](https://github.com/ethereum/execution-spec-tests/pull/837)). +- ✨ Add double RJUMPI stack validation tests ([#851](https://github.com/ethereum/execution-spec-tests/pull/851)). +- ✨ Add unreachable code sections tests ([#856](https://github.com/ethereum/execution-spec-tests/pull/856)). +- 💥 `PragueEIP7692` fork in tests has been updated to `Osaka` ([#869](https://github.com/ethereum/execution-spec-tests/pull/869)). +- ✨ Update [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110), [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251), [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685), and [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) tests for Devnet-4 ([#832](https://github.com/ethereum/execution-spec-tests/pull/832)). +- ✨ Add EIP-7069 and EIP-7620 failures and context vars tests ([#836](https://github.com/ethereum/execution-spec-tests/pull/836)). +- ✨ Add EOF EIP-4750 Stack validation in CALLF test ([#889](https://github.com/ethereum/execution-spec-tests/pull/889)). +- ✨ Add stack overflow by rule check to JUMPF tests ([#902](https://github.com/ethereum/execution-spec-tests/pull/902)). +- 🐞 Fix erroneous test with`CALLF` rule bug ([#907](https://github.com/ethereum/execution-spec-tests/pull/907)). +- ✨ Add test for EXTDELEGATECALL value cost ([#911](https://github.com/ethereum/execution-spec-tests/pull/911)). +- ✨ Add basic EOF execution tests ([#912](https://github.com/ethereum/execution-spec-tests/pull/912)). +- ✨ Add parametrized CALLF execution tests ([#913](https://github.com/ethereum/execution-spec-tests/pull/913)). +- ✨ Add CALLF execution tests ([#914](https://github.com/ethereum/execution-spec-tests/pull/914)). +- ✨ Add fibonacci and factorial CALLF tests ([#915](https://github.com/ethereum/execution-spec-tests/pull/915)). +- ✨ Add RJUMP* execution tests ([#916](https://github.com/ethereum/execution-spec-tests/pull/916)). +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) many delegations test ([#923](https://github.com/ethereum/execution-spec-tests/pull/923)). +- ✨ Add opcode validation tests ([#932](https://github.com/ethereum/execution-spec-tests/pull/932)). +- ✨ Add RJUMPI with JUMPF tests ([#928](https://github.com/ethereum/execution-spec-tests/pull/928)). +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) set code of non-empty-storage account test ([#948](https://github.com/ethereum/execution-spec-tests/pull/948)). +- ✨ Add PUSH* opcode tests ([#975](https://github.com/ethereum/execution-spec-tests/pull/975)). +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) implement 7702 test ideas ([#981](https://github.com/ethereum/execution-spec-tests/pull/981)). +- ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Remove delegation behavior of EXTCODE* ([#984](https://github.com/ethereum/execution-spec-tests/pull/984)). +- ✨ Add EIP-7620 RETURNCONTRACT behavior verification test ([#1109](https://github.com/ethereum/execution-spec-tests/pull/1109)). +- ✨ Add EIP-7069 p256verify EOF calls tests ([#1021](https://github.com/ethereum/execution-spec-tests/pull/1021)). +- ✨ Add EIP-7480 DATACOPY edge cases tests ([#1020](https://github.com/ethereum/execution-spec-tests/pull/1020)). +- ✨ Add EIP-7069 EXTCALL creation gas charge tests ([#1025](https://github.com/ethereum/execution-spec-tests/pull/1025)). +- ✨ Add generic precompile-absence test ([#1036](https://github.com/ethereum/execution-spec-tests/pull/1036)). +- ✨ Add test for [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) which uses the full discount table of G2 MSM ([#1038](https://github.com/ethereum/execution-spec-tests/pull/1038)). +- ✨ [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691) Blob throughput increase tests by parametrization of existing EIP-4844 tests ([#1023](https://github.com/ethereum/execution-spec-tests/pull/1023), [#1082](https://github.com/ethereum/execution-spec-tests/pull/1082)). +- ✨ Port [calldatacopy test](https://github.com/ethereum/tests/blob/ae4791077e8fcf716136e70fe8392f1a1f1495fb/src/GeneralStateTestsFiller/VMTests/vmTests/calldatacopyFiller.yml) ([#1056](https://github.com/ethereum/execution-spec-tests/pull/1056)). +- ✨ [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) Increase calldata cost ([#1004](https://github.com/ethereum/execution-spec-tests/pull/1004), [#1071](https://github.com/ethereum/execution-spec-tests/pull/1071)). +- ✨ Add CALLF invalid section index tests ([#1111](https://github.com/ethereum/execution-spec-tests/pull/1111)). +- ✨ Add JUMPF invalid section index tests ([#1112](https://github.com/ethereum/execution-spec-tests/pull/1112)). +- ✨ Add CALLF truncated immediate bytes tests ([#1114](https://github.com/ethereum/execution-spec-tests/pull/1114)). +- ✨ [EIP-152](https://eips.ethereum.org/EIPS/eip-152) Add tests for Blake2 compression function `F` precompile ([#1067](https://github.com/ethereum/execution-spec-tests/pull/1067)). +- ✨ Add CALLF non-returning section tests ([#1126](https://github.com/ethereum/execution-spec-tests/pull/1126)). +- ✨ Add DATALOADN truncated immediate bytes tests ([#1127](https://github.com/ethereum/execution-spec-tests/pull/1127)). +- 🔀 Update EIP-7702 test expectations according to [spec updates](https://github.com/ethereum/EIPs/pull/9248) ([#1129](https://github.com/ethereum/execution-spec-tests/pull/1129)). +- ✨ Add tests for CALLF and non-returning ([#1140](https://github.com/ethereum/execution-spec-tests/pull/1140)). +- 🔀 Update EIP-7251 according to spec updates [#9127](https://github.com/ethereum/EIPs/pull/9127), [#9289](https://github.com/ethereum/EIPs/pull/9289) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024), [#1155](https://github.com/ethereum/execution-spec-tests/pull/1155)). +- 🔀 Update EIP-7002 according to spec updates [#9119](https://github.com/ethereum/EIPs/pull/9119), [#9288](https://github.com/ethereum/EIPs/pull/9288) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024), [#1155](https://github.com/ethereum/execution-spec-tests/pull/1155)). +- 🔀 Update EIP-2935 according to spec updates [#9144](https://github.com/ethereum/EIPs/pull/9144), [#9287](https://github.com/ethereum/EIPs/pull/9287) ([#1046](https://github.com/ethereum/execution-spec-tests/pull/1046), [#1155](https://github.com/ethereum/execution-spec-tests/pull/1155)). +- ✨ Add DATALOADN validation and execution tests ([#1162](https://github.com/ethereum/execution-spec-tests/pull/1162)). +- ✨ Add EOF prefix tests ([#1187](https://github.com/ethereum/execution-spec-tests/pull/1187)). +- ✨ Add tests for EOF code header missing ([#1193](https://github.com/ethereum/execution-spec-tests/pull/1193)). +- ✨ Add tests for empty EOF type section ([#1194](https://github.com/ethereum/execution-spec-tests/pull/1194)). +- ✨ Add tests for multiple EOF type sections ([#1195](https://github.com/ethereum/execution-spec-tests/pull/1195)). +- ✨ Add EIP-7698 legacy EOF creation prevention tests ([#1206](https://github.com/ethereum/execution-spec-tests/pull/1206)). + +## [v3.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v3.0.0) - 2024-07-22 + +### 🧪 Test Cases + +- ✨ Port create2 return data test ([#497](https://github.com/ethereum/execution-spec-tests/pull/497)). +- ✨ Add tests for eof container's section bytes position smart fuzzing ([#592](https://github.com/ethereum/execution-spec-tests/pull/592)). +- ✨ Add `test_create_selfdestruct_same_tx_increased_nonce` which tests self-destructing a contract with a nonce > 1 ([#478](https://github.com/ethereum/execution-spec-tests/pull/478)). +- ✨ Add `test_double_kill` and `test_recreate` which test resurrection of accounts killed with `SELFDESTRUCT` ([#488](https://github.com/ethereum/execution-spec-tests/pull/488)). +- ✨ Add eof example valid invalid tests from ori, fetch EOF Container implementation ([#535](https://github.com/ethereum/execution-spec-tests/pull/535)). +- ✨ Add tests for [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) ([#499](https://github.com/ethereum/execution-spec-tests/pull/499)). +- ✨ [EIP-663](https://eips.ethereum.org/EIPS/eip-663): Add `test_dupn.py` and `test_swapn.py` ([#502](https://github.com/ethereum/execution-spec-tests/pull/502)). +- ✨ Add tests for [EIP-6110: Supply validator deposits on chain](https://eips.ethereum.org/EIPS/eip-6110) ([#530](https://github.com/ethereum/execution-spec-tests/pull/530)). +- ✨ Add tests for [EIP-7002: Execution layer triggerable withdrawals](https://eips.ethereum.org/EIPS/eip-7002) ([#530](https://github.com/ethereum/execution-spec-tests/pull/530)). +- ✨ Add tests for [EIP-7685: General purpose execution layer requests](https://eips.ethereum.org/EIPS/eip-7685) ([#530](https://github.com/ethereum/execution-spec-tests/pull/530)). +- ✨ Add tests for [EIP-2935: Serve historical block hashes from state](https://eips.ethereum.org/EIPS/eip-2935) ([#564](https://github.com/ethereum/execution-spec-tests/pull/564), [#585](https://github.com/ethereum/execution-spec-tests/pull/585)). +- ✨ Add tests for [EIP-4200: EOF - Static relative jumps](https://eips.ethereum.org/EIPS/eip-4200) ([#581](https://github.com/ethereum/execution-spec-tests/pull/581), [#666](https://github.com/ethereum/execution-spec-tests/pull/666)). +- ✨ Add tests for [EIP-7069: EOF - Revamped CALL instructions](https://eips.ethereum.org/EIPS/eip-7069) ([#595](https://github.com/ethereum/execution-spec-tests/pull/595)). +- 🐞 Fix typos in self-destruct collision test from erroneous pytest parametrization ([#608](https://github.com/ethereum/execution-spec-tests/pull/608)). +- ✨ Add tests for [EIP-3540: EOF - EVM Object Format v1](https://eips.ethereum.org/EIPS/eip-3540) ([#634](https://github.com/ethereum/execution-spec-tests/pull/634), [#668](https://github.com/ethereum/execution-spec-tests/pull/668)). +- 🔀 Update EIP-7002 tests to match spec changes in [ethereum/execution-apis#549](https://github.com/ethereum/execution-apis/pull/549) ([#600](https://github.com/ethereum/execution-spec-tests/pull/600)). +- ✨ Convert a few eip1153 tests from ethereum/tests repo into .py ([#440](https://github.com/ethereum/execution-spec-tests/pull/440)). +- ✨ Add tests for [EIP-7480: EOF - Data section access instructions](https://eips.ethereum.org/EIPS/eip-7480) ([#518](https://github.com/ethereum/execution-spec-tests/pull/518), [#664](https://github.com/ethereum/execution-spec-tests/pull/664)). +- ✨ Add tests for subcontainer kind validation from [EIP-7620: EOF Contract Creation](https://eips.ethereum.org/EIPS/eip-7620) for the cases with deeply nested containers and non-first code sections ([#676](https://github.com/ethereum/execution-spec-tests/pull/676)). +- ✨ Add tests for runtime stack overflow at CALLF instruction from [EIP-4750: EOF - Functions](https://eips.ethereum.org/EIPS/eip-4750) ([#678](https://github.com/ethereum/execution-spec-tests/pull/678)). +- ✨ Add tests for runtime stack overflow at JUMPF instruction from [EIP-6206: EOF - JUMPF and non-returning functions](https://eips.ethereum.org/EIPS/eip-6206) ([#690](https://github.com/ethereum/execution-spec-tests/pull/690)). +- ✨ Add tests for Devnet-1 version of [EIP-7702: Set EOA account code](https://eips.ethereum.org/EIPS/eip-7702) ([#621](https://github.com/ethereum/execution-spec-tests/pull/621)). + +### 🛠️ Framework + +- 🐞 Fix incorrect `!=` operator for `FixedSizeBytes` ([#477](https://github.com/ethereum/execution-spec-tests/pull/477)). +- ✨ Add Macro enum that represents byte sequence of Op instructions ([#457](https://github.com/ethereum/execution-spec-tests/pull/457)). +- ✨ Number of parameters used to call opcodes (to generate bytecode) is now checked ([#492](https://github.com/ethereum/execution-spec-tests/pull/492)). +- ✨ Libraries have been refactored to use `pydantic` for type checking in most test types ([#486](https://github.com/ethereum/execution-spec-tests/pull/486), [#501](https://github.com/ethereum/execution-spec-tests/pull/501), [#508](https://github.com/ethereum/execution-spec-tests/pull/508)). +- ✨ Opcodes are now subscriptable and it's used to define the data portion of the opcode: `Op.PUSH1(1) == Op.PUSH1[1] == b"\x60\x01"` ([#513](https://github.com/ethereum/execution-spec-tests/pull/513)). +- ✨ Added EOF fixture format ([#512](https://github.com/ethereum/execution-spec-tests/pull/512)). +- ✨ Verify filled EOF fixtures using `evmone-eofparse` during `fill` execution ([#519](https://github.com/ethereum/execution-spec-tests/pull/519)). +- ✨ Added `--traces` support when running with Hyperledger Besu ([#511](https://github.com/ethereum/execution-spec-tests/pull/511)). +- ✨ Use pytest's "short" traceback style (`--tb=short`) for failure summaries in the test report for more compact terminal output ([#542](https://github.com/ethereum/execution-spec-tests/pull/542)). +- ✨ The `fill` command now generates HTML test reports with links to the JSON fixtures and debug information ([#537](https://github.com/ethereum/execution-spec-tests/pull/537)). +- ✨ Add an Ethereum RPC client class for use with consume commands ([#556](https://github.com/ethereum/execution-spec-tests/pull/556)). +- ✨ Add a "slow" pytest marker, in order to be able to limit the filled tests until release ([#562](https://github.com/ethereum/execution-spec-tests/pull/562)). +- ✨ Add a CLI tool that generates blockchain tests as Python from a transaction hash ([#470](https://github.com/ethereum/execution-spec-tests/pull/470), [#576](https://github.com/ethereum/execution-spec-tests/pull/576)). +- ✨ Add more Transaction and Block exceptions from existing ethereum/tests repo ([#572](https://github.com/ethereum/execution-spec-tests/pull/572)). +- ✨ Add "description" and "url" fields containing test case documentation and a source code permalink to fixtures during `fill` and use them in `consume`-generated Hive test reports ([#579](https://github.com/ethereum/execution-spec-tests/pull/579)). +- ✨ Add git workflow evmone coverage script for any new lines mentioned in converted_ethereum_tests.txt ([#503](https://github.com/ethereum/execution-spec-tests/pull/503)). +- ✨ Add a new covariant marker `with_all_contract_creating_tx_types` that allows automatic parametrization of a test with all contract-creating transaction types at the current executing fork ([#602](https://github.com/ethereum/execution-spec-tests/pull/602)). +- ✨ Tests are now encouraged to declare a `pre: Alloc` parameter to get the pre-allocation object for the test, and use `pre.deploy_contract` and `pre.fund_eoa` to deploy contracts and fund accounts respectively, instead of declaring the `pre` as a dictionary or modifying its contents directly (see the [state test tutorial](https://eest.ethereum.org/v4.1.0/writing_tests/tutorials/state_transition/) for an updated example) ([#584](https://github.com/ethereum/execution-spec-tests/pull/584)). +- ✨ Enable loading of [ethereum/tests/BlockchainTests](https://github.com/ethereum/tests/tree/develop/BlockchainTests) ([#596](https://github.com/ethereum/execution-spec-tests/pull/596)). +- 🔀 Refactor `gentest` to use `ethereum_test_tools.rpc.rpc` by adding to `get_transaction_by_hash`, `debug_trace_call` to `EthRPC` ([#568](https://github.com/ethereum/execution-spec-tests/pull/568)). +- ✨ Write a properties file to the output directory and enable direct generation of a fixture tarball from `fill` via `--output=fixtures.tgz`([#627](https://github.com/ethereum/execution-spec-tests/pull/627)). +- 🔀 `ethereum_test_tools` library has been split into multiple libraries ([#645](https://github.com/ethereum/execution-spec-tests/pull/645)). +- ✨ Add the consume engine simulator and refactor the consume simulator suite ([#691](https://github.com/ethereum/execution-spec-tests/pull/691)). +- 🐞 Prevents forcing consume to use stdin as an input when running from hive ([#701](https://github.com/ethereum/execution-spec-tests/pull/701)). + +### 📋 Misc + +- 🐞 Fix CI by using Golang 1.21 in Github Actions to build geth ([#484](https://github.com/ethereum/execution-spec-tests/pull/484)). +- 💥 "Merge" has been renamed to "Paris" in the "network" field of the Blockchain tests, and in the "post" field of the State tests ([#480](https://github.com/ethereum/execution-spec-tests/pull/480)). +- ✨ Port entry point scripts to use [click](https://click.palletsprojects.com) and add tests ([#483](https://github.com/ethereum/execution-spec-tests/pull/483)). +- 💥 As part of the pydantic conversion, the fixtures have the following (possibly breaking) changes ([#486](https://github.com/ethereum/execution-spec-tests/pull/486)): + - State test field `transaction` now uses the proper zero-padded hex number format for fields `maxPriorityFeePerGas`, `maxFeePerGas`, and `maxFeePerBlobGas`. + - Fixtures' hashes (in the `_info` field) are now calculated by removing the "_info" field entirely instead of it being set to an empty dict. +- 🐞 Relax minor and patch dependency requirements to avoid conflicting package dependencies ([#510](https://github.com/ethereum/execution-spec-tests/pull/510)). +- 🔀 Update all CI actions to use their respective Node.js 20 versions, ahead of their Node.js 16 version deprecations ([#527](https://github.com/ethereum/execution-spec-tests/pull/527)). +- ✨ Releases now contain a `fixtures_eip7692.tar.gz` which contains all EOF fixtures ([#573](https://github.com/ethereum/execution-spec-tests/pull/573)). +- ✨ Use `solc-select` for tox when running locally and within CI ([#604](https://github.com/ethereum/execution-spec-tests/pull/604)). + +### 💥 Breaking Change + +- Cancun is now the latest deployed fork, and the development fork is now Prague ([#489](https://github.com/ethereum/execution-spec-tests/pull/489)). +- Stable fixtures artifact `fixtures.tar.gz` has been renamed to `fixtures_stable.tar.gz` ([#573](https://github.com/ethereum/execution-spec-tests/pull/573)). +- The "Blockchain Test Hive" fixture format has been renamed to "Blockchain Test Engine" and updated to more closely resemble the `engine_newPayload` format in the `execution-apis` specification () and now contains a single `"params"` field instead of multiple fields for each parameter ([#687](https://github.com/ethereum/execution-spec-tests/pull/687)). +- Output folder for fixtures has been renamed from "blockchain_tests_hive" to "blockchain_tests_engine" ([#687](https://github.com/ethereum/execution-spec-tests/pull/687)). + +## [v2.1.1](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.1.1) - 2024-03-09 + +### 🧪 Test Cases + +- 🐞 Dynamic create2 collision from different transactions same block ([#430](https://github.com/ethereum/execution-spec-tests/pull/430)). +- 🐞 Fix beacon root contract deployment tests so the account in the pre-alloc is not empty ([#425](https://github.com/ethereum/execution-spec-tests/pull/425)). +- 🔀 All beacon root contract tests are now contained in tests/cancun/eip4788_beacon_root/test_beacon_root_contract.py, and all state tests have been converted back to blockchain tests format ([#449](https://github.com/ethereum/execution-spec-tests/pull/449)). + +### 🛠️ Framework + +- ✨ Adds two `consume` commands [#339](https://github.com/ethereum/execution-spec-tests/pull/339): + + 1. `consume direct` - Execute a test fixture directly against a client using a `blocktest`-like command (currently only geth supported). + 2. `consume rlp` - Execute a test fixture in a hive simulator against a client that imports the test's genesis config and blocks as RLP upon startup. This is a re-write of the [ethereum/consensus](https://github.com/ethereum/hive/tree/master/simulators/ethereum/consensus) Golang simulator. + +- ✨ Add Prague to forks ([#419](https://github.com/ethereum/execution-spec-tests/pull/419)). +- ✨ Improve handling of the argument passed to `solc --evm-version` when compiling Yul code ([#418](https://github.com/ethereum/execution-spec-tests/pull/418)). +- 🐞 Fix `fill -m yul_test` which failed to filter tests that are (dynamically) marked as a yul test ([#418](https://github.com/ethereum/execution-spec-tests/pull/418)). +- 🔀 Helper methods `to_address`, `to_hash` and `to_hash_bytes` have been deprecated in favor of `Address` and `Hash`, which are automatically detected as opcode parameters and pushed to the stack in the resulting bytecode ([#422](https://github.com/ethereum/execution-spec-tests/pull/422)). +- ✨ `Opcodes` enum now contains docstrings with each opcode description, including parameters and return values, which show up in many development environments ([#424](https://github.com/ethereum/execution-spec-tests/pull/424)) @ThreeHrSleep. +- 🔀 Locally calculate state root for the genesis blocks in the blockchain tests instead of calling t8n ([#450](https://github.com/ethereum/execution-spec-tests/pull/450)). +- 🐞 Fix bug that causes an exception during test collection because the fork parameter contains `None` ([#452](https://github.com/ethereum/execution-spec-tests/pull/452)). +- ✨ The `_info` field in the test fixtures now contains a `hash` field, which is the hash of the test fixture, and a `hasher` script has been added which prints and performs calculations on top of the hashes of all fixtures (see `hasher -h`) ([#454](https://github.com/ethereum/execution-spec-tests/pull/454)). +- ✨ Adds an optional `verify_sync` field to hive blockchain tests (EngineAPI). When set to true a second client attempts to sync to the first client that executed the tests ([#431](https://github.com/ethereum/execution-spec-tests/pull/431)). +- 🐞 Fix manually setting the gas limit in the genesis test env for post genesis blocks in blockchain tests ([#472](https://github.com/ethereum/execution-spec-tests/pull/472)). + +### 📋 Misc + +- 🐞 Fix deprecation warnings due to outdated config in recommended VS Code project settings ([#420](https://github.com/ethereum/execution-spec-tests/pull/420)). +- 🐞 Fix typo in the selfdestruct revert tests module ([#421](https://github.com/ethereum/execution-spec-tests/pull/421)). + +## [v2.1.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.1.0) - 2024-01-29: 🐍🏖️ Cancun + +Release [v2.1.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.1.0) primarily fixes a small bug introduced within the previous release where transition forks are used within the new `StateTest` format. This was highlighted by @chfast within #405 (), where the fork name `ShanghaiToCancunAtTime15k` was found within state tests. + +### 🧪 Test Cases + +- ✨ [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Adds `test_blob_gas_subtraction_tx()` verifying the blob gas fee is subtracted from the sender before executing the blob tx ([#407](https://github.com/ethereum/execution-spec-tests/pull/407)). + +### 🛠️ Framework + +- 🐞 State tests generated with transition forks no longer use the transition fork name in the fixture output, instead they use the actual enabled fork according to the state test's block number and timestamp ([#406](https://github.com/ethereum/execution-spec-tests/pull/406)). + +### 📋 Misc + +- ✨ Use `run-parallel` and shared wheel packages for `tox` ([#408](https://github.com/ethereum/execution-spec-tests/pull/408)). + +## [v2.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.0.0) - 2024-01-25: 🐍🏖️ Cancun + +Release [v2.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v2.0.0) contains many important framework changes, including introduction of the `StateTest` format, and some additional Cancun and other test coverage. + +Due to changes in the framework, there is a breaking change in the directory structure in the release tarball, please see the dedicated "💥 Breaking Changes" section below for more information. + +### 🧪 Test Cases + +- ✨ [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Add `test_sufficient_balance_blob_tx()` and `test_sufficient_balance_blob_tx_pre_fund_tx()` ([#379](https://github.com/ethereum/execution-spec-tests/pull/379)). +- ✨ [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780): Add a reentrancy suicide revert test ([#372](https://github.com/ethereum/execution-spec-tests/pull/372)). +- ✨ [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153): Add `test_run_until_out_of_gas()` for transient storage opcodes ([#401](https://github.com/ethereum/execution-spec-tests/pull/401)). +- ✨ [EIP-198](https://eips.ethereum.org/EIPS/eip-198): Add tests for the MODEXP precompile ([#364](https://github.com/ethereum/execution-spec-tests/pull/364)). +- ✨ Tests for nested `CALL` and `CALLCODE` gas consumption with a positive value transfer (previously lacking coverage) ([#371](https://github.com/ethereum/execution-spec-tests/pull/371)). +- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fixed `test_invalid_tx_max_fee_per_blob_gas()` to account for extra gas required in the case where the account is incorrectly deduced the balance as if it had the correct block blob gas fee ([#370](https://github.com/ethereum/execution-spec-tests/pull/370)). +- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fixed `test_insufficient_balance_blob_tx()` to correctly calculate the minimum balance required for the accounts ([#379](https://github.com/ethereum/execution-spec-tests/pull/379)). +- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fix and enable `test_invalid_blob_tx_contract_creation` ([#379](https://github.com/ethereum/execution-spec-tests/pull/379)). +- 🔀 Convert all eligible `BlockchainTest`s to `StateTest`s (and additionally generate corresponding `BlockchainTest`s) ([#368](https://github.com/ethereum/execution-spec-tests/pull/368), [#370](https://github.com/ethereum/execution-spec-tests/pull/370)). + +### 🛠️ Framework + +- ✨ Add `StateTest` fixture format generation; `StateTests` now generate a `StateTest` and a corresponding `BlockchainTest` test fixture, previously only `BlockchainTest` fixtures were generated ([#368](https://github.com/ethereum/execution-spec-tests/pull/368)). +- ✨ Add `StateTestOnly` fixture format is now available and its only difference with `StateTest` is that it does not produce a `BlockchainTest` ([#368](https://github.com/ethereum/execution-spec-tests/pull/368)). +- ✨ Add `evm_bytes_to_python` command-line utility which converts EVM bytecode to Python Opcodes ([#357](https://github.com/ethereum/execution-spec-tests/pull/357)). +- ✨ Fork objects used to write tests can now be compared using the `>`, `>=`, `<`, `<=` operators, to check for a fork being newer than, newer than or equal, older than, older than or equal, respectively when compared against other fork ([#367](https://github.com/ethereum/execution-spec-tests/pull/367)). +- ✨ Add [solc 0.8.23](https://github.com/ethereum/solidity/releases/tag/v0.8.23) support ([#373](https://github.com/ethereum/execution-spec-tests/pull/373)). +- ✨ Add framework unit tests for post state exception verification ([#350](https://github.com/ethereum/execution-spec-tests/pull/350)). +- ✨ Add a helper class `ethereum_test_tools.TestParameterGroup` to define test parameters as dataclasses and auto-generate test IDs ([#364](https://github.com/ethereum/execution-spec-tests/pull/364)). +- ✨ Add a `--single-fixture-per-file` flag to generate one fixture JSON file per test case ([#331](https://github.com/ethereum/execution-spec-tests/pull/331)). +- 🐞 Storage type iterator is now fixed ([#369](https://github.com/ethereum/execution-spec-tests/pull/369)). +- 🐞 Fix type coercion in `FixtureHeader.join()` ([#398](https://github.com/ethereum/execution-spec-tests/pull/398)). +- 🔀 Locally calculate the transactions list's root instead of using the one returned by t8n when producing BlockchainTests ([#353](https://github.com/ethereum/execution-spec-tests/pull/353)). +- 🔀 Change custom exception classes to dataclasses to improve testability ([#386](https://github.com/ethereum/execution-spec-tests/pull/386)). +- 🔀 Update fork name from "Merge" to "Paris" used within the framework and tests ([#363](https://github.com/ethereum/execution-spec-tests/pull/363)). +- 💥 Replace `=` with `_` in pytest node ids and test fixture names ([#342](https://github.com/ethereum/execution-spec-tests/pull/342)). +- 💥 The `StateTest`, spec format used to write tests, is now limited to a single transaction per test ([#361](https://github.com/ethereum/execution-spec-tests/pull/361)). +- 💥 Tests must now use `BlockException` and `TransactionException` to define the expected exception of a given test, which can be used to test whether the client is hitting the proper exception when processing the block or transaction ([#384](https://github.com/ethereum/execution-spec-tests/pull/384)). +- 💥 `fill`: Remove the `--enable-hive` flag; now all test types are generated by default ([#358](https://github.com/ethereum/execution-spec-tests/pull/358)). +- 💥 Rename test fixtures names to match the corresponding pytest node ID as generated using `fill` ([#342](https://github.com/ethereum/execution-spec-tests/pull/342)). + +### 📋 Misc + +- ✨ Docs: Add a ["Consuming Tests"](https://eest.ethereum.org/main/consuming_tests/) section to the docs, where each test fixture format is described, along with the steps to consume them, and the description of the structures used in each format ([#375](https://github.com/ethereum/execution-spec-tests/pull/375)). +- 🔀 Docs: Update `t8n` tool branch to fill tests for development features in the [readme](https://github.com/ethereum/execution-spec-tests) ([#338](https://github.com/ethereum/execution-spec-tests/pull/338)). +- 🔀 Filling tool: Updated the default filling tool (`t8n`) to go-ethereum@master ([#368](https://github.com/ethereum/execution-spec-tests/pull/368)). +- 🐞 Docs: Fix error banner in online docs due to mermaid syntax error ([#398](https://github.com/ethereum/execution-spec-tests/pull/398)). +- 🐞 Docs: Fix incorrectly formatted nested lists in online doc ([#403](https://github.com/ethereum/execution-spec-tests/pull/403)). +- 🔀 CLI: `evm_bytes_to_python` is renamed to `evm_bytes` and now accepts flag `--assembly` to output the code in assembly format ([#844](https://github.com/ethereum/execution-spec-tests/pull/844)). + +### 💥 Breaking Changes + +A concrete example of the test name renaming and change in directory structure is provided below. + +1. Fixture output, including release tarballs, now contain subdirectories for different test types: + + 1. `blockchain_tests`: Contains `BlockchainTest` formatted tests + 2. `blockchain_tests_hive`: Contains `BlockchainTest` with Engine API call directives for use in hive + 3. `state_tests`: Contains `StateTest` formatted tests + +2. `StateTest`, spec format used to write tests, is now limited to a single transaction per test. +3. In this release the pytest node ID is now used for fixture names (previously only the test parameters were used), this should not be breaking. However, `=` in both node IDs (and therefore fixture names) have been replaced with `_`, which may break tooling that depends on the `=` character. +4. Produced `blockchain_tests` fixtures and their corresponding `blockchain_tests_hive` fixtures now contain the named exceptions `BlockException` and `TransactionException` as strings in the `expectException` and `validationError` fields, respectively. These exceptions can be used to test whether the client is hitting the proper exception when processing an invalid block. + + Blockchain test: + + ```json + "blocks": [ + { + ... + "expectException": "TransactionException.INSUFFICIENT_ACCOUNT_FUNDS", + ... + } + ... + ] + ``` + + Blockchain hive test: + + ```json + "engineNewPayloads": [ + { + ... + "validationError": "TransactionException.INSUFFICIENT_ACCOUNT_FUNDS", + ... + } + ... + ] + ``` + +#### Renaming and Release Tarball Directory Structure Change Example + +The fixture renaming provides a more consistent naming scheme between the pytest node ID and fixture name and allows the fixture name to be provided directly to pytest 5on the command line to execute individual tests in isolation, e.g. `pytest tests/frontier/opcodes/test_dup.py::test_dup[fork_Frontier]`. + +1. Pytest node ID example: + + 1. Previous node ID: `tests/frontier/opcodes/test_dup.py::test_dup[fork=Frontier]`. + 2. New node ID: `tests/frontier/opcodes/test_dup.py::test_dup[fork_Frontier]`. + +2. Fixture name example: + + 1. Previous fixture name: `000-fork=Frontier` + 2. New fixture name: `tests/frontier/opcodes/test_dup.py::test_dup[fork_Frontier]` (now the same as the pytest node ID). + +3. Fixture JSON file name example (within the release tarball): + + 1. Previous fixture file name: `fixtures/frontier/opcodes/dup/dup.json` (`BlockChainTest` format). + 2. New fixture file names (all present within the release tarball): + + - `fixtures/state_tests/frontier/opcodes/dup/dup.json` (`StateTest` format). + - `fixtures/blockchain_tests/frontier/opcodes/dup/dup.json` (`BlockChainTest` format). + - `fixtures/blockchain_tests_hive/frontier/opcodes/dup/dup.json` (a blockchain test in `HiveFixture` format). + +## [v1.0.6](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.6) - 2023-10-19: 🐍🏖️ Cancun Devnet 10 + +### 🧪 Test Cases + +- 🔀 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Update KZG point evaluation test vectors to use data from the official KZG setup and Mainnet Trusted Setup ([#336](https://github.com/ethereum/execution-spec-tests/pull/336)). + +### 🛠️ Framework + +- 🔀 Fixtures: Add a non-RLP format field (`rlp_decoded`) to invalid blocks ([#322](https://github.com/ethereum/execution-spec-tests/pull/322)). +- 🔀 Spec: Refactor state and blockchain spec ([#307](https://github.com/ethereum/execution-spec-tests/pull/307)). + +### 🔧 EVM Tools + +- ✨ Run geth's `evm blocktest` command to verify JSON fixtures after test case execution (`--verify-fixtures`) ([#325](https://github.com/ethereum/execution-spec-tests/pull/325)). +- ✨ Enable tracing support for `ethereum-spec-evm` ([#289](https://github.com/ethereum/execution-spec-tests/pull/289)). + +### 📋 Misc + +- ✨ Tooling: Add Python 3.12 support ([#309](https://github.com/ethereum/execution-spec-tests/pull/309)). +- ✨ Process: Added a Github pull request template ([#308](https://github.com/ethereum/execution-spec-tests/pull/308)). +- ✨ Docs: Changelog updated post release ([#321](https://github.com/ethereum/execution-spec-tests/pull/321)). +- ✨ Docs: Add [a section explaining execution-spec-tests release artifacts](https://eest.ethereum.org/v4.1.0/consuming_tests/) ([#334](https://github.com/ethereum/execution-spec-tests/pull/334)). +- 🔀 T8N Tool: Branch used to generate the tests for Cancun is now [lightclient/go-ethereum@devnet-10](https://github.com/lightclient/go-ethereum/tree/devnet-10) ([#336](https://github.com/ethereum/execution-spec-tests/pull/336)). + +### 💥 Breaking Change + +- Fixtures now use the Mainnet Trusted Setup merged on [consensus-specs#3521](https://github.com/ethereum/consensus-specs/pull/3521) ([#336](https://github.com/ethereum/execution-spec-tests/pull/336)). + +## [v1.0.5](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.5) - 2023-09-26: 🐍🏖️ Cancun Devnet 9 Release 3 + +This release mainly serves to update the EIP-4788 beacon roots address to `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`, as updated in [ethereum/EIPs/pull/7672](https://github.com/ethereum/EIPs/pull/7672). + +### 🧪 Test Cases + +- 🐞 [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Fix invalid blob txs pre-Cancun engine response ([#306](https://github.com/ethereum/execution-spec-tests/pull/306)). +- ✨ [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788): Final update to the beacon root address ([#312](https://github.com/ethereum/execution-spec-tests/pull/312)). + +### 📋 Misc + +- ✨ Docs: Changelog added ([#305](https://github.com/ethereum/execution-spec-tests/pull/305)). +- ✨ CI/CD: Run development fork tests in Github Actions ([#302](https://github.com/ethereum/execution-spec-tests/pull/302)). +- ✨ CI/CD: Generate test JSON fixtures on push ([#303](https://github.com/ethereum/execution-spec-tests/pull/303)). + +### 💥 Breaking Change + +Please use development fixtures from now on when testing Cancun. These refer to changes that are currently under development within clients: + +- fixtures: All tests until the last stable fork (Shanghai). +- fixtures_develop: All tests until the last development fork (Cancun). +- fixtures_hive: All tests until the last stable fork (Shanghai) in hive format (Engine API directives instead of the usual BlockchainTest format). +- fixtures_develop_hive: All tests until the last development fork (Cancun) in hive format. + +## [v1.0.4](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.4) - 2023-09-21: 🐍 Cancun Devnet 9 Release 2 + +This release adds additional coverage to the current set of Cancun tests, up to the [Devnet-9 Cancun specification](https://notes.ethereum.org/@ethpandaops/dencun-devnet-9). + +**Note:** Additional EIP-4788 updates from [ethereum/EIPs/pull/7672](https://github.com/ethereum/EIPs/pull/7672) will be included in the next release. + +### 🧪 Test Cases + +- ✨ [EIP-7516: BLOBBASEFEE opcode](https://eips.ethereum.org/EIPS/eip-7516): Add first and comprehensive tests (@marioevz in [#294](https://github.com/ethereum/execution-spec-tests/pull/294)). +- ✨ [EIP-4788: Beacon block root in the EVM](https://eips.ethereum.org/EIPS/eip-4788): Increase coverage (@spencer-tb in [#297](https://github.com/ethereum/execution-spec-tests/pull/297)). +- 🐞 [EIP-1153: Transient storage opcodes](https://eips.ethereum.org/EIPS/eip-1153): Remove conftest '+1153' in network field (@spencer-tb in [#299](https://github.com/ethereum/execution-spec-tests/pull/299)). + +### 🛠️ Framework + +- 🔀 [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788): Beacon root contract is pre-deployed at `0xbEAC020008aFF7331c0A389CB2AAb67597567d7a` (@spencer-tb in [#297](https://github.com/ethereum/execution-spec-tests/pull/297)). +- ✨ Deprecate empty accounts within framework (@spencer-tb in [#300](https://github.com/ethereum/execution-spec-tests/pull/300)). +- ✨ Fixture generation split based on hive specificity (@spencer-tb in [#301](https://github.com/ethereum/execution-spec-tests/pull/301)). +- 💥 `fill`: `--disable-hive` flag removed; replaced by `--enable-hive` (@spencer-tb in [#301](https://github.com/ethereum/execution-spec-tests/pull/301)). +- ✨ Add engine API forkchoice updated information in fixtures (@spencer-tb in [#256](https://github.com/ethereum/execution-spec-tests/pull/256)). + +## [v1.0.3](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.3) - 2023-09-14: 🐍 Cancun Devnet 9 Release + +See [v1.0.3](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.3). + +## [v1.0.2](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.2) - 2023-08-11: 🐍 Cancun Devnet 8 + 4788 v2 Pre-Release + +See [v1.0.2](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.2). + +## [v1.0.1](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.1) - 2023-08-03: 🐍 Cancun Devnet-8 Pre-Release + +See [v1.0.1](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.1). + +## [v1.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.0) - 2023-06-27: 🧪 Welcome to the Pytest Era + +See [v1.0.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v1.0.0). + +Older releases can be found on [the releases page](https://github.com/ethereum/execution-spec-tests/releases). diff --git a/docs/changelog_section_template.md b/docs/changelog_section_template.md new file mode 100644 index 00000000000..dfa30a4ec83 --- /dev/null +++ b/docs/changelog_section_template.md @@ -0,0 +1,19 @@ +# Changelog Section Template + +The following can be copy-pasted into the `CHANGELOG.md` file for a new release. + +## 🔜 [Unreleased] + +### 💥 Breaking Change + +### 🛠️ Framework + +#### `fill` + +#### `consume` + +#### `execute` + +### 📋 Misc + +### 🧪 Test Cases diff --git a/docs/dev/docs.md b/docs/dev/docs.md index 3be9a658e6b..96fe14f6044 100644 --- a/docs/dev/docs.md +++ b/docs/dev/docs.md @@ -22,6 +22,7 @@ Run all docs related checks: just spellcheck just lint-md just docs +just changelog ``` ### Local Deployment and Test diff --git a/packages/testing/pyproject.toml b/packages/testing/pyproject.toml index 28a07929f12..12afa968097 100644 --- a/packages/testing/pyproject.toml +++ b/packages/testing/pyproject.toml @@ -60,6 +60,7 @@ Homepage = "https://github.com/ethereum/execution-specs" Documentation = "https://eest.ethereum.org" Repository = "https://github.com/ethereum/execution-specs" Issues = "https://github.com/ethereum/execution-specs/issues" +Changelog = "https://eest.ethereum.org/main/CHANGELOG/" [dependency-groups] test = [ @@ -98,6 +99,7 @@ groupstats = "execution_testing.cli.show_pre_alloc_group_stats:main" extract_config = "execution_testing.cli.extract_config:extract_config" compare_fixtures = "execution_testing.cli.compare_fixtures:main" modify_static_test_gas_limits = "execution_testing.cli.modify_static_test_gas_limits:main" +validate_changelog = "execution_testing.cli.ci_helpers:validate_changelog" benchmark_parser = "execution_testing.cli.benchmark_parser:main" [tool.setuptools.packages.find] diff --git a/packages/testing/src/execution_testing/__init__.py b/packages/testing/src/execution_testing/__init__.py index 212afbde267..57ef786c7a1 100644 --- a/packages/testing/src/execution_testing/__init__.py +++ b/packages/testing/src/execution_testing/__init__.py @@ -53,7 +53,6 @@ EOA, Alloc, AuthorizationTuple, - BalAccountAbsentValues, BalAccountChange, BalAccountExpectation, BalBalanceChange, @@ -127,7 +126,6 @@ "Address", "Alloc", "AuthorizationTuple", - "BalAccountAbsentValues", "BalAccountChange", "BalAccountExpectation", "BalBalanceChange", diff --git a/packages/testing/src/execution_testing/cli/ci_helpers.py b/packages/testing/src/execution_testing/cli/ci_helpers.py index e606252b4c0..e24c569166e 100644 --- a/packages/testing/src/execution_testing/cli/ci_helpers.py +++ b/packages/testing/src/execution_testing/cli/ci_helpers.py @@ -1,7 +1,7 @@ """ CLI helper commands for CI static checks. -Contains a wrapper to markdownlint-cli2 validation which fails +Contains wrappers to markdownlint-cli2 and changelog validation that fail silently if external tools are not available, to avoid disruption to external contributors. """ @@ -96,3 +96,53 @@ def markdownlint(args: tuple[str, ...]) -> None: command = ["node", markdownlint] + args_list sys.exit(subprocess.run(command).returncode) + + +@click.command() +def validate_changelog() -> None: + """ + Validate changelog formatting to ensure bullet points end with proper + punctuation. + + Check that all bullet points (including nested ones) end with either: + - A period (.) for regular entries + - A colon (:) for section headers that introduce lists + """ + project_root = find_project_root() + changelog_path = Path(project_root / "docs/CHANGELOG.md") + + if not changelog_path.exists(): + click.echo(f"❌ Changelog file not found: {changelog_path}") + sys.exit(1) + + try: + with open(changelog_path, "r", encoding="utf-8") as f: + content = f.read() + except Exception as e: + click.echo(f"❌ Error reading changelog: {e}.") + sys.exit(1) + + # Find bullet points that don't end with period or colon + invalid_lines = [] + for line_num, line in enumerate(content.splitlines(), 1): + if re.match(r"^\s*-\s+", line) and re.search( + r"[^\.:]$", line.rstrip() + ): + invalid_lines.append((line_num, line.strip())) + + if invalid_lines: + click.echo( + f"❌ Found bullet points in {changelog_path} without proper " + "punctuation:" + ) + click.echo() + for line_num, line in invalid_lines: + click.echo(f"Line {line_num}: {line}") + click.echo() + click.echo("💡 All bullet points should end with:") + click.echo(" - A period (.) for regular entries.") + click.echo(" - A colon (:) for paragraphs that introduce lists.") + sys.exit(1) + else: + click.echo("✅ All bullet points have proper punctuation!") + sys.exit(0) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py index f5c567627bb..9a15a9c3ecc 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute.py @@ -851,10 +851,13 @@ def pytest_collection_modifyitems( if isinstance(item, EIPSpecTestItem): continue params: Dict[str, Any] = item.callspec.params # type: ignore - if "fork" not in params or params["fork"] is None: + if ( + "parametrized_fork" not in params + or params["parametrized_fork"] is None + ): items_for_removal.append(i) continue - fork: Fork | TransitionFork = params["fork"] + fork: Fork | TransitionFork = params["parametrized_fork"] spec_type, execute_format = get_spec_format_for_item(params) assert issubclass(execute_format, BaseExecute) markers = list(item.iter_markers()) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py index 5a733c09ad5..1b1bdb1d7b2 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py @@ -1922,10 +1922,14 @@ def pytest_collection_modifyitems( params = item.callspec.params elif hasattr(item, "params"): params = item.params - if not params or "fork" not in params or params["fork"] is None: + if ( + not params + or "parametrized_fork" not in params + or params["parametrized_fork"] is None + ): items_for_removal.append(i) continue - fork: Fork | TransitionFork = params["fork"] + fork: Fork | TransitionFork = params["parametrized_fork"] spec_type, fixture_format = get_spec_format_for_item(params) if isinstance(fixture_format, NotSetType): items_for_removal.append(i) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py index f5eab27ac65..88a0e586066 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/gen_test_doc/gen_test_doc.py @@ -446,7 +446,7 @@ def create_function_page_props( ) for value in values ] - fork = item.callspec.params.get("fork").name() # type: ignore + fork = item.callspec.params.get("parametrized_fork").name() # type: ignore test_type = get_test_function_test_type(item) test_type_value = item.callspec.params.get(test_type) fixture_type = test_type_value.format_name # type: ignore diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py index 08b2195410f..c6d4ea6ecf5 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/static_filler.py @@ -275,7 +275,7 @@ def collect(self: "FillerFile") -> Generator["FillerTestItem", None, None]: ps_id = fixture_format_parameter_set.id test_id = f"fork_{fork.name()}-{ps_id}" if "fork" in func_parameters: - params["fork"] = fork + params["parametrized_fork"] = fork if "pre" in func_parameters: fixturenames.append("pre") if "request" in func_parameters: diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py index 2dc7336f6e8..6f1bb468a18 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/forks.py @@ -118,7 +118,7 @@ def __init__( marks = [] self.fork_covariant_parameters = [ ForkCovariantParameter( - names=["fork"], + names=["parametrized_fork"], values=[ pytest.param( fork, @@ -671,7 +671,7 @@ def pytest_report_header(config: pytest.Config, start_path: Any) -> List[str]: @pytest.fixture(autouse=True) -def fork(request: pytest.FixtureRequest) -> None: +def parametrized_fork(request: pytest.FixtureRequest) -> None: """Parametrize test cases by fork.""" pass @@ -1234,7 +1234,9 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: ], ) ] - metafunc.parametrize("fork", pytest_params, scope="function") + metafunc.parametrize( + "parametrized_fork", pytest_params, scope="function" + ) return # Get the intersection between the test's validity marker and the current @@ -1243,7 +1245,7 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: test_fork_set & metafunc.config.selected_fork_set # type: ignore ) - if "fork" not in metafunc.fixturenames: + if "parametrized_fork" not in metafunc.fixturenames: return unsupported_forks: Set[Fork | TransitionFork] = ( @@ -1266,7 +1268,9 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: ], ) ] - metafunc.parametrize("fork", pytest_params, scope="function") + metafunc.parametrize( + "parametrized_fork", pytest_params, scope="function" + ) else: pytest_params = [] for fork in sorted(intersection_set): @@ -1570,7 +1574,7 @@ def pytest_collection_modifyitems( continue # --- validity markers --- - fork = params.get("fork") + fork = params.get("parametrized_fork") if fork is None: continue diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py index cb1aa6da1f3..381eb4712fd 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_fork_parametrizer_types.py @@ -19,7 +19,7 @@ [ pytest.param( [ForkParametrizer(fork=Frontier)], - ["fork"], + ["parametrized_fork"], [pytest.param(Frontier)], id="only_fork", ), @@ -34,7 +34,7 @@ ], ) ], - ["fork", "some_value"], + ["parametrized_fork", "some_value"], [pytest.param(Frontier, 1)], id="fork_with_single_covariant_parameter", ), @@ -50,7 +50,7 @@ ], ) ], - ["fork", "some_value"], + ["parametrized_fork", "some_value"], [pytest.param(Frontier, 1), pytest.param(Frontier, 2)], id="fork_with_single_covariant_parameter_multiple_values", ), @@ -69,7 +69,7 @@ ], ) ], - ["fork", "some_value"], + ["parametrized_fork", "some_value"], [ pytest.param(Frontier, 1, marks=[pytest.mark.some_mark]), pytest.param(Frontier, 2), @@ -90,7 +90,7 @@ ], ) ], - ["fork", "some_value", "another_value"], + ["parametrized_fork", "some_value", "another_value"], [pytest.param(Frontier, 1, 2)], id="fork_with_multiple_covariant_parameters", ), @@ -109,7 +109,7 @@ ], ) ], - ["fork", "some_value", "another_value"], + ["parametrized_fork", "some_value", "another_value"], [pytest.param(Frontier, 1, 2), pytest.param(Frontier, 1, 3)], id="fork_with_multiple_covariant_parameters_multiple_values", ), @@ -128,7 +128,7 @@ ], ) ], - ["fork", "some_value", "another_value"], + ["parametrized_fork", "some_value", "another_value"], [pytest.param(Frontier, 1, "a"), pytest.param(Frontier, 2, "b")], id="fork_with_single_multi_value_covariant_parameter_multiple_values", ), @@ -155,7 +155,7 @@ ) ], [ - "fork", + "parametrized_fork", "some_value", "another_value", "yet_another_value", @@ -191,7 +191,12 @@ ], ) ], - ["fork", "shared_value", "different_value_1", "different_value_2"], + [ + "parametrized_fork", + "shared_value", + "different_value_1", + "different_value_2", + ], [ pytest.param(Frontier, 1, "a", "x"), pytest.param(Frontier, 2, "b", "y"), diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py index 2a47ed80365..ed98551a10e 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py @@ -553,16 +553,26 @@ def _is_benchmark_test(request: pytest.FixtureRequest) -> bool: @pytest.fixture -def genesis_environment(request: pytest.FixtureRequest) -> Environment: +def env_gas_limit(request: pytest.FixtureRequest) -> int: """Return an Environment with appropriate gas limit.""" if _is_benchmark_test(request): - return Environment(gas_limit=BENCHMARKING_MAX_GAS) + return BENCHMARKING_MAX_GAS + return EnvironmentDefaults.gas_limit + + +@pytest.fixture +def genesis_environment( + request: pytest.FixtureRequest, env_gas_limit: int +) -> Environment: + """Return an Environment with appropriate gas limit.""" + if _is_benchmark_test(request): + return Environment(gas_limit=env_gas_limit) return Environment() @pytest.fixture -def env(request: pytest.FixtureRequest) -> Environment: +def env(request: pytest.FixtureRequest, env_gas_limit: int) -> Environment: """Return an Environment with appropriate gas limit.""" if _is_benchmark_test(request): - return Environment(gas_limit=BENCHMARKING_MAX_GAS) + return Environment(gas_limit=env_gas_limit) return Environment() diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py index d827d96927a..8b33474dfc4 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/execute_fill.py @@ -2,8 +2,10 @@ Shared pytest fixtures and hooks for EEST generation modes (fill and execute). """ +from __future__ import annotations + from pathlib import Path -from typing import Dict, List, Tuple +from typing import TYPE_CHECKING, Dict, List, Tuple import pytest from pytest import StashKey @@ -15,11 +17,20 @@ LabeledExecuteFormat, ) from execution_testing.fixtures import BaseFixture, LabeledFixtureFormat + +if TYPE_CHECKING: + from execution_testing.forks import Fork, TransitionFork +import sys + from execution_testing.logging import get_logger from execution_testing.rpc import EthRPC from execution_testing.specs import BaseTest from execution_testing.specs.base import OpMode -from execution_testing.test_types import EOA, Alloc, ChainConfig +from execution_testing.test_types import ( + EOA, + Alloc, + ChainConfig, +) from ..shared.address_stubs import AddressStubs, StubEOA from ..shared.helpers import get_rpc_endpoint @@ -310,9 +321,58 @@ def pytest_make_parametrize_id( readable test ids for the generated tests. """ del config + if argname == "parametrized_fork": + return f"fork_{val}" return f"{argname}_{val}" +@pytest.fixture(scope="function") +def fork( + parametrized_fork: Fork | TransitionFork, + monkeypatch: pytest.MonkeyPatch, + env_gas_limit: int, +) -> Fork | TransitionFork: + """ + Return a per-test fork variant whose ``_env_gas_limit`` tracks the + ``Environment.gas_limit`` used by the test. + """ + fork_variant = parametrized_fork.with_env_gas_limit(env_gas_limit) + + # Now we monkey-patch the `Environment` class with one that is aware of + # the fork that the test is using, and will update its `_env_gas_limit` + # automatically. + # TODO: This should not be necessary, we should treat the `env` object the + # same way we do `pre` and force it to be a singleton in the test's + # context. + from execution_testing.test_types.block_types import ( + Environment as OriginalEnvironment, + ) + + class _ForkAwareEnvironment(OriginalEnvironment): + """Transparently syncs ``gas_limit`` back to the fork variant.""" + + def model_post_init(self, __context: object) -> None: + super().model_post_init(__context) + fork_variant._env_gas_limit = int(self.gas_limit) + + def __setattr__(self, name: str, value: object) -> None: + super().__setattr__(name, value) + if name == "gas_limit": + fork_variant._env_gas_limit = int(self.gas_limit) + + # Replace Environment in every module that imported the original class + # so that both `Environment(...)` in test code and in conftest fixtures + # create _ForkAwareEnvironment instances. + for mod in list(sys.modules.values()): + try: + if getattr(mod, "Environment", None) is OriginalEnvironment: + monkeypatch.setattr(mod, "Environment", _ForkAwareEnvironment) + except Exception: + continue + + return fork_variant + + SPEC_TYPES_PARAMETERS: List[str] = list(BaseTest.spec_types.keys()) diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index c074c3da840..afdc3ccfbc0 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -184,7 +184,7 @@ def __repr__(cls) -> str: return cls.name() @staticmethod - def _maybe_transitioned(fork_cls: "BaseForkMeta") -> "BaseForkMeta": + def _maybe_transitioned(fork_cls: type) -> type: """ Return the transitioned fork, if a transition fork, otherwise return `fork_cls`. @@ -198,35 +198,54 @@ def _maybe_transitioned(fork_cls: "BaseForkMeta") -> "BaseForkMeta": @staticmethod def _is_subclass_of(a: "BaseForkMeta", b: "BaseForkMeta") -> bool: """ - Check if `a` is a subclass of `b`, taking fork transitions into - account. + Check if `a` is a subclass of `b`, taking fork transitions and + variants (created by `with_env_gas_limit`) into account. """ - a = BaseForkMeta._maybe_transitioned(a) - b = BaseForkMeta._maybe_transitioned(b) - return issubclass(a, b) + # Resolve variants to canonical identity so comparisons between + # a variant and a canonical descendant fork work as expected. + a_id: type = BaseForkMeta._identity(a) + b_id: type = BaseForkMeta._identity(b) + a_id = BaseForkMeta._maybe_transitioned(a_id) + b_id = BaseForkMeta._maybe_transitioned(b_id) + return issubclass(a_id, b_id) + + @staticmethod + def _identity(fork_cls: type) -> type: + """Return the canonical fork class, resolving variants.""" + base = getattr(fork_cls, "_base_fork", None) + return base if base is not None else fork_cls + + def __eq__(cls, other: object) -> bool: + """Compare fork identity, treating variants as equal to parents.""" + if not isinstance(other, BaseForkMeta): + return NotImplemented + return BaseForkMeta._identity(cls) is BaseForkMeta._identity(other) + + def __hash__(cls) -> int: + """Hash by canonical fork identity.""" + return id(BaseForkMeta._identity(cls)) def __gt__(cls, other: "BaseForkMeta") -> bool: """Compare if a fork is newer than some other fork (cls > other).""" - return cls is not other and BaseForkMeta._is_subclass_of(cls, other) + return cls != other and BaseForkMeta._is_subclass_of(cls, other) def __ge__(cls, other: "BaseForkMeta") -> bool: """ Compare if a fork is newer than or equal to some other fork (cls >= other). """ - return cls is other or BaseForkMeta._is_subclass_of(cls, other) + return cls == other or BaseForkMeta._is_subclass_of(cls, other) def __lt__(cls, other: "BaseForkMeta") -> bool: """Compare if a fork is older than some other fork (cls < other).""" - # "Older" means other is a subclass of cls, but not the same. - return cls is not other and BaseForkMeta._is_subclass_of(other, cls) + return cls != other and BaseForkMeta._is_subclass_of(other, cls) def __le__(cls, other: "BaseForkMeta") -> bool: """ Compare if a fork is older than or equal to some other fork (cls <= other). """ - return cls is other or BaseForkMeta._is_subclass_of(other, cls) + return cls == other or BaseForkMeta._is_subclass_of(other, cls) class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta): @@ -246,6 +265,10 @@ class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta): _ruleset_name: ClassVar[Optional[str]] = None _fork_by_timestamp: ClassVar[bool] = False _blob_constants: ClassVar[Dict[str, int]] = {} + + # Environment overrides (set on variants created by with_env_gas_limit) + _base_fork: ClassVar[Optional[Type["BaseFork"]]] = None + _env_gas_limit: ClassVar[int] = 0 _deployed: ClassVar[bool] = True _enabled_eips: ClassVar[Set[int]] = set() _enabling_forks: ClassVar[Set[Type["BaseFork"]]] = set() @@ -1109,6 +1132,24 @@ def children(cls) -> Set[Type["BaseFork"]]: """Return the children forks.""" return set(cls._children) + @classmethod + def with_env_gas_limit(cls, env_gas_limit: int) -> Type["BaseFork"]: + """Return a new fork class with the specified environment gas limit.""" + new_cls = type(cls.__name__, (cls,), {}) + # __init_subclass__ resets per-class overrides; restore from parent. + new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] + new_cls._base_fork = cls._base_fork or cls # type: ignore[attr-defined] + new_cls._transition_tool_name = ( # type: ignore[attr-defined] + cls._transition_tool_name + ) + new_cls._solc_name = cls._solc_name # type: ignore[attr-defined] + new_cls._ignore = cls._ignore # type: ignore[attr-defined] + new_cls._bpo_fork = cls._bpo_fork # type: ignore[attr-defined] + new_cls._ruleset_name = cls._ruleset_name # type: ignore[attr-defined] + # Prevent the variant from appearing in fork traversals. + cls._children.discard(new_cls) + return new_cls + @classmethod @abstractmethod def build_default_block_header( diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index eae6f4f0a3b..e40f100b709 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -24,6 +24,7 @@ Paris, Prague, Shanghai, + SpuriousDragon, ) from ..forks.transition import ( BerlinToLondonAt5, @@ -731,3 +732,54 @@ def test_eips() -> None: # noqa: D103 assert not Paris.is_eip_enabled(3675, 3855) assert not Paris.is_eip_enabled(3855, 3675) assert Shanghai.is_eip_enabled(3855) + + +def test_fork_variant_ordering() -> None: + """ + Variants from `with_env_gas_limit` must compare consistently with + their canonical parent: equal to the parent, ordered identically + against other canonical forks. + """ + variant = London.with_env_gas_limit(30_000_000) + + assert variant == London + assert hash(variant) == hash(London) + + assert variant > SpuriousDragon + assert variant >= SpuriousDragon + assert variant < Cancun + assert variant <= Cancun + + assert not (variant > London) + assert not (variant < London) + assert variant >= London + assert variant <= London + + +def test_transition_fork_variant_equality() -> None: + """ + Variants of a transition fork created via `with_env_gas_limit` must + compare equal to their canonical parent and to each other, even when + different gas limits are used. Distinct canonical transition forks + must remain unequal. + """ + canonical = CancunToPragueAtTime15k + variant_a = canonical.with_env_gas_limit(30_000_000) + variant_b = canonical.with_env_gas_limit(45_000_000) + variant_c = canonical.with_env_gas_limit(30_000_000) + + assert variant_a is not canonical + assert variant_a is not variant_b + assert variant_a is not variant_c + + assert variant_a == canonical + assert variant_b == canonical + assert variant_a == variant_b + assert variant_a == variant_c + + assert hash(variant_a) == hash(canonical) + assert hash(variant_b) == hash(canonical) + assert hash(variant_c) == hash(canonical) + + assert canonical != PragueToOsakaAtTime15k + assert variant_a != PragueToOsakaAtTime15k diff --git a/packages/testing/src/execution_testing/forks/transition_base_fork.py b/packages/testing/src/execution_testing/forks/transition_base_fork.py index 3dca0cb1d31..482b3c877ff 100644 --- a/packages/testing/src/execution_testing/forks/transition_base_fork.py +++ b/packages/testing/src/execution_testing/forks/transition_base_fork.py @@ -1,8 +1,8 @@ """Base objects used to define transition forks.""" -from typing import Any, Callable, ClassVar, Dict, Type +from typing import Any, Callable, ClassVar, Dict, Optional, Type -from .base_fork import BaseFork +from .base_fork import BaseFork, BaseForkMeta class TransitionBaseMetaClass(type): @@ -15,6 +15,19 @@ def name(cls) -> str: """ raise Exception("Not implemented") + def __eq__(cls, other: object) -> bool: + """ + Compare transition fork identity, treating variants created by + `with_env_gas_limit` as equal to their canonical parent. + """ + if not isinstance(other, type): + return NotImplemented + return BaseForkMeta._identity(cls) is BaseForkMeta._identity(other) + + def __hash__(cls) -> int: + """Hash by canonical transition fork identity.""" + return id(BaseForkMeta._identity(cls)) + def transitions_to(cls) -> Type[BaseFork]: """ Return fork where the transition ends. @@ -75,6 +88,8 @@ class TransitionBaseClass(metaclass=TransitionBaseMetaClass): at_block: ClassVar[int] = 0 at_timestamp: ClassVar[int] = 0 _ignore: ClassVar[bool] = False + _env_gas_limit: ClassVar[int] = 0 + _base_fork: ClassVar[Optional[Type["TransitionBaseClass"]]] = None @classmethod def fork_at( @@ -106,6 +121,19 @@ def ruleset(cls) -> Dict[str, int]: """ raise Exception("Not implemented") + @classmethod + def with_env_gas_limit( + cls, env_gas_limit: int + ) -> Type["TransitionBaseClass"]: + """ + Return a new transition fork class with the specified environment + gas limit. + """ + new_cls = type(cls.__name__, (cls,), {}) + new_cls._env_gas_limit = env_gas_limit # type: ignore[attr-defined] + new_cls._base_fork = cls._base_fork or cls # type: ignore[attr-defined] + return new_cls + def transition_fork( to_fork: Type[BaseFork], @@ -134,23 +162,30 @@ class NewTransitionClass( ): _ignore = ignore + @classmethod + def _propagate_env(cls, fork: Type[BaseFork]) -> Type[BaseFork]: + if cls._env_gas_limit: + return fork.with_env_gas_limit(cls._env_gas_limit) + return fork + @classmethod def transitions_to(cls) -> Type[BaseFork]: - return to_fork + return cls._propagate_env(to_fork) @classmethod def transitions_from(cls) -> Type[BaseFork]: - return from_fork + return cls._propagate_env(from_fork) @classmethod def fork_at( cls, *, block_number: int = 0, timestamp: int = 0 ) -> Type[BaseFork]: - return ( + fork = ( to_fork if block_number >= at_block and timestamp >= at_timestamp else from_fork ) + return cls._propagate_env(fork) @classmethod def name(cls) -> str: diff --git a/packages/testing/src/execution_testing/test_types/__init__.py b/packages/testing/src/execution_testing/test_types/__init__.py index b9029ceb3ad..979a76d49ba 100644 --- a/packages/testing/src/execution_testing/test_types/__init__.py +++ b/packages/testing/src/execution_testing/test_types/__init__.py @@ -3,7 +3,6 @@ from .account_types import EOA, Alloc from .blob_types import Blob from .block_access_list import ( - BalAccountAbsentValues, BalAccountChange, BalAccountExpectation, BalBalanceChange, @@ -55,7 +54,6 @@ "DETERMINISTIC_FACTORY_ADDRESS", "Alloc", "AuthorizationTuple", - "BalAccountAbsentValues", "BalAccountChange", "BalAccountExpectation", "BalBalanceChange", diff --git a/packages/testing/src/execution_testing/tools/utility/generators.py b/packages/testing/src/execution_testing/tools/utility/generators.py index ca28a5b9fe1..78a9f172c51 100644 --- a/packages/testing/src/execution_testing/tools/utility/generators.py +++ b/packages/testing/src/execution_testing/tools/utility/generators.py @@ -483,9 +483,9 @@ def gas_test( if cold_gas is None: cold_gas = subject_code.gas_cost(fork) - if cold_gas < 0: + if cold_gas <= 0: raise ValueError( - f"Target gas allocations (cold_gas) must be >= 0, got {cold_gas}" + f"Target gas allocations (cold_gas) must be > 0, got {cold_gas}" ) if warm_gas is None: if subject_code_warm is not None: @@ -503,12 +503,18 @@ def gas_test( balance=subject_balance, address=subject_address, ) - - # Auxiliary instructions charged for at every gas run + # 2 times GAS, POP, CALL, 6 times PUSH1 - instructions charged for at every + # gas run + gas_costs = fork.gas_costs() + opcode_gas_cost = gas_costs.BASE + opcode_pop_cost = gas_costs.BASE + opcode_push_cost = gas_costs.VERY_LOW gas_single_gas_run = ( - Op.GAS + Op.CALL(gas=Op.GAS, address_warm=True) + Op.POP - ).gas_cost(fork=fork) - + 2 * opcode_gas_cost + + opcode_pop_cost + + gas_costs.WARM_ACCESS + + 6 * opcode_push_cost + ) address_legacy_harness = pre.deploy_contract( code=( # warm subject and baseline without executing @@ -618,15 +624,8 @@ def gas_test( LEGACY_CALL_SUCCESS ) - gas_sstore = Op.SSTORE(1, 1).gas_cost(fork=fork) if tx_gas is None: - tx_gas = ( - 5 * gas_single_gas_run - + cold_gas - + 4 * warm_gas - + 5 * gas_sstore - + 500_000 - ) + tx_gas = gas_single_gas_run + cold_gas + 500_000 tx = Transaction( to=address_legacy_harness, gas_limit=tx_gas, sender=sender ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 2226d9f78ff..ba4fbd5f221 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -9,7 +9,6 @@ Address, Alloc, AuthorizationTuple, - BalAccountAbsentValues, BalAccountExpectation, BalBalanceChange, BalCodeChange, @@ -2698,158 +2697,3 @@ def test_bal_gas_limit_boundary( post={}, genesis_environment=Environment(gas_limit=gas_limit), ) - - -@pytest.mark.parametrize( - "pre_value", - [ - pytest.param(0x00, id="slot_starts_empty"), - pytest.param(0x11, id="slot_starts_nonzero"), - pytest.param(0xBB, id="intermediate_equals_pre"), - ], -) -def test_bal_intra_tx_multiple_sstores_same_slot( - pre: Alloc, - blockchain_test: BlockchainTestFiller, - pre_value: int, -) -> None: - """ - Test that consecutive SSTOREs to the same slot within one tx produce a - single storage change with the final post-value; intermediate writes - (0xAA, 0xBB) must not appear in the BAL. - """ - alice = pre.fund_eoa(amount=10**18) - - code = ( - Op.SSTORE(0x01, 0xAA) + Op.SSTORE(0x01, 0xBB) + Op.SSTORE(0x01, 0xCC) - ) - contract = pre.deploy_contract(code=code, storage={0x01: pre_value}) - - tx = Transaction( - sender=alice, - to=contract, - gas_limit=200_000, - ) - - blockchain_test( - pre=pre, - blocks=[ - Block( - txs=[tx], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - alice: BalAccountExpectation( - nonce_changes=[ - BalNonceChange( - block_access_index=1, post_nonce=1 - ), - ], - ), - contract: BalAccountExpectation( - storage_changes=[ - BalStorageSlot( - slot=0x01, - slot_changes=[ - BalStorageChange( - block_access_index=1, - post_value=0xCC, - ), - ], - ), - ], - storage_reads=[], - balance_changes=[], - code_changes=[], - absent_values=BalAccountAbsentValues( - storage_changes=[ - BalStorageSlot( - slot=0x01, - slot_changes=[ - BalStorageChange( - block_access_index=1, - post_value=0xAA, - ), - BalStorageChange( - block_access_index=1, - post_value=0xBB, - ), - ], - ), - ], - ), - ), - } - ), - ) - ], - post={ - alice: Account(nonce=1), - contract: Account(storage={0x01: 0xCC}), - }, - ) - - -@pytest.mark.parametrize( - "pre_value,writes", - [ - pytest.param( - 0xCC, [0xAA, 0xBB, 0xCC], id="nonzero_pre_returns_to_pre" - ), - pytest.param( - 0x00, [0xAA, 0xBB, 0x00], id="empty_pre_ephemeral_writes" - ), - ], -) -def test_bal_intra_tx_sstores_same_slot_net_zero( - pre: Alloc, - blockchain_test: BlockchainTestFiller, - pre_value: int, - writes: list[int], -) -> None: - """ - Test that consecutive SSTOREs to the same slot within one tx with a - net-zero result are filtered: the slot must appear in storage_reads - (it was accessed) but must not appear in storage_changes. - """ - alice = pre.fund_eoa(amount=10**18) - - code = Op.SSTORE(0x01, writes[0]) - for v in writes[1:]: - code += Op.SSTORE(0x01, v) - contract = pre.deploy_contract(code=code, storage={0x01: pre_value}) - - tx = Transaction( - sender=alice, - to=contract, - gas_limit=200_000, - ) - - blockchain_test( - pre=pre, - blocks=[ - Block( - txs=[tx], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - alice: BalAccountExpectation( - nonce_changes=[ - BalNonceChange( - block_access_index=1, post_nonce=1 - ), - ], - ), - contract: BalAccountExpectation( - storage_reads=[0x01], - storage_changes=[], - balance_changes=[], - code_changes=[], - ), - } - ), - ) - ], - post={ - alice: Account(nonce=1), - contract: Account(storage={0x01: pre_value}), - }, - ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index bd89ac5f66b..dd307611502 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -69,8 +69,6 @@ | `test_bal_multiple_storage_writes_same_slot` | Ensure BAL tracks multiple writes to same storage slot across transactions | Alice calls contract 3 times in same block. Contract increments slot 1 on each call: 0 → 1 → 2 → 3 | BAL **MUST** include contract with slot 1 having three `slot_changes`: txIndex=1 (value 1), txIndex=2 (value 2), txIndex=3 (value 3). Each transaction's write must be recorded separately. | ✅ Completed | | `test_bal_nested_delegatecall_storage_writes_net_zero` | Ensure BAL correctly filters net-zero storage changes across nested DELEGATECALL frames | Parametrized by nesting depth (1-3). Root contract has slot 0 = 1. Each frame writes a different intermediate value via DELEGATECALL chain, deepest frame writes back to original value (1). Example depth=2: 1 → 2 → 3 → 1 | BAL **MUST** include root contract with `storage_reads` for slot 0 but **MUST NOT** include `storage_changes` (net-zero). All delegate contracts **MUST** have empty changes. Tests that frame merging correctly removes parent's intermediate writes when child reverts to pre-tx value. | ✅ Completed | | `test_bal_cross_tx_storage_revert_to_zero` | Ensure BAL captures storage changes when tx2 reverts slot back to original value (blobhash regression test) | Alice sends tx1 writing slot 0=0xABCD (from 0x0), then tx2 writing slot 0=0x0 (back to original) | BAL **MUST** include contract with slot 0 having two `slot_changes`: txIndex=1 (0xABCD) and txIndex=2 (0x0). Cross-transaction net-zero **MUST NOT** be filtered. | ✅ Completed | -| `test_bal_intra_tx_multiple_sstores_same_slot` | Ensure BAL coalesces consecutive SSTOREs to the same slot within one tx into a single storage change with the final post-value | Contract executes `SSTORE(0x01, 0xAA) + SSTORE(0x01, 0xBB) + SSTORE(0x01, 0xCC)` in one tx. Parametrized by `pre_value`: `slot_starts_empty` (0x00), `slot_starts_nonzero` (0x11), `intermediate_equals_pre` (0xBB, where the second write transiently matches the pre-state). | BAL **MUST** include contract with slot `0x01` having exactly one `slot_changes` entry: `txIndex=1, post_value=0xCC`. Intermediate values `0xAA` and `0xBB` **MUST NOT** appear as separate entries (enforced via `absent_values`). | ✅ Completed | -| `test_bal_intra_tx_sstores_same_slot_net_zero` | Ensure BAL filters net-zero result when multiple SSTOREs to the same slot occur within one tx | Parametrized: `nonzero_pre_returns_to_pre` (pre=0xCC, writes 0xAA→0xBB→0xCC) and `empty_pre_ephemeral_writes` (pre=0x00, writes 0xAA→0xBB→0x00). Final value equals pre-state in both cases. | BAL **MUST** include contract with slot `0x01` in `storage_reads` (slot was accessed) and **MUST NOT** include slot `0x01` in `storage_changes` (net-zero). | ✅ Completed | | `test_bal_create_contract_init_revert` | Ensure BAL correctly handles CREATE when parent call reverts | Caller calls factory, factory executes CREATE (succeeds), then factory REVERTs rolling back the CREATE | BAL **MUST** include Alice with `nonce_changes`. Caller and factory with no changes (reverted). Created contract address appears in BAL but **MUST NOT** have `nonce_changes` or `code_changes` (CREATE was rolled back). Contract address **MUST NOT** exist in post-state. | ✅ Completed | | `test_bal_create_oog_code_deposit` | Ensure BAL correctly handles CREATE OOG during code deposit | Alice calls factory contract that executes CREATE with init code returning 10,000 bytes. Transaction has insufficient gas for code deposit. Factory nonce increments, CREATE returns 0 and stores in slot 1. | BAL **MUST** include Alice with `nonce_changes`. Factory with `nonce_changes` (incremented by CREATE) and `storage_changes` (slot 1 = 0). Contract address with empty changes (read during collision check). **MUST NOT** include nonce or code changes for contract address (rolled back on OOG). Contract address **MUST NOT** exist in post-state. | ✅ Completed | | `test_bal_create_early_failure` | Ensure BAL correctly handles CREATE that fails before accessing contract address | Factory (balance=50) attempts CREATE(value=100). CREATE fails due to insufficient endowment (100 > 50). Factory stores CREATE result (0) in slot 0. | BAL **MUST** include Alice with `nonce_changes`. Factory with `storage_changes` (slot 0 = 0) but **MUST NOT** have `nonce_changes` (CREATE failed before nonce increment). Contract address **MUST NOT** appear in BAL (never accessed - CREATE failed before `track_address`). This is distinct from collision/OOG failures where contract address IS in BAL. | ✅ Completed | diff --git a/tests/benchmark/compute/precompile/test_alt_bn128.py b/tests/benchmark/compute/precompile/test_alt_bn128.py index d95345f5132..dfb63a9aeab 100644 --- a/tests/benchmark/compute/precompile/test_alt_bn128.py +++ b/tests/benchmark/compute/precompile/test_alt_bn128.py @@ -40,35 +40,6 @@ id="bn128_add", marks=pytest.mark.repricing, ), - pytest.param( - 0x06, - concatenate_parameters( - [ - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - ] - ), - Precompile.BN128_ADD, - id="bn128_double", - marks=pytest.mark.repricing, - ), - # Second point is the negative of the first one - pytest.param( - 0x06, - concatenate_parameters( - [ - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "063C909C4720840CB5134CB9F59FA749755796819658D32EFC0D288198F37266", - "18B18ACFB4C2C30276DB5411368E7185B311DD124691610C5D3B74034E093DC9", - "2A27BDD69A111C1D033CF8FC8BE1B1142229D40FD218F75E401363953F898AE1", - ] - ), - Precompile.BN128_ADD, - id="bn128_add_negative", - marks=pytest.mark.repricing, - ), # Ported from # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCase.cs#L326 pytest.param( diff --git a/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py b/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py index 6ee241be0fc..1dc82ea1ed4 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py @@ -18,7 +18,6 @@ compute_create_address, ) from execution_testing import Macros as Om -from execution_testing.forks.helpers import Fork from . import CreateOpcodeParams, PytestParameterEnum from .spec import ref_spec_1153 @@ -272,7 +271,6 @@ def test_tstore_rollback_on_failed_create( state_test: StateTestFiller, pre: Alloc, create_opcode: Op, - fork: Fork, ) -> None: """ Test TSTORE is rolled back after failed CREATE/CREATE2 initcode. @@ -298,13 +296,11 @@ def test_tstore_rollback_on_failed_create( # # TLOAD(1)==0: return_size = 0x600a > max code size -> fail # TLOAD(1)==0x6000: return_size = 0x0a <= max code size -> succeed - max_code_size = fork.max_code_size() - initcode = ( Op.TLOAD(1) - + Op.PUSH4(max_code_size + 0x0A) + + Op.PUSH2(0x600A) + Op.SUB - + Op.TSTORE(1, max_code_size) + + Op.TSTORE(1, 0x6000) + Op.PUSH1(0) + Op.RETURN ) diff --git a/tests/frontier/opcodes/test_all_opcodes.py b/tests/frontier/opcodes/test_all_opcodes.py index 774df19e4af..35c8be2953f 100644 --- a/tests/frontier/opcodes/test_all_opcodes.py +++ b/tests/frontier/opcodes/test_all_opcodes.py @@ -223,6 +223,9 @@ def constant_gas_opcodes(fork: Fork) -> Generator[ParameterSet, None, None]: # delta used by gas_test. Excluded to keep the test meaningful. if fork.is_eip_enabled(8037) and opcode in (Op.CREATE, Op.CREATE2): continue + if opcode.gas_cost(fork) == 0: + # zero constant gas opcodes - untestable + continue yield pytest.param( opcode, id=f"{opcode}", @@ -264,5 +267,4 @@ def test_constant_gas( subject_code=opcode, subject_code_warm=warm_opcode, tear_down_code=prepare_suffix(opcode), - out_of_gas_testing=opcode.gas_cost(fork) > 0, ) diff --git a/tests/shanghai/eip3860_initcode/test_initcode.py b/tests/shanghai/eip3860_initcode/test_initcode.py index f76bca44c2a..08e56b48c48 100644 --- a/tests/shanghai/eip3860_initcode/test_initcode.py +++ b/tests/shanghai/eip3860_initcode/test_initcode.py @@ -605,7 +605,6 @@ def test_create2_oversized_initcode_with_insufficient_balance( pre: Alloc, initcode_oversize: bool, expected_storage_1: int, - fork: Fork, ) -> None: """ Test CREATE2 with oversized initcode and insufficient balance. @@ -622,9 +621,7 @@ def test_create2_oversized_initcode_with_insufficient_balance( - Initcode within limit: insufficient balance pushes 0, execution continues, SSTORE(1, 1) executes, so storage slot 1 becomes 1. """ - initcode_size = ( - fork.max_initcode_size() * 2 if initcode_oversize else 0x100 - ) + initcode_size = 0x20000 if initcode_oversize else 0x100 caller_code = ( Op.CREATE2(1123123123, 0, initcode_size, 0) + Op.POP + Op.SSTORE(1, 1) ) diff --git a/tox.ini b/tox.ini index f390f3ada51..98b485cbbd5 100644 --- a/tox.ini +++ b/tox.ini @@ -74,6 +74,11 @@ commands = printf '\n\033[1m execution-specs has migrated from tox to just.\033[0m\n Install just: https://just.systems/man/en/pre-built-binaries.html\n\n This tox env can be run using just via:\n \033[1mjust docs\033[0m\n\n' false +[testenv:changelog] +commands = + printf '\n\033[1m execution-specs has migrated from tox to just.\033[0m\n Install just: https://just.systems/man/en/pre-built-binaries.html\n\n This tox env can be run using just via:\n \033[1mjust changelog\033[0m\n\n' + false + [testenv:markdownlint] commands = printf '\n\033[1m execution-specs has migrated from tox to just.\033[0m\n Install just: https://just.systems/man/en/pre-built-binaries.html\n\n This tox env can be run using just via:\n \033[1mjust lint-md\033[0m\n\n' From 8732abefaecea103ba9b630ed583ac042e58b4e8 Mon Sep 17 00:00:00 2001 From: kclowes Date: Tue, 19 May 2026 00:28:46 -0600 Subject: [PATCH 088/186] feat(tests): EIP-7843 Add test cases for multi-blocks and fork transition (#2858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(tests): EIP-7843 Add test cases for multi-blocks and fork transition * PR feedback * doc: update comment --------- Co-authored-by: 蔡佳誠 Louis Tsai <72684086+LouisTsai-Csie@users.noreply.github.com> --- tests/amsterdam/eip7843_slotnum/spec.py | 22 ++++++ .../eip7843_slotnum/test_eip_mainnet.py | 53 +++++++++++++++ .../eip7843_slotnum/test_fork_transition.py | 68 +++++++++++++++++++ .../amsterdam/eip7843_slotnum/test_slotnum.py | 54 +++++++++++---- 4 files changed, 182 insertions(+), 15 deletions(-) create mode 100644 tests/amsterdam/eip7843_slotnum/spec.py create mode 100644 tests/amsterdam/eip7843_slotnum/test_eip_mainnet.py create mode 100644 tests/amsterdam/eip7843_slotnum/test_fork_transition.py diff --git a/tests/amsterdam/eip7843_slotnum/spec.py b/tests/amsterdam/eip7843_slotnum/spec.py new file mode 100644 index 00000000000..a96172631f4 --- /dev/null +++ b/tests/amsterdam/eip7843_slotnum/spec.py @@ -0,0 +1,22 @@ +"""Reference spec for [EIP-7843: SLOTNUM](https://eips.ethereum.org/EIPS/eip-7843).""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ReferenceSpec: + """Reference specification.""" + + git_path: str + version: str + + +ref_spec_7843 = ReferenceSpec( + git_path="EIPS/eip-7843.md", + version="6bc5d6b7acbc016a79fa573f98975093b5c2ca52", +) + + +@dataclass(frozen=True) +class Spec: + """Constants and parameters from EIP-7843.""" diff --git a/tests/amsterdam/eip7843_slotnum/test_eip_mainnet.py b/tests/amsterdam/eip7843_slotnum/test_eip_mainnet.py new file mode 100644 index 00000000000..0cca8f2cd21 --- /dev/null +++ b/tests/amsterdam/eip7843_slotnum/test_eip_mainnet.py @@ -0,0 +1,53 @@ +""" +Mainnet marked execute checklist tests for +[EIP-7843: SLOTNUM](https://eips.ethereum.org/EIPS/eip-7843). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Environment, + Op, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_7843 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7843.git_path +REFERENCE_SPEC_VERSION = ref_spec_7843.version + +pytestmark = [pytest.mark.valid_at("EIP7843"), pytest.mark.mainnet] + + +def test_slotnum_mainnet( + state_test: StateTestFiller, + pre: Alloc, +) -> None: + """ + Test that SLOTNUM is callable and returns a non-zero slot number. + + Asserts on ``POP(SLOTNUM)`` rather than the slot value itself + so the test remains valid when ``execute``-ed against a live network, + where the slot number is whatever the consensus layer transmits and + cannot be controlled by the test. + """ + contract = pre.deploy_contract( + code=Op.POP(Op.SLOTNUM) + Op.SSTORE(0, 1), + storage={"0x00": "0xdeadbeef"}, + ) + tx = Transaction( + ty=0x02, + to=contract, + sender=pre.fund_eoa(), + gas_limit=200_000, + ) + post = {contract: Account(storage={"0x00": 1})} + + state_test( + env=Environment(), + pre=pre, + tx=tx, + post=post, + ) diff --git a/tests/amsterdam/eip7843_slotnum/test_fork_transition.py b/tests/amsterdam/eip7843_slotnum/test_fork_transition.py new file mode 100644 index 00000000000..210e3a5001b --- /dev/null +++ b/tests/amsterdam/eip7843_slotnum/test_fork_transition.py @@ -0,0 +1,68 @@ +"""Tests for EIP-7843 fork transition behavior.""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Block, + BlockchainTestFiller, + Op, + Transaction, +) + +from .spec import ref_spec_7843 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7843.git_path +REFERENCE_SPEC_VERSION = ref_spec_7843.version + + +@pytest.mark.valid_at_transition_to("EIP7843") +def test_slotnum_at_fork_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test SLOTNUM behavior across the EIP-7843 fork transition. + + Before EIP-7843, opcode 0x4B is undefined: execution halts with an + invalid-opcode exception and consumes all gas, so no SSTORE is observed. + + From EIP-7843 onward, SLOTNUM pushes the block's slot number provided + by the consensus layer and the SSTORE succeeds. + + The contract keys storage by block number so each block's outcome is + independently visible in the final post-state: + + * block 1 (pre-fork): slot 1 stays 0 — execution halted before SSTORE. + * block 2 (transition): slot 2 == ``at_fork_slot``. + * block 3 (post-fork): slot 3 == ``post_fork_slot``. + """ + sender = pre.fund_eoa() + contract = pre.deploy_contract(Op.SSTORE(Op.NUMBER, Op.SLOTNUM) + Op.STOP) + + at_fork_slot = 200 + post_fork_slot = 201 + + blocks = [ + Block( + timestamp=ts, + slot_number=slot, + txs=[Transaction(sender=sender, to=contract, gas_limit=100_000)], + ) + for ts, slot in [ + (14_999, None), + (15_000, at_fork_slot), + (15_001, post_fork_slot), + ] + ] + post = { + contract: Account( + storage={ + 1: 0, + 2: at_fork_slot, + 3: post_fork_slot, + }, + ), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) diff --git a/tests/amsterdam/eip7843_slotnum/test_slotnum.py b/tests/amsterdam/eip7843_slotnum/test_slotnum.py index 65358ebb31c..c3387c957e4 100644 --- a/tests/amsterdam/eip7843_slotnum/test_slotnum.py +++ b/tests/amsterdam/eip7843_slotnum/test_slotnum.py @@ -1,11 +1,11 @@ """Tests for EIP-7843 (SLOTNUM).""" -from dataclasses import dataclass - import pytest from execution_testing import ( Account, Alloc, + Block, + BlockchainTestFiller, Environment, Fork, Op, @@ -13,19 +13,7 @@ Transaction, ) - -@dataclass(frozen=True) -class ReferenceSpec: - """Reference specification.""" - - git_path: str - version: str - - -ref_spec_7843 = ReferenceSpec( - git_path="EIPS/eip-7843.md", - version="6bc5d6b7acbc016a79fa573f98975093b5c2ca52", -) +from .spec import ref_spec_7843 REFERENCE_SPEC_GIT_PATH = ref_spec_7843.git_path REFERENCE_SPEC_VERSION = ref_spec_7843.version @@ -124,3 +112,39 @@ def test_slotnum_gas_cost( tx=tx, post=post, ) + + +def test_slotnum_distinct_per_block( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test that SLOTNUM returns each block's own slot number. + + Runs four consecutive blocks with deliberately non-monotonic slot + numbers to disprove any caching or ordering assumption in the opcode + implementation. Each block runs the same contract, which keys storage + by block ``NUMBER`` so every block's outcome is independently visible + in the final post-state. + """ + sender = pre.fund_eoa() + contract = pre.deploy_contract(Op.SSTORE(Op.NUMBER, Op.SLOTNUM) + Op.STOP) + + # Non-monotonic on purpose: decrease, increase, jump to large value. + slot_numbers = [100, 42, 7, 2**32] + + blocks = [ + Block( + slot_number=slot, + txs=[Transaction(sender=sender, to=contract, gas_limit=100_000)], + ) + for slot in slot_numbers + ] + + post = { + contract: Account( + storage={i + 1: slot for i, slot in enumerate(slot_numbers)}, + ), + } + + blockchain_test(pre=pre, blocks=blocks, post=post) From 31d7e698973703d4863ed0a4b099c4484d47594e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 19 May 2026 09:25:19 +0200 Subject: [PATCH 089/186] feat(tests): EIP-7778 multi-tx mixed gas regimes block accounting (#2871) Add `test_3tx_mixed_gas_regimes` exercising the EIP-7778 identity `block.gas_used == sum_i max(pre_refund_i, floor_i)` across a block where each tx hits a different regime: tx1: SSTORE-set fresh slot (no refund, pre_refund > floor) tx2: SSTORE-clear x10 (normal refund, refund not clipped to floor) tx3: 1000 zero-byte calldata to STOP (floor binds upward) Per-tx sender balances are also asserted so the floor-binding tx locks in `floor * gas_price` (not `pre_refund * gas_price`), the multi-tx accumulator bug EIP-7778 prevents. The 2-tx `test_multi_transaction_gas_accounting` never combines a refund- bearing tx with a floor-binding tx in the same block. --- .../test_gas_accounting.py | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py index 1b6a6be1d81..058be9e2997 100644 --- a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py @@ -529,3 +529,119 @@ def test_multiple_refund_types_in_one_tx( ], post=post, ) + + +@pytest.mark.execute(pytest.mark.skip(reason="Requires specific gas price")) +@pytest.mark.valid_from("EIP7778") +def test_mixed_gas_regimes( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + fork: Fork, +) -> None: + """ + Lock in `block.gas_used == sum_i max(pre_refund_i, floor_i)` across a + block where each tx hits a different EIP-7778 regime. + + tx1: SSTORE-set fresh slot (no refund, pre_refund > floor). + tx2: SSTORE-clear x10 (normal refund, refund not clipped to floor). + tx3: 1000 zero-byte calldata to STOP (floor binds upward). + + The 2-tx `test_multi_transaction_gas_accounting` covers a refund tx + plus a minimal extra tx but never combines a refund-bearing tx with + a floor-binding tx in the same block. Per-tx sender balance is also + asserted to lock in that the floor-binding tx pays + `floor * gas_price`, not `pre_refund * gas_price`. + """ + intrinsic_cost_calc = fork.transaction_intrinsic_cost_calculator() + data_floor_calc = fork.transaction_data_floor_cost_calculator() + initial_fund = 10**18 + + post = Alloc() + + # tx1: SSTORE-set to a fresh slot. No refund. + tx1_code = Op.SSTORE(0, 1, original_value=0, new_value=1) + tx1_target = pre.deploy_contract(code=tx1_code) + tx1_sender = pre.fund_eoa(initial_fund) + tx1_data = b"" + tx1_pre_refund = intrinsic_cost_calc( + calldata=tx1_data, + return_cost_deducted_prior_execution=True, + ) + tx1_code.gas_cost(fork) + tx1_floor = data_floor_calc(data=tx1_data) + assert tx1_pre_refund > tx1_floor, "tx1: pre_refund must exceed floor" + tx1_contribution = max(tx1_pre_refund, tx1_floor) + tx1 = Transaction( + to=tx1_target, + gas_limit=tx1_contribution, + sender=tx1_sender, + data=tx1_data, + # TODO: gas_used in expected_receipt is ignored by + # verify_transaction_receipt; only cumulative_gas_used is + # checked. To be fixed by #2855. + expected_receipt={"gas_used": tx1_contribution}, + ) + tx1_gas_price = tx1.gas_price if tx1.gas_price else tx1.max_fee_per_gas + assert tx1_gas_price is not None + post[tx1_target] = Account(storage={0: 1}) + post[tx1_sender] = Account( + balance=initial_fund - tx1_contribution * tx1_gas_price + ) + + # tx2: SSTORE-clear with normal refund, refund not clipped to floor. + ( + tx2_post_refund, + tx2_pre_refund, + tx2_floor, + tx2, + ) = build_refund_tx( + fork=fork, + pre=pre, + post=post, + refund_types={RefundTypes.STORAGE_CLEAR}, + refunds_count=10, + ) + assert tx2_pre_refund > tx2_floor, "tx2: pre_refund must exceed floor" + assert tx2_post_refund > tx2_floor, ( + "tx2: refund must not be clipped to floor" + ) + tx2_contribution = max(tx2_pre_refund, tx2_floor) + + # tx3: floor-binding via 1000 zero bytes of calldata to STOP. + tx3_target = pre.deterministic_deploy_contract(deploy_code=Op.STOP) + tx3_sender = pre.fund_eoa(initial_fund) + tx3_data = b"\x00" * 1000 + tx3_pre_refund = intrinsic_cost_calc( + calldata=tx3_data, + return_cost_deducted_prior_execution=True, + ) + tx3_floor = data_floor_calc(data=tx3_data) + assert tx3_floor > tx3_pre_refund, "tx3: floor must bind upward" + tx3_contribution = max(tx3_pre_refund, tx3_floor) + tx3 = Transaction( + to=tx3_target, + gas_limit=tx3_contribution, + sender=tx3_sender, + data=tx3_data, + # TODO: gas_used in expected_receipt is ignored by + # verify_transaction_receipt; only cumulative_gas_used is + # checked. To be fixed by #2855. + expected_receipt={"gas_used": tx3_contribution}, + ) + tx3_gas_price = tx3.gas_price if tx3.gas_price else tx3.max_fee_per_gas + assert tx3_gas_price is not None + post[tx3_sender] = Account( + balance=initial_fund - tx3_contribution * tx3_gas_price + ) + + total_gas_used = tx1_contribution + tx2_contribution + tx3_contribution + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx1, tx2, tx3], + expected_gas_used=total_gas_used, + ) + ], + post=post, + ) From b7a206679816763f2777949ac669bedc416c70b0 Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 19 May 2026 11:16:01 +0200 Subject: [PATCH 090/186] fix(ci): redirect Go caches to a per-job temp dir (#2774) Self-hosted runners persist `$GOMODCACHE` (`/data/gh-home/go/pkg/mod`) across jobs, so the `actions/setup-go` cache restore extracts a tarball on top of files that already exist and emits hundreds of `tar: Cannot open: File exists` lines before bailing out with `Failed to restore`. The build still succeeds because the on-disk modules are reused, but the log noise is alarming and the ~500 MB cache download is wasted. Set `GOMODCACHE` and `GOCACHE` to `${{ runner.temp }}/go/...` before each `setup-go` invocation so the cache always lands in an empty, job-scoped directory. Behaviour on GitHub-hosted runners is unchanged; self-hosted runners stop colliding without losing the GHA cache. --- .github/actions/build-benchmark-genesis/action.yaml | 9 +++++++++ .github/actions/build-evm-client/geth/action.yaml | 9 +++++++++ .github/workflows/hive-consume.yaml | 8 ++++++++ .github/workflows/hive-execute.yaml | 8 ++++++++ 4 files changed, 34 insertions(+) diff --git a/.github/actions/build-benchmark-genesis/action.yaml b/.github/actions/build-benchmark-genesis/action.yaml index 1838ed22c91..81d35d6c3c7 100644 --- a/.github/actions/build-benchmark-genesis/action.yaml +++ b/.github/actions/build-benchmark-genesis/action.yaml @@ -18,6 +18,15 @@ runs: ref: master path: hive + # Redirect Go's module/build caches to a per-job temp dir so the + # actions/setup-go cache restore extracts into an empty target. On + # self-hosted runners $GOMODCACHE persists across jobs and would + # otherwise collide with the cache tarball ("File exists" from tar). + - name: Use ephemeral Go cache dirs + shell: bash + run: | + echo "GOMODCACHE=${{ runner.temp }}/go/mod" >> "$GITHUB_ENV" + echo "GOCACHE=${{ runner.temp }}/go/build" >> "$GITHUB_ENV" - name: Setup Go for Hive uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: diff --git a/.github/actions/build-evm-client/geth/action.yaml b/.github/actions/build-evm-client/geth/action.yaml index 8dd39d43254..7770f0192c1 100644 --- a/.github/actions/build-evm-client/geth/action.yaml +++ b/.github/actions/build-evm-client/geth/action.yaml @@ -42,6 +42,15 @@ runs: repository: ${{ inputs.repo }} ref: ${{ steps.geth-sha.outputs.sha }} path: go-ethereum + # See note in build-benchmark-genesis/action.yaml: redirect Go caches + # to a per-job temp dir so setup-go's cache restore doesn't collide + # with a persistent $GOMODCACHE on self-hosted runners. + - name: Use ephemeral Go cache dirs + if: steps.cache-restore.outputs.cache-hit != 'true' + shell: bash + run: | + echo "GOMODCACHE=${{ runner.temp }}/go/mod" >> "$GITHUB_ENV" + echo "GOCACHE=${{ runner.temp }}/go/build" >> "$GITHUB_ENV" - name: Setup golang if: steps.cache-restore.outputs.cache-hit != 'true' uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 3d726814465..e08a8c61808 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -141,6 +141,14 @@ jobs: ref: master path: hive + # Redirect Go's caches to a per-job temp dir so the setup-go cache + # restore doesn't collide with a persistent $GOMODCACHE on + # self-hosted runners (see build-benchmark-genesis/action.yaml). + - name: Use ephemeral Go cache dirs + shell: bash + run: | + echo "GOMODCACHE=${{ runner.temp }}/go/mod" >> "$GITHUB_ENV" + echo "GOCACHE=${{ runner.temp }}/go/build" >> "$GITHUB_ENV" - name: Setup go env and cache uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: diff --git a/.github/workflows/hive-execute.yaml b/.github/workflows/hive-execute.yaml index b00a5c0571f..4719a1faeb6 100644 --- a/.github/workflows/hive-execute.yaml +++ b/.github/workflows/hive-execute.yaml @@ -52,6 +52,14 @@ jobs: ref: master path: hive + # Redirect Go's caches to a per-job temp dir so the setup-go cache + # restore doesn't collide with a persistent $GOMODCACHE on + # self-hosted runners (see build-benchmark-genesis/action.yaml). + - name: Use ephemeral Go cache dirs + shell: bash + run: | + echo "GOMODCACHE=${{ runner.temp }}/go/mod" >> "$GITHUB_ENV" + echo "GOCACHE=${{ runner.temp }}/go/build" >> "$GITHUB_ENV" - name: Setup Go uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: From 852715c86bd553bfcce408e8f42f88e6d9307095 Mon Sep 17 00:00:00 2001 From: felix Date: Tue, 19 May 2026 12:17:59 +0200 Subject: [PATCH 091/186] feat(spec-specs, tests): Add EIP-7976 Increase Calldata Floor Cost (#2861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(tests): adds EIP-7976 test and required framework changes (#2115) * feat(tests): adds tests and src changes for 7976 Co-authored-by: Toni Wahrstätter <51536394+nerolation@users.noreply.github.com> * feat: EIP got updated * fix: ruff * feat: implemented PR feedback * fix: make eip-7934 block-size filler fork-aware for amsterdam by enforcing tx gas caps and adaptive calldata sizing so --until=amsterdam fills pass * fix: fix * fix: fix * fix: mypy --------- Co-authored-by: Toni Wahrstätter <51536394+nerolation@users.noreply.github.com> * refactor(tests-eip-7976): Condition tests to EIP inclusion * chores: update refspec * fix(tests): drop GAS_ prefix from gas_costs attribute references Align the EIP-7976 mixin and tests with the GasCosts dataclass rename on forks/amsterdam (GAS_TX_BASE -> TX_BASE, GAS_TX_DATA_TOKEN_FLOOR -> TX_DATA_TOKEN_FLOOR, GAS_VERY_LOW -> VERY_LOW, etc.). * fix(tests): compose EIP-7976 floor cost via calldata_gas_calculator Override `calldata_gas_calculator` (floor mode only) instead of `transaction_data_floor_cost_calculator`. The previous override shadowed EIP-7981's `transaction_data_floor_cost_calculator` in the Amsterdam MRO (auto-loader sorts by EIP number ascending, so EIP7976 is more derived and its method wins without calling super), dropping the access list floor contribution. Routing the change through `calldata_gas_calculator` lets EIP-7623's data floor calculator pick it up, which EIP-7981 then extends via super. * fix: ci fails due to static tests out of gas * fix: mario feedback * fix: remove duplicate test --------- Co-authored-by: Toni Wahrstätter <51536394+nerolation@users.noreply.github.com> Co-authored-by: marioevz Co-authored-by: spencer-tb --- .../forks/forks/eips/amsterdam/eip_7976.py | 47 + src/ethereum/forks/amsterdam/transactions.py | 4 +- src/ethereum/forks/amsterdam/vm/gas.py | 2 +- .../__init__.py | 3 + .../conftest.py | 362 +++++++ .../helpers.py | 56 ++ .../spec.py | 28 + .../test_additional_coverage.py | 936 ++++++++++++++++++ .../test_eip_mainnet.py | 107 ++ .../test_execution_gas.py | 173 ++++ .../test_refunds.py | 335 +++++++ .../test_transaction_validity.py | 384 +++++++ .../stRandom2/test_random_statetest644.py | 12 +- ...evert_precompiled_touch_exact_oog_paris.py | 3 +- .../test_transaction_data_costs652.py | 3 +- 15 files changed, 2446 insertions(+), 9 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7976.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/__init__.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/conftest.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/helpers.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/spec.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/test_additional_coverage.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/test_eip_mainnet.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/test_execution_gas.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/test_refunds.py create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/test_transaction_validity.py diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7976.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7976.py new file mode 100644 index 00000000000..b126395a4c7 --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7976.py @@ -0,0 +1,47 @@ +""" +EIP-7976: Increase Calldata Floor Cost. + +Increase the calldata floor cost to 64/64 gas per byte to reduce maximum block +size. + +https://eips.ethereum.org/EIPS/eip-7976 +""" + +from dataclasses import replace + +from execution_testing.base_types import Bytes +from execution_testing.base_types.conversions import BytesConvertible + +from ....base_fork import BaseFork, CalldataGasCalculator +from ....gas_costs import GasCosts + + +class EIP7976(BaseFork): + """EIP-7976 class.""" + + @classmethod + def gas_costs(cls) -> GasCosts: + """Transaction data floor token cost is increased from 10 to 16.""" + return replace( + super(EIP7976, cls).gas_costs(), + TX_DATA_TOKEN_FLOOR=16, + ) + + @classmethod + def calldata_gas_calculator(cls) -> CalldataGasCalculator: + """ + In floor mode, count four tokens per calldata byte uniformly so + the data floor cost becomes ``4 * bytes * TX_DATA_TOKEN_FLOOR`` + (64/64 gas per byte). Standard mode keeps EIP-7623 semantics so + that composition with downstream EIPs (e.g. EIP-7981) stays + intact via ``super().transaction_data_floor_cost_calculator()``. + """ + super_fn = super(EIP7976, cls).calldata_gas_calculator() + gas_costs = cls.gas_costs() + + def fn(*, data: BytesConvertible, floor: bool = False) -> int: + if floor: + return len(Bytes(data)) * 4 * gas_costs.TX_DATA_TOKEN_FLOOR + return super_fn(data=data, floor=False) + + return fn diff --git a/src/ethereum/forks/amsterdam/transactions.py b/src/ethereum/forks/amsterdam/transactions.py index 2436773d645..cc867fc4941 100644 --- a/src/ethereum/forks/amsterdam/transactions.py +++ b/src/ethereum/forks/amsterdam/transactions.py @@ -611,8 +611,8 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: GasCosts.AUTH_PER_EMPTY_ACCOUNT * len(tx.authorizations) ) - # Floor tokens from calldata. - floor_tokens_in_calldata = tokens_in_calldata + # EIP-7976 floor tokens: all calldata bytes count uniformly. + floor_tokens_in_calldata = ulen(tx.data) * GasCosts.TX_DATA_TOKEN_STANDARD # Total floor tokens. total_floor_tokens = floor_tokens_in_calldata + tokens_in_access_list diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index fc427587318..ef9e86c90c3 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -106,7 +106,7 @@ class GasCosts: TX_BASE = Uint(21000) TX_CREATE = Uint(32000) TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) + TX_DATA_TOKEN_FLOOR = Uint(16) TX_ACCESS_LIST_ADDRESS = Uint(2400) TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/__init__.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/__init__.py new file mode 100644 index 00000000000..3eb2006603d --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/__init__.py @@ -0,0 +1,3 @@ +""" +Test [EIP-7976: Increase calldata floor cost](https://eips.ethereum.org/EIPS/eip-7976). +""" diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/conftest.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/conftest.py new file mode 100644 index 00000000000..78de4e79df2 --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/conftest.py @@ -0,0 +1,362 @@ +"""Fixtures for the EIP-7976 tests.""" + +from typing import List, Sequence + +import pytest +from execution_testing import ( + EOA, + AccessList, + Address, + Alloc, + AuthorizationTuple, + Bytecode, + Bytes, + Fork, + Hash, + Op, + Transaction, + TransactionException, + add_kzg_version, +) + +from ...osaka.eip7594_peerdas.spec import Spec as EIP_7594_Spec +from .helpers import DataTestType, find_floor_cost_threshold + + +@pytest.fixture +def to( + request: pytest.FixtureRequest, + pre: Alloc, +) -> Address | None: + """Create the sender account.""" + param = getattr(request, "param", Op.STOP) + + if param is None: + return None + if isinstance(param, str) and param == "eoa": + return pre.fund_eoa(amount=0) + if isinstance(param, Bytecode): + return pre.deploy_contract(param) + + raise ValueError(f"Invalid value for `to` fixture: {param}") + + +@pytest.fixture +def protected() -> bool: + """ + Return whether the transaction is protected or not. Only valid for type-0 + transactions. + """ + return True + + +@pytest.fixture +def access_list() -> List[AccessList] | None: + """Access list for the transaction.""" + return None + + +@pytest.fixture +def authorization_refund() -> bool: + """ + Return whether the transaction has an existing authority in the + authorization list. + """ + return False + + +@pytest.fixture +def authorization_list( + request: pytest.FixtureRequest, + pre: Alloc, + authorization_refund: bool, +) -> List[AuthorizationTuple] | None: + """ + Authorization-list for the transaction. + + This fixture needs to be parametrized indirectly in order to generate the + authorizations with valid signers using `pre` in this function, and the + parametrized value should be a list of addresses. + """ + param = getattr(request, "param", None) + if param is None: + return None + return [ + AuthorizationTuple( + signer=pre.fund_eoa(1 if authorization_refund else 0), + address=address, + ) + for address in param + ] + + +@pytest.fixture +def blob_versioned_hashes(ty: int) -> Sequence[Hash] | None: + """Versioned hashes for the transaction.""" + if ty == 3: + return add_kzg_version( + [Hash(1)], + EIP_7594_Spec.BLOB_COMMITMENT_VERSION_KZG, + ) + return None + + +@pytest.fixture +def contract_creating_tx(to: Address | None) -> bool: + """Return whether the transaction creates a contract or not.""" + return to is None + + +@pytest.fixture +def intrinsic_gas_data_floor_minimum_delta() -> int: + """ + Induce a minimum delta between the transaction intrinsic gas cost and the + floor data gas cost. + """ + return 0 + + +@pytest.fixture +def tx_data( + fork: Fork, + data_test_type: DataTestType, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + contract_creating_tx: bool, + intrinsic_gas_data_floor_minimum_delta: int, +) -> Bytes: + """ + All tests in this file use data that is generated dynamically depending on + the case and the attributes of the transaction in order to reach the edge + cases where the floor gas cost is equal or barely greater than the + intrinsic gas cost. + + We have two different types of tests: + + - FLOOR_GAS_COST_LESS_THAN_OR_EQUAL_TO_INTRINSIC_GAS: The floor gas cost is + less than or equal to the intrinsic gas cost, which means that the size + of the data is not enough to trigger the floor gas cost. + + - FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS: The floor gas cost is greater + than the intrinsic gas cost, which means that the size of the data is + enough to trigger the floor gas cost. + + E.g. Given a transaction with a single access list and a single storage + key, its intrinsic gas cost (as of Amsterdam fork) can be calculated as: + + - 21,000 gas for the transaction + - 2,400 gas for the access list + - 1,900 gas for the storage key + - 16 gas for each non-zero byte in the data + - 4 gas for each zero byte in the data + + Its floor data gas cost can be calculated as: + - 21,000 gas for the transaction + - 64 gas for each byte in the data + + Notice that the data included in the transaction affects both the intrinsic + gas cost and the floor data cost, but at different rates. + + The purpose of this function is to find the exact amount of data where the + floor data gas cost starts exceeding the intrinsic gas cost. + + After a binary search we find that adding X bytes of data triggers the + floor gas cost. + + Therefore, this function will return a Bytes object with the appropriate + amount of data for each test type. + """ + + def bytes_to_data(byte_count: int) -> Bytes: + return Bytes(b"\x01" * byte_count) + + fork_intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + + def transaction_intrinsic_cost_calculator(byte_count: int) -> int: + return ( + fork_intrinsic_cost_calculator( + calldata=bytes_to_data(byte_count), + contract_creation=contract_creating_tx, + access_list=access_list, + authorization_list_or_count=authorization_list, + return_cost_deducted_prior_execution=True, + ) + + intrinsic_gas_data_floor_minimum_delta + ) + + fork_data_floor_cost_calculator = ( + fork.transaction_data_floor_cost_calculator() + ) + + def transaction_data_floor_cost_calculator(byte_count: int) -> int: + return fork_data_floor_cost_calculator(data=bytes_to_data(byte_count)) + + # Start with zero data and check the difference in the gas calculator + # between the intrinsic gas cost and the floor gas cost. + if transaction_data_floor_cost_calculator( + 0 + ) >= transaction_intrinsic_cost_calculator(0): + # Special case which is a transaction with no extra intrinsic gas costs + # other than the data cost, any data will trigger the floor gas cost. + if ( + data_test_type + == DataTestType.FLOOR_GAS_COST_LESS_THAN_OR_EQUAL_TO_INTRINSIC_GAS + ): + return Bytes(b"") + else: + return Bytes(b"\0") + + threshold_bytes = find_floor_cost_threshold( + floor_data_gas_cost_calculator=transaction_data_floor_cost_calculator, + intrinsic_gas_cost_calculator=transaction_intrinsic_cost_calculator, + ) + + if ( + data_test_type + == DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS + ): + return bytes_to_data(threshold_bytes + 1) + return bytes_to_data(threshold_bytes) + + +@pytest.fixture +def tx_gas_delta() -> int: + """ + Gas delta to modify the gas amount included with the transaction. + + If negative, the transaction will be invalid because the intrinsic gas cost + is greater than the gas limit. + + This value operates regardless of whether the floor data gas cost is + reached or not. + + If the value is greater than zero, the transaction will also be valid and + the test will check that transaction processing does not consume more gas + than it should. + """ + return 0 + + +@pytest.fixture +def tx_intrinsic_gas_cost_before_execution( + fork: Fork, + tx_data: Bytes, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + contract_creating_tx: bool, +) -> int: + """ + Return the intrinsic gas cost that is applied before the execution start. + + This value never includes the floor data gas cost. + """ + intrinsic_gas_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + return intrinsic_gas_cost_calculator( + calldata=tx_data, + contract_creation=contract_creating_tx, + access_list=access_list, + authorization_list_or_count=authorization_list, + return_cost_deducted_prior_execution=True, + ) + + +@pytest.fixture +def tx_intrinsic_gas_cost_including_floor_data_cost( + fork: Fork, + tx_data: Bytes, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + contract_creating_tx: bool, +) -> int: + """ + Transaction intrinsic gas cost. + + The calculated value takes into account the normal intrinsic gas cost and + the floor data gas cost if it is greater than the intrinsic gas cost. + + In other words, this is the value that is required for the transaction to + be valid. + """ + intrinsic_gas_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + return intrinsic_gas_cost_calculator( + calldata=tx_data, + contract_creation=contract_creating_tx, + access_list=access_list, + authorization_list_or_count=authorization_list, + ) + + +@pytest.fixture +def tx_floor_data_cost( + fork: Fork, + tx_data: Bytes, +) -> int: + """Floor data cost for the given transaction data.""" + fork_data_floor_cost_calculator = ( + fork.transaction_data_floor_cost_calculator() + ) + return fork_data_floor_cost_calculator(data=tx_data) + + +@pytest.fixture +def tx_gas_limit( + tx_intrinsic_gas_cost_including_floor_data_cost: int, + tx_gas_delta: int, +) -> int: + """ + Gas limit for the transaction. + + The gas delta is added to the intrinsic gas cost to generate different test + scenarios. + """ + return tx_intrinsic_gas_cost_including_floor_data_cost + tx_gas_delta + + +@pytest.fixture +def tx_error( + tx_gas_delta: int, data_test_type: DataTestType +) -> TransactionException | None: + """Transaction error, only expected if the gas delta is negative.""" + if tx_gas_delta < 0: + if ( + data_test_type + == DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS + ): + return TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST + else: + return TransactionException.INTRINSIC_GAS_TOO_LOW + return None + + +@pytest.fixture +def tx( + sender: EOA, + ty: int, + tx_data: Bytes, + to: Address | None, + protected: bool, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + blob_versioned_hashes: Sequence[Hash] | None, + tx_gas_limit: int, + tx_error: TransactionException | None, +) -> Transaction: + """Create the transaction used in each test.""" + return Transaction( + ty=ty, + sender=sender, + data=tx_data, + to=to, + protected=protected, + access_list=access_list, + authorization_list=authorization_list, + gas_limit=tx_gas_limit, + blob_versioned_hashes=blob_versioned_hashes, + error=tx_error, + ) diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/helpers.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/helpers.py new file mode 100644 index 00000000000..163db27662b --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/helpers.py @@ -0,0 +1,56 @@ +"""Helpers for testing EIP-7976.""" + +from enum import Enum, auto +from typing import Callable + + +class DataTestType(Enum): + """Enum for the different types of data tests.""" + + FLOOR_GAS_COST_LESS_THAN_OR_EQUAL_TO_INTRINSIC_GAS = auto() + FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS = auto() + + +def find_floor_cost_threshold( + floor_data_gas_cost_calculator: Callable[[int], int], + intrinsic_gas_cost_calculator: Callable[[int], int], +) -> int: + """ + Find the minimum amount of tokens that will trigger the floor gas cost, by + using a binary search and the intrinsic gas cost and floor data + calculators. + """ + + def floor_cost(n: int) -> int: + return floor_data_gas_cost_calculator(n) + + def intrinsic_cost(n: int) -> int: + return intrinsic_gas_cost_calculator(n) + + # Start with 1000 tokens and if the intrinsic gas cost is greater than the + # floor gas cost, multiply the number of tokens by 2 until it's not. + tokens = 1000 + while floor_cost(tokens) < intrinsic_cost(tokens): + tokens *= 2 + + # Binary search to find the minimum number of tokens that will trigger the + # floor gas cost. + left = 0 + right = tokens + while left < right: + tokens = (left + right) // 2 + if floor_cost(tokens) < intrinsic_cost(tokens): + left = tokens + 1 + else: + right = tokens + tokens = left + + if floor_cost(tokens) > intrinsic_cost(tokens): + tokens -= 1 + + # Verify that increasing the tokens by one would always trigger the floor + # gas cost. + assert floor_cost(tokens) <= intrinsic_cost(tokens), "invalid case" + assert floor_cost(tokens + 1) > intrinsic_cost(tokens + 1), "invalid case" + + return tokens diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/spec.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/spec.py new file mode 100644 index 00000000000..209153c0d2a --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/spec.py @@ -0,0 +1,28 @@ +"""Defines EIP-7976 specification constants and functions.""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ReferenceSpec: + """Defines the reference spec version and git path.""" + + git_path: str + version: str + + +ref_spec_7976 = ReferenceSpec( + "EIPS/eip-7976.md", "83d473b0504d316a06ce58ae581e7f03b5d54fe1" +) + + +# Constants +@dataclass(frozen=True) +class Spec: + """ + Parameters from the EIP-7976 specifications as defined at + https://eips.ethereum.org/EIPS/eip-7976. + """ + + STANDARD_TOKEN_COST = 4 + TOTAL_COST_FLOOR_PER_TOKEN = 16 diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_additional_coverage.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_additional_coverage.py new file mode 100644 index 00000000000..c62550daa9d --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_additional_coverage.py @@ -0,0 +1,936 @@ +""" +Additional test coverage for [EIP-7976: Increase calldata floor cost](https://eips.ethereum.org/EIPS/eip-7976). + +This module tests: +1. Token calculation verification with different byte compositions +2. Maximum calldata size handling +3. Memory expansion interaction with floor cost +4. Nested contract calls verification +5. Exact threshold boundary testing +6. Authorization list gas cost verification +7. Gas refund cap interaction with floor cost +""" + +from typing import List + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + AuthorizationTuple, + Bytecode, + Bytes, + Fork, + Op, + StateTestFiller, + Transaction, + TransactionReceipt, +) + +from .spec import ref_spec_7976 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7976.git_path +REFERENCE_SPEC_VERSION = ref_spec_7976.version + +pytestmark = [pytest.mark.valid_from("EIP7976")] + + +class TestTokenCalculation: + """Test token calculation with different byte compositions.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account.""" + return pre.fund_eoa() + + @pytest.fixture + def to(self, pre: Alloc) -> Address: + """Deploy a simple contract that does nothing.""" + return pre.deploy_contract(Op.STOP) + + @pytest.mark.parametrize( + "calldata,expected_standard_tokens,description", + [ + pytest.param( + Bytes(b"\x00" * 100), + 100, + "all_zero_bytes", + id="all_zero_bytes", + ), + pytest.param( + Bytes(b"\x01" * 100), + 400, + "all_nonzero_bytes", + id="all_nonzero_bytes", + ), + pytest.param( + Bytes(b"\x01" * 75 + b"\x00" * 25), + 325, # 75*4 + 25*1 + "75_percent_nonzero", + id="75_percent_nonzero", + ), + pytest.param( + Bytes(b"\x01" * 25 + b"\x00" * 75), + 175, # 25*4 + 75*1 + "25_percent_nonzero", + id="25_percent_nonzero", + ), + pytest.param( + Bytes(b"\x01\x02\x03\x00"), + 13, # 3*4 + 1*1 + "three_nonzero_one_zero", + id="three_nonzero_one_zero", + ), + pytest.param( + Bytes(b"\xff" * 50 + b"\x00" * 50), + 250, # 50*4 + 50*1 + "half_and_half", + id="half_and_half", + ), + ], + ) + def test_token_calculation_verification( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + to: Address, + calldata: Bytes, + expected_standard_tokens: int, + description: str, + fork: Fork, + ) -> None: + """ + Verify token calculation is correct for different byte compositions. + + Standard calldata token formula: + tokens = zero_bytes + (nonzero_bytes * 4) + + Floor token formula introduced in EIP-7976: + floor_tokens = 4 * calldata_bytes + """ + # Calculate expected costs + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost_before_execution = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + return_cost_deducted_prior_execution=True, + ) + + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + floor_cost = floor_cost_calculator(data=calldata) + + # Verify floor token calculation: + # floor_cost = TX_BASE + (floor_tokens * floor_token_cost) + # where floor_tokens = 4 * calldata_bytes + gas_costs = fork.gas_costs() + floor_token_cost = gas_costs.TX_DATA_TOKEN_FLOOR + expected_floor_tokens = len(calldata) * 4 + expected_floor_cost = gas_costs.TX_BASE + ( + expected_floor_tokens * floor_token_cost + ) + assert floor_cost == expected_floor_cost, ( + f"Floor cost mismatch for {description}: " + f"{floor_cost} != {expected_floor_cost} " + f"(floor_tokens={expected_floor_tokens}, " + f"floor_cost_per_token={floor_token_cost})" + ) + + expected_intrinsic_cost = gas_costs.TX_BASE + ( + expected_standard_tokens * gas_costs.TX_DATA_TOKEN_STANDARD + ) + assert intrinsic_cost_before_execution == expected_intrinsic_cost, ( + f"Intrinsic cost mismatch for {description}: " + f"{intrinsic_cost_before_execution} != {expected_intrinsic_cost} " + f"(standard_tokens={expected_standard_tokens})" + ) + + # Create transaction with exact gas needed + total_intrinsic_cost = max(intrinsic_cost_before_execution, floor_cost) + tx = Transaction( + sender=sender, + to=to, + data=calldata, + gas_limit=total_intrinsic_cost, + ) + + # Expected gas used should be the floor cost if it's greater + expected_gas_used = total_intrinsic_cost + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=expected_gas_used + ) + + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +class TestMaximumCalldata: + """Test maximum calldata size handling.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account with massive balance.""" + return pre.fund_eoa() + + @pytest.fixture + def to(self, pre: Alloc) -> Address: + """Deploy a simple contract.""" + return pre.deploy_contract(Op.STOP) + + def test_maximum_calldata_size( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + to: Address, + fork: Fork, + ) -> None: + """ + Test transaction with large calldata size (~10M gas worth). + + This verifies that floor cost calculation doesn't overflow and + gas metering is accurate at scale. + """ + # Calculate calldata size that would cost approximately 10M gas + # (below the default block gas limit to avoid EIP-7825 cap issues) + # Using all non-zero bytes for maximum density + # floor_cost = TX_BASE + (TX_DATA_TOKEN_FLOOR * tokens) + # For non-zero bytes: tokens = bytes * 4 + gas_costs = fork.gas_costs() + target_gas = 10_000_000 + floor_token_cost = gas_costs.TX_DATA_TOKEN_FLOOR + target_tokens = (target_gas - gas_costs.TX_BASE) // floor_token_cost + # Use all non-zero bytes for maximum token density + num_bytes = target_tokens // 4 + + calldata = Bytes(b"\x01" * num_bytes) + + # Calculate expected costs + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + floor_cost = floor_cost_calculator(data=calldata) + + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + ) + + # Floor cost should dominate for data-heavy transaction + assert floor_cost > 5_000_000, "Floor cost should be substantial" + expected_gas = max(intrinsic_cost, floor_cost) + + # Add buffer for execution (cold address access + STOP opcode) + execution_buffer = 3000 + gas_limit = expected_gas + execution_buffer + + tx = Transaction( + sender=sender, + to=to, + data=calldata, + gas_limit=gas_limit, + ) + + # Gas used should be the floor cost (execution is minimal) + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=expected_gas + ) + + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +class TestMemoryExpansion: + """Test memory expansion interaction with floor cost.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account.""" + return pre.fund_eoa() + + @pytest.fixture + def to(self, pre: Alloc) -> Address: + """ + Deploy a contract that causes memory expansion. + + The contract performs CALLDATACOPY to expand memory, then stops. + This ensures memory expansion gas is counted in execution gas. + """ + # CALLDATACOPY(destOffset=0, offset=0, length=CALLDATASIZE) + # This will copy all calldata to memory starting at offset 0 + code = ( + Op.CALLDATASIZE # Push calldata size + + Op.PUSH1(0) # Push offset (0) + + Op.PUSH1(0) # Push destOffset (0) + + Op.CALLDATACOPY # Copy calldata to memory + + Op.STOP + ) + return pre.deploy_contract(code) + + @pytest.mark.parametrize( + "calldata_size", + [ + pytest.param(1024, id="1kb"), + pytest.param(10240, id="10kb"), + pytest.param(32768, id="32kb"), + ], + ) + def test_memory_expansion_with_calldata( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + to: Address, + calldata_size: int, + fork: Fork, + ) -> None: + """ + Test memory expansion gas is counted in execution_gas not floor. + + The transaction pays max(standard_cost + execution_gas, floor_cost) + where execution_gas includes memory expansion costs. + """ + # Create calldata with non-zero bytes to trigger floor cost + calldata = Bytes(b"\x01" * calldata_size) + + # Calculate costs + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost_before_execution = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + return_cost_deducted_prior_execution=True, + ) + + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + floor_cost = floor_cost_calculator(data=calldata) + + code = ( + Op.CALLDATASIZE + + Op.PUSH1(0) + + Op.PUSH1(0) + + Op.CALLDATACOPY( + data_size=calldata_size, + new_memory_size=calldata_size, + ) + + Op.STOP + ) + execution_gas = code.gas_cost(fork) + + # Total gas is intrinsic + execution + total_with_execution = intrinsic_cost_before_execution + execution_gas + + # The actual gas used is max(total_with_execution, floor_cost) + expected_gas = max(total_with_execution, floor_cost) + + tx = Transaction( + sender=sender, + to=to, + data=calldata, + gas_limit=expected_gas + 100000, # Add buffer for safety + ) + + # Verify the transaction executes successfully + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +class TestNestedContractCalls: + """Test that nested contract calls don't trigger additional floor costs.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account.""" + return pre.fund_eoa() + + @pytest.fixture + def contract_b(self, pre: Alloc) -> Address: + """ + Deploy Contract B that receives calldata and stores something. + + This contract will be called by Contract A with calldata. + """ + # Simply store a value to show it was executed + code = Op.PUSH1(42) + Op.PUSH1(0) + Op.SSTORE + Op.STOP + return pre.deploy_contract(code) + + @pytest.fixture + def contract_a(self, pre: Alloc, contract_b: Address) -> Address: + """ + Deploy Contract A that calls Contract B with calldata. + + This contract performs a CALL to contract_b with some calldata. + """ + # Prepare call to contract_b with 100 bytes of data + # CALL(gas, address, value, argsOffset, argsSize, retOffset, retSize) + code = ( + # Store some data in memory to pass as calldata + Op.PUSH1(100) # Size + + Op.PUSH1(0) # Offset + + Op.PUSH1(0xFF) # Value to fill + + Op.MSTORE + + + # Perform CALL + Op.PUSH1(0) # retSize + + Op.PUSH1(0) # retOffset + + Op.PUSH1(100) # argsSize (100 bytes) + + Op.PUSH1(0) # argsOffset + + Op.PUSH1(0) # value + + Op.PUSH20(contract_b.hex()) # address + + Op.GAS # gas (all remaining) + + Op.CALL + + Op.STOP + ) + return pre.deploy_contract(code) + + def test_nested_call_no_additional_floor_cost( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + contract_a: Address, + contract_b: Address, + fork: Fork, + ) -> None: + """ + Verify only the transaction's calldata affects floor cost. + + Internal CALL operations with calldata don't trigger additional + floor costs. + """ + # Transaction calldata (sent to contract_a) + tx_calldata = Bytes(b"\x01" * 200) + + # Calculate floor cost based ONLY on transaction calldata + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + floor_cost = floor_cost_calculator(data=tx_calldata) + + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost = intrinsic_cost_calculator( + calldata=tx_calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + ) + + # The floor cost should only consider the transaction's calldata, + # not the calldata passed in the internal CALL + tokens_tx = len(tx_calldata) * 4 # All non-zero bytes + gas_costs = fork.gas_costs() + expected_floor_cost = gas_costs.TX_BASE + ( + tokens_tx * gas_costs.TX_DATA_TOKEN_FLOOR + ) + assert floor_cost == expected_floor_cost + + tx = Transaction( + sender=sender, + to=contract_a, + data=tx_calldata, + gas_limit=intrinsic_cost + 500000, # Add execution gas buffer + ) + + state_test( + pre=pre, + post={ + contract_b: { + "storage": {0: 42}, # Verify contract_b was executed + } + }, + tx=tx, + ) + + def test_delegatecall_no_additional_floor_cost( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + fork: Fork, + ) -> None: + """ + Verify DELEGATECALL operations don't trigger additional floor costs. + """ + # Contract that will be delegatecalled + delegate_code = Op.PUSH1(99) + Op.PUSH1(0) + Op.SSTORE + Op.STOP + delegate_contract = pre.deploy_contract(delegate_code) + + # Contract that performs DELEGATECALL + # DELEGATECALL(gas, address, argsOffset, argsSize, retOffset, retSize) + caller_code = ( + Op.PUSH1(0) # retSize + + Op.PUSH1(0) # retOffset + + Op.PUSH1(64) # argsSize + + Op.PUSH1(0) # argsOffset + + Op.PUSH20(delegate_contract.hex()) # address + + Op.GAS # gas + + Op.DELEGATECALL + + Op.STOP + ) + caller_contract = pre.deploy_contract(caller_code, storage={}) + + # Transaction calldata + tx_calldata = Bytes(b"\x01" * 150) + + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost = intrinsic_cost_calculator( + calldata=tx_calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + ) + + tx = Transaction( + sender=sender, + to=caller_contract, + data=tx_calldata, + gas_limit=intrinsic_cost + 500000, + ) + + state_test( + pre=pre, + post={ + caller_contract: { + "storage": { + 0: 99 + }, # DELEGATECALL executes in caller's context + } + }, + tx=tx, + ) + + +class TestExactThresholdBoundary: + """Test exact threshold where floor_cost == intrinsic_cost.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account.""" + return pre.fund_eoa() + + @pytest.fixture + def to(self, pre: Alloc) -> Address: + """Deploy a simple contract.""" + return pre.deploy_contract(Op.STOP) + + @pytest.mark.parametrize( + "access_list,authorization_list", + [ + pytest.param(None, None, id="no_extras"), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + None, + id="with_access_list", + ), + ], + indirect=["authorization_list"], + ) + @pytest.mark.parametrize( + "ty", + [ + # Type 1 (EIP-2930) introduced access lists + pytest.param(1, id="type_1"), + pytest.param(2, id="type_2"), + ], + ) + @pytest.mark.parametrize( + "threshold_offset", + [ + pytest.param(0, id="below_threshold"), + pytest.param(1, id="above_threshold"), + pytest.param(2, id="above_threshold_plus_2"), + ], + ) + def test_exact_threshold_boundary( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + to: Address, + fork: Fork, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + ty: int, + threshold_offset: int, + ) -> None: + """ + Find exact calldata byte count N where floor_cost == intrinsic_cost. + + Test with N, N+1, and N+2 bytes to verify max() function + switches correctly. + """ + from .helpers import find_floor_cost_threshold + + def bytes_to_data(byte_count: int) -> Bytes: + """Convert byte count to calldata bytes.""" + return Bytes(b"\x01" * byte_count) + + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + + def intrinsic_cost(byte_count: int) -> int: + return intrinsic_cost_calculator( + calldata=bytes_to_data(byte_count), + contract_creation=False, + access_list=access_list, + authorization_list_or_count=authorization_list, + return_cost_deducted_prior_execution=True, + ) + + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + + def floor_cost(byte_count: int) -> int: + return floor_cost_calculator(data=bytes_to_data(byte_count)) + + # Find the threshold + threshold_bytes = find_floor_cost_threshold( + floor_data_gas_cost_calculator=floor_cost, + intrinsic_gas_cost_calculator=intrinsic_cost, + ) + + byte_count = threshold_bytes + threshold_offset + calldata = bytes_to_data(byte_count) + intrinsic_raw = intrinsic_cost(byte_count) + floor_raw = floor_cost(byte_count) + + if threshold_offset == 0: + assert intrinsic_raw >= floor_raw, ( + "At threshold: intrinsic should dominate" + ) + else: + assert floor_raw > intrinsic_raw, ( + f"Above threshold: floor should dominate. " + f"floor={floor_raw}, intrinsic={intrinsic_raw}" + ) + + intrinsic_total = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=access_list, + authorization_list_or_count=authorization_list, + ) + + tx = Transaction( + ty=ty, + sender=sender, + to=to, + nonce=0, + data=calldata, + gas_limit=intrinsic_total, + access_list=access_list, + authorization_list=authorization_list, + ) + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=intrinsic_total + ) + + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +class TestAuthorizationListGasCost: + """Verify authorization list gas costs are included correctly.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account.""" + return pre.fund_eoa() + + @pytest.fixture + def to(self, pre: Alloc) -> Address: + """Deploy a simple contract.""" + return pre.deploy_contract(Op.STOP) + + @pytest.mark.parametrize( + "num_authorizations", + [ + pytest.param(1, id="single_auth"), + pytest.param(5, id="five_auths"), + pytest.param(10, id="ten_auths"), + ], + ) + def test_authorization_list_intrinsic_gas( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + to: Address, + fork: Fork, + num_authorizations: int, + ) -> None: + """ + Verify authorization list gas costs are included in intrinsic gas. + + Each authorization in the list adds a fixed gas cost to the + intrinsic gas. This should be accounted for before comparing + with floor cost. + """ + # Create authorization list + authorization_list = [ + AuthorizationTuple( + signer=pre.fund_eoa(0), + address=Address(i + 1), + ) + for i in range(num_authorizations) + ] + + # Use calldata that triggers floor cost + calldata = Bytes(b"\x01" * 500) + + # Calculate costs + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost_with_auth = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=authorization_list, + ) + + intrinsic_cost_without_auth = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + ) + + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + floor_cost = floor_cost_calculator(data=calldata) + + # Each authorization adds calldata cost for the authorization tuple + # plus G_AUTHORIZATION gas cost. The difference we see should be + # primarily from the authorization gas but may include calldata costs + # for encoding the authorization list. + actual_auth_cost = ( + intrinsic_cost_with_auth - intrinsic_cost_without_auth + ) + # Just verify that there is a positive cost increase + assert actual_auth_cost > 0, ( + f"Authorization should add gas cost, got: {actual_auth_cost}" + ) + + # The transaction should pay max(intrinsic_with_auth, floor_cost) + expected_gas = max(intrinsic_cost_with_auth, floor_cost) + + tx = Transaction( + ty=4, # Type 4 supports authorization lists + sender=sender, + to=to, + data=calldata, + gas_limit=expected_gas, + authorization_list=authorization_list, + ) + + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=expected_gas + ) + + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +class TestRefundCapInteraction: + """Test that the 1/5 refund cap interacts correctly with floor cost.""" + + @pytest.fixture + def sender(self, pre: Alloc) -> Address: + """Create sender account.""" + return pre.fund_eoa() + + def test_refund_cap_at_one_fifth( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + fork: Fork, + ) -> None: + """ + Test that refunds are capped at the fork max refund quotient. + + Even if the refund counter is high, the actual refund cannot exceed + the fork cap. Use minimal calldata to avoid floor cost interference. + """ + # Use minimal calldata so floor cost doesn't dominate + calldata = Bytes(b"") + + # Deploy contract that clears multiple storage slots + # This generates a large refund counter + num_slots = 10 + code = Bytecode() + storage = {i: 1 for i in range(num_slots)} # noqa: C420 + + for i in range(num_slots): + code += Op.SSTORE(i, 0, original_value=1, new_value=0) + + code += Op.STOP + contract = pre.deploy_contract( + code, + storage=storage, # type: ignore[arg-type] + ) + + # Calculate costs + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost_before_execution = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + return_cost_deducted_prior_execution=True, + ) + + execution_gas = code.gas_cost(fork) + + total_gas_before_refund = ( + intrinsic_cost_before_execution + execution_gas + ) + + refund_counter = code.refund(fork) + + # Actual refund is capped by the fork max refund quotient. + refund_cap = total_gas_before_refund // fork.max_refund_quotient() + actual_refund = min(refund_counter, refund_cap) + + # Verify that refund counter exceeds cap + assert refund_counter > refund_cap, ( + "Test requires refund_counter > refund cap" + ) + + # Gas after refund (floor cost is minimal with empty calldata) + expected_gas = total_gas_before_refund - actual_refund + + tx = Transaction( + sender=sender, + to=contract, + data=calldata, + gas_limit=total_gas_before_refund, + ) + + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=expected_gas + ) + + # Verify all storage slots are cleared + expected_storage = dict.fromkeys(range(num_slots), 0) + + state_test( + pre=pre, + post={ + contract: { + "storage": expected_storage, + } + }, + tx=tx, + ) + + def test_floor_cost_not_reduced_by_refunds( + self, + state_test: StateTestFiller, + pre: Alloc, + sender: Address, + fork: Fork, + ) -> None: + """ + Verify floor cost acts as a true floor and is never reduced. + + Even with large refunds, the transaction must pay at least the + floor cost. + """ + # Use calldata that strongly triggers floor cost + calldata = Bytes(b"\x01" * 1000) + + # Deploy contract that clears storage + code = Op.SSTORE(0, 0, original_value=1, new_value=0) + Op.STOP + contract = pre.deploy_contract( + code, + storage={0: 1}, + ) + + # Calculate costs + floor_cost_calculator = fork.transaction_data_floor_cost_calculator() + floor_cost = floor_cost_calculator(data=calldata) + + intrinsic_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + intrinsic_cost_before_execution = intrinsic_cost_calculator( + calldata=calldata, + contract_creation=False, + access_list=None, + authorization_list_or_count=None, + return_cost_deducted_prior_execution=True, + ) + + execution_gas = code.gas_cost(fork) + + total_gas_before_refund = ( + intrinsic_cost_before_execution + execution_gas + ) + refund = min( + code.refund(fork), + total_gas_before_refund // fork.max_refund_quotient(), + ) + gas_after_refund = total_gas_before_refund - refund + + # Even after refund, we should pay at least floor cost + expected_gas = max(gas_after_refund, floor_cost) + + # Verify floor cost is the dominant factor + assert expected_gas == floor_cost, ( + "Floor cost should dominate for data-heavy transaction" + ) + + # Gas limit must satisfy both execution needs and floor cost + gas_limit = max(total_gas_before_refund, floor_cost) + + tx = Transaction( + sender=sender, + to=contract, + data=calldata, + gas_limit=gas_limit, + ) + + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=expected_gas + ) + + state_test( + pre=pre, + post={ + contract: { + "storage": {0: 0}, + } + }, + tx=tx, + ) diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_eip_mainnet.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_eip_mainnet.py new file mode 100644 index 00000000000..7926edd7032 --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_eip_mainnet.py @@ -0,0 +1,107 @@ +""" +abstract: Crafted tests for mainnet of [EIP-7976: Increase calldata floor cost](https://eips.ethereum.org/EIPS/eip-7976). +""" # noqa: E501 + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + Hash, + StateTestFiller, + Transaction, + add_kzg_version, +) + +from ...osaka.eip7594_peerdas.spec import Spec as EIP_7594_Spec +from .helpers import DataTestType +from .spec import ref_spec_7976 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7976.git_path +REFERENCE_SPEC_VERSION = ref_spec_7976.version + +pytestmark = [pytest.mark.valid_at("EIP7976"), pytest.mark.mainnet] + + +@pytest.mark.parametrize( + "ty,protected,access_list,blob_versioned_hashes,authorization_list", + [ + pytest.param(0, True, None, None, None, id="type_0_protected"), + pytest.param(0, False, None, None, None, id="type_0_unprotected"), + pytest.param( + 1, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + None, + None, + id="type_1", + ), + pytest.param( + 2, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + None, + None, + id="type_2", + ), + pytest.param( + 3, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + add_kzg_version( + [Hash(x) for x in range(1)], + EIP_7594_Spec.BLOB_COMMITMENT_VERSION_KZG, + ), + None, + id="type_3", + marks=pytest.mark.fill( + pytest.mark.skip(reason="Blob txs not supported by fill") + ), + ), + pytest.param( + 4, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + None, + [Address(1)], + id="type_4", + ), + ], + indirect=["authorization_list"], +) +@pytest.mark.parametrize( + "tx_gas_delta", + [ + pytest.param(0, id=""), + ], +) +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id=""), + ], + indirect=True, +) +@pytest.mark.parametrize( + "data_test_type", + [ + pytest.param( + DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS, + id="", + ), + ], +) +def test_eip_7976( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions without access lists + and contract creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_execution_gas.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_execution_gas.py new file mode 100644 index 00000000000..a46c9d5daf6 --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_execution_gas.py @@ -0,0 +1,173 @@ +""" +Test [EIP-7976: Increase calldata floor cost](https://eips.ethereum.org/EIPS/eip-7976). +""" + +from typing import List + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + AuthorizationTuple, + Bytes, + Fork, + Op, + StateTestFiller, + Transaction, + TransactionReceipt, +) + +from .helpers import DataTestType +from .spec import ref_spec_7976 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7976.git_path +REFERENCE_SPEC_VERSION = ref_spec_7976.version + +pytestmark = [pytest.mark.valid_from("EIP7976")] + + +@pytest.fixture +def data_test_type() -> DataTestType: + """Return data test type.""" + return DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS + + +class TestGasConsumption: + """Test gas consumption with EIP-7976 active.""" + + @pytest.fixture + def intrinsic_gas_data_floor_minimum_delta(self) -> int: + """ + Force a minimum delta in order to have some gas to execute the invalid + opcode. + """ + return 50_000 + + @pytest.fixture + def to( + self, + pre: Alloc, + ) -> Address | None: + """ + Return a contract that consumes all gas when executed by calling an + invalid opcode. + """ + return pre.deploy_contract(Op.INVALID) + + @pytest.mark.parametrize( + "ty,protected,authorization_list", + [ + pytest.param(0, False, None, id="type_0_unprotected"), + pytest.param(0, True, None, id="type_0_protected"), + pytest.param(1, True, None, id="type_1"), + pytest.param(2, True, None, id="type_2"), + pytest.param(3, True, None, id="type_3"), + pytest.param(4, True, [Address(1)], id="type_4"), + ], + indirect=["authorization_list"], + ) + @pytest.mark.parametrize( + "tx_gas_delta", + [ + # Test with exact gas and extra gas. + pytest.param(1, id="extra_gas"), + pytest.param(0, id="exact_gas"), + ], + ) + def test_full_gas_consumption( + self, + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, + ) -> None: + """ + Test executing a transaction that fully consumes its execution gas + allocation. + """ + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=tx.gas_limit + ) + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +class TestGasConsumptionBelowDataFloor: + """Test gas consumption barely below the floor data cost (1 gas below).""" + + @pytest.fixture + def contract_creating_tx(self) -> bool: + """Use a constant in order to avoid circular fixture dependencies.""" + return False + + @pytest.fixture + def to( + self, + pre: Alloc, + fork: Fork, + tx_data: Bytes, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + tx_floor_data_cost: int, + ) -> Address | None: + """ + Return a contract that consumes almost all the gas before reaching the + floor data cost. + """ + intrinsic_gas_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + execution_gas = tx_floor_data_cost - intrinsic_gas_cost_calculator( + calldata=tx_data, + contract_creation=False, + access_list=access_list, + authorization_list_or_count=authorization_list, + return_cost_deducted_prior_execution=True, + ) + assert execution_gas > 0 + + return pre.deploy_contract( + (Op.JUMPDEST * (execution_gas - 1)) + Op.STOP + ) + + @pytest.mark.parametrize( + "ty,protected,authorization_list", + [ + pytest.param(0, False, None, id="type_0_unprotected"), + pytest.param(0, True, None, id="type_0_protected"), + pytest.param(1, True, None, id="type_1"), + pytest.param(2, True, None, id="type_2"), + pytest.param(3, True, None, id="type_3"), + pytest.param(4, True, [Address(1)], id="type_4"), + ], + indirect=["authorization_list"], + ) + @pytest.mark.parametrize( + "tx_gas_delta", + [ + # Test with exact gas and extra gas, to verify that the refund is + # correctly applied to the full consumed execution gas. + pytest.param(0, id="exact_gas"), + ], + ) + def test_gas_consumption_below_data_floor( + self, + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, + tx_floor_data_cost: int, + ) -> None: + """ + Test executing a transaction that almost consumes the floor data cost. + """ + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=tx_floor_data_cost + ) + state_test( + pre=pre, + post={}, + tx=tx, + ) diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_refunds.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_refunds.py new file mode 100644 index 00000000000..4fcddcd316c --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_refunds.py @@ -0,0 +1,335 @@ +""" +Test [EIP-7976: Increase calldata floor cost](https://eips.ethereum.org/EIPS/eip-7976). +""" + +from enum import Enum +from typing import Dict, List + +import pytest +from execution_testing import ( + Address, + Alloc, + AuthorizationTuple, + Bytecode, + Fork, + Op, + RefundTypes, + StateTestFiller, + Transaction, + TransactionReceipt, +) + +from .helpers import DataTestType +from .spec import ref_spec_7976 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7976.git_path +REFERENCE_SPEC_VERSION = ref_spec_7976.version + +pytestmark = [pytest.mark.valid_from("EIP7976")] + + +class RefundTestType(Enum): + """Refund test type.""" + + EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR = 0 + """ + The execution gas minus the refund is greater than the data floor, hence + the execution gas cost is charged. + """ + EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR = 1 + """ + The execution gas minus the refund is less than the data floor, hence the + data floor cost is charged. + """ + EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR = 2 + """The execution gas minus the refund is equal to the data floor.""" + + +@pytest.fixture +def data_test_type() -> DataTestType: + """Return data test type.""" + return DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS + + +@pytest.fixture +def authorization_list( + pre: Alloc, refund_type: RefundTypes +) -> List[AuthorizationTuple] | None: + """ + Modify fixture from conftest to automatically read the refund_type + information. + """ + if refund_type != RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY: + return None + return [AuthorizationTuple(signer=pre.fund_eoa(1), address=Address(1))] + + +@pytest.fixture +def ty(refund_type: RefundTypes) -> int: + """ + Modify fixture from conftest to automatically read the refund_type + information. + """ + if refund_type == RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY: + return 4 + if refund_type == RefundTypes.STORAGE_CLEAR: + return 2 + raise ValueError(f"Unknown refund type: {refund_type}") + + +@pytest.fixture +def max_refund(fork: Fork, refund_type: RefundTypes) -> int: + """Return the max refund gas of the transaction.""" + gas_costs = fork.gas_costs() + max_refund = ( + gas_costs.REFUND_STORAGE_CLEAR + if refund_type == RefundTypes.STORAGE_CLEAR + else 0 + ) + max_refund += ( + gas_costs.REFUND_AUTH_PER_EXISTING_ACCOUNT + if refund_type == RefundTypes.AUTHORIZATION_EXISTING_AUTHORITY + else 0 + ) + return max_refund + + +@pytest.fixture +def prefix_code_gas(fork: Fork, refund_type: RefundTypes) -> int: + """Return the minimum execution gas cost due to the refund type.""" + if refund_type == RefundTypes.STORAGE_CLEAR: + # Minimum code to generate a storage clear is Op.SSTORE(0, 0). + return ( + Op.SSTORE( + key_warm=False, + original_value=1, + new_value=0, + ) + + Op.PUSH1(0) * 2 + ).gas_cost(fork) + return 0 + + +@pytest.fixture +def prefix_code(refund_type: RefundTypes) -> Bytecode: + """Return the minimum execution gas cost due to the refund type.""" + if refund_type == RefundTypes.STORAGE_CLEAR: + # Clear the storage to trigger a refund. + return Op.SSTORE(0, 0) + return Bytecode() + + +@pytest.fixture +def code_storage(refund_type: RefundTypes) -> Dict: + """Return the minimum execution gas cost due to the refund type.""" + if refund_type == RefundTypes.STORAGE_CLEAR: + # Pre-set the storage to be cleared. + return {0: 1} + return {} + + +@pytest.fixture +def contract_creating_tx() -> bool: + """ + Override fixture in order to avoid a circular fixture dependency since none + of these tests are contract creating transactions. + """ + return False + + +@pytest.fixture +def intrinsic_gas_data_floor_minimum_delta() -> int: + """ + Induce a minimum delta between the transaction intrinsic gas cost and the + floor data gas cost. + + Since at least one of the cases requires some execution gas expenditure + (SSTORE clearing), we need to introduce an increment of the floor data cost + above the transaction intrinsic gas cost, otherwise the floor data cost + would always be the below the execution gas cost even after the refund is + applied. + + This value has been set as of Amsterdam and should be adjusted if the gas + costs change. + """ + return 250 + + +@pytest.fixture +def execution_gas_used( + fork: Fork, + tx_intrinsic_gas_cost_before_execution: int, + tx_floor_data_cost: int, + max_refund: int, + prefix_code_gas: int, + refund_test_type: RefundTestType, +) -> int: + """ + Return the amount of gas that needs to be consumed by the execution. + + This gas amount is on top of the transaction intrinsic gas cost. + + If this value were zero it would result in the refund being applied to the + execution gas cost and the resulting amount being always below the floor + data cost, hence we need to find a higher value in this function to ensure + we get both scenarios where the refund drives the execution cost below the + floor data cost and above the floor data cost. + """ + + def execution_gas_cost(execution_gas: int) -> int: + total_gas_used = tx_intrinsic_gas_cost_before_execution + execution_gas + return total_gas_used - min( + max_refund, total_gas_used // fork.max_refund_quotient() + ) + + execution_gas = prefix_code_gas + + assert execution_gas_cost(execution_gas) < tx_floor_data_cost, ( + "tx_floor_data_cost is too low, there might have been a gas cost " + "change that caused this test to fail. Try increasing the " + "intrinsic_gas_data_floor_minimum_delta fixture." + ) + + # Dumb for-loop to find the execution gas cost that will result in the + # expected refund. + while execution_gas_cost(execution_gas) < tx_floor_data_cost: + execution_gas += 1 + if ( + refund_test_type + == RefundTestType.EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR + ): + return execution_gas + elif ( + refund_test_type + == RefundTestType.EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR + ): + # Keep incrementing until we actually get gas_used > tx_floor_data_cost + # (adding just 1 may not be enough due to refund cap boundary effects) + while execution_gas_cost(execution_gas) <= tx_floor_data_cost: + execution_gas += 1 + return execution_gas + elif ( + refund_test_type + == RefundTestType.EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR + ): + return execution_gas - 1 + + raise ValueError("Invalid refund test type") + + +@pytest.fixture +def refund( + fork: Fork, + tx_intrinsic_gas_cost_before_execution: int, + execution_gas_used: int, + max_refund: int, +) -> int: + """Return the refund gas of the transaction.""" + total_gas_used = ( + tx_intrinsic_gas_cost_before_execution + execution_gas_used + ) + return min(max_refund, total_gas_used // fork.max_refund_quotient()) + + +@pytest.fixture +def to( + pre: Alloc, + execution_gas_used: int, + prefix_code: Bytecode, + prefix_code_gas: int, + code_storage: Dict, +) -> Address | None: + """ + Return a contract that consumes the expected execution gas. + + At the moment we naively use JUMPDEST to consume the gas, which can yield + very big contracts. + + Ideally, we can use memory expansion to consume gas. + """ + extra_gas = execution_gas_used - prefix_code_gas + return pre.deploy_contract( + prefix_code + (Op.JUMPDEST * extra_gas) + Op.STOP, + storage=code_storage, + ) + + +@pytest.fixture +def tx_gas_limit( + tx_intrinsic_gas_cost_including_floor_data_cost: int, + tx_intrinsic_gas_cost_before_execution: int, + execution_gas_used: int, +) -> int: + """ + Gas limit for the transaction. + + The gas delta is added to the intrinsic gas cost to generate different test + scenarios. + """ + tx_gas_limit = tx_intrinsic_gas_cost_before_execution + execution_gas_used + assert tx_gas_limit >= tx_intrinsic_gas_cost_including_floor_data_cost + return tx_gas_limit + + +@pytest.mark.parametrize( + "refund_test_type", + [ + RefundTestType.EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR, + RefundTestType.EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR, + RefundTestType.EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR, + ], +) +@pytest.mark.with_all_refund_types() +def test_gas_refunds_from_data_floor( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, + tx_floor_data_cost: int, + tx_intrinsic_gas_cost_before_execution: int, + execution_gas_used: int, + refund: int, + refund_test_type: RefundTestType, +) -> None: + """ + Test gas refunds deducted from the execution gas cost and not the data + floor. + """ + gas_used = ( + tx_intrinsic_gas_cost_before_execution + execution_gas_used - refund + ) + if ( + refund_test_type + == RefundTestType.EXECUTION_GAS_MINUS_REFUND_LESS_THAN_DATA_FLOOR + ): + assert gas_used < tx_floor_data_cost + elif ( + refund_test_type + == RefundTestType.EXECUTION_GAS_MINUS_REFUND_GREATER_THAN_DATA_FLOOR + ): + assert gas_used > tx_floor_data_cost + elif ( + refund_test_type + == RefundTestType.EXECUTION_GAS_MINUS_REFUND_EQUAL_TO_DATA_FLOOR + ): + assert gas_used == tx_floor_data_cost + else: + raise ValueError("Invalid refund test type") + if gas_used < tx_floor_data_cost: + gas_used = tx_floor_data_cost + # This is the actual test verification: + # - During test filling, the receipt returned by the transition tool + # (t8n) is verified against the expected receipt. + # - During test consumption, this is reflected in the balance difference + # and the state root. + tx.expected_receipt = TransactionReceipt(cumulative_gas_used=gas_used) + state_test( + pre=pre, + post={ + tx.to: { + # Verify that the storage was cleared (for storage clear + # refund). See `code_storage` fixture for more details. + "storage": {0: 0}, + } + }, + tx=tx, + ) diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_transaction_validity.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_transaction_validity.py new file mode 100644 index 00000000000..f12c8f11444 --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_transaction_validity.py @@ -0,0 +1,384 @@ +""" +Test [EIP-7976: Increase calldata floor cost](https://eips.ethereum.org/EIPS/eip-7976). +""" + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + Hash, + Op, + StateTestFiller, + Transaction, + add_kzg_version, +) + +from ...osaka.eip7594_peerdas.spec import Spec as EIP_7594_Spec +from .helpers import DataTestType +from .spec import ref_spec_7976 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7976.git_path +REFERENCE_SPEC_VERSION = ref_spec_7976.version + +pytestmark = [pytest.mark.valid_from("EIP7976")] + + +# All tests in this file are parametrized with the following parameters: +pytestmark += [ + pytest.mark.parametrize( + "tx_gas_delta", + [ + # Test the case where the included gas is greater than the + # intrinsic gas to verify that the data floor does not consume more + # gas than it should. + pytest.param(1, id="extra_gas"), + pytest.param(0, id="exact_gas"), + pytest.param( + -1, id="insufficient_gas", marks=pytest.mark.exception_test + ), + ], + ), + pytest.mark.parametrize( + "data_test_type", + [ + pytest.param( + DataTestType.FLOOR_GAS_COST_LESS_THAN_OR_EQUAL_TO_INTRINSIC_GAS, + id="floor_gas_less_than_or_equal_to_intrinsic_gas", + ), + pytest.param( + DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS, + id="floor_gas_greater_than_intrinsic_gas", + ), + ], + ), +] + + +@pytest.mark.parametrize( + "protected", + [ + pytest.param(True, id="protected"), + pytest.param(False, id="unprotected"), + ], +) +@pytest.mark.parametrize( + "ty", + [pytest.param(0, id="type_0")], +) +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id="to_eoa"), + pytest.param(None, id="contract_creating"), + pytest.param(Op.STOP, id=""), + ], + indirect=True, +) +def test_transaction_validity_type_0( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions without access lists and + contract creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id="to_eoa"), + pytest.param(None, id="contract_creating"), + pytest.param(Op.STOP, id=""), + ], + indirect=True, +) +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + None, + id="no_access_list", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + id="single_access_list_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_access_list_single_storage_key", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(k) for k in range(10)], + ) + ], + id="single_access_list_multiple_storage_keys", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[]) + for a in range(10) + ], + id="multiple_access_lists_no_storage_keys", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[Hash(0)]) + for a in range(10) + ], + id="multiple_access_lists_single_storage_key", + ), + pytest.param( + [ + AccessList( + address=Address(a), + storage_keys=[Hash(k) for k in range(10)], + ) + for a in range(10) + ], + id="multiple_access_lists_multiple_storage_keys", + ), + ], +) +@pytest.mark.parametrize( + "ty", + [pytest.param(1, id="type_1"), pytest.param(2, id="type_2")], +) +def test_transaction_validity_type_1_type_2( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions with access lists and contract + creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + None, + id="no_access_list", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + id="single_access_list_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_access_list_single_storage_key", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(k) for k in range(10)], + ) + ], + id="single_access_list_multiple_storage_keys", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[]) + for a in range(10) + ], + id="multiple_access_lists_no_storage_keys", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[Hash(0)]) + for a in range(10) + ], + id="multiple_access_lists_single_storage_key", + ), + pytest.param( + [ + AccessList( + address=Address(a), + storage_keys=[Hash(k) for k in range(10)], + ) + for a in range(10) + ], + id="multiple_access_lists_multiple_storage_keys", + ), + ], +) +@pytest.mark.parametrize( + # Blobs don't really have an effect because the blob gas does is not + # considered in the intrinsic gas calculation, but we still test it to make + # sure that the transaction is correctly processed. + "blob_versioned_hashes", + [ + pytest.param( + add_kzg_version( + [Hash(x) for x in range(1)], + EIP_7594_Spec.BLOB_COMMITMENT_VERSION_KZG, + ), + id="single_blob", + ), + pytest.param( + add_kzg_version( + [Hash(x) for x in range(6)], + EIP_7594_Spec.BLOB_COMMITMENT_VERSION_KZG, + ), + id="multiple_blobs", + ), + ], +) +@pytest.mark.parametrize( + "ty", + [pytest.param(3, id="type_3")], +) +def test_transaction_validity_type_3( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions with access lists, blobs, but no + contract creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + None, + id="no_access_list", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + id="single_access_list_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_access_list_single_storage_key", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(k) for k in range(10)], + ) + ], + id="single_access_list_multiple_storage_keys", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[]) + for a in range(10) + ], + id="multiple_access_lists_no_storage_keys", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[Hash(0)]) + for a in range(10) + ], + id="multiple_access_lists_single_storage_key", + ), + pytest.param( + [ + AccessList( + address=Address(a), + storage_keys=[Hash(k) for k in range(10)], + ) + for a in range(10) + ], + id="multiple_access_lists_multiple_storage_keys", + ), + ], +) +@pytest.mark.parametrize( + "authorization_list", + [ + pytest.param( + [Address(1)], + id="single_authorization", + ), + pytest.param( + [Address(i + 1) for i in range(10)], + id="multiple_authorizations", + ), + ], + indirect=True, +) +@pytest.mark.parametrize( + "ty", + [pytest.param(4, id="type_4")], +) +def test_transaction_validity_type_4( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions with access lists, authorization + lists, but no contract creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "ty", + [pytest.param(0, id="type_0"), pytest.param(2, id="type_2")], +) +@pytest.mark.parametrize( + "to", + [ + pytest.param( + Op.PUSH0 + + Op.PUSH0 + + Op.PUSH0 + + Op.PUSH0 + + Op.PUSH0 + + Op.PUSH0 + + Op.CREATE2 + + Op.STOP, + id="contract_with_create2", + ), + ], + indirect=True, +) +def test_transaction_validity_with_create2( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions calling a contract that uses + CREATE2 internally. This verifies that internal contract creation via + CREATE2 doesn't interfere with the floor gas cost mechanism. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) diff --git a/tests/ported_static/stRandom2/test_random_statetest644.py b/tests/ported_static/stRandom2/test_random_statetest644.py index 6d36dd43b81..79e94782a18 100644 --- a/tests/ported_static/stRandom2/test_random_statetest644.py +++ b/tests/ported_static/stRandom2/test_random_statetest644.py @@ -15,6 +15,7 @@ StateTestFiller, Transaction, ) +from execution_testing.forks import Fork from execution_testing.vm import Op REFERENCE_SPEC_GIT_PATH = "N/A" @@ -29,6 +30,7 @@ def test_random_statetest644( state_test: StateTestFiller, pre: Alloc, + fork: Fork, ) -> None: """Geth Failed this test on Frontier and Homestead.""" coinbase = Address(0x02EBBA385BD7F6DDE6C57E2D3929A11A1EA0DA7E) @@ -141,13 +143,15 @@ def test_random_statetest644( address=Address(0x02EBBA385BD7F6DDE6C57E2D3929A11A1EA0DA7E), # noqa: E501 ) + tx_data = Bytes( + "7300000000000000000000000000000000000000013b7ea30da9ff11bd5f11e4529c93ce4b37d5a256d61e1f1a0ecccb5fbb21fec97f6b3d456b8caaaa84ef30a44fd8779fae5a48354b937835d82d57999d194d4edfbaf0a8dd026d727e3315a53e907b0e1873b4dcb7f806014bc23164e8cc0560256f0c6a8c09c0df2f0f8208ff622bb459d46ffab16ce9d64bcf9cec668338ebbc7f9e64656ae99c617d0dd709c1f78f96bea46e2df76db8418e2b657fc77ff2f979952911a73b767a6ce270c7392d2ff340648610fe0219aaf24df2b26e97e2761497bc6b97dea1269de3aca3b69ec7098a7257114a4a2e22c401ec6319bc2deb70980ebef372a327809b3c2473ab86578d2fccd458e6b99a277c4a1d3e96351fbebe62fe63d300444afd3a9077c20905d2a92b5b2945de6bf9b28d1d42795ca74b029dce6934312994a31fed72e45da26c73c636b40b1f6d529f35488625624a9dfd0b62309f286277b5ab6259b2fd62144722631c4722737300000000000000000000000000000000000000056317345497f13368b2a96595a00933d8dd6dc111a13b90768f330898544a443407620316d3625614816282f1e9622e741d730346ad0b28ea31b7c3d398881dc11ebc97869461631d791a38fa" # noqa: E501 + ) + floor_cost = fork.transaction_data_floor_cost_calculator()(data=tx_data) tx = Transaction( sender=sender, to=Address(0x0000000000000000000000000000000000000001), - data=Bytes( - "7300000000000000000000000000000000000000013b7ea30da9ff11bd5f11e4529c93ce4b37d5a256d61e1f1a0ecccb5fbb21fec97f6b3d456b8caaaa84ef30a44fd8779fae5a48354b937835d82d57999d194d4edfbaf0a8dd026d727e3315a53e907b0e1873b4dcb7f806014bc23164e8cc0560256f0c6a8c09c0df2f0f8208ff622bb459d46ffab16ce9d64bcf9cec668338ebbc7f9e64656ae99c617d0dd709c1f78f96bea46e2df76db8418e2b657fc77ff2f979952911a73b767a6ce270c7392d2ff340648610fe0219aaf24df2b26e97e2761497bc6b97dea1269de3aca3b69ec7098a7257114a4a2e22c401ec6319bc2deb70980ebef372a327809b3c2473ab86578d2fccd458e6b99a277c4a1d3e96351fbebe62fe63d300444afd3a9077c20905d2a92b5b2945de6bf9b28d1d42795ca74b029dce6934312994a31fed72e45da26c73c636b40b1f6d529f35488625624a9dfd0b62309f286277b5ab6259b2fd62144722631c4722737300000000000000000000000000000000000000056317345497f13368b2a96595a00933d8dd6dc111a13b90768f330898544a443407620316d3625614816282f1e9622e741d730346ad0b28ea31b7c3d398881dc11ebc97869461631d791a38fa" # noqa: E501 - ), - gas_limit=48887, + data=tx_data, + gas_limit=max(48887, floor_cost), value=0xF3107CE3, ) diff --git a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py index ff07e21b0d5..ef19a867f29 100644 --- a/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py +++ b/tests/ported_static/stRevertTest/test_revert_precompiled_touch_exact_oog_paris.py @@ -927,11 +927,12 @@ def test_revert_precompiled_touch_exact_oog_paris( ] tx_gas = [22500, 120000, 69000] + floor_cost = fork.transaction_data_floor_cost_calculator()(data=tx_data[d]) tx = Transaction( sender=sender, to=target, data=tx_data[d], - gas_limit=tx_gas[g], + gas_limit=max(tx_gas[g], floor_cost), nonce=1, error=_exc, ) diff --git a/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py b/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py index eead8f124ba..6e8dca69a78 100644 --- a/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py +++ b/tests/ported_static/stTransactionTest/test_transaction_data_costs652.py @@ -68,11 +68,12 @@ def test_transaction_data_costs652( ] tx_gas = [22000, 72000] + floor_cost = fork.transaction_data_floor_cost_calculator()(data=tx_data[d]) tx = Transaction( sender=sender, to=Address(0xB94F5374FCE5EDBC8E2A8697C15331677E6EBF0B), data=tx_data[d], - gas_limit=tx_gas[g], + gas_limit=max(tx_gas[g], floor_cost), ) post = {sender: Account(nonce=1)} From 84b22c02acbaf1c40d00b1b4499688b1cf456bc3 Mon Sep 17 00:00:00 2001 From: Ignacio Hagopian Date: Tue, 19 May 2026 09:36:48 -0300 Subject: [PATCH 092/186] fix(specs): delay get_code calls in CALL-like opcodes (#2473) Signed-off-by: jsign --- .../forks/amsterdam/vm/instructions/system.py | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/system.py b/src/ethereum/forks/amsterdam/vm/instructions/system.py index b5d0c9c3990..9bf8b99171b 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/system.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/system.py @@ -293,7 +293,6 @@ def generic_call( memory_input_size: U256, memory_output_start_position: U256, memory_output_size: U256, - code: Bytes, disable_precompiles: bool, ) -> None: """ @@ -308,6 +307,10 @@ def generic_call( push(evm.stack, U256(0)) return + tx_state = evm.message.tx_env.state + code_hash = get_account(tx_state, code_address).code_hash + code = get_code(tx_state, code_hash) + call_data = memory_read_bytes( evm.memory, memory_input_start_position, memory_input_size ) @@ -419,9 +422,6 @@ def call(evm: Evm) -> None: if code_address not in evm.accessed_addresses: evm.accessed_addresses.add(code_address) - code_hash = get_account(tx_state, code_address).code_hash - code = get_code(tx_state, code_hash) - message_call_gas = calculate_message_call_gas( value, gas, @@ -452,7 +452,6 @@ def call(evm: Evm) -> None: memory_input_size, memory_output_start_position, memory_output_size, - code, is_delegated, ) @@ -523,9 +522,6 @@ def callcode(evm: Evm) -> None: if code_address not in evm.accessed_addresses: evm.accessed_addresses.add(code_address) - code_hash = get_account(tx_state, code_address).code_hash - code = get_code(tx_state, code_hash) - message_call_gas = calculate_message_call_gas( value, gas, @@ -557,7 +553,6 @@ def callcode(evm: Evm) -> None: memory_input_size, memory_output_start_position, memory_output_size, - code, is_delegated, ) @@ -666,7 +661,6 @@ def delegatecall(evm: Evm) -> None: check_gas(evm, access_gas_cost + extend_memory.cost) # STATE ACCESS - tx_state = evm.message.tx_env.state if is_cold_access: evm.accessed_addresses.add(code_address) @@ -684,9 +678,6 @@ def delegatecall(evm: Evm) -> None: if code_address not in evm.accessed_addresses: evm.accessed_addresses.add(code_address) - code_hash = get_account(tx_state, code_address).code_hash - code = get_code(tx_state, code_hash) - message_call_gas = calculate_message_call_gas( U256(0), gas, @@ -711,7 +702,6 @@ def delegatecall(evm: Evm) -> None: memory_input_size, memory_output_start_position, memory_output_size, - code, is_delegated, ) @@ -756,7 +746,6 @@ def staticcall(evm: Evm) -> None: check_gas(evm, access_gas_cost + extend_memory.cost) # STATE ACCESS - tx_state = evm.message.tx_env.state if is_cold_access: evm.accessed_addresses.add(to) @@ -774,9 +763,6 @@ def staticcall(evm: Evm) -> None: if code_address not in evm.accessed_addresses: evm.accessed_addresses.add(code_address) - code_hash = get_account(tx_state, code_address).code_hash - code = get_code(tx_state, code_hash) - message_call_gas = calculate_message_call_gas( U256(0), gas, @@ -801,7 +787,6 @@ def staticcall(evm: Evm) -> None: memory_input_size, memory_output_start_position, memory_output_size, - code, is_delegated, ) From db42a899a55dc7de9fd5a9000847b12b5ff4f9e5 Mon Sep 17 00:00:00 2001 From: felix Date: Tue, 19 May 2026 15:51:41 +0200 Subject: [PATCH 093/186] feat(spec-specs, tests): Add EIP-7981 Increase Access List Cost (#2877) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: devnet script optimization to avoid merge conflicts * feat: mario feedback * refactor: 8037+7981 harmonization, add zero-valued access list token scaffolding * fix: add comment * feat(tests): adds EIP-7981 test and required framework changes (#2144) * feat: adds 7981 src changes + tests * fix: sam feedback * fix: ethereum-spec-lint: 'the item .. has changed relative positions', do we really need this check * feat: EIPs 11340 update implemented * fix: sam feedback * refactor(tests-eip-7981): Constrain tests to EIP inclusion * fix: harmonize with 8037, correct access list token placement and remove docstring conflicts * fix(specs,tests): EIP-7981 - Update implementation and specs (#2682) * fix(specs,tests): EIP-7981 - Update implementation and specs * fix: tooling+unused * fix: ACCESS_LIST_ADDRESS_FLOOR_TOKENS and ACCESS_LIST_STORAGE_KEY_FLOOR_TOKENS are now populated --------- Co-authored-by: Felix H * chores: update refspec * fix(tests): drop GAS_ prefix from gas_costs attribute references Align the EIP-7981 mixin and tests with the GasCosts dataclass rename on forks/amsterdam. * chore: update refspec (both 706296e06bf9b700bf046cfaa80bd5c3ebbc89c3 and 71d3353c3f6776485539fe2ec526b7cc80780bfc would not change the fixtures we currently output, cosmetic only) * chore: update refspec (cosmetic change, no action required) * feat(tests): EIP-7981 zero-byte calldata floor cost rejection (#2869) --------- Co-authored-by: marioevz Co-authored-by: Toni Wahrstätter <51536394+nerolation@users.noreply.github.com> Co-authored-by: spencer-tb Co-authored-by: Paweł Bylica --- .../src/execution_testing/forks/base_fork.py | 7 +- .../forks/forks/eips/amsterdam/eip_7981.py | 111 +++++++ .../forks/forks/eips/prague/eip_7623.py | 7 +- .../execution_testing/forks/forks/forks.py | 8 +- src/ethereum/forks/amsterdam/transactions.py | 20 ++ .../__init__.py | 1 + .../conftest.py | 260 ++++++++++++++++ .../helpers.py | 30 ++ .../eip7981_increase_access_list_cost/spec.py | 28 ++ .../test_access_list_cost.py | 263 +++++++++++++++++ .../test_eip_mainnet.py | 149 ++++++++++ .../test_transaction_validity.py | 279 ++++++++++++++++++ 12 files changed, 1159 insertions(+), 4 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7981.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/__init__.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/conftest.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/helpers.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/spec.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/test_access_list_cost.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/test_eip_mainnet.py create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/test_transaction_validity.py diff --git a/packages/testing/src/execution_testing/forks/base_fork.py b/packages/testing/src/execution_testing/forks/base_fork.py index 03059aff283..f6d5edb2bf9 100644 --- a/packages/testing/src/execution_testing/forks/base_fork.py +++ b/packages/testing/src/execution_testing/forks/base_fork.py @@ -61,7 +61,12 @@ class TransactionDataFloorCostCalculator(Protocol): Calculate the transaction floor cost due to its calldata for a given fork. """ - def __call__(self, *, data: BytesConvertible) -> int: + def __call__( + self, + *, + data: BytesConvertible, + access_list: List[AccessList] | None = None, + ) -> int: """Return transaction gas cost of calldata given its contents.""" pass diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7981.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7981.py new file mode 100644 index 00000000000..b2f927b507c --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7981.py @@ -0,0 +1,111 @@ +""" +EIP-7981: Increase Access List Cost. + +Price access lists for data to reduce maximum block size. + +https://eips.ethereum.org/EIPS/eip-7981 +""" + +from typing import List, Sized + +from execution_testing.base_types import AccessList +from execution_testing.base_types.conversions import BytesConvertible + +from ....base_fork import ( + BaseFork, + TransactionDataFloorCostCalculator, + TransactionIntrinsicCostCalculator, +) + + +class EIP7981(BaseFork): + """EIP-7981 class.""" + + @classmethod + def _access_list_floor_tokens( + cls, access_list: List[AccessList] | None + ) -> int: + """ + Return ``access_list_bytes * 4`` floor tokens for the access list. + + Every byte of each address (20 bytes) and storage key (32 bytes) + contributes four floor tokens, so zero and non-zero bytes are + charged equally per EIP-7981. + """ + if not access_list: + return 0 + total_bytes = 0 + for access in access_list: + total_bytes += len(access.address) + for slot in access.storage_keys: + total_bytes += len(slot) + return total_bytes * 4 + + @classmethod + def transaction_data_floor_cost_calculator( + cls, + ) -> TransactionDataFloorCostCalculator: + """ + Add access list floor tokens to the inherited calldata floor cost. + """ + super_fn = super(EIP7981, cls).transaction_data_floor_cost_calculator() + gas_costs = cls.gas_costs() + + def fn( + *, + data: BytesConvertible, + access_list: List[AccessList] | None = None, + ) -> int: + return ( + super_fn(data=data) + + cls._access_list_floor_tokens(access_list) + * gas_costs.TX_DATA_TOKEN_FLOOR + ) + + return fn + + @classmethod + def transaction_intrinsic_cost_calculator( + cls, + ) -> TransactionIntrinsicCostCalculator: + """ + Charge access list data at the floor token cost on top of the + inherited intrinsic cost and enforce the combined data floor. + """ + super_fn = super(EIP7981, cls).transaction_intrinsic_cost_calculator() + gas_costs = cls.gas_costs() + data_floor_cost_calculator = ( + cls.transaction_data_floor_cost_calculator() + ) + + def fn( + *, + calldata: BytesConvertible = b"", + contract_creation: bool = False, + access_list: List[AccessList] | None = None, + authorization_list_or_count: Sized | int | None = None, + return_cost_deducted_prior_execution: bool = False, + ) -> int: + intrinsic_cost: int = super_fn( + calldata=calldata, + contract_creation=contract_creation, + access_list=access_list, + authorization_list_or_count=authorization_list_or_count, + return_cost_deducted_prior_execution=True, + ) + intrinsic_cost += ( + cls._access_list_floor_tokens(access_list) + * gas_costs.TX_DATA_TOKEN_FLOOR + ) + + if return_cost_deducted_prior_execution: + return intrinsic_cost + + return max( + intrinsic_cost, + data_floor_cost_calculator( + data=calldata, access_list=access_list + ), + ) + + return fn diff --git a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py index 1a073f11a92..d52c5601a16 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/prague/eip_7623.py @@ -62,7 +62,12 @@ def transaction_data_floor_cost_calculator( calldata_gas_calculator = cls.calldata_gas_calculator() gas_costs = cls.gas_costs() - def fn(*, data: BytesConvertible) -> int: + def fn( + *, + data: BytesConvertible, + access_list: List[AccessList] | None = None, + ) -> int: + del access_list return ( calldata_gas_calculator(data=data, floor=True) + gas_costs.TX_BASE diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 41dc660309e..748047b4827 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -812,8 +812,12 @@ def transaction_data_floor_cost_calculator( ) -> TransactionDataFloorCostCalculator: """At frontier, the transaction data floor cost is a constant zero.""" - def fn(*, data: BytesConvertible) -> int: - del data + def fn( + *, + data: BytesConvertible, + access_list: List[AccessList] | None = None, + ) -> int: + del data, access_list return 0 return fn diff --git a/src/ethereum/forks/amsterdam/transactions.py b/src/ethereum/forks/amsterdam/transactions.py index cc867fc4941..d0961a2ba35 100644 --- a/src/ethereum/forks/amsterdam/transactions.py +++ b/src/ethereum/forks/amsterdam/transactions.py @@ -30,6 +30,22 @@ TX_MAX_GAS_LIMIT = Uint(16_777_216) +ACCESS_LIST_ADDRESS_FLOOR_TOKENS = Uint(80) +""" +Floor data tokens contributed by a single access list address per +[EIP-7981]. + +[EIP-7981]: https://eips.ethereum.org/EIPS/eip-7981 +""" + +ACCESS_LIST_STORAGE_KEY_FLOOR_TOKENS = Uint(128) +""" +Floor data tokens contributed by a single access list storage key per +[EIP-7981]. + +[EIP-7981]: https://eips.ethereum.org/EIPS/eip-7981 +""" + @slotted_freezable @dataclass @@ -601,6 +617,10 @@ def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]: access_list_cost += ( ulen(access.slots) * GasCosts.TX_ACCESS_LIST_STORAGE_KEY ) + tokens_in_access_list += ACCESS_LIST_ADDRESS_FLOOR_TOKENS + tokens_in_access_list += ( + ulen(access.slots) * ACCESS_LIST_STORAGE_KEY_FLOOR_TOKENS + ) # Data token floor cost for access list bytes. access_list_cost += tokens_in_access_list * GasCosts.TX_DATA_TOKEN_FLOOR diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/__init__.py b/tests/amsterdam/eip7981_increase_access_list_cost/__init__.py new file mode 100644 index 00000000000..bbbd9412cb8 --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/__init__.py @@ -0,0 +1 @@ +"""Tests for EIP-7981: Increase Access List Cost.""" diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/conftest.py b/tests/amsterdam/eip7981_increase_access_list_cost/conftest.py new file mode 100644 index 00000000000..104a73e464a --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/conftest.py @@ -0,0 +1,260 @@ +"""Fixtures for the EIP-7981 tests.""" + +from typing import List, Sequence + +import pytest +from execution_testing import ( + EOA, + AccessList, + Address, + Alloc, + AuthorizationTuple, + Bytecode, + Bytes, + Fork, + Hash, + Op, + Transaction, + TransactionException, + add_kzg_version, +) + +from ...cancun.eip4844_blobs.spec import Spec as EIP_4844_Spec + + +@pytest.fixture +def to( + request: pytest.FixtureRequest, + pre: Alloc, +) -> Address | None: + """Create the recipient address.""" + if hasattr(request, "param"): + param = request.param + else: + param = Op.STOP + + if param is None: + return None + if isinstance(param, str) and param == "eoa": + return pre.fund_eoa(amount=0) + if isinstance(param, Bytecode): + return pre.deploy_contract(param) + + raise ValueError(f"Invalid value for `to` fixture: {param}") + + +@pytest.fixture +def protected() -> bool: + """ + Return whether the transaction is protected or not. Only valid for type-0 + transactions. + """ + return True + + +@pytest.fixture +def access_list() -> List[AccessList] | None: + """Access list for the transaction.""" + return None + + +@pytest.fixture +def authorization_refund() -> bool: + """ + Return whether the transaction has an existing authority in the + authorization list. + """ + return False + + +@pytest.fixture +def authorization_list( + request: pytest.FixtureRequest, + pre: Alloc, + authorization_refund: bool, + tx_type: int, +) -> List[AuthorizationTuple] | None: + """ + Authorization-list for the transaction. + + This fixture needs to be parametrized indirectly in order to generate the + authorizations with valid signers using `pre` in this function, and the + parametrized value should be a list of addresses. + """ + if not hasattr(request, "param"): + if tx_type == 4: + return [ + AuthorizationTuple( + signer=pre.fund_eoa(1 if authorization_refund else 0), + address=Address(1), + ) + ] + return None + if request.param is None: + if tx_type == 4: + return [ + AuthorizationTuple( + signer=pre.fund_eoa(1 if authorization_refund else 0), + address=Address(1), + ) + ] + return None + return [ + AuthorizationTuple( + signer=pre.fund_eoa(1 if authorization_refund else 0), + address=address, + ) + for address in request.param + ] + + +@pytest.fixture +def blob_versioned_hashes(tx_type: int) -> Sequence[Hash] | None: + """Versioned hashes for the transaction.""" + return ( + add_kzg_version( + [Hash(1)], + EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG, + ) + if tx_type == 3 + else None + ) + + +@pytest.fixture +def contract_creating_tx(to: Address | None) -> bool: + """Return whether the transaction creates a contract or not.""" + return to is None + + +@pytest.fixture +def tx_data() -> Bytes: + """ + Transaction data. + + Default is empty, but can be parametrized to test different scenarios. + """ + return Bytes(b"") + + +@pytest.fixture +def tx_gas_delta() -> int: + """ + Gas delta to modify the gas amount included with the transaction. + + If negative, the transaction will be invalid because the intrinsic gas cost + is greater than the gas limit. + + This value operates regardless of whether the floor data gas cost is + reached or not. + + If the value is greater than zero, the transaction will also be valid and + the test will check that transaction processing does not consume more gas + than it should. + """ + return 0 + + +@pytest.fixture +def tx_intrinsic_gas_cost_before_execution( + fork: Fork, + tx_data: Bytes, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + contract_creating_tx: bool, +) -> int: + """ + Return the intrinsic gas cost that is applied before the execution start. + + This value never includes the floor data gas cost. + """ + intrinsic_gas_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + return intrinsic_gas_cost_calculator( + calldata=tx_data, + contract_creation=contract_creating_tx, + access_list=access_list, + authorization_list_or_count=authorization_list, + return_cost_deducted_prior_execution=True, + ) + + +@pytest.fixture +def tx_intrinsic_gas_cost_including_floor_data_cost( + fork: Fork, + tx_data: Bytes, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + contract_creating_tx: bool, +) -> int: + """ + Transaction intrinsic gas cost. + + The calculated value takes into account the normal intrinsic gas cost and + the floor data gas cost if it is greater than the intrinsic gas cost. + + In other words, this is the value that is required for the transaction to + be valid. + """ + intrinsic_gas_cost_calculator = ( + fork.transaction_intrinsic_cost_calculator() + ) + return intrinsic_gas_cost_calculator( + calldata=tx_data, + contract_creation=contract_creating_tx, + access_list=access_list, + authorization_list_or_count=authorization_list, + ) + + +@pytest.fixture +def tx_gas_limit( + tx_intrinsic_gas_cost_including_floor_data_cost: int, + tx_gas_delta: int, +) -> int: + """ + Gas limit for the transaction. + + The gas delta is added to the intrinsic gas cost to generate different test + scenarios. + """ + return tx_intrinsic_gas_cost_including_floor_data_cost + tx_gas_delta + + +@pytest.fixture +def tx_error( + tx_gas_delta: int, +) -> TransactionException | None: + """Transaction error, only expected if the gas delta is negative.""" + if tx_gas_delta < 0: + return TransactionException.INTRINSIC_GAS_TOO_LOW + return None + + +@pytest.fixture +def tx( + sender: EOA, + tx_type: int, + tx_data: Bytes, + to: Address | None, + protected: bool, + access_list: List[AccessList] | None, + authorization_list: List[AuthorizationTuple] | None, + blob_versioned_hashes: Sequence[Hash] | None, + tx_gas_limit: int, + tx_error: TransactionException | None, +) -> Transaction: + """Create the transaction used in each test.""" + return Transaction( + ty=tx_type, + sender=sender, + data=tx_data, + to=to, + protected=protected, + access_list=access_list, + authorization_list=authorization_list, + gas_limit=tx_gas_limit, + blob_versioned_hashes=blob_versioned_hashes, + error=tx_error, + ) diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/helpers.py b/tests/amsterdam/eip7981_increase_access_list_cost/helpers.py new file mode 100644 index 00000000000..503905014f2 --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/helpers.py @@ -0,0 +1,30 @@ +"""Helpers for testing EIP-7981.""" + +from typing import List + +from execution_testing import AccessList + + +def calculate_access_list_floor_tokens(access_list: List[AccessList]) -> int: + """ + Calculate the number of floor tokens in an access list. + + According to EIP-7981 (aligned with EIP-7976), floor tokens are + calculated from the raw access list byte length: + floor_tokens = total_bytes * 4 + + Where bytes come from: + - 20 bytes per address + - 32 bytes per storage key + """ + total_bytes = 0 + + for access in access_list: + # Count bytes in address (20 bytes) + total_bytes += len(access.address) + + # Count bytes in each storage key (32 bytes each) + for slot in access.storage_keys: + total_bytes += len(slot) + + return total_bytes * 4 diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/spec.py b/tests/amsterdam/eip7981_increase_access_list_cost/spec.py new file mode 100644 index 00000000000..30ff97e4fcc --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/spec.py @@ -0,0 +1,28 @@ +"""Defines EIP-7981 specification constants and functions.""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ReferenceSpec: + """Defines the reference spec version and git path.""" + + git_path: str + version: str + + +ref_spec_7981 = ReferenceSpec( + "EIPS/eip-7981.md", "954963fb6315dffadd9c40d48e4dae313e20cff5" +) + + +# Constants +@dataclass(frozen=True) +class Spec: + """ + Parameters from the EIP-7981 specifications as defined at + https://eips.ethereum.org/EIPS/eip-7981. + """ + + ACCESS_LIST_ADDRESS_COST = 2400 + ACCESS_LIST_STORAGE_KEY_COST = 1900 diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/test_access_list_cost.py b/tests/amsterdam/eip7981_increase_access_list_cost/test_access_list_cost.py new file mode 100644 index 00000000000..e9479b276c9 --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/test_access_list_cost.py @@ -0,0 +1,263 @@ +""" +abstract: Tests for access list cost calculations in [EIP-7981: Increase Access List Cost](https://eips.ethereum.org/EIPS/eip-7981). +""" # noqa: E501 + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + Bytes, + Fork, + Hash, + StateTestFiller, + Transaction, + TransactionReceipt, +) + +from .helpers import calculate_access_list_floor_tokens +from .spec import ref_spec_7981 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7981.git_path +REFERENCE_SPEC_VERSION = ref_spec_7981.version + +pytestmark = pytest.mark.valid_at("EIP7981") + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list,expected_floor_tokens", + [ + pytest.param( + [AccessList(address=Address(0), storage_keys=[])], + # 20 bytes total: 20 * 4 = 80 floor tokens + 80, + id="single_zero_address_no_keys", + ), + pytest.param( + [ + AccessList( + address=Address( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ), + storage_keys=[], + ) + ], + # 20 bytes total: 20 * 4 = 80 floor tokens + 80, + id="single_nonzero_address_no_keys", + ), + pytest.param( + [AccessList(address=Address(0), storage_keys=[Hash(0)])], + # Total bytes: 20 + 32 = 52, floor tokens: 52 * 4 = 208 + 208, + id="zero_address_zero_key", + ), + pytest.param( + [ + AccessList( + address=Address( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ), + storage_keys=[ + Hash( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ) + ], + ) + ], + # Total bytes: 20 + 32 = 52, floor tokens: 52 * 4 = 208 + 208, + id="nonzero_address_nonzero_key", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(0), Hash(1), Hash(2)], + ) + ], + # Total bytes: 20 + (3 * 32) = 116, floor tokens: 116 * 4 = 464 + 464, + id="one_address_three_keys", + ), + pytest.param( + [ + AccessList(address=Address(1), storage_keys=[Hash(0)]), + AccessList(address=Address(2), storage_keys=[Hash(1)]), + ], + # Total bytes: 2 * (20 + 32) = 104, floor tokens: 104 * 4 = 416 + 416, + id="two_addresses_with_keys", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_access_list_token_calculation( + state_test: StateTestFiller, + fork: Fork, + pre: Alloc, + tx: Transaction, + access_list: list, + expected_floor_tokens: int, +) -> None: + """ + Test that access list floor tokens are calculated correctly. + + Every access list byte contributes four floor tokens regardless of + whether it is zero or non-zero. Verify both the reference helper and + the fork's floor cost calculator agree with the expected token count. + """ + assert ( + calculate_access_list_floor_tokens(access_list) + == expected_floor_tokens + ) + + gas_costs = fork.gas_costs() + expected_floor_cost = ( + expected_floor_tokens * gas_costs.TX_DATA_TOKEN_FLOOR + + gas_costs.TX_BASE + ) + actual_floor_cost = fork.transaction_data_floor_cost_calculator()( + data=b"", access_list=access_list + ) + assert actual_floor_cost == expected_floor_cost + + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list,tx_data", + [ + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + Bytes(b"\x01" * 100), + id="access_list_and_calldata", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(i) for i in range(10)], + ) + ], + Bytes(b"\x00" * 50 + b"\x01" * 50), + id="large_access_list_mixed_calldata", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_access_list_floor_cost_with_calldata( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, + tx_intrinsic_gas_cost_including_floor_data_cost: int, +) -> None: + """ + Test that the floor cost correctly accounts for both access list + and calldata tokens. + + According to EIP-7981: + - total_floor_data_tokens = + floor_tokens_in_calldata + floor_tokens_in_access_list + - floor_gas = + TX_BASE_COST + total_floor_data_tokens * TOTAL_COST_FLOOR_PER_TOKEN + """ + tx.expected_receipt = TransactionReceipt( + cumulative_gas_used=tx_intrinsic_gas_cost_including_floor_data_cost + ) + + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + [ + AccessList( + address=Address(i), + storage_keys=[Hash(j) for j in range(5)], + ) + for i in range(1, 6) + ], + id="five_addresses_five_keys_each", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_large_access_list_cost( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test gas costs for large access lists. + + With EIP-7981, large access lists should incur: + 1. Storage access costs (2400 per address + 1900 per key) + 2. Data footprint costs (16 per floor token) + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + [ + AccessList(address=Address(1), storage_keys=[Hash(0)]), + AccessList(address=Address(1), storage_keys=[Hash(0)]), + ], + id="duplicate_access_list_entries", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_duplicate_access_list_entries( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test that duplicate access list entries are charged multiple times. + + According to EIP-2930, non-unique addresses and storage keys are allowed + and charged multiple times. EIP-7981 should maintain this behavior. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/test_eip_mainnet.py b/tests/amsterdam/eip7981_increase_access_list_cost/test_eip_mainnet.py new file mode 100644 index 00000000000..771828d80b8 --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/test_eip_mainnet.py @@ -0,0 +1,149 @@ +""" +abstract: Crafted tests for mainnet of [EIP-7981: Increase Access List Cost](https://eips.ethereum.org/EIPS/eip-7981). +""" # noqa: E501 + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + Hash, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_7981 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7981.git_path +REFERENCE_SPEC_VERSION = ref_spec_7981.version + +pytestmark = [pytest.mark.valid_at("EIP7981"), pytest.mark.mainnet] + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_address_single_key", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(0), Hash(1), Hash(2)], + ) + ], + id="single_address_multiple_keys", + ), + pytest.param( + [ + AccessList(address=Address(1), storage_keys=[Hash(0)]), + AccessList(address=Address(2), storage_keys=[Hash(1)]), + ], + id="multiple_addresses", + ), + pytest.param( + [ + AccessList( + address=Address( + 0xDE0B295669A9FD93D5F28D9EC85E40F4CB697BAE + ), + storage_keys=[ + Hash( + 0x0000000000000000000000000000000000000000000000000000000000000003 + ), + Hash( + 0x0000000000000000000000000000000000000000000000000000000000000007 + ), + ], + ) + ], + id="realistic_address_and_keys", + ), + ], +) +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id="to_eoa"), + ], + indirect=True, +) +def test_access_list_gas_cost( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test that transactions with access lists are charged correctly + according to EIP-7981. + + The test verifies that: + 1. Access lists are charged for storage access (existing behavior) + 2. Access lists are charged for their data footprint (new in EIP-7981) + 3. Access list data contributes to the floor gas cost + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + [ + AccessList( + address=Address(0), + storage_keys=[Hash(0) for _ in range(10)], + ) + ], + id="all_zero_bytes", + ), + pytest.param( + [ + AccessList( + address=Address( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ), + storage_keys=[ + Hash( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ) + for _ in range(5) + ], + ) + ], + id="all_nonzero_bytes", + ), + ], +) +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id=""), + ], + indirect=True, +) +def test_access_list_data_cost_edge_cases( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test edge cases for access list data costs. + + Tests include: + - All zero bytes in access list + - All non-zero bytes in access list + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/test_transaction_validity.py b/tests/amsterdam/eip7981_increase_access_list_cost/test_transaction_validity.py new file mode 100644 index 00000000000..1f995b1f1b7 --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/test_transaction_validity.py @@ -0,0 +1,279 @@ +""" +abstract: Tests for transaction validity with [EIP-7981: Increase Access List Cost](https://eips.ethereum.org/EIPS/eip-7981). +""" # noqa: E501 + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + Bytes, + Hash, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_7981 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7981.git_path +REFERENCE_SPEC_VERSION = ref_spec_7981.version + +pytestmark = pytest.mark.valid_at("EIP7981") + + +@pytest.mark.exception_test +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list,tx_gas_delta", + [ + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + -1, + id="insufficient_gas_by_one", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + -100, + id="insufficient_gas_by_hundred", + ), + pytest.param( + [ + AccessList( + address=Address(1), + storage_keys=[Hash(i) for i in range(10)], + ) + ], + -1, + id="large_access_list_insufficient_gas", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_insufficient_gas_for_access_list( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test that transactions with insufficient gas for access list costs + are rejected. + + With EIP-7981, the intrinsic gas must cover: + - Base transaction cost + - Calldata costs + - Access list storage costs + - Access list data costs (new in EIP-7981) + - Floor cost including access list tokens + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.exception_test +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list,tx_data,tx_gas_delta", + [ + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + Bytes(b"\x01" * 1000), + -1, + id="large_calldata_and_access_list_insufficient_gas", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + Bytes(b"\x00" * 1000), + -1, + id="large_zero_calldata_and_access_list_insufficient_gas", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_floor_cost_validation_with_access_list( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test that the floor cost validation includes access list tokens. + + According to EIP-7981: + - Any transaction with a gas limit below the floor cost is invalid + - Floor cost = TX_BASE_COST + TOTAL_COST_FLOOR_PER_TOKEN * + total_floor_data_tokens + - total_floor_data_tokens = + floor_tokens_in_calldata + floor_tokens_in_access_list + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list,tx_gas_delta", + [ + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + 0, + id="exact_gas", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + 1, + id="one_extra_gas", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + 1000, + id="plenty_extra_gas", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +def test_valid_gas_limits_with_access_list( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test that transactions with sufficient gas are valid. + + Tests various gas limit scenarios: + - Exact intrinsic gas + - Slightly more than intrinsic gas + - Much more than intrinsic gas + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.with_all_tx_types(selector=lambda tx_type: tx_type >= 1) +@pytest.mark.parametrize( + "access_list,tx_data", + [ + pytest.param( + [AccessList(address=Address(0), storage_keys=[Hash(0)] * 100)], + Bytes(b"\x00" * 1000), + id="zero_heavy_data_and_access_list", + ), + pytest.param( + [ + AccessList( + address=Address( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ), + storage_keys=[ + Hash( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ) + ] + * 50, + ) + ], + Bytes(b"\xff" * 500), + id="nonzero_heavy_data_and_access_list", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +@pytest.mark.parametrize( + "tx_gas_delta", + [pytest.param(0, id="")], +) +def test_mixed_zero_nonzero_bytes_floor_cost( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test floor cost calculation with mixed zero and non-zero bytes. + + This ensures floor gas uses floor token counting: + - Each data byte contributes 4 floor tokens + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "tx_type,access_list", + [ + pytest.param( + 0, + None, + id="type_0_no_access_list", + ), + pytest.param( + 1, + [], + id="type_1_empty_access_list", + ), + pytest.param( + 2, + [], + id="type_2_empty_access_list", + ), + pytest.param( + 3, + [], + id="type_3_empty_access_list", + ), + pytest.param( + 4, + [], + id="type_4_empty_access_list", + ), + ], +) +@pytest.mark.parametrize( + "to", + [pytest.param("eoa", id="")], + indirect=True, +) +@pytest.mark.parametrize( + "tx_gas_delta", + [pytest.param(0, id="")], +) +def test_transactions_without_access_list( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test that transactions without access lists still work correctly. + + EIP-7981 should only affect transactions with non-empty access lists. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) From 23305dcf642e3d4acaf6b4cd26eca47f5753e215 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 19 May 2026 19:58:04 +0530 Subject: [PATCH 094/186] chore: fix lint issues --- src/ethereum/forks/cancun/fork.py | 5 +- src/ethereum/forks/osaka/fork.py | 7 +- src/ethereum/forks/paris/fork.py | 150 ++++++++++++++---------------- src/ethereum/forks/prague/fork.py | 9 +- 4 files changed, 79 insertions(+), 92 deletions(-) diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index 7d9812d089c..e2871abbd6a 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -59,7 +59,6 @@ from .state_tracker import ( BlockState, TransactionState, - create_ether, destroy_account, extract_block_diff, get_account, @@ -856,12 +855,12 @@ def process_withdrawals( ) amounts.append(int(wd.amount)) addresses.append(wd.address) - + payload = encode( ["uint256", "uint64[]", "address[]"], [MAX_FAILED_WITHDRAWALS_TO_PROCESS, amounts, addresses], ) - + out = process_unchecked_system_transaction( block_env=block_env, target_address=DEPOSIT_CONTRACT_ADDRESS, diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index b97aaaf16c7..c3f7f4c98d5 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -69,7 +69,6 @@ from .state_tracker import ( BlockState, TransactionState, - create_ether, destroy_account, extract_block_diff, get_account, @@ -1055,12 +1054,12 @@ def process_withdrawals( ) amounts.append(int(wd.amount)) addresses.append(wd.address) - + payload = encode( ["uint256", "uint64[]", "address[]"], [MAX_FAILED_WITHDRAWALS_TO_PROCESS, amounts, addresses], ) - + out = process_unchecked_system_transaction( block_env=block_env, target_address=DEPOSIT_CONTRACT_ADDRESS, @@ -1109,7 +1108,7 @@ def process_block_rewards( address = hex_to_address(addr) balance = get_account(reward_state, address).balance + U256(amount) set_account_balance(reward_state, address, balance) - + incorporate_tx_into_block(reward_state) diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 06588805700..9990c80eacc 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -34,7 +34,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, encode_receipt @@ -43,14 +49,16 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -63,16 +71,14 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message +from .vm.gas import GasCosts from .vm.interpreter import MessageCallOutput, process_message_call BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") SYSTEM_TRANSACTION_GAS = Uint(30000000) @@ -190,9 +196,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -206,7 +214,10 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_env=block_env, transactions=block.transactions, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, block_diff.storage_changes + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -224,6 +235,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block_logs_bloom != block.header.bloom: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -351,6 +363,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -363,6 +376,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -393,7 +408,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -466,17 +481,14 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( +def process_unchecked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, - system_contract_code: Bytes, data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction with the given code. - - Prefer calling `process_unchecked_system_transaction` unless the contract - code has already been read from the state. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -484,8 +496,6 @@ def process_system_transaction( The block scoped environment. target_address : Address of the contract to call. - system_contract_code : - Code of the contract to call. data : Data to pass to the contract. @@ -495,12 +505,19 @@ def process_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + tx_env = vm.TransactionEnvironment( origin=SYSTEM_ADDRESS, gas_price=block_env.base_fee_per_gas, gas=SYSTEM_TRANSACTION_GAS, access_list_addresses=set(), access_list_storage_keys=set(), + state=system_tx_state, index_in_block=None, tx_hash=None, ) @@ -526,44 +543,9 @@ def process_system_transaction( system_tx_output = process_message_call(system_tx_message) - return system_tx_output - + incorporate_tx_into_block(system_tx_state) -def process_unchecked_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, - ) - - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, - ) + return system_tx_output def apply_body( @@ -633,6 +615,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -648,21 +632,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -678,6 +661,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -699,34 +683,35 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee, ) # transfer base fee to fee collector address - fee_collector_balance_after = get_account( - block_env.state, FEE_COLLECTOR_ADDRESS - ).balance + U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) - if fee_collector_balance_after != 0: + base_fee = U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) + if base_fee != 0: + fee_collector_balance = get_account( + tx_state, FEE_COLLECTOR_ADDRESS + ).balance set_account_balance( - block_env.state, + tx_state, FEE_COLLECTOR_ADDRESS, - fee_collector_balance_after, + fee_collector_balance + base_fee, ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund @@ -745,6 +730,8 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_block_rewards( block_env: vm.BlockEnvironment, @@ -772,7 +759,8 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - account = get_account(block_env.state, BLOCK_REWARDS_CONTRACT_ADDRESS) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) if account.code_hash == EMPTY_CODE_HASH: return @@ -782,8 +770,10 @@ def process_block_rewards( addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) - balance = get_account(block_env.state, address).balance + U256(amount) - set_account_balance(block_env.state, address, balance) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: @@ -792,12 +782,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -815,12 +805,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index 742c376cd3c..15eda90deec 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -68,7 +68,6 @@ from .state_tracker import ( BlockState, TransactionState, - create_ether, destroy_account, extract_block_diff, get_account, @@ -794,7 +793,7 @@ def apply_body( rlp.encode(wd), ) - process_withdrawals(block_env, withdrawals) + process_withdrawals(block_env, block_output, withdrawals) process_general_purpose_requests( block_env=block_env, @@ -1050,12 +1049,12 @@ def process_withdrawals( ) amounts.append(int(wd.amount)) addresses.append(wd.address) - + payload = encode( ["uint256", "uint64[]", "address[]"], [MAX_FAILED_WITHDRAWALS_TO_PROCESS, amounts, addresses], ) - + out = process_unchecked_system_transaction( block_env=block_env, target_address=DEPOSIT_CONTRACT_ADDRESS, @@ -1104,7 +1103,7 @@ def process_block_rewards( address = hex_to_address(addr) balance = get_account(reward_state, address).balance + U256(amount) set_account_balance(reward_state, address, balance) - + incorporate_tx_into_block(reward_state) From 62b914c27cb5a18bc85e9b498633594876d6ab43 Mon Sep 17 00:00:00 2001 From: Guruprasad Kamath <48196632+gurukamath@users.noreply.github.com> Date: Tue, 19 May 2026 16:51:20 +0200 Subject: [PATCH 095/186] fix(tests): call delegation access disambiguation (#2882) call with insufficient balance shoudn't access delegation --- .../test_block_access_lists_opcodes.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index de18e83bc98..671a84c6397 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -2422,11 +2422,12 @@ def test_bal_call_revert_insufficient_funds( Caller (balance=100): SLOAD(0x01) → call_opcode(target, value=1000) → SSTORE(0x02, result). The call fails because 1000 > 100. The - failure happens after delegation resolution, so when the target is - a 7702-delegated EOA both target and delegation target appear in - the BAL — distinct from the OOG case (see - test_bal_call_7702_delegation_and_oog) where the static-check - optimization keeps the delegation target out of the BAL. + failure happens after delegation resolution. However, the delegation + target's account has not been read yet. + So when the target is a 7702-delegated EOA, the target itself appears in + the BAL since it is already read. The delegation target however, + does not appear in the BAL, since it does not need to be read + for verifying sufficient balance. Access-list warming does NOT add to BAL on its own — only EVM access does — so the BAL is identical across warm/cold variants. @@ -2477,7 +2478,7 @@ def test_bal_call_revert_insufficient_funds( access_list=access_list, ) - account_expectations: Dict[Address, BalAccountExpectation] = { + account_expectations: Dict[Address, BalAccountExpectation | None] = { alice: BalAccountExpectation( nonce_changes=[BalNonceChange(block_access_index=1, post_nonce=1)], ), @@ -2495,10 +2496,13 @@ def test_bal_call_revert_insufficient_funds( # Target accessed before balance check fails. target: BalAccountExpectation.empty(), } + if delegated: assert delegation_target is not None - # Delegation resolved before balance check fails. - account_expectations[delegation_target] = BalAccountExpectation.empty() + # Delegation target must NOT appear in the BAL — get_account + # for code_address only runs inside generic_call, which is + # never invoked when the balance check fails. + account_expectations[delegation_target] = None block = Block( txs=[tx], From 0ae5a904599f260519c0961abb0590da6b9d00c6 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 19 May 2026 21:43:34 +0530 Subject: [PATCH 096/186] chore: fix lint issues --- .../execution_testing/client_clis/clis/ethrex.py | 16 ---------------- .../fixtures/tests/test_blockchain.py | 4 ++-- src/ethereum/forks/cancun/fork.py | 2 +- src/ethereum/forks/paris/fork.py | 7 ++++--- src/ethereum/forks/prague/fork.py | 12 +----------- 5 files changed, 8 insertions(+), 33 deletions(-) diff --git a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py index 0ccebcd4ed7..d85a1e7ce86 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py +++ b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py @@ -56,22 +56,6 @@ class EthrexExceptionMapper(ExceptionMapper): BlockException.INVALID_BASEFEE_PER_GAS: ( "Base fee per gas is incorrect" ), - BlockException.INVALID_BLOCK_ACCESS_LIST: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_HASH: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_EXTRA_ACCOUNT: ( - "Block access list hash does not match the one in " - "the header after executing" - ), - BlockException.INVALID_BAL_MISSING_ACCOUNT: ( - "Block access list hash does not match the one in " - "the header after executing" - ), } mapping_regex = { TransactionException.PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS: ( diff --git a/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py b/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py index 6f46633a3cb..8009f7fa230 100644 --- a/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py +++ b/packages/testing/src/execution_testing/fixtures/tests/test_blockchain.py @@ -1578,7 +1578,7 @@ def _amsterdam_payload_header() -> FixtureHeader: ommers_hash=Hash(1), fee_recipient=Address(2), state_root=Hash(3), - transactions_trie=Hash(4), + transactions_root=Hash(4), receipts_root=Hash(5), logs_bloom=Bloom(6), difficulty=7, @@ -1650,7 +1650,7 @@ def test_from_fixture_header_injects_body_on_pre_bal_fork(self) -> None: ommers_hash=Hash(1), fee_recipient=Address(2), state_root=Hash(3), - transactions_trie=Hash(4), + transactions_root=Hash(4), receipts_root=Hash(5), logs_bloom=Bloom(6), difficulty=7, diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index e2871abbd6a..fc2e22e040f 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -95,7 +95,6 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") -SYSTEM_TRANSACTION_GAS = Uint(30000000) DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0xbabe2bed00000000000000000000000000000003" ) @@ -109,6 +108,7 @@ BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) +SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = U64(262144) VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 9990c80eacc..7eaa6565799 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -81,7 +81,6 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") -SYSTEM_TRANSACTION_GAS = Uint(30000000) DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0xbabe2bed00000000000000000000000000000003" ) @@ -91,7 +90,7 @@ FEE_COLLECTOR_ADDRESS = hex_to_address( "0x1559000000000000000000000000000000000000" ) -MAX_FAILED_WITHDRAWALS_TO_PROCESS = 4 +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -216,7 +215,9 @@ def state_transition(chain: BlockChain, block: Block) -> None: ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( - block_diff.account_changes, block_diff.storage_changes + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index 15eda90deec..4bb4eae2ec8 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -106,7 +106,6 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") -SYSTEM_TRANSACTION_GAS = Uint(30000000) DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0xbabe2bed00000000000000000000000000000003" ) @@ -120,6 +119,7 @@ BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) +SYSTEM_TRANSACTION_GAS = Uint(30000000) MAX_BLOB_GAS_PER_BLOCK = U64(262144) VERSIONED_HASH_VERSION_KZG = b"\x01" BLOB_FEE_COLLECTOR = hex_to_address( @@ -783,16 +783,6 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - # Gnosis: populate withdrawals trie here because - # process_withdrawals() is a system call that doesn't - # receive block_output (upstream does this internally). - for i, wd in enumerate(withdrawals): - trie_set( - block_output.withdrawals_trie, - rlp.encode(Uint(i)), - rlp.encode(wd), - ) - process_withdrawals(block_env, block_output, withdrawals) process_general_purpose_requests( From 252c309a73f07b836d606aebfa4afb2cfec3a65e Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 19 May 2026 21:47:48 +0530 Subject: [PATCH 097/186] chore: update shanghai fork --- src/ethereum/forks/shanghai/fork.py | 184 +++++++++++++--------------- 1 file changed, 84 insertions(+), 100 deletions(-) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index b4e74edeaca..2cbf38e4108 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -35,7 +35,13 @@ InvalidSenderError, NonceMismatchError, ) -from ethereum.state import EMPTY_CODE_HASH, Address +from ethereum.merkle_patricia_trie import root, trie_set +from ethereum.state import ( + EMPTY_CODE_HASH, + Address, + State, + apply_changes_to_state, +) from . import vm from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt @@ -44,14 +50,16 @@ InsufficientMaxFeePerGasError, PriorityFeeGreaterThanMaxFeeError, ) -from .state import ( - State, +from .state_tracker import ( + BlockState, + TransactionState, destroy_account, + extract_block_diff, get_account, get_code, + incorporate_tx_into_block, increment_nonce, set_account_balance, - state_root, ) from .transactions import ( AccessListTransaction, @@ -64,19 +72,16 @@ recover_sender, validate_transaction, ) -from .trie import root, trie_set from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message from .vm import Message +from .vm.gas import GasCosts from .vm.interpreter import MessageCallOutput, process_message_call BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -GAS_LIMIT_ADJUSTMENT_FACTOR = Uint(1024) -GAS_LIMIT_MINIMUM = Uint(5000) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") -SYSTEM_TRANSACTION_GAS = Uint(30000000) DEPOSIT_CONTRACT_ADDRESS = hex_to_address( "0xbabe2bed00000000000000000000000000000003" ) @@ -87,6 +92,7 @@ "0x1559000000000000000000000000000000000000" ) MAX_FAILED_WITHDRAWALS_TO_PROCESS = 4 +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -191,9 +197,11 @@ def state_transition(chain: BlockChain, block: Block) -> None: if block.ommers != (): raise InvalidBlock + block_state = BlockState(pre_state=chain.state) + block_env = vm.BlockEnvironment( chain_id=chain.chain_id, - state=chain.state, + state=block_state, block_gas_limit=block.header.gas_limit, block_hashes=get_last_256_block_hashes(chain), coinbase=block.header.coinbase, @@ -208,7 +216,12 @@ def state_transition(chain: BlockChain, block: Block) -> None: transactions=block.transactions, withdrawals=block.withdrawals, ) - block_state_root = state_root(block_env.state) + block_diff = extract_block_diff(block_state) + block_state_root, _ = chain.state.compute_state_root_and_trie_changes( + block_diff.account_changes, + block_diff.storage_changes, + block_diff.storage_clears, + ) transactions_root = root(block_output.transactions_trie) receipt_root = root(block_output.receipts_trie) block_logs_bloom = logs_bloom(block_output.block_logs) @@ -229,6 +242,7 @@ def state_transition(chain: BlockChain, block: Block) -> None: if withdrawals_root != block.header.withdrawals_root: raise InvalidBlock + apply_changes_to_state(chain.state, block_diff) chain.blocks.append(block) if len(chain.blocks) > 255: # Real clients have to store more blocks to deal with reorgs, but the @@ -356,6 +370,7 @@ def check_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, tx: Transaction, + tx_state: TransactionState, ) -> Tuple[Address, Uint]: """ Check if the transaction is includable in the block. @@ -368,6 +383,8 @@ def check_transaction( The block output for the current block. tx : The transaction. + tx_state : + The transaction state tracker. Returns ------- @@ -398,7 +415,7 @@ def check_transaction( if tx.gas > gas_available: raise GasUsedExceedsLimitError("gas used exceeds limit") sender_address = recover_sender(block_env.chain_id, tx) - sender_account = get_account(block_env.state, sender_address) + sender_account = get_account(tx_state, sender_address) if isinstance(tx, FeeMarketTransaction): if tx.max_fee_per_gas < tx.max_priority_fee_per_gas: @@ -471,17 +488,14 @@ def make_receipt( return encode_receipt(tx, receipt) -def process_system_transaction( +def process_unchecked_system_transaction( block_env: vm.BlockEnvironment, target_address: Address, - system_contract_code: Bytes, data: Bytes, ) -> MessageCallOutput: """ - Process a system transaction with the given code. - - Prefer calling `process_unchecked_system_transaction` unless the contract - code has already been read from the state. + Process a system transaction without checking if the contract contains + code or if the transaction fails. Parameters ---------- @@ -489,8 +503,6 @@ def process_system_transaction( The block scoped environment. target_address : Address of the contract to call. - system_contract_code : - Code of the contract to call. data : Data to pass to the contract. @@ -500,12 +512,19 @@ def process_system_transaction( Output of processing the system transaction. """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + tx_env = vm.TransactionEnvironment( origin=SYSTEM_ADDRESS, gas_price=block_env.base_fee_per_gas, gas=SYSTEM_TRANSACTION_GAS, access_list_addresses=set(), access_list_storage_keys=set(), + state=system_tx_state, index_in_block=None, tx_hash=None, ) @@ -531,44 +550,9 @@ def process_system_transaction( system_tx_output = process_message_call(system_tx_message) - return system_tx_output - + incorporate_tx_into_block(system_tx_state) -def process_unchecked_system_transaction( - block_env: vm.BlockEnvironment, - target_address: Address, - data: Bytes, -) -> MessageCallOutput: - """ - Process a system transaction without checking if the contract contains code - or if the transaction fails. - - Parameters - ---------- - block_env : - The block scoped environment. - target_address : - Address of the contract to call. - data : - Data to pass to the contract. - - Returns - ------- - system_tx_output : `MessageCallOutput` - Output of processing the system transaction. - - """ - system_contract_code = get_code( - block_env.state, - get_account(block_env.state, target_address).code_hash, - ) - - return process_system_transaction( - block_env, - target_address, - system_contract_code, - data, - ) + return system_tx_output def apply_body( @@ -590,8 +574,6 @@ def apply_body( ---------- block_env : The block scoped environment. - block_output : - The block output for the current block. transactions : Transactions included in the block. withdrawals : @@ -610,17 +592,7 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - # Gnosis: populate withdrawals trie here because - # process_withdrawals() is a system call that doesn't - # receive block_output (upstream does this internally). - for i, wd in enumerate(withdrawals): - trie_set( - block_output.withdrawals_trie, - rlp.encode(Uint(i)), - rlp.encode(wd), - ) - - process_withdrawals(block_env, withdrawals) + process_withdrawals(block_env, block_output, withdrawals) return block_output @@ -655,6 +627,8 @@ def process_transaction( Index of the transaction in the block. """ + tx_state = TransactionState(parent=block_env.state) + trie_set( block_output.transactions_trie, rlp.encode(index), @@ -670,21 +644,20 @@ def process_transaction( block_env=block_env, block_output=block_output, tx=tx, + tx_state=tx_state, ) - sender_account = get_account(block_env.state, sender) + sender_account = get_account(tx_state, sender) effective_gas_fee = tx.gas * effective_gas_price gas = tx.gas - intrinsic_gas - increment_nonce(block_env.state, sender) + increment_nonce(tx_state, sender) sender_balance_after_gas_fee = ( Uint(sender_account.balance) - effective_gas_fee ) - set_account_balance( - block_env.state, sender, U256(sender_balance_after_gas_fee) - ) + set_account_balance(tx_state, sender, U256(sender_balance_after_gas_fee)) access_list_addresses = set() access_list_storage_keys = set() @@ -701,6 +674,7 @@ def process_transaction( gas=gas, access_list_addresses=access_list_addresses, access_list_storage_keys=access_list_storage_keys, + state=tx_state, index_in_block=index, tx_hash=get_transaction_hash(encode_transaction(tx)), ) @@ -722,34 +696,31 @@ def process_transaction( transaction_fee = tx_gas_used_after_refund * priority_fee_per_gas # refund gas - sender_balance_after_refund = get_account( - block_env.state, sender - ).balance + U256(gas_refund_amount) - set_account_balance(block_env.state, sender, sender_balance_after_refund) + sender_balance_after_refund = get_account(tx_state, sender).balance + U256( + gas_refund_amount + ) + set_account_balance(tx_state, sender, sender_balance_after_refund) # transfer miner fees coinbase_balance_after_mining_fee = get_account( - block_env.state, block_env.coinbase + tx_state, block_env.coinbase ).balance + U256(transaction_fee) set_account_balance( - block_env.state, - block_env.coinbase, - coinbase_balance_after_mining_fee, + tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) # transfer base fee to fee collector address - fee_collector_balance_after = get_account( - block_env.state, FEE_COLLECTOR_ADDRESS - ).balance + U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) - if fee_collector_balance_after != 0: + base_fee = U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) + if base_fee != 0: + fee_collector_balance = get_account( + tx_state, FEE_COLLECTOR_ADDRESS + ).balance set_account_balance( - block_env.state, - FEE_COLLECTOR_ADDRESS, - fee_collector_balance_after, + tx_state, FEE_COLLECTOR_ADDRESS, fee_collector_balance + base_fee ) for address in tx_output.accounts_to_delete: - destroy_account(block_env.state, address) + destroy_account(tx_state, address) block_output.block_gas_used += tx_gas_used_after_refund @@ -768,9 +739,12 @@ def process_transaction( block_output.block_logs += tx_output.logs + incorporate_tx_into_block(tx_state) + def process_withdrawals( block_env: vm.BlockEnvironment, + block_output: vm.BlockOutput, withdrawals: Tuple[Withdrawal, ...], ) -> None: """ @@ -780,13 +754,20 @@ def process_withdrawals( """ amounts = [] addresses = [] - for w in withdrawals: - amounts.append(int(w.amount)) - addresses.append(w.address) + for i, wd in enumerate(withdrawals): + trie_set( + block_output.withdrawals_trie, + rlp.encode(Uint(i)), + rlp.encode(wd), + ) + amounts.append(int(wd.amount)) + addresses.append(wd.address) + payload = encode( ["uint256", "uint64[]", "address[]"], [MAX_FAILED_WITHDRAWALS_TO_PROCESS, amounts, addresses], ) + out = process_unchecked_system_transaction( block_env=block_env, target_address=DEPOSIT_CONTRACT_ADDRESS, @@ -822,7 +803,8 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - account = get_account(block_env.state, BLOCK_REWARDS_CONTRACT_ADDRESS) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) if account.code_hash == EMPTY_CODE_HASH: return @@ -832,8 +814,10 @@ def process_block_rewards( addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) - balance = get_account(block_env.state, address).balance + U256(amount) - set_account_balance(block_env.state, address, balance) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: @@ -842,12 +826,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: The bounds of the gas limit, ``max_adjustment_delta``, is set as the quotient of the parent block's gas limit and the - ``GAS_LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is + ``LIMIT_ADJUSTMENT_FACTOR``. Therefore, if the gas limit that is passed through as a parameter is greater than or equal to the *sum* of the parent's gas and the adjustment delta then the limit for gas is too high and fails this function's check. Similarly, if the limit is less than or equal to the *difference* of the parent's gas and the adjustment - delta *or* the predefined ``GAS_LIMIT_MINIMUM`` then this function's + delta *or* the predefined ``LIMIT_MINIMUM`` then this function's check fails because the gas limit doesn't allow for a sufficient or reasonable amount of gas to be used on a block. @@ -865,12 +849,12 @@ def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: True if gas limit constraints are satisfied, False otherwise. """ - max_adjustment_delta = parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR + max_adjustment_delta = parent_gas_limit // GasCosts.LIMIT_ADJUSTMENT_FACTOR if gas_limit >= parent_gas_limit + max_adjustment_delta: return False if gas_limit <= parent_gas_limit - max_adjustment_delta: return False - if gas_limit < GAS_LIMIT_MINIMUM: + if gas_limit < GasCosts.LIMIT_MINIMUM: return False return True From 476b5c18a3d10d0dd270c99ca00635ad5e1394fd Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 19 May 2026 22:48:07 +0530 Subject: [PATCH 098/186] chore: cosmetic changes --- src/ethereum/forks/shanghai/fork.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 2cbf38e4108..955f7aa3817 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -574,6 +574,8 @@ def apply_body( ---------- block_env : The block scoped environment. + block_output : + The block output for the current block. transactions : Transactions included in the block. withdrawals : From dcda9b3fe570b2d2c03e0aed2ce99e38505d0ecb Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 19 May 2026 23:19:49 +0530 Subject: [PATCH 099/186] chore: update claude file --- CLAUDE.md | 102 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 32 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 4279c282d13..5dbf65c221a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,10 @@ This is the **Gnosis chain fork** of the Ethereum Execution Layer Specifications The `master` branch is the main branch. The `forks/amsterdam` branch tracks upstream through Amsterdam. -## Build and Development +## Tooling + +- **uv** is the package manager. **just** is the command runner (`just --list`). +- The `execution_testing` package under `packages/testing/` is a UV workspace member. Requires: Python 3.11+, `uv` (>=0.7.0), `geth` in `$PATH`. PyPy 7.3.19+ needed for full CI. @@ -58,13 +61,17 @@ uv run mkdocs serve uvx pre-commit install ``` +## Linting + +When done with changes, ask the user if they'd like to run `/lint` before committing. Don't skip this unless the user explicitly says to. + ### CI Workflows (`.github/workflows/`) There are two phases in the test pipeline: **fill** (generate fixtures from the EELS spec — proves spec is internally consistent) and **consume** (feed fixtures to a real client via Hive — proves client compatibility). Currently only fill runs automatically on PRs; consume has no working automated PR gate. **Core test pipeline** (`test.yaml`): Runs on PRs. Fill only — no consume. Jobs: `static`, `py3` (fill Paris->Osaka), `pypy3`, `tests_pytest_py3`, `tests_pytest_pypy3`. Setup action (`.github/actions/setup-env/`) installs Rust, build-essential, tox, and downloads geth. -**Hive integration** (`hive-consume.yaml`): Runs on PRs touching hive paths or `forks/**` pushes. Intended to consume fixtures against `go-ethereum-gnosis` via Hive (4 modes: Engine, RLP, Sync, Dev Mode). Currently broken: it downloads upstream Ethereum fixtures (`FIXTURES_URL`) instead of generating Gnosis fixtures via fill, so the state roots never match. Uses `gnosischain/hive` repo (branch `master`) and `gnosis.yaml` client config. +**Hive integration** (`hive-consume.yaml`): Runs on PRs touching hive paths or `forks/**` pushes. Intended to consume fixtures against `go-ethereum-gnosis` via Hive (4 modes: Engine, RLP, Sync, Dev Mode). Uses `gnosischain/hive` repo (branch `master`) and `latest.yaml` client config. **Manual hive workflows** (workflow_dispatch only, not automated on PRs): @@ -73,21 +80,21 @@ There are two phases in the test pipeline: **fill** (generate fixtures from the **All workflow files:** -| File | Trigger | What it does | -|------------------------------------|-----------------------------------|------------------------------------------------------------------------------------| -| test.yaml | PR, push to master | Core pipeline: static checks, py3 fill, pypy3 fill, framework unit tests | -| test-docs.yaml | PR, push | mkdocs build, markdownlint, changelog validation | +| File | Trigger | What it does | +|------------------------------------|-----------------------------------|-------------------------------------------------------------------------------------| +| test.yaml | PR, push to master | Core pipeline: static checks, py3 fill, pypy3 fill, framework unit tests | +| test-docs.yaml | PR, push | mkdocs build, markdownlint, changelog validation | | hive-consume.yaml | PR (hive paths), push to forks/** | Hive integration: Engine/RLP/Sync simulators + Dev Mode against go-ethereum-gnosis | -| benchmark.yaml | push to forks/** | Gas benchmarks, fixed opcode benchmarks | -| eest_hive_gnosis.yaml | manual | Fill + consume against a single Gnosis client | -| eest_hive_gnosis_multi_client.yaml | manual | Fill once, then consume against 4 Gnosis clients (reth/geth/nethermind/erigon) | -| eest_hive_matrix.yaml | manual | Upstream hive matrix testing | -| run_eest_remote.yaml | manual | Run EEST tests on a remote machine | -| release_fixture_full.yaml | manual | Generate and publish full fixture releases | -| release_fixture_feature.yaml | manual | Generate fixtures for a feature branch | -| gh-pages.yaml | push to master | Deploy spec docs to GitHub Pages | -| eip-rebase.yaml | manual | Rebase EIP feature branches | -| update-devnet-branch.yaml | manual | Update devnet branches | +| benchmark.yaml | push to forks/** | Gas benchmarks, fixed opcode benchmarks | +| eest_hive_gnosis.yaml | manual | Fill + consume against a single Gnosis client | +| eest_hive_gnosis_multi_client.yaml | manual | Fill once, then consume against 4 Gnosis clients (reth/geth/nethermind/erigon) | +| eest_hive_matrix.yaml | manual | Upstream hive matrix testing | +| run_eest_remote.yaml | manual | Run EEST tests on a remote machine | +| release_fixture_full.yaml | manual | Generate and publish full fixture releases | +| release_fixture_feature.yaml | manual | Generate fixtures for a feature branch | +| gh-pages.yaml | push to master | Deploy spec docs to GitHub Pages | +| eip-rebase.yaml | manual | Rebase EIP feature branches | +| update-devnet-branch.yaml | manual | Update devnet branches | ## Architecture @@ -131,26 +138,57 @@ Each fork package follows a consistent internal structure: Uses `ethereum-types` package for domain types: `U256`, `Uint`, `Bytes`, `Address`, etc. Full type annotations throughout; mypy runs in strict mode. -## Code Conventions +## Code Style - **Line length**: 79 characters (enforced by ruff) - **Max cyclomatic complexity**: 7 -- **Imports**: explicit only (no star imports), relative within packages -- **Docstrings**: Google-style, imperative mood ("Return" not "Returns") -- **Naming**: Avoid EIP numbers in identifiers; use descriptive English words +- **Imports**: explicit only (no star imports), relative within packages; import isolation enforced by `ethereum-spec-lint` — never import from future or ancient (2+ back) forks +- **Docstrings**: imperative mood ("Return" not "Returns"), blank line after summary for multi-line +- **Naming**: `snake_case` for variables/functions, `PascalCase` for classes, `UPPER_CASE` for constants; avoid EIP numbers in identifiers, use descriptive English words - **Cross-fork changes**: Keep differences between forks minimal for clean diffs. When modifying multiple forks, start with one fork, get feedback, then propagate - **Patch tool**: Use `python src/ethereum_spec_tools/patch_tool.py ` to propagate unstaged changes across forks - **Custom dictionary**: `whitelist.txt` for codespell exceptions +- **`pathlib` over `os.path`** + +## Branches + +- There is no main branch. Default branch = most active fork (currently forks/amsterdam). Run git remote show origin | grep HEAD to check. +- `mainnet` — stable specs for forks live on mainnet +- `forks/amsterdam` — PRs target this default branch +- PRs strictly follow the template in `.github/PULL_REQUEST_TEMPLATE.md`. In the Checklist section, include unchecked items that don't apply — only remove them if they are truly irrelevant to the PR type. + +## PR Reviews + +When reviewing PRs that implement or test EIPs: + +1. Identify the EIP number(s) from the branch name, PR title, or changed file paths +2. Fetch each EIP spec from `https://eips.ethereum.org/EIPS/eip-` before starting the review +3. Verify the implementation matches the EIP's specification requirements + +## When to Use Skills + +- Writing or modifying tests → run `/write-test` first +- Writing or modifying pytester-based plugin tests → run `/pytester` first +- Filling test fixtures → run `/fill-tests` first +- Implementing an EIP or modifying fork code in `src/` → run `/implement-eip` first +- Modifying GitHub Actions workflows → run `/edit-workflow` first +- Assessing EIP complexity or scope → run `/assess-eip` +- Working on EIP test coverage or checklists → run `/eip-checklist` first +- Checking if config/skills are stale → run `/audit-config` +- Writing or modifying docstrings in `src/ethereum/` → run `/write-docstring` first +- Done with changes and ready to lint → run `/lint` + +## Available Skills + +- `/write-test` — test writing patterns, fixtures, markers, bytecode helpers +- `/pytester` — pytester execution modes, isolation, output handling for plugin tests +- `/fill-tests` — `fill` CLI reference, flags, debugging, benchmark tests +- `/implement-eip` — fork structure, import rules, adding opcodes/precompiles/tx types +- `/edit-workflow` — GitHub Actions conventions and version pinning +- `/assess-eip` — structured EIP complexity assessment +- `/eip-checklist` — EIP testing checklist system for tracking coverage +- `/lint` — full static analysis suite with auto-fix workflow +- `/audit-config` — verify CLAUDE.md and skills are still accurate +- `/write-docstring` — narrative Markdown docstring conventions for the spec +- `/grammar-check` — audit grammar in documentation and code comments -## Current Status (as of 2026-02-03) - -**PR #2** (`gnosis-osaka` -> `master`): "Implement Gnosis spec post-shangai on forks/osaka" - -- `static`: PASS (all lint/type checks) -- `py3`: PASS (50,738 tests, Paris->Osaka) -- `tests_pytest_py3` / `tests_pytest_pypy3`: PASS -- `pypy3`: FAIL — exit code 143 (killed by CI, timeout/OOM, not a test failure) -- Hive Engine/RLP/Sync: FAIL — Docker cache miss (ephemeral runners can't reliably share week-based cache keys) -- Hive Dev Mode: FAIL — merkle root mismatch because it uses **upstream Ethereum fixtures** (`FIXTURES_URL` points to `ethereum/execution-spec-tests`) against a Gnosis-configured client - -See `plan.md` for pending tasks. From 4eaaa4190bce9757ec5599ecb217209281432827 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 20 May 2026 00:02:59 +0530 Subject: [PATCH 100/186] chore: update workflow --- .github/workflows/hive-consume.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 23aba069ccd..f3eb93efad9 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -64,7 +64,7 @@ concurrency: env: # Use direct URL instead of release spec (e.g., fusaka@v0.1.0) to avoid GitHub API rate limits - FIXTURES_URL: https://github.com/gnosischain/execution-spec-tests/releases/download/v0.1.0/fixtures_osaka.tar.gz + FIXTURES_URL: https://github.com/gnosischain/execution-spec-tests/releases/download/v0.1.0/fixtures_fusaka.tar.gz jobs: cache-docker-images: From b52292054bdbb8eac4630fa1a7c0a19280830490 Mon Sep 17 00:00:00 2001 From: felix Date: Tue, 19 May 2026 22:59:56 +0200 Subject: [PATCH 101/186] feat(spec-specs, tests): Add EIP-8024 Backward compatible SWAPN, DUPN, EXCHANGE (#2881) * feat: devnet script optimization to avoid merge conflicts * feat: mario feedback * feat(src): EIP-8024 tests added (#2021) * feat(test): update EIP-8024 refspec and align on latest changes to EIP (#2095) * feat(test): EIP-8024 update (#2301) * feat: 8024 updates * fix: handle data opcodes appropriately * chore: fixes after rebase; gas constants were renamed * chore: update refspec to latest * feat(test): Add test vectors from EIP changes * fix(src,test): correct EXCHANGE JUMPDEST range; add missing EIP-8024 test vectors * nit: assert tests match EIP cases directly, for readability * nit: `m, n` -> `n, m` for consistency with EIP * refactor: simplify `encode_pair` assumption wrt `m` - Changes related to latest updates: https://github.com/ethereum/EIPs/pull/11351/changes --------- Co-authored-by: fselmo * refactor(tests): Condition EIP-8024 tests to EIP inclusion * fix(tests-eip-8024): Fix cross-eip failures (EIP-8037) (#2656) * fix: mypy * fix(specs): align EIP-8024 DUPN/SWAPN/EXCHANGE gas references Add OPCODE_DUPN, OPCODE_SWAPN, OPCODE_EXCHANGE constants (= VERY_LOW) to the GasCosts class and use them in place of the retired module-level GAS_VERY_LOW reference, matching the per-opcode naming convention used by the rest of the stack instructions. * fix(tests): rename GAS_VERY_LOW to VERY_LOW in EIP-8024 mixin Align DUPN/SWAPN/EXCHANGE gas lookups with the GasCosts dataclass attribute rename on forks/amsterdam. * fix(tests): EIP-8037 workaround * test(tests-eip-8024): end-of-code stack underflow regression (#2741) Add regression coverage for the EIP-8024 consensus bug where DUPN/SWAPN/ EXCHANGE at end of code, with one fewer stack item than the zero-decoded immediate requires, must halt with stack underflow rather than succeeding via a graceful STOP. Parametrized state test over DUPN (144 items), SWAPN (145), EXCHANGE (16) asserting the pre-opcode marker is not persisted, which catches clients that treat the missing immediate as an implicit STOP. Bounty: https://github.com/ethereum-bounty/nethermind/issues/12 Fix: https://github.com/NethermindEth/nethermind/pull/11178 --------- Co-authored-by: felipe Co-authored-by: marioevz Co-authored-by: spencer-tb Co-authored-by: Bhargava Shastry --- .../forks/forks/eips/amsterdam/eip_8024.py | 41 + .../src/execution_testing/vm/opcodes.py | 262 ++++++ src/ethereum/forks/amsterdam/vm/gas.py | 3 + .../amsterdam/vm/instructions/__init__.py | 8 + .../forks/amsterdam/vm/instructions/stack.py | 107 ++- src/ethereum/forks/amsterdam/vm/runtime.py | 26 + src/ethereum/forks/amsterdam/vm/stack.py | 79 +- .../eip8024_dupn_swapn_exchange/__init__.py | 1 + .../eip8024_dupn_swapn_exchange/spec.py | 52 ++ .../eip8024_dupn_swapn_exchange/test_dupn.py | 352 ++++++++ .../test_eip_vectors.py | 831 ++++++++++++++++++ .../test_endofcode_underflow.py | 79 ++ .../test_exchange.py | 444 ++++++++++ .../test_pc_advancement.py | 314 +++++++ .../eip8024_dupn_swapn_exchange/test_swapn.py | 382 ++++++++ tests/frontier/opcodes/test_all_opcodes.py | 85 +- 16 files changed, 3060 insertions(+), 6 deletions(-) create mode 100644 packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_8024.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/__init__.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/spec.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/test_dupn.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/test_eip_vectors.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/test_endofcode_underflow.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/test_pc_advancement.py create mode 100644 tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_8024.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_8024.py new file mode 100644 index 00000000000..dadf752e8e2 --- /dev/null +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_8024.py @@ -0,0 +1,41 @@ +""" +EIP-8024: Backward compatible SWAPN, DUPN, EXCHANGE. + +Introduce additional instructions for manipulating the stack which allow +accessing the stack at higher depths. + +https://eips.ethereum.org/EIPS/eip-8024 +""" + +from typing import Callable, Dict, List + +from execution_testing.vm import OpcodeBase, Opcodes + +from ....base_fork import BaseFork + + +class EIP8024(BaseFork): + """EIP-8024 class.""" + + @classmethod + def valid_opcodes(cls) -> List[Opcodes]: + """Add SWAPN, DUPN, EXCHANGE.""" + return [ + Opcodes.SWAPN, + Opcodes.DUPN, + Opcodes.EXCHANGE, + ] + super(EIP8024, cls).valid_opcodes() + + @classmethod + def opcode_gas_map( + cls, + ) -> Dict[OpcodeBase, int | Callable[[OpcodeBase], int]]: + """Add gas costs for SWAPN, DUPN, EXCHANGE.""" + gas_costs = cls.gas_costs() + base_map = super(EIP8024, cls).opcode_gas_map() + return { + **base_map, + Opcodes.SWAPN: gas_costs.VERY_LOW, + Opcodes.DUPN: gas_costs.VERY_LOW, + Opcodes.EXCHANGE: gas_costs.VERY_LOW, + } diff --git a/packages/testing/src/execution_testing/vm/opcodes.py b/packages/testing/src/execution_testing/vm/opcodes.py index 96fcd6599a3..49563887cb7 100644 --- a/packages/testing/src/execution_testing/vm/opcodes.py +++ b/packages/testing/src/execution_testing/vm/opcodes.py @@ -511,6 +511,156 @@ def __call__(self, *args_t: OpcodeCallArg, **kwargs: Any) -> Bytecode: return pre_opcode_bytecode + self +def _exchange_encoder(*args: int | bytes) -> bytes: + """ + Encoder for EXCHANGE opcode following encode_pair logic from EIP-8024. + + Supports two modes: + 1. bytes input: Returns verbatim (for testing invalid immediate bytes) + 2. int input(s): Validates and encodes using encode_pair logic + + Parameters + ---------- + *args : int | bytes + Either bytes (returned verbatim) or 1-2 ints (encoded) + + Returns + ------- + bytes + The immediate byte for EXCHANGE opcode + + """ + # If bytes are provided, return them verbatim (for testing invalid ranges) + if len(args) == 1 and isinstance(args[0], bytes): + return args[0] + + # If one int is provided, it's the immediate byte value directly + if len(args) == 1 and isinstance(args[0], int): + return int.to_bytes(args[0], 1, "big") + + # If two ints are provided, use encode_pair logic from EIP-8024 + if len(args) == 2: + n, m = args + if not isinstance(n, int) or not isinstance(m, int): + raise TypeError( + "EXCHANGE requires int arguments when using two parameters" + ) + + # encode_pair logic from EIP-8024 + # n is first stack index, m is second (n < m, n + m <= 30) + if not (1 <= n < m and n + m <= 30): + raise ValueError( + f"EXCHANGE indices must satisfy: 1 <= n < m, " + f"n + m <= 30, got n={n}, m={m}" + ) + if m <= 16: + q, r = n - 1, m - 1 + else: + q, r = 29 - m, n - 1 + k = 16 * q + r + imm = k ^ 143 + return int.to_bytes(imm, 1, "big") + + raise ValueError(f"EXCHANGE requires 1 or 2 arguments, got {len(args)}") + + +def _dupn_swapn_encoder(*args: int | bytes) -> bytes: + """ + Encoder for DUPN/SWAPN opcodes following encode_single logic from EIP-8024. + + Supports two modes: + 1. bytes input: Returns verbatim (for testing invalid immediate bytes) + 2. int input: Validates and encodes using encode_single logic + + Parameters + ---------- + *args : int | bytes + Either bytes (returned verbatim) or a single int (encoded) + + Returns + ------- + bytes + The immediate byte for DUPN/SWAPN opcode + + """ + if len(args) != 1: + raise ValueError( + f"DUPN/SWAPN requires exactly 1 argument, got {len(args)}" + ) + + arg = args[0] + + # If bytes are provided, return them verbatim (for testing invalid ranges) + if isinstance(arg, bytes): + return arg + + # If int is provided, use encode_single logic from EIP-8024 + if isinstance(arg, int): + # encode_single logic: n is stack index (17-235) + if not (17 <= arg <= 235): + raise ValueError( + f"DUPN/SWAPN index must be in range [17, 235], got {arg}" + ) + imm = (arg + 111) % 256 + return int.to_bytes(imm, 1, "big") + + raise TypeError( + f"DUPN/SWAPN requires int or bytes argument, got {type(arg)}" + ) + + +def _swapn_stack_properties_modifier(data: bytes) -> tuple[int, int, int, int]: + n = int.from_bytes(data, "big") + if n <= 90 or n >= 128: + min_stack_height = (n + 145) % 256 + else: + # Undefined behavior + min_stack_height = 0 + return ( + 0, + 0, + min_stack_height + 1, + min_stack_height + 1, + ) + + +def _dupn_stack_properties_modifier(data: bytes) -> tuple[int, int, int, int]: + n = int.from_bytes(data, "big") + if n <= 90 or n >= 128: + min_stack_height = (n + 145) % 256 + else: + # Undefined behavior + min_stack_height = 0 + return ( + 0, + 1, + min_stack_height, + min_stack_height + 1, + ) + + +def _exchange_stack_properties_modifier( + data: bytes, +) -> tuple[int, int, int, int]: + n = int.from_bytes(data, "big") + if n > 81 and n < 128: + # Undefined behavior + min_stack_height = 0 + else: + k = n ^ 143 + q, r = divmod(k, 16) + if q < r: + min_stack_height = max(q + 1, r + 1) + else: + min_stack_height = max(r + 1, 29 - q) + return ( + 0, + 0, + min_stack_height + 1, + min_stack_height + 1, + ) + + class Opcodes(Opcode, Enum): """ Enum containing all known opcodes. @@ -5110,6 +5260,118 @@ class Opcodes(Opcode, Enum): Source: [evm.codes/#A4](https://www.evm.codes/#A4) """ + DUPN = Opcode( + 0xE6, + pushed_stack_items=1, + data_portion_length=1, + data_portion_formatter=_dupn_swapn_encoder, + stack_properties_modifier=_dupn_stack_properties_modifier, + ) + """ + DUPN() + ---- + + Description + ---- + + - deduct 3 gas + - read uint8 operand imm + - n = imm + 1 + - n'th (1-based) stack item is duplicated at the top of the stack + - Stack validation: stack_height >= n + + + Inputs + ---- + + Outputs + ---- + + Fork + ---- + Amsterdam + + Gas + ---- + 3 + + """ + + SWAPN = Opcode( + 0xE7, + data_portion_length=1, + data_portion_formatter=_dupn_swapn_encoder, + stack_properties_modifier=_swapn_stack_properties_modifier, + ) + """ + SWAPN() + ---- + + Description + ---- + + - deduct 3 gas + - read uint8 operand imm + - n = imm + 1 + - n + 1th stack item is swapped with the top stack item (1-based). + - Stack validation: stack_height >= n + 1 + + + Inputs + ---- + + Outputs + ---- + + Fork + ---- + Amsterdam + + Gas + ---- + 3 + + """ + + EXCHANGE = Opcode( + 0xE8, + data_portion_length=1, + data_portion_formatter=_exchange_encoder, + stack_properties_modifier=_exchange_stack_properties_modifier, + ) + """ + EXCHANGE[x, y] + ---- + + Description + ---- + Exchanges two stack positions. Two nybbles, n is high 4 bits + 1, + then m is 4 low bits + 1. + Exchanges the n+1'th item with the n + m + 1 item. + + Inputs x and y when the opcode is used as `EXCHANGE[x, y]`, are equal to: + - x = n + 1 + - y = n + m + 1 + Which each equals to 1-based stack positions swapped. + + Inputs + ---- + n + m + 1, or ((imm >> 4) + (imm &0x0F) + 3) from the raw immediate, + + Outputs + ---- + n + m + 1, or ((imm >> 4) + (imm &0x0F) + 3) from the raw immediate, + + Fork + ---- + Amsterdam + + Gas + ---- + 3 + + """ + CREATE = Opcode( 0xF0, popped_stack_items=3, diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index ef9e86c90c3..14ad5d09203 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -171,6 +171,9 @@ class GasCosts: OPCODE_PUSH0 = BASE OPCODE_DUP = VERY_LOW OPCODE_SWAP = VERY_LOW + OPCODE_DUPN = VERY_LOW + OPCODE_SWAPN = VERY_LOW + OPCODE_EXCHANGE = VERY_LOW # Dynamic Opcode Components OPCODE_RETURNDATACOPY_BASE = VERY_LOW diff --git a/src/ethereum/forks/amsterdam/vm/instructions/__init__.py b/src/ethereum/forks/amsterdam/vm/instructions/__init__.py index d858b5053f0..06295ec86f1 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/__init__.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/__init__.py @@ -189,6 +189,11 @@ class Ops(enum.Enum): SWAP15 = 0x9E SWAP16 = 0x9F + # EIP-8024: Stack access instructions + DUPN = 0xE6 + SWAPN = 0xE7 + EXCHANGE = 0xE8 + # Memory Operations MLOAD = 0x51 MSTORE = 0x52 @@ -352,6 +357,9 @@ class Ops(enum.Enum): Ops.SWAP14: stack_instructions.swap14, Ops.SWAP15: stack_instructions.swap15, Ops.SWAP16: stack_instructions.swap16, + Ops.DUPN: stack_instructions.dupn, + Ops.SWAPN: stack_instructions.swapn, + Ops.EXCHANGE: stack_instructions.exchange, Ops.LOG0: log_instructions.log0, Ops.LOG1: log_instructions.log1, Ops.LOG2: log_instructions.log2, diff --git a/src/ethereum/forks/amsterdam/vm/instructions/stack.py b/src/ethereum/forks/amsterdam/vm/instructions/stack.py index 366cf79f5e4..6e2886493a0 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/stack.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/stack.py @@ -13,7 +13,7 @@ from functools import partial -from ethereum_types.numeric import U256, Uint +from ethereum_types.numeric import U8, U256, Uint from .. import Evm, stack from ..exceptions import StackUnderflowError @@ -22,6 +22,7 @@ charge_gas, ) from ..memory import buffer_read +from ..stack import decode_pair, decode_single def pop(evm: Evm) -> None: @@ -209,3 +210,107 @@ def swap_n(evm: Evm, item_number: int) -> None: swap14 = partial(swap_n, item_number=14) swap15 = partial(swap_n, item_number=15) swap16 = partial(swap_n, item_number=16) + + +def dupn(evm: Evm) -> None: + """ + Duplicate the Nth stack item (from top of the stack) to the top of stack. + The item number is read from the immediate byte following the opcode and + decoded using the EIP-8024 index shifting rules. + + Parameters + ---------- + evm : + The current EVM frame. + + """ + # STACK + pass + + # GAS + charge_gas(evm, GasCosts.OPCODE_DUPN) + + # OPERATION + immediate_data = U8( + buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0] + ) + item_number = decode_single(immediate_data) + if int(item_number) > len(evm.stack): + raise StackUnderflowError + data_to_duplicate = evm.stack[-item_number] + stack.push(evm.stack, data_to_duplicate) + + # PROGRAM COUNTER + evm.pc += Uint(2) + + +def swapn(evm: Evm) -> None: + """ + Swap the top stack item with the Nth stack item. + The value N is read from the immediate byte following the opcode and + decoded using the EIP-8024 index shifting rules. + + Parameters + ---------- + evm : + The current EVM frame. + + """ + # STACK + pass + + # GAS + charge_gas(evm, GasCosts.OPCODE_SWAPN) + + # OPERATION + immediate_data = U8( + buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0] + ) + item_number = decode_single(immediate_data) + # SWAPN with decoded value n swaps top (position 1) with position (n+1) + if int(item_number) + 1 > len(evm.stack): + raise StackUnderflowError + # stack[-1] is top (position 1), stack[-(item_number+1)] is position (n+1) + evm.stack[-1], evm.stack[-(item_number + U8(1))] = ( + evm.stack[-(item_number + U8(1))], + evm.stack[-1], + ) + + # PROGRAM COUNTER + evm.pc += Uint(2) + + +def exchange(evm: Evm) -> None: + """ + Exchange the Nth stack item with the Mth stack item. + The values N and M are decoded from the immediate byte using the + EIP-8024 index shifting rules. + + Parameters + ---------- + evm : + The current EVM frame. + + """ + # STACK + pass + + # GAS + charge_gas(evm, GasCosts.OPCODE_EXCHANGE) + + # OPERATION + immediate_data = U8( + buffer_read(evm.code, U256(evm.pc + Uint(1)), U256(1))[0] + ) + n, m = decode_pair(immediate_data) + # EXCHANGE swaps position (n+1) with position (m+1) + depth = max(n, m) + U8(1) + if int(depth) > len(evm.stack): + raise StackUnderflowError + evm.stack[-(n + U8(1))], evm.stack[-(m + U8(1))] = ( + evm.stack[-(m + U8(1))], + evm.stack[-(n + U8(1))], + ) + + # PROGRAM COUNTER + evm.pc += Uint(2) diff --git a/src/ethereum/forks/amsterdam/vm/runtime.py b/src/ethereum/forks/amsterdam/vm/runtime.py index 0aa5ddd5e20..60fd42b52c9 100644 --- a/src/ethereum/forks/amsterdam/vm/runtime.py +++ b/src/ethereum/forks/amsterdam/vm/runtime.py @@ -28,6 +28,8 @@ def get_valid_jump_destinations(code: Bytes) -> Set[Uint]: * The jump destination should have the `JUMPDEST` opcode (0x5B). * The jump destination shouldn't be part of the data corresponding to `PUSH-N` opcodes. + * The jump destination shouldn't be part of the immediate byte + corresponding to `DUPN`, `SWAPN`, or `EXCHANGE` opcodes (EIP-8024). Note - Jump destinations are 0-indexed. @@ -63,6 +65,30 @@ def get_valid_jump_destinations(code: Bytes) -> Set[Uint]: # opcodes. push_data_size = current_opcode.value - Ops.PUSH1.value + 1 pc += Uint(push_data_size) + elif current_opcode in (Ops.DUPN, Ops.SWAPN): + # EIP-8024: DUPN/SWAPN invalid immediate range is + # 90 < x < 128, i.e. 0x5B (91) to 0x7F (127). + # Invalid immediates are not skipped so the byte + # remains at an instruction boundary. + if ( + pc + Uint(1) < ulen(code) + and 0x5B <= code[pc + Uint(1)] <= 0x7F + ): + pass + else: + pc += Uint(1) + elif current_opcode == Ops.EXCHANGE: + # EIP-8024: EXCHANGE invalid immediate range is + # 81 < x < 128, i.e. 0x52 (82) to 0x7F (127). + # Invalid immediates are not skipped so the byte + # remains at an instruction boundary. + if ( + pc + Uint(1) < ulen(code) + and 0x52 <= code[pc + Uint(1)] <= 0x7F + ): + pass + else: + pc += Uint(1) pc += Uint(1) diff --git a/src/ethereum/forks/amsterdam/vm/stack.py b/src/ethereum/forks/amsterdam/vm/stack.py index a87b0a47079..98ba815cb73 100644 --- a/src/ethereum/forks/amsterdam/vm/stack.py +++ b/src/ethereum/forks/amsterdam/vm/stack.py @@ -11,11 +11,84 @@ Implementation of the stack operators for the EVM. """ -from typing import List +from typing import List, Tuple -from ethereum_types.numeric import U256 +from ethereum_types.numeric import U8, U256 -from .exceptions import StackOverflowError, StackUnderflowError +from .exceptions import ( + InvalidParameter, + StackOverflowError, + StackUnderflowError, +) + + +def decode_single(x: U8) -> U8: + """ + Decode the immediate byte for DUPN/SWAPN to get the stack index. + + Return n with 17 <= n <= 235. + + Parameters + ---------- + x : int + The immediate byte value (0-90 or 128-255). + + Returns + ------- + int + The stack index n, where 17 <= n <= 235. + + Raises + ------ + InvalidParameter + If x is in the forbidden range (90 < x < 128 or x > 255). + + """ + if not (U8(0) <= x <= U8(90) or U8(128) <= x <= U8(255)): + raise InvalidParameter( + f"DUPN/SWAPN immediate byte {x} is out of range. " + "Valid range: 0 <= x <= 90 or 128 <= x <= 255" + ) + + return U8((int(x) + 145) % 256) + + +def decode_pair(x: U8) -> Tuple[U8, U8]: + """ + Decode the immediate byte for EXCHANGE to get two stack indices. + + Return (n, m) with 1 <= n <= 14 and n < m <= 30 - n. + + Parameters + ---------- + x : int + The immediate byte value (0-81 or 128-255). + + Returns + ------- + Tuple[int, int] + The two stack indices (n, m), where + 1 <= n <= 14 and n < m <= 30 - n. + + Raises + ------ + InvalidParameter + If x is in the forbidden range (81 < x < 128 or x > 255). + + """ + if not (U8(0) <= x <= U8(81) or U8(128) <= x <= U8(255)): + raise InvalidParameter( + f"EXCHANGE immediate byte {x} is in the forbidden " + "range 82 <= x <= 127\n" + "Valid range: 0 <= x <= 81 or 128 <= x <= 255" + ) + + k = U8(int(x) ^ 143) + q, r = divmod(k, U8(16)) + if q < r: + return q + U8(1), r + U8(1) + else: + return r + U8(1), U8(29) - q def pop(stack: List[U256]) -> U256: diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/__init__.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/__init__.py new file mode 100644 index 00000000000..3440302c87f --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/__init__.py @@ -0,0 +1 @@ +"""Tests for [EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024).""" diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/spec.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/spec.py new file mode 100644 index 00000000000..5f0037c67d8 --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/spec.py @@ -0,0 +1,52 @@ +"""Reference spec for [EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024).""" + +from dataclasses import dataclass +from typing import Tuple + +from ethereum_types.numeric import U8 + +from ethereum.forks.amsterdam.vm.stack import decode_pair as _decode_pair +from ethereum.forks.amsterdam.vm.stack import decode_single as _decode_single + + +@dataclass(frozen=True) +class ReferenceSpec: + """Reference specification.""" + + git_path: str + version: str + + +ref_spec_8024 = ReferenceSpec( + git_path="EIPS/eip-8024.md", + version="380cb02832a6ed5310bfde51591e580ca6d1f3cd", +) + + +@dataclass(frozen=True) +class Spec: + """Constants and parameters from EIP-8024.""" + + # Gas cost for DUPN, SWAPN, and EXCHANGE + GAS_COST: int = 3 + + # DUPN/SWAPN stack index range (after decoding) + MIN_STACK_INDEX: int = 17 + MAX_STACK_INDEX: int = 235 + + # EXCHANGE constraints: 1 <= n < m <= 29, n + m <= 30 + EXCHANGE_MIN_N: int = 1 + EXCHANGE_MAX_N: int = 14 + EXCHANGE_MAX_M: int = 29 + EXCHANGE_MAX_SUM: int = 30 + + +def decode_pair(x: int) -> Tuple[int, int]: + """Decode a pair with proper typing for tests.""" + n, m = _decode_pair(U8(x)) + return int(n), int(m) + + +def decode_single(x: int) -> int: + """Decode single with proper typing for tests.""" + return int(_decode_single(U8(x))) diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/test_dupn.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_dupn.py new file mode 100644 index 00000000000..8b9bced64dc --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_dupn.py @@ -0,0 +1,352 @@ +""" +DUPN instruction tests. + +Tests for DUPN instruction in +[EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Bytecode, + Op, + StateTestFiller, + Transaction, +) + +from .spec import decode_single, ref_spec_8024 + +REFERENCE_SPEC_GIT_PATH = ref_spec_8024.git_path +REFERENCE_SPEC_VERSION = ref_spec_8024.version + +pytestmark = pytest.mark.valid_from("EIP8024") + + +@pytest.mark.parametrize( + "stack_index", + [17, 18, 32, 64, 107, 108, 200, 235], + ids=lambda x: f"dupn_stack_{x}", +) +def test_dupn_basic( + stack_index: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test DUPN with various stack indices (17-235).""" + sender = pre.fund_eoa() + + # Build stack with enough items, then use DUPN to duplicate the nth item + # DUPN with immediate x duplicates the decode_single(x)th stack item + stack_height = stack_index + expected_value = 0xBEEF + stack_index + + # Push values onto stack: the value at the target position will + # be expected_value + code = Bytecode() + for i in range(stack_height): + if i == 0: + # The first push will end up at position stack_index from top + code += Op.PUSH2(expected_value) + else: + code += Op.PUSH2(0x1000 + i) + + # Pass stack index directly - encoder will handle encoding + code += Op.DUPN[stack_index] + # Store the duplicated value + code += Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = {contract_address: Account(storage={0: expected_value})} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + [0, 45, 90, 128, 200, 255], + ids=lambda x: f"dupn_imm_{x}", +) +def test_dupn_valid_immediates( + immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test DUPN with valid immediate values (0-90 and 128-255).""" + sender = pre.fund_eoa() + + # Decode the immediate to get the stack index + stack_index = decode_single(immediate) + stack_height = stack_index + expected_value = 0xCAFE + immediate + + # Push values onto stack + code = Bytecode() + for i in range(stack_height): + if i == 0: + code += Op.PUSH2(expected_value) + else: + code += Op.PUSH2(0x1000 + i) + + # Pass immediate as bytes (raw immediate byte for testing) + code += Op.DUPN[immediate.to_bytes(1, "big")] + code += Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=10_000_000) + + post = {contract_address: Account(storage={0: expected_value})} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + [0, 45, 90, 128, 200, 255], + ids=lambda x: f"dupn_underflow_imm_{x}", +) +def test_dupn_stack_underflow( + immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test DUPN causes transaction failure on stack underflow.""" + sender = pre.fund_eoa() + + # Decode the immediate to get the stack index + stack_index = decode_single(immediate) + # Push one less than required to trigger underflow + insufficient_items = stack_index - 1 + + code = Op.SSTORE(0, 1) + for i in range(insufficient_items): + code += Op.PUSH1(i) + # Pass immediate as bytes (raw immediate byte for testing) + # Needs stack_index items, underflow + code += Op.DUPN[immediate.to_bytes(1, "big")] + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should fail, contract storage unchanged + post = {contract_address: Account(storage={0: 0})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_endofcode_behavior( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test DUPN when the immediate byte is beyond the end of code. + + Per EIP-8024, code[pc + 1] evaluates to 0 if beyond the end of the code, + matching PUSH behavior. With immediate = 0, decode_single(0) = 145, so + DUPN duplicates the 145th stack item. + + This test verifies the transaction succeeds (doesn't revert) when DUPN + is the last byte of the code with no immediate byte following it. + """ + sender = pre.fund_eoa() + + # decode_single(0) = 145, which duplicates the 145th item from top + # We need 145 items on the stack for this to succeed + stack_height = 145 + marker_value = 0x42 + + # Build code: store marker, push enough items, then DUPN (no immediate) + code = Bytecode() + code += Op.SSTORE(0, marker_value) # Store marker + + # Push 145 items to stack so DUPN with implicit imm=0 succeeds + for i in range(stack_height): + code += Op.PUSH1(i % 256) + + # Add just the DUPN opcode without immediate byte + # After DUPN, pc += 2 goes beyond code, causing implicit STOP + code += Op.DUPN # no immediate + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # If tx succeeds, storage[0] = marker_value + # Bad implementation would revert and have empty storage + post = {contract_address: Account(storage={0: marker_value})} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "invalid_immediate", + list(range(91, 128)), # 0x5b to 0x7f (JUMPDEST and PUSH opcodes) + ids=lambda x: f"dupn_invalid_imm_0x{x:02x}", +) +def test_dupn_invalid_immediate_aborts( + invalid_immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test DUPN with invalid immediate values (90 < x < 128) aborts execution. + + Per EIP-8024, immediate values in range [91, 127] (0x5b-0x7f) are invalid + because they correspond to JUMPDEST (0x5b) and PUSH opcodes (0x60-0x7f). + Attempting to execute DUPN with these immediates should abort. + """ + sender = pre.fund_eoa() + + # Build stack with enough items for any valid immediate + # Maximum stack index is 235, so push 235 items + code = Bytecode() + for i in range(235): + code += Op.PUSH1(i % 256) + + # Attempt DUPN with invalid immediate - should abort + # Pass as bytes (raw immediate byte for testing invalid ranges) + code += Op.DUPN[invalid_immediate.to_bytes(1, "big")] + + # This should never execute + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=10_000_000) + + # Transaction should fail - invalid immediate causes abort + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_dupn_jump_to_immediate_byte_0x5b_succeeds( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test that jumping to 0x5b after DUPN succeeds (backward compatibility). + + Bytecode: PUSH1(4) JUMP DUPN[0x5b] + Hex: 6004 56 e6 5b + Position 4 contains 0x5b which is an INVALID immediate for DUPN. + Per EIP-8024, 0x5b is preserved as valid JUMPDEST for compatibility. + The DUPN instruction is never executed due to the jump. + """ + sender = pre.fund_eoa() + + # Build code that jumps to 0x5b after DUPN opcode + code = Bytecode() + code += Op.PUSH1(4) # Push jump target (position 4) + code += Op.JUMP # Jump to position 4 + # Pass as bytes (raw immediate byte for testing) + code += Op.DUPN[b"\x5b"] # Position 3-4: DUPN + 0x5b (invalid immediate) + + # This SHOULD execute because 0x5b is a valid JUMPDEST + code += Op.SSTORE(0, 0x42) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction succeeds - 0x5b is preserved as valid JUMPDEST + post = {contract_address: Account(storage={0: 0x42})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_dupn_jump_to_valid_immediate_fails( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test jumping to a valid immediate byte fails. + + Bytecode: PUSH1(4) JUMP DUPN[0x00] + Hex: 6004 56 e6 00 + Position 4 contains 0x00 which is a VALID immediate for DUPN. + Valid immediates are skipped in JUMPDEST analysis, so jump fails. + """ + sender = pre.fund_eoa() + + # Build code that tries to jump to a valid immediate + code = Bytecode() + code += Op.PUSH1(4) # Push jump target (position 4) + code += Op.JUMP # Try to jump to position 4 + # Pass as bytes (raw immediate byte for testing) + code += Op.DUPN[b"\x00"] # Position 3-4: DUPN + 0x00 (valid immediate) + + # This should never execute + code += Op.SSTORE(0, 0x42) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction fails - position 4 is a valid immediate, not JUMPDEST + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_dupn_with_dup1_sequence( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test DUPN duplicating the bottom item after building stack with DUP1. + + Stack layout: PUSH1(1) PUSH1(0) DUP1*15 DUPN[0x80] + Before DUPN: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + After DUPN[0x80] (decode_single(0x80)=17): [1, 0, 0, ..., 0, 1] + Result: 18 stack items, top=1, bottom=1, rest=0 + """ + sender = pre.fund_eoa() + + # Build the stack: PUSH1(1), PUSH1(0), 15x DUP1 + code = Bytecode() + code += Op.PUSH1(1) # Bottom of stack (position 17 after DUP1s) + code += Op.PUSH1(0) + for _ in range(15): + code += Op.DUP1 + + # Stack now has 17 items: + # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + # DUPN with immediate 0x80 (decode_single(0x80) = 17) duplicates pos 17 + # Pass as bytes (raw immediate byte for testing) + code += Op.DUPN[b"\x80"] + + # Store all stack values to verify + for i in range(18): + code += Op.PUSH1(i) + Op.SSTORE + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Expected: top (position 0) = 1, bottom (position 17) = 1, all others = 0 + expected_storage = {} + for i in range(18): + if i == 0: + expected_storage[i] = 1 # Top of stack after DUPN + elif i == 17: + expected_storage[i] = 1 # Bottom of stack + else: + expected_storage[i] = 0 # All middle values + + post = {contract_address: Account(storage=expected_storage)} + + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/test_eip_vectors.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_eip_vectors.py new file mode 100644 index 00000000000..382d6d540d7 --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_eip_vectors.py @@ -0,0 +1,831 @@ +""" +EIP-8024 Official Test Vectors. + +Test vectors from the EIP-8024 specification: +[EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Bytecode, + Op, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_8024 + +REFERENCE_SPEC_GIT_PATH = ref_spec_8024.git_path +REFERENCE_SPEC_VERSION = ref_spec_8024.version + +pytestmark = pytest.mark.valid_from("EIP8024") + + +def test_eip_vector_dupn_duplicate_bottom( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 60016000808080808080808080808080808080e680. + + Results in 18 stack items, top=1, bottom=1, rest=0. + + PUSH1 1, PUSH1 0, 15x DUP1, DUPN[0x80] + - After 15 DUP1s: 17 items [0,0,0,...,0,1] + - DUPN[0x80]: decode_single(0x80)=17, duplicate position 17 (value 1) + - Result: 18 items, top=1, bottom=1 + """ + sender = pre.fund_eoa() + + # Build the exact bytecode from the EIP + code = Op.PUSH1[0x1] + Op.PUSH1[0x0] + Op.DUP1 * 15 + Op.DUPN[17] + assert bytes(code) == bytes.fromhex( + "60016000808080808080808080808080808080e680" + ) + + # Verify by storing top and bottom values + code += Op.PUSH1(0) + Op.SSTORE # Store top (should be 1) at key 0 + + # Pop 16 items to get to bottom 2 items + code += Op.POP * 16 + # Stack now has 1 item (bottom value = 1) + + # Store bottom value at key 1 + code += Op.PUSH1(1) + Op.SSTORE # Store bottom (should be 1) at key 1 + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 1, # top = 1 (from DUPN duplicating position 17) + 1: 1, # bottom = 1 (original PUSH1 1) + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_swapn_swap_with_bottom( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 600160008080808080808080808080808080806002e780. + + Results in 18 stack items, top=1, bottom=2, rest=0. + + PUSH1 1, PUSH1 0, 15x DUP1, PUSH1 2, SWAPN[0x80] + - After PUSH1 2: 18 items with top=2, bottom=1 + - SWAPN[0x80]: decode_single(0x80)=17, swap pos 1 with pos (17+1)=18 + - Result: 18 items, top=1, bottom=2 + """ + sender = pre.fund_eoa() + + # Build the exact bytecode from the EIP + code = ( + Op.PUSH1[0x1] + + Op.PUSH1[0x0] + + Op.DUP1 * 15 + + Op.PUSH1[0x2] + + Op.SWAPN[17] + ) + assert bytes(code) == bytes.fromhex( + "600160008080808080808080808080808080806002e780" + ) + + # Verify by storing top and bottom values + code += Op.PUSH1(0) + Op.SSTORE # Store top (should be 1) at key 0 + + # Pop 16 items to get to bottom 1 item + code += Op.POP * 16 + # Stack now has 1 item (bottom value = 2) + + # Store bottom value at key 1 + code += Op.PUSH1(1) + Op.SSTORE # Store bottom (should be 2) at key 1 + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 1, # top = 1 (swapped from bottom) + 1: 2, # bottom = 2 (swapped from top) + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_exchange_swap_positions( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 600060016002e88e. + + Results in 3 stack items, from top to bottom: [2, 0, 1]. + + PUSH1 0, PUSH1 1, PUSH1 2, EXCHANGE[0x8e] + - After pushes: [2, 1, 0] (top to bottom) + - EXCHANGE[0x8e]: decode_pair(0x8e)=(1,2), swap positions 2 and 3 + - Result: [2, 0, 1] + """ + sender = pre.fund_eoa() + + # Build the exact bytecode from the EIP + code = Op.PUSH1[0x0] + Op.PUSH1[0x1] + Op.PUSH1[0x2] + Op.EXCHANGE[b"\x8e"] + assert bytes(code) == bytes.fromhex("600060016002e88e") + + # Store all 3 stack values + code += Op.PUSH1(0) + Op.SSTORE # Store position 1 / top (should be 2) + code += Op.PUSH1(1) + Op.SSTORE # Store position 2 (should be 0) + code += Op.PUSH1(2) + Op.SSTORE # Store position 3 / bottom (should be 1) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 2, # top = 2 (unchanged) + 1: 0, # position 2 = 0 (swapped from position 3) + 2: 1, # bottom = 1 (swapped from position 2) + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_swapn_invalid_immediate_reverts( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: e75b reverts. + + SWAPN with immediate 0x5b (91) is in the invalid range (90 < x < 128). + This should cause an exceptional halt. + """ + sender = pre.fund_eoa() + + # Build the exact bytecode from the EIP: SWAPN[0x5b] + # 0x5b = 91 which is in the forbidden range + code = Bytecode( + Op.SWAPN[b"\x5b"], + popped_stack_items=0, + pushed_stack_items=0, + terminating=True, + ) + assert bytes(code) == bytes.fromhex("e75b") + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should fail, storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_jump_over_invalid_dupn( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 600456e65b executes successfully. + + PUSH1 04, JUMP, DUPN[0x5b] + - The DUPN at position 2 has immediate 0x5b which would be invalid + - But we JUMP to position 4 (the 0x5b byte), which is a valid JUMPDEST + - The DUPN instruction is never executed + """ + sender = pre.fund_eoa() + + # Build the exact bytecode: PUSH1 04, JUMP, DUPN[0x5b] + # Position 0: PUSH1 (0x60) + # Position 1: 0x04 + # Position 2: JUMP (0x56) + # Position 3: DUPN (0xe6) + # Position 4: 0x5b (JUMPDEST when executed as opcode) + code = Bytecode( + Op.PUSH1[0x4] + Op.JUMP + Op.DUPN[b"\x5b"], + popped_stack_items=0, + pushed_stack_items=0, + ) + assert bytes(code) == bytes.fromhex("600456e65b") + + # After jumping to JUMPDEST, mark success + code += Op.PUSH1(1) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should succeed + post = {contract_address: Account(storage={0: 1})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_exchange_with_iszero( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 60008080e88e15. + + Results in 3 stack items, top=1, rest=0. + + PUSH1 0, DUP1, DUP1, EXCHANGE[0x8e], ISZERO + - After DUP1s: [0, 0, 0] + - EXCHANGE[0x8e]: decode_pair(0x8e)=(1,2), swap pos 2 and 3 + - ISZERO: pop 0, push 1 + - Result: [1, 0, 0] + """ + sender = pre.fund_eoa() + + # Build the exact bytecode from the EIP + code = Op.PUSH1[0x0] + Op.DUP1 + Op.DUP1 + Op.EXCHANGE[b"\x8e"] + Op.ISZERO + assert bytes(code) == bytes.fromhex("60008080e88e15") + + # Store all 3 stack values + code += Op.PUSH1(0) + Op.SSTORE # Store top (should be 1) + code += Op.PUSH1(1) + Op.SSTORE # Store position 2 (should be 0) + code += Op.PUSH1(2) + Op.SSTORE # Store position 3 (should be 0) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 1, # top = 1 (from ISZERO) + 1: 0, # position 2 = 0 + 2: 0, # bottom = 0 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_dupn_stack_underflow( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 6000808080808080808080808080808080e680. + + Results in exceptional halt (stack underflow). + + PUSH1 0, 15x DUP1, DUPN[0x80] + - After 15 DUP1s: 16 items + - DUPN[0x80]: decode_single(0x80)=17, needs position 17 but only 16 items + - Result: exceptional halt + """ + sender = pre.fund_eoa() + + # Build the exact bytecode from the EIP + code = Op.PUSH1[0x0] + Op.DUP1 * 15 + Op.DUPN[b"\x80"] + assert bytes(code) == bytes.fromhex( + "6000808080808080808080808080808080e680" + ) + + # This should not execute due to stack underflow + code += Op.PUSH1(1) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should fail, storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_dupn_followed_by_jumpdest( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e6805b [DUPN 17, JUMPDEST]. + + Verify that DUPN with immediate 0x80 (128) correctly consumes the + immediate byte. The 0x5b following the DUPN is a separate JUMPDEST + instruction, not part of DUPN. decode_single(0x80) = 17, so DUPN + duplicates the 17th stack item. + """ + sender = pre.fund_eoa() + + # Push 17 items so DUPN[17] (immediate 0x80 / 128) succeeds + marker_value = 0xBEEF + code = Bytecode() + code += Op.PUSH2(marker_value) # This will be at position 17 + for i in range(16): + code += Op.PUSH1(i) + + # DUPN[17] encodes to immediate 0x80 (128), followed by JUMPDEST + # Bytecode: e6 80 5b + code += Op.DUPN[17] + Op.JUMPDEST + + # Store the duplicated value (should be marker_value) + code += Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # DUPN should duplicate position 17 (marker_value) + post = {contract_address: Account(storage={0: marker_value})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_dupn_invalid_0x60( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e6605b [INVALID_DUPN, PUSH1 0x5b]. + + DUPN with immediate 0x60 (96) is in the invalid range (91-127). + Execution should abort with exceptional halt. + """ + sender = pre.fund_eoa() + + # Push enough items on stack for any potential operation + code = Bytecode() + for i in range(235): + code += Op.PUSH1(i % 256) + + # DUPN with invalid immediate 0x60 - should abort + # Hex: e6 60 5b + code += Op.DUPN[b"\x60"] + + # This should never execute due to invalid immediate + code += Op.PUSH1(0x5B) # Would be PUSH1 0x5b if we got here + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=10_000_000) + + # Transaction should fail, storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_swapn_invalid_0x61( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e7610000 [INVALID_SWAPN, PUSH2 0x0000]. + + SWAPN with immediate 0x61 (97) is in the invalid range (91-127). + Execution should abort with exceptional halt. + """ + sender = pre.fund_eoa() + + # Push enough items on stack for any potential operation + code = Bytecode() + for i in range(236): + code += Op.PUSH1(i % 256) + + # SWAPN with invalid immediate 0x61 - should abort + # Hex: e7 61 00 00 + code += Op.SWAPN[b"\x61"] + + # These bytes would be PUSH2 0x0000 if we got here + code += Op.PUSH2(0x0000) + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=10_000_000) + + # Transaction should fail, storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_dupn_invalid_0x5f( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e65f [INVALID_DUPN, PUSH0]. + + DUPN with immediate 0x5f (95) is in the invalid range (91-127). + Execution should abort with exceptional halt. + """ + sender = pre.fund_eoa() + + # Push enough items on stack for any potential operation + code = Bytecode() + for i in range(235): + code += Op.PUSH1(i % 256) + + # DUPN with invalid immediate 0x5f - should abort + # Hex: e6 5f + code += Op.DUPN[b"\x5f"] + + # This should never execute + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=10_000_000) + + # Transaction should fail, storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_exchange_0x9d( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e89d [EXCHANGE 2 3]. + + EXCHANGE with immediate 0x9d (157 decimal). + decode_pair(0x9d) = (2, 3), swaps positions 3 and 4. + """ + sender = pre.fund_eoa() + + # Build stack with 4 items: positions 1, 2, 3, 4 from top + # Values: [top=0x1111, pos2=0x2222, pos3=0x3333, pos4=0x4444] + code = Bytecode() + code += Op.PUSH2(0x4444) # Position 4 (will be swapped) + code += Op.PUSH2(0x3333) # Position 3 (will be swapped) + code += Op.PUSH2(0x2222) # Position 2 + code += Op.PUSH2(0x1111) # Position 1 (top) + + # EXCHANGE with immediate 0x9d - swaps positions 3 and 4 + # Hex: e8 9d + code += Op.EXCHANGE[b"\x9d"] + + # Store all values to verify the swap + code += Op.PUSH1(0) + Op.SSTORE # Position 1 (top) + code += Op.PUSH1(1) + Op.SSTORE # Position 2 + code += Op.PUSH1(2) + Op.SSTORE # Position 3 (was 4) + code += Op.PUSH1(3) + Op.SSTORE # Position 4 (was 3) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # After EXCHANGE[0x9d]: positions 3 and 4 are swapped + post = { + contract_address: Account( + storage={ + 0: 0x1111, # Position 1 unchanged + 1: 0x2222, # Position 2 unchanged + 2: 0x4444, # Position 3 now has value from position 4 + 3: 0x3333, # Position 4 now has value from position 3 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_exchange_0x2f( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e82f [EXCHANGE 1 19]. + + EXCHANGE with immediate 0x2f (47 decimal). + decode_pair(0x2f) = (1, 19), swaps positions 2 and 20. + """ + sender = pre.fund_eoa() + + # Build stack with 20 items + # Position 2 and position 20 will be swapped + code = Bytecode() + code += Op.PUSH2(0xBBBB) # Position 20 (bottom, will be swapped) + for i in range(17): + code += Op.PUSH2(0x1000 + i) # Positions 3-19 + code += Op.PUSH2(0xAAAA) # Position 2 (will be swapped) + code += Op.PUSH2(0x1111) # Position 1 (top) + + # EXCHANGE with immediate 0x2f - swaps positions 2 and 20 + # Hex: e8 2f + code += Op.EXCHANGE[b"\x2f"] + + # Store position 1, 2, and 20 to verify + code += Op.PUSH1(0) + Op.SSTORE # Position 1 (top, unchanged) + code += Op.PUSH1(1) + Op.SSTORE # Position 2 (was 0xBBBB from pos 20) + + # Pop to get to position 20 + for _ in range(17): + code += Op.POP + + code += Op.PUSH1(2) + Op.SSTORE # Position 20 (was 0xAAAA from pos 2) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # After EXCHANGE[0x2f]: positions 2 and 20 are swapped + post = { + contract_address: Account( + storage={ + 0: 0x1111, # Position 1 unchanged + 1: 0xBBBB, # Position 2 now has value from position 20 + 2: 0xAAAA, # Position 20 now has value from position 2 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_exchange_valid_0x50( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e850 [EXCHANGE 14 16]. + + EXCHANGE with immediate 0x50 (80 decimal) is valid. + decode_pair(0x50) = (14, 16), swaps positions 15 and 17. + """ + sender = pre.fund_eoa() + + # Build stack with 17 items, with known values at positions 15 and 17 + code = Bytecode() + for i in range(17): + stack_pos = 17 - i # Position from top (1-indexed) + if stack_pos == 15: + code += Op.PUSH2(0xAAAA) + elif stack_pos == 17: + code += Op.PUSH2(0xBBBB) + else: + code += Op.PUSH2(0x1000 + i) + + # EXCHANGE with immediate 0x50 - swaps positions 15 and 17 + code += Op.EXCHANGE[b"\x50"] + + # Store swapped positions to verify + # Pop to position 15 (pop 14 items) + for _ in range(14): + code += Op.POP + code += Op.PUSH1(0) + Op.SSTORE # Position 15 (was 0xBBBB) + code += Op.POP # Skip position 16 + code += Op.PUSH1(1) + Op.SSTORE # Position 17 (was 0xAAAA) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 0xBBBB, # Position 15 now has value from 17 + 1: 0xAAAA, # Position 17 now has value from 15 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_exchange_valid_0x51( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e851 [EXCHANGE 14 15]. + + EXCHANGE with immediate 0x51 (81 decimal) is valid. + decode_pair(0x51) = (14, 15), swaps positions 15 and 16. + """ + sender = pre.fund_eoa() + + # Build stack with 16 items, with known values at positions 15 and 16 + code = Bytecode() + for i in range(16): + stack_pos = 16 - i + if stack_pos == 15: + code += Op.PUSH2(0xAAAA) + elif stack_pos == 16: + code += Op.PUSH2(0xBBBB) + else: + code += Op.PUSH2(0x1000 + i) + + # EXCHANGE with immediate 0x51 - swaps positions 15 and 16 + code += Op.EXCHANGE[b"\x51"] + + # Pop to position 15 (pop 14 items) + for _ in range(14): + code += Op.POP + code += Op.PUSH1(0) + Op.SSTORE # Position 15 (was 0xBBBB) + code += Op.PUSH1(1) + Op.SSTORE # Position 16 (was 0xAAAA) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 0xBBBB, # Position 15 now has value from 16 + 1: 0xAAAA, # Position 16 now has value from 15 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_exchange_end_of_code( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector: 600260008080808080600160008080808080808080e8. + + EXCHANGE at end of code, immediate = 0x00 (beyond code). + decode_pair(0) = (9, 16), swaps positions 10 and 17. + Results in 17 stack items, bottom=1, 10th from top=2, rest=0. + """ + sender = pre.fund_eoa() + + # Build exact bytecode from the EIP + code = ( + Op.PUSH1[0x2] + + Op.PUSH1[0x0] + + Op.DUP1 * 5 + + Op.PUSH1[0x1] + + Op.PUSH1[0x0] + + Op.DUP1 * 8 + + Op.EXCHANGE + ) + assert bytes(code) == bytes.fromhex( + "600260008080808080600160008080808080808080e8" + ) + # 17 items on stack: + # pos 1-8: 0, pos 9: 0, pos 10: 1, pos 11-16: 0, pos 17: 2 + # After EXCHANGE(9,16): swap pos 10 and 17 -> pos 10=2, pos 17=1 + + # Store marker before opcode to verify success + # Since EXCHANGE is at end of code, we verify by checking that the + # operation completed by storing the 10th and bottom items + contract_address = pre.deploy_contract( + code=Op.SSTORE(0, 0x42) + code + Op.STOP + ) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Verify marker was stored (tx succeeded) + post = {contract_address: Account(storage={0: 0x42})} + state_test(pre=pre, post=post, tx=tx) + + +def test_eip_vector_exchange_30_items( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + EIP test vector (30-item EXCHANGE). + + Bytecode: 600080...(27x DUP1)...60016002e88f. + decode_pair(0x8f / 143) = (1, 29), swaps positions 2 and 30. + Results in 30 stack items, top=2, bottom=1, rest=0. + """ + sender = pre.fund_eoa() + + code = ( + Op.PUSH1[0x0] + + Op.DUP1 * 27 + + Op.PUSH1[0x1] + + Op.PUSH1[0x2] + + Op.EXCHANGE[b"\x8f"] + ) + assert bytes(code) == bytes.fromhex("6000" + "80" * 27 + "60016002e88f") + # 30 items: pos 1=2, pos 2=1, rest=0 + # After EXCHANGE(1,29): swap pos 2 and 30 -> pos 2=0, pos 30=1 + # Result: top=2, bottom=1, rest=0 + + # Store top value + code += Op.PUSH1(0) + Op.SSTORE # top = 2 + + # Pop to get to bottom + code += Op.POP * 28 + + # Store bottom value + code += Op.PUSH1(1) + Op.SSTORE # bottom = 1 + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 2, # top = 2 (unchanged) + 1: 1, # bottom = 1 (swapped from position 2) + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_vector_exchange_invalid_0x52( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test vector: e852 [INVALID_EXCHANGE, MSTORE]. + + EXCHANGE with immediate 0x52 (82 decimal) is in the invalid + range (82-127). Execution should abort with exceptional halt. + """ + sender = pre.fund_eoa() + + # Push enough items on stack for any potential operation + code = Bytecode() + for i in range(30): + code += Op.PUSH1(i) + + # EXCHANGE with invalid immediate 0x52 - should abort + # Hex: e8 52 + code += Op.EXCHANGE[b"\x52"] + + # This would be MSTORE if we got here (0x52 = MSTORE opcode) + code += Op.MSTORE + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should fail, storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "eip8024_opcode,stack_items", + [ + pytest.param(Op.DUPN, 145, id="dupn"), + pytest.param(Op.SWAPN, 146, id="swapn"), + pytest.param(Op.EXCHANGE, 17, id="exchange"), + ], +) +def test_eip_vector_end_of_code( + pre: Alloc, + state_test: StateTestFiller, + eip8024_opcode: Op, + stack_items: int, +) -> None: + """ + Test EIP-8024 opcodes at end of code (no immediate byte). + + When an opcode appears at end of code, code[pc+1] = 0 beyond end of code. + - DUPN: decode_single(0) = 145, needs 145 items on stack + - SWAPN: decode_single(0) = 145, needs 146 items on stack + - EXCHANGE: decode_pair(0) = (9, 16), needs 17 items on stack + + Store a marker before the opcode to verify the transaction succeeded, + since adding any opcode after would make that opcode byte the immediate. + """ + sender = pre.fund_eoa() + marker_value = 0x42 + + code = ( + # store marker for verification + Op.SSTORE(0, marker_value) + # push minimum required stack items for the opcode + + Op.PUSH0 * stack_items + # end-of-code EIP-8024 opcode + + eip8024_opcode + ) + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # verify marker was stored (tx succeeded) + post = {contract_address: Account(storage={0: marker_value})} + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/test_endofcode_underflow.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_endofcode_underflow.py new file mode 100644 index 00000000000..b07d8622bbc --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_endofcode_underflow.py @@ -0,0 +1,79 @@ +""" +EIP-8024 end-of-code stack underflow regression tests. + +When DUPN/SWAPN/EXCHANGE is the last byte of code, the missing immediate +byte decodes to `0` per EIP-8024, and the opcode must still execute with +that zero-decoded immediate. When the stack is short of the resulting +required depth, execution must halt with stack underflow — clients must +not treat the missing immediate as a graceful STOP. + +See: +- EIP-8024: https://eips.ethereum.org/EIPS/eip-8024 +- Bounty: https://github.com/ethereum-bounty/nethermind/issues/12 +- Fix: https://github.com/NethermindEth/nethermind/pull/11178 +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Op, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_8024 + +REFERENCE_SPEC_GIT_PATH = ref_spec_8024.git_path +REFERENCE_SPEC_VERSION = ref_spec_8024.version + +pytestmark = pytest.mark.valid_from("EIP8024") + + +@pytest.mark.parametrize( + "eip8024_opcode,pushed_items", + [ + # DUPN: decode_single(0) = 145, needs 145 items — push 144. + pytest.param(Op.DUPN, 144, id="dupn"), + # SWAPN: decode_single(0) = 145, needs 146 items — push 145. + pytest.param(Op.SWAPN, 145, id="swapn"), + # EXCHANGE: decode_pair(0) = (9, 16), needs 17 items — push 16. + pytest.param(Op.EXCHANGE, 16, id="exchange"), + ], +) +def test_end_of_code_stack_underflow( + pre: Alloc, + state_test: StateTestFiller, + eip8024_opcode: Op, + pushed_items: int, +) -> None: + """ + Test EIP-8024 opcodes at end of code with one fewer stack item than + required by the zero-decoded immediate. + + Per EIP-8024, `code[pc + 1]` evaluates to `0` when beyond end of code. + The opcode must still execute and, with insufficient stack depth for + the decoded immediate, must halt with stack underflow. + + A buggy implementation that treats the missing immediate as an + implicit STOP would incorrectly succeed and persist the marker + stored before the opcode. + """ + sender = pre.fund_eoa() + marker_value = 0x42 + + code = ( + # store marker that must not persist if the opcode underflows + Op.SSTORE(0, marker_value) + # one fewer item than the zero-decoded immediate requires + + Op.PUSH0 * pushed_items + # end-of-code EIP-8024 opcode, no immediate byte + + eip8024_opcode + ) + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction must fail (stack underflow), leaving storage untouched. + post = {contract_address: Account(storage={})} + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py new file mode 100644 index 00000000000..78016b78ee2 --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py @@ -0,0 +1,444 @@ +""" +EXCHANGE instruction tests. + +Tests for EXCHANGE instruction in +[EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Bytecode, + Fork, + Op, + StateTestFiller, + Transaction, +) + +from .spec import decode_pair, ref_spec_8024 + +REFERENCE_SPEC_GIT_PATH = ref_spec_8024.git_path +REFERENCE_SPEC_VERSION = ref_spec_8024.version + +pytestmark = pytest.mark.valid_from("EIP8024") + + +@pytest.mark.parametrize( + "n,m", + [ + (1, 2), # Swap positions 2 and 3 + (1, 16), # Swap positions 2 and 17 + (1, 29), # Swap positions 2 and 30 (n + m = 30) + (5, 10), # Swap positions 6 and 11 + (13, 17), # Swap positions 14 and 18 (n + m = 30) + (14, 16), # Swap positions 15 and 17 (n + m = 30) + ], + ids=lambda x: f"{x}", +) +def test_exchange_basic( + n: int, + m: int, + pre: Alloc, + fork: Fork, + state_test: StateTestFiller, +) -> None: + """Test EXCHANGE with various n and m values.""" + sender = pre.fund_eoa() + + # EXCHANGE with decoded (n, m) swaps position (n+1) with position (m+1) + stack_height = m + 1 # Need at least m+1 items + value_at_n_plus_1 = 0xAAAA + value_at_m_plus_1 = 0xBBBB + + # Build stack with known values at swap positions (n+1) and (m+1) + code = Bytecode() + for i in range(stack_height): + # Stack position is 1-indexed from top, so i=0 is bottom + stack_pos = stack_height - i # Position from top (1-indexed) + if stack_pos == n + 1: + code += Op.PUSH2(value_at_n_plus_1) + elif stack_pos == m + 1: + code += Op.PUSH2(value_at_m_plus_1) + else: + code += Op.PUSH2(0x1000 + i) + + # Pass n and m directly - encoder will handle encoding + code += Op.EXCHANGE[n, m] + + # Store all stack values to verify the swap + for i in range(stack_height): + code += Op.PUSH1(i) + Op.SSTORE + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + gas_limit = 1_000_000 + if fork.is_eip_enabled(8037): + gas_limit = 5_000_000 + + tx = Transaction(to=contract_address, sender=sender, gas_limit=gas_limit) + + # Build expected storage + expected_storage = {} + for i in range(stack_height): + stack_pos = i + 1 # Position from top (1-indexed) + if stack_pos == n + 1: + expected_storage[i] = value_at_m_plus_1 # Now has value from m+1 + elif stack_pos == m + 1: + expected_storage[i] = value_at_n_plus_1 # Now has value from n+1 + else: + # Original value at this position + original_i = stack_height - stack_pos + expected_storage[i] = 0x1000 + original_i + + post = {contract_address: Account(storage=expected_storage)} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + [0, 1, 15, 78, 79, 80, 81, 128, 129, 200, 255], + ids=lambda x: f"exchange_imm_{x}", +) +def test_exchange_valid_immediates( + immediate: int, + pre: Alloc, + fork: Fork, + state_test: StateTestFiller, +) -> None: + """Test EXCHANGE with valid immediate values (0-81 and 128-255).""" + sender = pre.fund_eoa() + + # Decode the immediate to get the stack indices + # EXCHANGE with decoded (n, m) swaps position (n+1) with position (m+1) + n, m = decode_pair(immediate) + stack_height = m + 1 # Need at least m+1 items + value_at_n_plus_1 = 0xAAAA + value_at_m_plus_1 = 0xBBBB + + # Build stack + code = Bytecode() + for i in range(stack_height): + stack_pos = stack_height - i + if stack_pos == n + 1: + code += Op.PUSH2(value_at_n_plus_1) + elif stack_pos == m + 1: + code += Op.PUSH2(value_at_m_plus_1) + else: + code += Op.PUSH2(0x1000 + i) + + # Pass immediate as bytes (raw immediate byte for testing) + code += Op.EXCHANGE[immediate.to_bytes(1, "big")] + + # Store the swapped values + for i in range(stack_height): + code += Op.PUSH1(i) + Op.SSTORE + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + gas_limit = 1_000_000 + if fork.is_eip_enabled(8037): + gas_limit = 5_000_000 + + tx = Transaction(to=contract_address, sender=sender, gas_limit=gas_limit) + + # Build expected storage + expected_storage = {} + for i in range(stack_height): + stack_pos = i + 1 + if stack_pos == n + 1: + expected_storage[i] = value_at_m_plus_1 + elif stack_pos == m + 1: + expected_storage[i] = value_at_n_plus_1 + else: + original_i = stack_height - stack_pos + expected_storage[i] = 0x1000 + original_i + + post = {contract_address: Account(storage=expected_storage)} + + state_test(pre=pre, post=post, tx=tx) + + +def test_exchange_preserves_other_items( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test EXCHANGE only swaps specified items, leaving others unchanged.""" + sender = pre.fund_eoa() + + # Use n=1, m=5 - EXCHANGE swaps positions (n+1)=2 and (m+1)=6 + n, m = 1, 5 + + # Create a stack with 6 distinct values + code = Bytecode() + code += Op.PUSH2(0x1111) # Position 6 from top (will be swapped) + code += Op.PUSH2(0x2222) # Position 5 from top + code += Op.PUSH2(0x3333) # Position 4 from top + code += Op.PUSH2(0x4444) # Position 3 from top + code += Op.PUSH2(0x5555) # Position 2 from top (will be swapped) + code += Op.PUSH2(0x6666) # Position 1 (top) + + # EXCHANGE swaps position 2 with position 6 + # Pass n and m directly - encoder will handle encoding + code += Op.EXCHANGE[n, m] + + # Store all values + code += Op.PUSH1(0) + Op.SSTORE # Position 1 (0x6666, unchanged) + code += Op.PUSH1(1) + Op.SSTORE # Position 2 (was 0x1111, swapped from 6) + code += Op.PUSH1(2) + Op.SSTORE # Position 3 (0x4444, unchanged) + code += Op.PUSH1(3) + Op.SSTORE # Position 4 (0x3333, unchanged) + code += Op.PUSH1(4) + Op.SSTORE # Position 5 (0x2222, unchanged) + code += Op.PUSH1(5) + Op.SSTORE # Position 6 (was 0x5555, swapped from 2) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 0x6666, # Position 1 unchanged + 1: 0x1111, # Was at position 6, now at position 2 + 2: 0x4444, # Position 3 unchanged + 3: 0x3333, # Position 4 unchanged + 4: 0x2222, # Position 5 unchanged + 5: 0x5555, # Was at position 2, now at position 6 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + # Boundaries of both valid ranges (0x00, 0x51, 0x80, 0xFF) + [0, 78, 79, 80, 81, 128, 129, 255], + ids=lambda x: f"underflow_imm_{x}", +) +def test_exchange_stack_underflow( + immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test EXCHANGE causes transaction failure on stack underflow.""" + sender = pre.fund_eoa() + + # EXCHANGE needs m+1 items. Push one less to trigger underflow. + n, m = decode_pair(immediate) + insufficient_depth = m # m+1 required, push only m + + code = Bytecode() + code += Op.SSTORE(0, 1) # Marker + + for i in range(insufficient_depth): + code += Op.PUSH1(i) + + code += Op.EXCHANGE[immediate.to_bytes(1, "big")] + code += Op.SSTORE(0, 2) # Should never execute + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should fail, contract storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_endofcode_behavior( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test EXCHANGE when the immediate byte is beyond the end of code. + + Per EIP-8024, code[pc + 1] evaluates to 0 if beyond the end of the code, + matching PUSH behavior. With immediate = 0, decode_pair(0) = (9, 16), so + EXCHANGE swaps positions 10 and 17. + + This test verifies the transaction succeeds (doesn't revert) when EXCHANGE + is the last byte of the code with no immediate byte following it. + """ + sender = pre.fund_eoa() + + # decode_pair(0) = (9, 16), which swaps positions 10 and 17 + # We need 17 items on the stack for this to succeed + stack_height = 17 + marker_value = 0x42 + + # Build code: store marker, push enough items, then EXCHANGE (no immediate) + code = Bytecode() + code += Op.PUSH1(marker_value) + Op.PUSH1(0) + Op.SSTORE # Store marker + + # Push 17 items to stack so EXCHANGE with implicit imm=0 succeeds + for i in range(stack_height): + code += Op.PUSH1(i) + + # Add just the EXCHANGE opcode without immediate byte + # After EXCHANGE, pc += 2 goes beyond code, causing implicit STOP + code += Op.EXCHANGE # no immediate + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # If tx succeeds, storage[0] = marker_value + # Bad implementation would revert and have empty storage + post = {contract_address: Account(storage={0: marker_value})} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + [ + # valid immediates (0-81 / 128-255): skipped during JUMPDEST + # analysis, not reachable as jump targets + 0x00, + 0x4F, # 79 + 0x50, # 80 — POP (valid for EXCHANGE) + 0x51, # 81 — MLOAD (valid for EXCHANGE) + # invalid immediates (82-127): not skipped during JUMPDEST + # analysis, only 0x5B (91) is a JUMPDEST + 0x52, # 82 — MSTORE (first invalid immediate) + 0x5A, # 90 — GAS (invalid immediate) + 0x5B, # 91 — JUMPDEST, only case where jump succeeds + 0x5C, # 92 — TLOAD (invalid immediate) + 0x60, # 96 — PUSH1 (invalid immediate) + 0x7F, # 127 — PUSH32 (last invalid immediate) + # valid immediates again (128-255) + 0x80, # 128 + 0xFF, # 255 + ], + ids=lambda x: f"imm_0x{x:02x}", +) +def test_exchange_jump_to_immediate_byte( + immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test jumping to EXCHANGE immediate byte position. + + Valid immediates are skipped (can't jump to them). + Invalid immediates are not skipped - only 0x5B (JUMPDEST) allows jumping. + """ + sender = pre.fund_eoa() + + # Bytecode: PUSH1(4) JUMP EXCHANGE[imm] - position 4 is the immediate byte + code = Bytecode() + code += Op.PUSH1(4) + code += Op.JUMP + code += Op.EXCHANGE[immediate.to_bytes(1, "big")] + + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + if immediate == 0x5B: # JUMPDEST - only case where jump succeeds + post = {contract_address: Account(storage={0: 0x42})} + else: + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_exchange_with_push_sequence( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test EXCHANGE swapping positions 10 and 17 with a push sequence. + + Build 17 stack items with markers at positions 10 and 17. + EXCHANGE[0x00]: decode_pair(0) = (9, 16), swaps positions 10 and 17. + """ + sender = pre.fund_eoa() + + # Build 17 items with markers at positions 10 and 17 + code = Bytecode() + for i in range(17): + stack_pos = 17 - i # Position from top (1-indexed) + if stack_pos == 10: + code += Op.PUSH2(0xAAAA) + elif stack_pos == 17: + code += Op.PUSH2(0xBBBB) + else: + code += Op.PUSH1(0) + + # EXCHANGE with immediate 0 (decode_pair(0) = (9, 16)) + # swaps pos 10 and 17 + code += Op.EXCHANGE[b"\x00"] + + # Store all stack values to verify + for i in range(17): + code += Op.PUSH1(i) + Op.SSTORE + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Expected: position 9 has 0xBBBB (from pos 17), position 16 has + # 0xAAAA (from pos 10), rest = 0 + expected_storage = {} + for i in range(17): + stack_pos = i + 1 # 1-indexed position from top + if stack_pos == 10: + expected_storage[i] = 0xBBBB # Swapped from position 17 + elif stack_pos == 17: + expected_storage[i] = 0xAAAA # Swapped from position 10 + else: + expected_storage[i] = 0 + + post = {contract_address: Account(storage=expected_storage)} + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + range(82, 128), # Forbidden range: 0x52-0x7F + ids=lambda x: f"imm_{x}", +) +def test_exchange_invalid_immediate_aborts( + immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test EXCHANGE aborts with invalid immediates (82-127). + + This range is forbidden because it overlaps with JUMPDEST and PUSH opcodes. + """ + sender = pre.fund_eoa() + + code = Bytecode() + code += Op.SSTORE(0, 1) # Marker + + # Push 30 items (max needed for any valid EXCHANGE) + for i in range(30): + code += Op.PUSH1(i) + + code += Op.EXCHANGE[immediate.to_bytes(1, "big")] + code += Op.SSTORE(0, 2) # Should never execute + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Execution aborted, transaction reverts + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/test_pc_advancement.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_pc_advancement.py new file mode 100644 index 00000000000..b98cf813e44 --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_pc_advancement.py @@ -0,0 +1,314 @@ +""" +Program Counter (PC) advancement tests for EIP-8024 opcodes. + +Tests that verify DUPN, SWAPN, and EXCHANGE correctly advance the PC by 2 bytes +(opcode + immediate byte) as specified in +[EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Bytecode, + Op, + StateTestFiller, + Transaction, +) + +from .spec import ref_spec_8024 + +REFERENCE_SPEC_GIT_PATH = ref_spec_8024.git_path +REFERENCE_SPEC_VERSION = ref_spec_8024.version + +pytestmark = pytest.mark.valid_from("EIP8024") + + +def test_dupn_pc_advances_by_2( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Verify PC advances by 2 after DUPN (opcode + immediate byte). + + Tests that DUPN consumes the immediate byte and advances PC correctly. + """ + sender = pre.fund_eoa() + + code = Bytecode() + + # Push 17 values so DUPN[17] will work + for i in range(17): + code += Op.PUSH1(i) + + # Capture PC before DUPN and store it + code += Op.PC + code += Op.PUSH1(1) + Op.SSTORE # Store PC_before at key 1 + + # Execute DUPN - should advance PC by 2 (opcode + immediate) + code += Op.DUPN[17] + + # Capture PC after DUPN and store it + code += Op.PC + code += Op.PUSH1(2) + Op.SSTORE # Store PC_after at key 2 + + # Calculate difference: get both values and subtract + code += Op.PUSH1(1) + Op.SLOAD # Load PC_before + code += Op.PUSH1(2) + Op.SLOAD # Load PC_after + code += Op.SUB # PC_after - PC_before (SUB does: second - top) + + # Store the difference + code += Op.PUSH1(0) + Op.SSTORE + + # Clean up intermediate storage + code += Op.PUSH1(0) + Op.PUSH1(1) + Op.SSTORE # Clear key 1 + code += Op.PUSH1(0) + Op.PUSH1(2) + Op.SSTORE # Clear key 2 + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # The difference should be: + # PUSH1(2) + SSTORE(1) + DUPN(2) + PC(1) = 6 + # Note: Keys 1 and 2 are used for intermediate storage + post = { + contract_address: Account( + storage={ + 0: 6, # PC_after - PC_before (the main result) + # Keys 1 and 2 contain PC_before and PC_after for debugging + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_swapn_pc_advances_by_2( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Verify PC advances by 2 after SWAPN (opcode + immediate byte). + + Tests that SWAPN consumes the immediate byte and advances PC correctly. + """ + sender = pre.fund_eoa() + + code = Bytecode() + + # Push 18 values so SWAPN[17] will work (needs 18 items on stack) + for i in range(18): + code += Op.PUSH1(i) + + # Capture PC before SWAPN and store it + code += Op.PC + code += Op.PUSH1(1) + Op.SSTORE + + # Execute SWAPN - should advance PC by 2 (opcode + immediate) + code += Op.SWAPN[17] + + # Capture PC after SWAPN and store it + code += Op.PC + code += Op.PUSH1(2) + Op.SSTORE + + # Calculate difference + code += Op.PUSH1(1) + Op.SLOAD # Load PC_before + code += Op.PUSH1(2) + Op.SLOAD # Load PC_after + code += Op.SUB # PC_after - PC_before + + # Store the difference + code += Op.PUSH1(0) + Op.SSTORE + + # Clean up intermediate storage + code += Op.PUSH1(0) + Op.PUSH1(1) + Op.SSTORE # Clear key 1 + code += Op.PUSH1(0) + Op.PUSH1(2) + Op.SSTORE # Clear key 2 + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 6, # PUSH1(2) + SSTORE(1) + SWAPN(2) + PC(1) = 6 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_exchange_pc_advances_by_2( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Verify PC advances by 2 after EXCHANGE (opcode + immediate byte). + + Tests that EXCHANGE consumes the immediate byte and advances PC correctly. + """ + sender = pre.fund_eoa() + + code = Bytecode() + + # Push 6 values so EXCHANGE[1, 5] will work (needs 6 items on stack) + for i in range(6): + code += Op.PUSH1(i) + + # Capture PC before EXCHANGE and store it + code += Op.PC + code += Op.PUSH1(1) + Op.SSTORE + + # Execute EXCHANGE - should advance PC by 2 (opcode + immediate) + code += Op.EXCHANGE[1, 5] + + # Capture PC after EXCHANGE and store it + code += Op.PC + code += Op.PUSH1(2) + Op.SSTORE + + # Calculate difference + code += Op.PUSH1(1) + Op.SLOAD # Load PC_before + code += Op.PUSH1(2) + Op.SLOAD # Load PC_after + code += Op.SUB # PC_after - PC_before + + # Store the difference + code += Op.PUSH1(0) + Op.SSTORE + + # Clean up intermediate storage + code += Op.PUSH1(0) + Op.PUSH1(1) + Op.SSTORE # Clear key 1 + code += Op.PUSH1(0) + Op.PUSH1(2) + Op.SSTORE # Clear key 2 + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 6, # PUSH1(2) + SSTORE(1) + EXCHANGE(2) + PC(1) = 6 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_dupn_multiple_consecutive_pc_advancement( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Verify PC advances correctly with multiple consecutive DUPN opcodes. + + Tests that each DUPN independently advances PC by 2 bytes. + """ + sender = pre.fund_eoa() + + code = Bytecode() + + # Push enough values for multiple DUPNs + for i in range(20): + code += Op.PUSH1(i) + + # Capture initial PC + code += Op.PC + code += Op.PUSH1(1) + Op.SSTORE + + # Execute three consecutive DUPNs + code += Op.DUPN[17] + code += Op.DUPN[18] + code += Op.DUPN[19] + + # Capture final PC + code += Op.PC + code += Op.PUSH1(2) + Op.SSTORE + + # Calculate difference + code += Op.PUSH1(1) + Op.SLOAD # Load PC_before + code += Op.PUSH1(2) + Op.SLOAD # Load PC_after + code += Op.SUB # PC_after - PC_before + + # Store the difference + code += Op.PUSH1(0) + Op.SSTORE + + # Clean up intermediate storage + code += Op.PUSH1(0) + Op.PUSH1(1) + Op.SSTORE # Clear key 1 + code += Op.PUSH1(0) + Op.PUSH1(2) + Op.SSTORE # Clear key 2 + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: 10, # PUSH1(2) + SSTORE(1) + DUPN(2)*3 + PC(1) = 10 + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_mixed_opcodes_pc_advancement( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Verify PC advances correctly with mixed DUPN, SWAPN, and EXCHANGE opcodes. + + Tests that different EIP-8024 opcodes each correctly advance PC by 2 bytes. + """ + sender = pre.fund_eoa() + + code = Bytecode() + + # Push enough values for all operations + for i in range(30): + code += Op.PUSH1(i) + + # Capture initial PC + code += Op.PC + code += Op.PUSH1(1) + Op.SSTORE + + # Execute one of each opcode + code += Op.DUPN[17] + code += Op.SWAPN[18] + code += Op.EXCHANGE[1, 5] + + # Capture final PC + code += Op.PC + code += Op.PUSH1(2) + Op.SSTORE + + # Calculate difference + code += Op.PUSH1(1) + Op.SLOAD # Load PC_before + code += Op.PUSH1(2) + Op.SLOAD # Load PC_after + code += Op.SUB # PC_after - PC_before + + # Store the difference + code += Op.PUSH1(0) + Op.SSTORE + + # Clean up intermediate storage + code += Op.PUSH1(0) + Op.PUSH1(1) + Op.SSTORE # Clear key 1 + code += Op.PUSH1(0) + Op.PUSH1(2) + Op.SSTORE # Clear key 2 + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + # PUSH1(2) + SSTORE(1) + DUPN(2) + SWAPN(2) + # + EXCHANGE(2) + PC(1) = 10 + 0: 10, + } + ) + } + + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py new file mode 100644 index 00000000000..d471d757f93 --- /dev/null +++ b/tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py @@ -0,0 +1,382 @@ +""" +SWAPN instruction tests. + +Tests for SWAPN instruction in +[EIP-8024: Stack Access Instructions](https://eips.ethereum.org/EIPS/eip-8024). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Bytecode, + Op, + StateTestFiller, + Transaction, +) + +from .spec import decode_single, ref_spec_8024 + +REFERENCE_SPEC_GIT_PATH = ref_spec_8024.git_path +REFERENCE_SPEC_VERSION = ref_spec_8024.version + +pytestmark = pytest.mark.valid_from("EIP8024") + + +@pytest.mark.parametrize( + "stack_index", + [17, 18, 32, 64, 107, 108, 200, 235], + ids=lambda x: f"swapn_stack_{x}", +) +def test_swapn_basic( + stack_index: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test SWAPN with various stack indices (17-235).""" + sender = pre.fund_eoa() + + # SWAPN with decoded value n swaps position 1 with position (n+1) + # So we need stack_height = stack_index + 1 items + stack_height = stack_index + 1 + top_value = 0xAAAA + swap_target_value = 0xBBBB + + # Build stack with known values at top and swap position (n+1) + code = Bytecode() + + # First push ends up at position (stack_index+1) from top + code += Op.PUSH2(swap_target_value) + + # Pushes in-between + for i in range(1, stack_height - 1): + code += Op.PUSH2(0x1000 + i) + + # Last push ends up at top + code += Op.PUSH2(top_value) + + # Pass stack index directly - encoder will handle encoding + code += Op.SWAPN[stack_index] + + # Store both swapped values to verify + code += Op.PUSH1(0) + Op.SSTORE # New top (was swap_target_value) + + # Pop intermediate values to get to the swapped position + for _ in range(stack_index - 1): + code += Op.POP + + code += Op.PUSH1(1) + Op.SSTORE # New position (was top_value) + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + post = { + contract_address: Account( + storage={ + 0: swap_target_value, # Top now has the swapped value + 1: top_value, # Position (stack_index+1) now has original top + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.parametrize( + "immediate", + [0, 45, 90, 128, 200, 255], + ids=lambda x: f"swapn_imm_{x}", +) +def test_swapn_valid_immediates( + immediate: int, + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test SWAPN with valid immediate values (0-90 and 128-255).""" + sender = pre.fund_eoa() + + # Decode the immediate to get the stack index + # SWAPN with decoded value n swaps position 1 with position (n+1) + stack_index = decode_single(immediate) + stack_height = stack_index + 1 + top_value = 0xAAAA + swap_target_value = 0xBBBB + + # Build stack + code = Bytecode() + + # First push ends up at position (stack_index+1) from top + code += Op.PUSH2(swap_target_value) + + # Pushes in-between + for i in range(1, stack_height - 1): + code += Op.PUSH2(0x1000 + i) + + # Last push ends up at top + code += Op.PUSH2(top_value) + + # Pass immediate as bytes (raw immediate byte for testing) + code += Op.SWAPN[immediate.to_bytes(1, "big")] + + # Store the new top value + code += Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=10_000_000) + + post = { + contract_address: Account( + storage={ + 0: swap_target_value, # Top now has the swapped value + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + +def test_swapn_preserves_other_stack_items( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test SWAPN only swaps the specified items, leaving others unchanged.""" + sender = pre.fund_eoa() + + # Use stack index 17 (smallest valid) + # SWAPN with n=17 swaps position 1 with position 18, so need 18 items + stack_index = 17 + stack_height = stack_index + 1 # Need 18 items + + # Create a stack with 18 distinct values + code = Bytecode() + for i in range(stack_height): + code += Op.PUSH2(0x1000 + i) + + # SWAPN swaps top (position 1) with position 18 + # Pass stack index directly - encoder will handle encoding + code += Op.SWAPN[stack_index] + + # Store all values to verify only the swapped ones changed + for i in range(stack_height): + code += Op.PUSH1(i) + Op.SSTORE + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # After swap: position 1 and position 18 are swapped + # Original stack (top to bottom): 0x1011, 0x1010, ..., 0x1001, 0x1000 + # After SWAPN[0]: 0x1000, 0x1010, ..., 0x1001, 0x1011 + expected_storage = {} + for i in range(stack_height): + if i == 0: + expected_storage[i] = 0x1000 # Was at bottom, now at top + elif i == stack_height - 1: + expected_storage[i] = 0x1011 # Was at top, now at bottom + else: + expected_storage[i] = 0x1000 + (stack_height - 1 - i) + + post = {contract_address: Account(storage=expected_storage)} + + state_test(pre=pre, post=post, tx=tx) + + +def test_swapn_stack_underflow( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """Test SWAPN causes transaction failure on stack underflow.""" + sender = pre.fund_eoa() + + # SWAPN with immediate 0x80 (n=17) swaps position 1 with position 18 + # Need 18 items, so push only 17 to trigger underflow + code = Bytecode() + for i in range(17): + code += Op.PUSH1(i) + # Pass immediate as bytes (raw immediate byte for testing) + # decode_single(0x80) = 17, needs 18 items but only 17 + code += Op.SWAPN[b"\x80"] + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction should fail, contract storage unchanged + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_endofcode_behavior( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test SWAPN when the immediate byte is beyond the end of code. + + Per EIP-8024, code[pc + 1] evaluates to 0 if beyond the end of the code, + matching PUSH behavior. With immediate = 0, decode_single(0) = 145, so + SWAPN swaps position 1 with position 146. + + This test verifies the transaction succeeds (doesn't revert) when SWAPN + is the last byte of the code with no immediate byte following it. + """ + sender = pre.fund_eoa() + + # decode_single(0) = 145, which swaps position 1 with position 146 + # We need 146 items on the stack for this to succeed + stack_height = 146 + marker_value = 0x42 + + # Build code: store marker, push enough items, then SWAPN (no immediate) + code = Bytecode() + code += Op.PUSH1(marker_value) + Op.PUSH1(0) + Op.SSTORE # Store marker + + # Push 146 items to stack so SWAPN with implicit imm=0 succeeds + for i in range(stack_height): + code += Op.PUSH1(i % 256) + + # Add just the SWAPN opcode without immediate byte + # After SWAPN, pc += 2 goes beyond code, causing implicit STOP + code += Op.SWAPN # no immediate + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # If tx succeeds, storage[0] = marker_value + # Bad implementation would revert and have empty storage + post = {contract_address: Account(storage={0: marker_value})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_swapn_jump_to_immediate_byte_0x5b_succeeds( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test that jumping to 0x5b after SWAPN succeeds (backward compat). + + Bytecode: PUSH1(4) JUMP SWAPN[0x5b] + Hex: 6004 56 e7 5b + Position 4 contains 0x5b which is an INVALID immediate for SWAPN. + Per EIP-8024, 0x5b is preserved as valid JUMPDEST for compatibility. + The SWAPN instruction is never executed due to the jump. + """ + sender = pre.fund_eoa() + + # Build code that jumps to 0x5b after SWAPN opcode + code = Bytecode() + code += Op.PUSH1(4) # Push jump target (position 4) + code += Op.JUMP # Jump to position 4 + # Pass as bytes (raw immediate byte for testing) + code += Op.SWAPN[b"\x5b"] # Position 3-4: SWAPN + 0x5b (invalid) + + # This SHOULD execute because 0x5b is a valid JUMPDEST + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction succeeds - 0x5b is preserved as valid JUMPDEST + post = {contract_address: Account(storage={0: 0x42})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_swapn_jump_to_valid_immediate_fails( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test jumping to a valid immediate byte fails. + + Bytecode: PUSH1(4) JUMP SWAPN[0x00] + Hex: 6004 56 e7 00 + Position 4 contains 0x00 which is a VALID immediate for SWAPN. + Valid immediates are skipped in JUMPDEST analysis, so jump fails. + """ + sender = pre.fund_eoa() + + # Build code that tries to jump to a valid immediate + code = Bytecode() + code += Op.PUSH1(4) # Push jump target (position 4) + code += Op.JUMP # Try to jump to position 4 + # Pass as bytes (raw immediate byte for testing) + code += Op.SWAPN[b"\x00"] # Position 3-4: SWAPN + 0x00 (valid) + + # This should never execute + code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Transaction fails - position 4 is a valid immediate, not JUMPDEST + post = {contract_address: Account(storage={})} + + state_test(pre=pre, post=post, tx=tx) + + +def test_swapn_with_dup1_and_push( + pre: Alloc, + state_test: StateTestFiller, +) -> None: + """ + Test SWAPN swapping top and bottom after building stack with DUP1. + + Stack layout: PUSH1(1) PUSH1(0) DUP1*15 PUSH1(2) SWAPN[0x80] + Before SWAPN: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + After SWAPN[0x80] (decode_single(0x80)=17, swaps pos 1 and 18): + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2] + Result: 18 stack items, top=1, bottom=2, rest=0 + """ + sender = pre.fund_eoa() + + # Build the stack: PUSH1(1), PUSH1(0), 15x DUP1, PUSH1(2) + code = Bytecode() + code += Op.PUSH1(1) # Position 18 after DUP1s and final PUSH1 + code += Op.PUSH1(0) + for _ in range(15): + code += Op.DUP1 + code += Op.PUSH1(2) # Top of stack (position 1) + + # Stack: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + # SWAPN with immediate 0x80 (decode_single(0x80)=17) swaps pos 1 and 18 + # Pass as bytes (raw immediate byte for testing) + code += Op.SWAPN[b"\x80"] + + # Store all stack values to verify + for i in range(18): + code += Op.PUSH1(i) + Op.SSTORE + + code += Op.STOP + + contract_address = pre.deploy_contract(code=code) + + tx = Transaction(to=contract_address, sender=sender, gas_limit=1_000_000) + + # Expected: top (position 0) = 1, bottom (position 17) = 2, rest = 0 + expected_storage = {} + for i in range(18): + if i == 0: + expected_storage[i] = 1 # Was at bottom, now at top + elif i == 17: + expected_storage[i] = 2 # Was at top, now at bottom + else: + expected_storage[i] = 0 # All middle values + + post = {contract_address: Account(storage=expected_storage)} + + state_test(pre=pre, post=post, tx=tx) diff --git a/tests/frontier/opcodes/test_all_opcodes.py b/tests/frontier/opcodes/test_all_opcodes.py index 774df19e4af..c13bb4f1563 100644 --- a/tests/frontier/opcodes/test_all_opcodes.py +++ b/tests/frontier/opcodes/test_all_opcodes.py @@ -81,9 +81,17 @@ def test_all_opcodes( valid_opcodes = set(fork.valid_opcodes()) all_opcodes = set(Opcode(i) for i in range(0xFF + 1)) for opcode in sorted(valid_opcodes | all_opcodes): + test_opcode: Opcode | Bytecode = opcode + if opcode.has_data_portion(): + if opcode in [Op.SWAPN, Op.DUPN]: + test_opcode = opcode[17] + elif opcode == Op.EXCHANGE: + test_opcode = opcode[1, 2] + else: + test_opcode = opcode[0] code_contract[opcode] = pre.deploy_contract( balance=10, - code=prepare_stack(opcode) + opcode + prepare_suffix(opcode), + code=prepare_stack(opcode) + test_opcode + prepare_suffix(opcode), storage={}, ) @@ -171,9 +179,11 @@ def test_stack_overflow( value_code_failed = 0xDEADBEEF value_code_worked = 1 + push_opcode = Op.PUSH0 if Op.PUSH0 in fork.valid_opcodes() else Op.PUSH1(0) + contract = pre.deploy_contract( code=Op.SSTORE(slot_code_worked, value_code_worked) - + Op.PUSH1(0) * pre_stack_items + + push_opcode * pre_stack_items + opcode + Op.STOP, storage={slot_code_worked: value_code_failed}, @@ -197,6 +207,72 @@ def test_stack_overflow( ) +def fork_opcodes_with_non_increasing_stack( + fork: Fork, +) -> Iterator[Op]: + """ + Yields opcodes which are valid for `fork` and decrease or leave static the + operand stack. + """ + for opcode in fork.valid_opcodes(): + if opcode.pushed_stack_items <= opcode.popped_stack_items: + if opcode not in [ + # Incompatible with this test: + Op.REVERT, # Reverts the storage required + Op.JUMP, # Tries to jump to non-jumpdest + Op.BLOCKHASH, # Incompatible with state_test + Op.SELFDESTRUCT, # selfdestructs the contract in old forks + ]: + yield opcode + + +@pytest.mark.parametrize_by_fork( + "opcode", fork_opcodes_with_non_increasing_stack +) +def test_max_stack( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + opcode: Op, + env: Environment, +) -> None: + """ + Test that opcodes that don't push more items than they pop from the + stack can operate when the stack is full. + """ + pre_stack_items = fork.max_stack_height() + slot_code_worked = 1 + value_code_failed = 0xDEADBEEF + value_code_worked = 1 + + push_opcode = Op.PUSH0 if Op.PUSH0 in fork.valid_opcodes() else Op.PUSH1(0) + + contract = pre.deploy_contract( + code=Op.SSTORE(slot_code_worked, value_code_worked) + + push_opcode * pre_stack_items + + opcode + + Op.STOP, + storage={slot_code_worked: value_code_failed}, + ) + gas_limit = 100_000 + if fork.is_eip_enabled(8037): + gas_limit = 500_000 + tx = Transaction( + gas_limit=gas_limit, + to=contract, + sender=pre.fund_eoa(), + protected=fork.supports_protected_txs(), + ) + expected_storage = {slot_code_worked: value_code_worked} + + state_test( + env=env, + pre=pre, + tx=tx, + post={contract: Account(storage=expected_storage)}, + ) + + def prepare_stack_constant_gas_oog(opcode: Opcode) -> Bytecode: """Prepare valid stack for opcode.""" if opcode == Op.JUMPI: @@ -241,6 +317,11 @@ def test_constant_gas( """Test that constant gas opcodes work as expected.""" # Using Op.GAS as salt to guarantee no address collision on CREATE2. create2_salt = Op.GAS if opcode == Op.CREATE2 else Bytecode() + if opcode.has_data_portion(): + if opcode in [Op.SWAPN, Op.DUPN]: + opcode = opcode[17] + else: + opcode = opcode[0] setup_code = ( Op.MLOAD(0) + Op.POP From 21507778e593c9172c3d91844b616b42c2dc4afb Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 19 May 2026 15:49:50 -0700 Subject: [PATCH 102/186] chore(spec-tool): check bpo forks in linter (#2803) --- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../bls12_381/bls12_381_g1.py | 4 +- .../bls12_381/bls12_381_g2.py | 4 +- .../lint/lints/glacier_forks_hygiene.py | 57 ++++++++++++++++++- vulture_whitelist.py | 1 + 16 files changed, 83 insertions(+), 31 deletions(-) diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index fa0d3ec4c2d..d1f63224a0c 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -58,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -138,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index a5b2be04018..2fd32313f89 100644 --- a/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/amsterdam/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -59,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -139,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index f77ff60a32c..d5681ee503b 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -55,7 +55,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -135,7 +135,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index b49ec065e7c..cc2d969dd86 100644 --- a/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo2/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -56,7 +56,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -136,7 +136,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index fa0d3ec4c2d..d1f63224a0c 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -58,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -138,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index a5b2be04018..2fd32313f89 100644 --- a/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo3/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -59,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -139,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index fa0d3ec4c2d..d1f63224a0c 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -58,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -138,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index a5b2be04018..2fd32313f89 100644 --- a/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo4/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -59,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -139,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index fa0d3ec4c2d..d1f63224a0c 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -58,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -138,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index a5b2be04018..2fd32313f89 100644 --- a/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/bpo5/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -59,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -139,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index fa0d3ec4c2d..d1f63224a0c 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -58,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -138,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index a5b2be04018..2fd32313f89 100644 --- a/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/osaka/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -59,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -139,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py index fa0d3ec4c2d..d1f63224a0c 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g1.py @@ -58,7 +58,7 @@ def bls12_g1_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) # OPERATION p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) @@ -138,7 +138,7 @@ def bls12_map_fp_to_g1(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) # OPERATION fp = int.from_bytes(data, "big") diff --git a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py index a5b2be04018..2fd32313f89 100644 --- a/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py +++ b/src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/bls12_381_g2.py @@ -59,7 +59,7 @@ def bls12_g2_add(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD) # OPERATION p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) @@ -139,7 +139,7 @@ def bls12_map_fp2_to_g2(evm: Evm) -> None: raise InvalidParameter("Invalid Input Length") # GAS - charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP)) + charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP) # OPERATION field_element = bytes_to_fq2(data) diff --git a/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py b/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py index f3d82b3943e..55d58c6a264 100644 --- a/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py +++ b/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py @@ -55,6 +55,14 @@ def __init__(self) -> None: "gray_glacier": 11400000, } + @staticmethod + def _needs_lint(fork_name: str) -> bool: + return ( + fork_name == "dao_fork" + or fork_name.endswith("_glacier") + or fork_name.startswith("bpo") + ) + def lint( self, forks: List[Hardfork], position: int ) -> Sequence[Diagnostic]: @@ -66,7 +74,7 @@ def lint( # Nothing to compare against! return [] - if fork_name != "dao_fork" and not fork_name.endswith("_glacier"): + if not self._needs_lint(fork_name): # Nothing to compare against or non-glacier fork! return [] @@ -139,9 +147,13 @@ def compare( ) continue - if item == "BOMB_DELAY_BLOCKS": + if fork_name.endswith("_glacier") and item == "BOMB_DELAY_BLOCKS": previous_item.value.value = self.delay_blocks[fork_name] + if fork_name.startswith("bpo"): + if item.startswith("GasCosts.BLOB_"): + continue + if not compare_ast(previous_item, current_item): add_diagnostic( diagnostics, @@ -237,7 +249,46 @@ def visit_ClassDef(self, klass: ast.ClassDef) -> None: """ Visit a class. """ - self._insert(klass.name, klass) + self.path.append(klass.name) + super().generic_visit(klass) + popped = self.path.pop() + assert popped == klass.name + + def visit_Name(self, node: ast.Name) -> None: + """ + Visit a name. + """ + self._insert(node.id, node) + + def visit_Attribute(self, node: ast.Attribute) -> None: + """ + Visit an attribute. + """ + self._insert(node.attr, node) + + def visit_Subscript(self, node: ast.Subscript) -> None: + """ + Visit a subscript. + """ + self.visit(node.value) + self.visit(node.slice) + + def visit_Pass(self, node: ast.Pass) -> None: + """ + Visit a pass. + """ + pass + + def visit_Tuple(self, node: ast.Tuple) -> None: + """ + Visit a tuple. + """ + for idx, child in enumerate(node.elts): + name = f"[{idx}]" + self.path.append(name) + self.visit(child) + popped = self.path.pop() + assert name == popped def visit_Assign(self, assign: ast.Assign) -> None: """ diff --git a/vulture_whitelist.py b/vulture_whitelist.py index 6f0d557c766..6b045fb9e8b 100644 --- a/vulture_whitelist.py +++ b/vulture_whitelist.py @@ -133,6 +133,7 @@ # src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py GlacierForksHygiene GlacierForksHygiene.visit_AnnAssign +GlacierForksHygiene.visit_Pass # src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py ImportHygiene From 42fb0f6aafee790ca427e45507501110cbbfcb3a Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Wed, 20 May 2026 01:39:24 -0700 Subject: [PATCH 103/186] fix(ci,tooling): skip code coverage of glacier/bpo/dao forks (#2886) --- pyproject.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 40fd1eef299..b0c10143486 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -298,8 +298,9 @@ markers = [ [tool.coverage.run] omit = [ - "*/ethereum/*_glacier/*", - "*/ethereum/dao_fork/*", + "*/ethereum/forks/*_glacier/*", + "*/ethereum/forks/dao_fork/*", + "*/ethereum/forks/bpo*/*", ] [tool.docc] From 76f336f440c8cf005877d7b1d17390789fcf7bab Mon Sep 17 00:00:00 2001 From: felix Date: Wed, 20 May 2026 14:02:52 +0200 Subject: [PATCH 104/186] chore(tests): create `spec.py` for EIP-7778 (#2887) --- .../spec.py | 24 +++++++++++++++++++ .../test_gas_accounting.py | 6 +++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 tests/amsterdam/eip7778_block_gas_accounting_without_refunds/spec.py diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/spec.py b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/spec.py new file mode 100644 index 00000000000..ed60bde819c --- /dev/null +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/spec.py @@ -0,0 +1,24 @@ +"""Defines EIP-7778 specification constants and functions.""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ReferenceSpec: + """Defines the reference spec version and git path.""" + + git_path: str + version: str + + +ref_spec_7778 = ReferenceSpec( + "EIPS/eip-7778.md", "ce17d00b8341032a946301944124c4a6013032d6" +) + + +@dataclass(frozen=True) +class Spec: + """ + Parameters from the EIP-7778 specifications as defined at + https://eips.ethereum.org/EIPS/eip-7778. + """ diff --git a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py index 058be9e2997..d1b9f9121af 100644 --- a/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py +++ b/tests/amsterdam/eip7778_block_gas_accounting_without_refunds/test_gas_accounting.py @@ -24,8 +24,10 @@ from execution_testing.base_types import HashInt from execution_testing.vm import Op -REFERENCE_SPEC_GIT_PATH = "EIPS/eip-7778.md" -REFERENCE_SPEC_VERSION = "ce17d00b8341032a946301944124c4a6013032d6" +from .spec import ref_spec_7778 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7778.git_path +REFERENCE_SPEC_VERSION = ref_spec_7778.version def build_refund_tx( From 561198dc81b19f09c806a2914e001cac55410bef Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 20 May 2026 17:46:33 +0530 Subject: [PATCH 105/186] feat: t8n tool changes for pre-merge forks (#26) --- .github/configs/feature.yaml | 4 +- .github/configs/fork-ranges.yaml | 2 +- .github/workflows/eest_hive_gnosis.yaml | 33 +-- .../eest_hive_gnosis_multi_client.yaml | 33 +-- .../eest_hive_gnosis_multi_client_until.yaml | 131 ++++++++++++ .github/workflows/eest_hive_matrix.yaml | 23 +- .github/workflows/test.yaml | 2 +- GNOSIS.md | 106 +++++++++- Justfile | 4 +- deposit_contract.bin | 1 - .../client_clis/clis/geth.py | 3 + .../client_clis/clis/nethermind.py | 7 +- .../client_clis/clis/reth.py | 3 +- .../execution_testing/fixtures/blockchain.py | 65 +++++- .../forks/contracts/block_reward_contract.bin | Bin 1008 -> 880 bytes .../forks/forks/eips/shanghai/eip_4895.py | 31 +++ .../execution_testing/forks/forks/forks.py | 66 +++--- .../src_contracts/block_reward_contract.sol | 52 +++-- .../src/execution_testing/specs/blockchain.py | 11 +- .../blockchain_london_invalid_filled.json | 4 +- .../blockchain_london_valid_filled.json | 4 +- ...kchain_shanghai_invalid_filled_engine.json | 76 ++++--- ...ockchain_shanghai_valid_filled_engine.json | 64 +++--- ...ncun_blockchain_test_engine_tx_type_0.json | 48 ++--- ...inid_cancun_blockchain_test_tx_type_0.json | 52 ++--- .../chainid_cancun_state_test_tx_type_0.json | 4 +- .../chainid_cancun_state_test_tx_type_1.json | 4 +- ...id_istanbul_blockchain_test_tx_type_0.json | 4 +- ...inid_london_blockchain_test_tx_type_0.json | 4 +- ...aris_blockchain_test_engine_tx_type_0.json | 52 ++--- .../chainid_paris_state_test_tx_type_0.json | 4 +- ...ghai_blockchain_test_engine_tx_type_0.json | 48 ++--- ...chainid_shanghai_state_test_tx_type_0.json | 4 +- .../fixtures/tx_simple_type_0_shanghai.json | 18 +- .../specs/tests/test_fixtures.py | 6 +- .../test_types/block_types.py | 8 + src/ethereum/forks/arrow_glacier/fork.py | 196 ++++++++++++----- .../forks/arrow_glacier/vm/interpreter.py | 6 +- src/ethereum/forks/berlin/fork.py | 181 +++++++++++----- src/ethereum/forks/berlin/vm/interpreter.py | 6 +- src/ethereum/forks/cancun/fork.py | 48 +++-- src/ethereum/forks/constantinople/fork.py | 178 +++++++++++----- .../forks/constantinople/vm/interpreter.py | 6 +- src/ethereum/forks/gray_glacier/fork.py | 196 ++++++++++++----- .../forks/gray_glacier/vm/interpreter.py | 6 +- src/ethereum/forks/istanbul/fork.py | 178 +++++++++++----- src/ethereum/forks/istanbul/vm/interpreter.py | 6 +- src/ethereum/forks/london/fork.py | 198 +++++++++++++----- src/ethereum/forks/london/vm/interpreter.py | 6 +- src/ethereum/forks/muir_glacier/fork.py | 178 +++++++++++----- .../forks/muir_glacier/vm/interpreter.py | 6 +- src/ethereum/forks/osaka/fork.py | 43 ++-- src/ethereum/forks/paris/fork.py | 33 +-- src/ethereum/forks/prague/fork.py | 43 ++-- src/ethereum/forks/shanghai/fork.py | 47 +++-- .../evm_tools/t8n/__init__.py | 5 +- .../block_rewards/__init__.py | 0 .../block_rewards/conftest.py | 0 .../block_rewards/test_block_rewards.py | 88 +++++++- tests/frontier/scenarios/test_scenarios.py | 10 +- tests/london/fee_collection/__init__.py | 1 + .../fee_collection/test_fee_collection.py | 138 ++++++++++++ tests/london/system_address_state/__init__.py | 1 + .../test_system_address_in_state.py | 140 +++++++++++++ .../eip4895_withdrawals/test_withdrawals.py | 6 +- 65 files changed, 2166 insertions(+), 765 deletions(-) create mode 100644 .github/workflows/eest_hive_gnosis_multi_client_until.yaml delete mode 100644 deposit_contract.bin rename tests/{paris => constantinople}/block_rewards/__init__.py (100%) rename tests/{paris => constantinople}/block_rewards/conftest.py (100%) rename tests/{paris => constantinople}/block_rewards/test_block_rewards.py (65%) create mode 100644 tests/london/fee_collection/__init__.py create mode 100644 tests/london/fee_collection/test_fee_collection.py create mode 100644 tests/london/system_address_state/__init__.py create mode 100644 tests/london/system_address_state/test_system_address_in_state.py diff --git a/.github/configs/feature.yaml b/.github/configs/feature.yaml index 77091ed6c72..2cb3430119d 100644 --- a/.github/configs/feature.yaml +++ b/.github/configs/feature.yaml @@ -1,7 +1,7 @@ -# Unless filling for special features, all features should fill for previous forks (starting from Paris) too +# Unless filling for special features, all features should fill for previous forks (starting from ConstantinopleFix) too mainnet: evm-type: eels - fill-params: --from=Paris --until=Osaka --generate-all-formats + fill-params: --from=ConstantinopleFix --until=Osaka --generate-all-formats benchmark: evm-type: benchmark diff --git a/.github/configs/fork-ranges.yaml b/.github/configs/fork-ranges.yaml index 8609e760fbc..dcb4ea65ba1 100644 --- a/.github/configs/fork-ranges.yaml +++ b/.github/configs/fork-ranges.yaml @@ -2,7 +2,7 @@ # Features using --until are automatically split using applicable ranges. # Features using --fork (single fork) are never split. - label: pre-cancun - from: Paris + from: ConstantinopleFix until: Shanghai - label: cancun from: Cancun diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 0f276d9434e..042d05b04da 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -12,10 +12,10 @@ on: required: true default: "nethermind-gnosis" test_dir: - description: "Test directory to execute" - required: true - default: "osaka" - + description: "Optional test directory under tests/ (e.g. osaka). Leave empty to fill all tests." + required: false + default: "" + jobs: test: runs-on: ubuntu-latest @@ -37,18 +37,19 @@ jobs: run: | cd hive go install ./... - cd .. - + - name: Start Hive in background run: | cd hive - ~/go/bin/hive --dev --client "${{ github.event.inputs.client }}" \ + ~/go/bin/hive \ + --dev \ + --client "${{ github.event.inputs.client }}" \ --dev.addr=127.0.0.1:3000 \ --loglevel=5 \ --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - + - name: Install wait-on utility run: npm install -g wait-on @@ -61,7 +62,7 @@ jobs: run: | curl -LsSf https://astral.sh/uv/install.sh | sh echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # uv installs here on Ubuntu - + - name: Bootstrap Python and install deps run: | pip install uv @@ -70,17 +71,21 @@ jobs: uv sync --all-extras uv pip install solc-select uv run solc-select use 0.8.24 --always-install - + - name: Run fill run: | - uv run fill "tests/${{ github.event.inputs.test_dir }}" --fork "${{ github.event.inputs.fork }}" --clean -v -x + uv run fill "tests/${{ github.event.inputs.test_dir }}" --fork "${{ github.event.inputs.fork }}" --generate-all-formats --clean -v -x - - name: Run test against client + - name: Run consume against ${{ github.event.inputs.client }} env: HIVE_SIMULATOR: http://127.0.0.1:3000 run: | - FORK_LOWER=$(echo "${{ github.event.inputs.fork }}" | tr '[:upper:]' '[:lower:]') - uv run consume engine -v --input "fixtures/blockchain_tests_engine/for_$FORK_LOWER" + if [ -d "fixtures/blockchain_tests_engine" ]; then + uv run consume engine -v --input fixtures/blockchain_tests_engine/ + fi + if [ -d "fixtures/blockchain_tests" ]; then + uv run consume rlp -v --input fixtures/blockchain_tests/ + fi - name: Upload Hive logs if: always() diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index f5ca06405b7..a20fa60c143 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -8,15 +8,15 @@ on: required: true default: "Osaka" test_dir: - description: "Test directory to execute" - required: true - default: "osaka" - + description: "Optional test directory under tests/ (e.g. osaka). Leave empty to fill all tests." + required: false + default: "" + jobs: fill: name: Generate Fixtures runs-on: ubuntu-latest - + steps: - name: Checkout the repository uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 @@ -25,7 +25,7 @@ jobs: run: | curl -LsSf https://astral.sh/uv/install.sh | sh echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - + - name: Bootstrap Python and install deps run: | uv python install 3.11 @@ -33,16 +33,16 @@ jobs: uv sync --all-extras uv pip install solc-select uv run solc-select use 0.8.24 --always-install - + - name: Run fill to generate fixtures run: | - uv run fill tests/${{ github.event.inputs.test_dir }} --fork ${{ github.event.inputs.fork }} --clean -v -x + uv run fill "tests/${{ github.event.inputs.test_dir }}" --fork ${{ github.event.inputs.fork }} --generate-all-formats --clean -v -x - name: Upload generated fixtures uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with: name: test-fixtures - path: fixtures/blockchain_tests_engine/ + path: fixtures/ test: name: ${{ matrix.client }} @@ -65,7 +65,7 @@ jobs: uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: test-fixtures - path: fixtures/blockchain_tests_engine/ + path: fixtures/ - name: Clone Hive repository run: git clone -b master https://github.com/gnosischain/hive.git @@ -80,8 +80,7 @@ jobs: run: | cd hive go install ./... - cd .. - + - name: Start Hive in background run: | cd hive @@ -104,7 +103,7 @@ jobs: run: | curl -LsSf https://astral.sh/uv/install.sh | sh echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - + - name: Bootstrap Python and install deps run: | uv python install 3.11 @@ -115,8 +114,12 @@ jobs: env: HIVE_SIMULATOR: http://127.0.0.1:3000 run: | - FORK_LOWER=$(echo "${{ github.event.inputs.fork }}" | tr '[:upper:]' '[:lower:]') - uv run consume engine -v --input "fixtures/blockchain_tests_engine/for_$FORK_LOWER" + if [ -d "fixtures/blockchain_tests_engine" ]; then + uv run consume engine -v --input fixtures/blockchain_tests_engine/ + fi + if [ -d "fixtures/blockchain_tests" ]; then + uv run consume rlp -v --input fixtures/blockchain_tests/ + fi - name: Upload Hive logs for ${{ matrix.client }} if: always() diff --git a/.github/workflows/eest_hive_gnosis_multi_client_until.yaml b/.github/workflows/eest_hive_gnosis_multi_client_until.yaml new file mode 100644 index 00000000000..a6b1afadc36 --- /dev/null +++ b/.github/workflows/eest_hive_gnosis_multi_client_until.yaml @@ -0,0 +1,131 @@ +name: EEST → Hive (Multi-Client, --until) + +on: + workflow_dispatch: + inputs: + until_fork: + description: "Fork passed to --until" + required: true + default: "Osaka" + test_dir: + description: "Optional test directory under tests/ (e.g. osaka). Leave empty to fill all tests." + required: false + default: "" + +jobs: + fill: + name: Generate Fixtures (--until) + runs-on: ubuntu-latest + + steps: + - name: Checkout the repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 + + - name: Install uv + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + + - name: Bootstrap Python and install deps + run: | + uv python install 3.11 + uv python pin 3.11 + uv sync --all-extras + uv pip install solc-select + uv run solc-select use 0.8.24 --always-install + + - name: Run fill to generate fixtures + run: | + uv run fill "tests/${{ github.event.inputs.test_dir }}" --from=ConstantinopleFix --until=${{ github.event.inputs.until_fork }} --generate-all-formats --clean -v -x + + - name: Upload generated fixtures + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: + name: test-fixtures + path: fixtures/ + + test: + name: ${{ matrix.client }} + runs-on: ubuntu-latest + needs: fill + strategy: + fail-fast: false + matrix: + client: + - reth-gnosis + - go-ethereum-gnosis + - nethermind-gnosis + - erigon-gnosis + + steps: + - name: Checkout the repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 + + - name: Download fixtures from fill job + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: test-fixtures + path: fixtures/ + + - name: Clone Hive repository + run: git clone -b master https://github.com/gnosischain/hive.git + + - name: Install Go (for Hive) + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version: ">=1.24" + cache-dependency-path: hive/go.sum + + - name: Build and install Hive + run: | + cd hive + go install ./... + + - name: Start Hive in background + run: | + cd hive + ~/go/bin/hive \ + --dev \ + --client "${{ matrix.client }}" \ + --dev.addr=127.0.0.1:3000 \ + --loglevel=5 \ + --sim.loglevel=5 \ + --docker.output \ + --docker.pull > hive.log 2>&1 & + + - name: Install wait-on utility + run: npm install -g wait-on + + - name: Wait for Hive to listen on port 3000 + run: | + set -xe + npx wait-on --timeout 600000 tcp:127.0.0.1:3000 + + - name: Install uv + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + + - name: Bootstrap Python and install deps + run: | + uv python install 3.11 + uv python pin 3.11 + uv sync --all-extras + + - name: Run consume against ${{ matrix.client }} + env: + HIVE_SIMULATOR: http://127.0.0.1:3000 + run: | + if [ -d "fixtures/blockchain_tests_engine" ]; then + uv run consume engine -v --input fixtures/blockchain_tests_engine/ + fi + if [ -d "fixtures/blockchain_tests" ]; then + uv run consume rlp -v --input fixtures/blockchain_tests/ + fi + + - name: Upload Hive logs for ${{ matrix.client }} + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: + name: hive-log-${{ matrix.client }} + path: hive/hive.log diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index 874725347ba..1d313420c1b 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -6,7 +6,7 @@ on: fork: description: "Fork passed to --fork" required: true - default: "Prague" + default: "Osaka" client: description: "Client passed to --client" required: true @@ -14,8 +14,8 @@ on: test_dirs: description: "Comma-separated list of EIP numbers or directory names" required: true - default: "prague" - + default: "osaka" + jobs: # Prepare matrix from input prepare: @@ -130,12 +130,13 @@ jobs: run: | cd hive go install ./... - cd .. - name: Start Hive in background run: | cd hive - ~/go/bin/hive --dev --client "${{ github.event.inputs.client }}" \ + ~/go/bin/hive \ + --dev \ + --client "${{ github.event.inputs.client }}" \ --dev.addr=127.0.0.1:3000 \ --loglevel=5 \ --sim.loglevel=5 \ @@ -166,14 +167,18 @@ jobs: - name: Run fill run: | - uv run fill "tests/${{ matrix.test_dir }}" --fork "${{ github.event.inputs.fork }}" --clean -v -x + uv run fill "tests/${{ matrix.test_dir }}" --fork "${{ github.event.inputs.fork }}" --generate-all-formats --clean -v -x - - name: Run test against client + - name: Run consume against ${{ github.event.inputs.client }} env: HIVE_SIMULATOR: http://127.0.0.1:3000 run: | - FORK_LOWER=$(echo "${{ matrix.test_dir }}" | cut -d'/' -f1) - uv run consume engine -v --input "fixtures/blockchain_tests_engine/for_$FORK_LOWER" + if [ -d "fixtures/blockchain_tests_engine" ]; then + uv run consume engine -v --input fixtures/blockchain_tests_engine/ + fi + if [ -d "fixtures/blockchain_tests" ]; then + uv run consume rlp -v --input fixtures/blockchain_tests/ + fi - name: Sanitize artifact name id: sanitize-name diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 03f416ebcad..168322671f7 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -83,7 +83,7 @@ jobs: matrix: include: - label: pre-cancun - from_fork: Paris + from_fork: ConstantinopleFix until_fork: Shanghai - label: cancun from_fork: Cancun diff --git a/GNOSIS.md b/GNOSIS.md index a11134cf28b..3af40da0b57 100644 --- a/GNOSIS.md +++ b/GNOSIS.md @@ -8,6 +8,70 @@ The authoritative specifications for Gnosis execution layer differences live in - [posdao-post-merge.md](https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md) — block rewards system call, system transaction rules - [withdrawals.md](https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md) — withdrawal system calls +- [network-upgrades/london.md](https://github.com/gnosischain/specs/blob/master/network-upgrades/london.md) — EIP-1559 fee collector (pre-merge) +- [network-upgrades/istanbul.md](https://github.com/gnosischain/specs/blob/master/network-upgrades/istanbul.md) — EIP-1283 re-enabled, EIP-2200 not included +- [network-upgrades/berlin.md](https://github.com/gnosischain/specs/blob/master/network-upgrades/berlin.md) — identical to Ethereum mainnet + +## Fork history + +Gnosis chain launched in 2018 with Constantinople already active. Frontier, Homestead, and Byzantium predate Gnosis and were never activated on Gnosis mainnet. The following forks are marked `ignore=True` in the test framework (skipped during fill): + +- DAOFork, TangerineWhistle, SpuriousDragon — pre-Gnosis Ethereum-only forks +- MuirGlacier, ArrowGlacier, GrayGlacier — difficulty-bomb-only forks, not activated on Gnosis + +The active Gnosis fork sequence starts at ConstantinopleFix: + +```text +ConstantinopleFix → Istanbul → Berlin → London → +Paris (Merge) → Shanghai → Cancun → Prague → Osaka +``` + +Pre-merge forks (ConstantinopleFix → London) use AuRa consensus. Paris and later use standard Ethereum PoS. + +### Known divergences (pre-merge) + +- **Istanbul**: Gnosis re-enabled EIP-1283 (not EIP-2200). The current `istanbul/fork.py` follows Ethereum mainnet semantics (EIP-2200). This does not affect the t8n block-level machinery but may cause SSTORE gas mismatches in tests targeting the exact Istanbul EIP-1283 behaviour. +- **Constantinople**: EIP-1283 was activated, then de-activated in the Gnosis-specific ConstantinopleFix fork (block 2,508,800). This fork is not separately represented; Constantinople here follows standard Ethereum semantics. + +## AuRa consensus encoding (pre-merge) + +Pre-merge Gnosis blocks (Constantinople → London) use Authority Round (AuRa) consensus instead of Ethereum's PoW. AuRa-encoded fixture headers differ from standard Ethereum headers in three fields: + +| Header field | Standard Ethereum | AuRa (Gnosis pre-merge) | +|---|---|---| +| `nonce` | 8-byte PoW nonce (`Bytes8`) | 65-byte ECDSA seal (`r‖s‖v`) over the unsealed header | +| `mixHash` / `prev_randao` | PoW mix hash | AuRa step (block number as `uint256`) | +| `difficulty` | Calculated PoW difficulty | Fixed: `(1 << 128) - 2` | + +Genesis blocks use an all-zero 65-byte seal. Non-genesis seals are signed with the test validator key (`TestPrivateKey`). The unsealed header excludes `prev_randao` and `nonce` fields before hashing. + +AuRa encoding is applied automatically by the fixture framework for any fork where `header_zero_difficulty_required()` returns `False` (all pre-merge forks). `header_zero_difficulty_required()` is overridden to `True` starting with Paris (EIP-3675), so post-merge forks use standard encoding automatically. + +Implementation: `packages/testing/src/execution_testing/fixtures/blockchain.py` — `rlp_encode_list` property and `_aura_signature` cached property on `FixtureHeader`. + +The block environment also sets AuRa-specific values for pre-merge non-genesis blocks: + +- `fee_recipient` → `TestAddress` +- `difficulty` → `(1 << 128) - 2` + +Implementation: `packages/testing/src/execution_testing/test_types/block_types.py` — `Environment.set_fork_requirements()`. + +## Fixture generation strategy + +| Recipe | `--from` | `--until` | Encoding | Purpose | +|---|---|---|---|---| +| `just fill` | `ConstantinopleFix` | `Osaka` (latest) | AuRa (pre-merge), standard (post-merge) | Gnosis Hive client tests | +| `just fill-pypy` | `ConstantinopleFix` | `Osaka` (latest) | AuRa (pre-merge), standard (post-merge) | PyPy fill verification | +| `just json-loader` | `Paris` | `Osaka` (latest) | Standard only | EELS Python spec validation | + +Pre-merge forks are excluded from `json-loader` because EELS validates headers using standard Ethereum rules (8-byte `Bytes8` nonce, PoW difficulty check) which are incompatible with AuRa headers. + +The `just fill` recipe (and `fill-pypy`) starts from `ConstantinopleFix` because: + +1. Gnosis chain launched at ConstantinopleFix — pre-ConstantinopleFix forks never existed on Gnosis mainnet. +2. The `BLOCK_REWARDS_CONTRACT` pre-allocation is defined on `ConstantinopleFix` in the test framework — the first fork that actually ran on Gnosis mainnet. + +`SYSTEM_ADDRESS` is pre-allocated in genesis via `ConstantinopleFix.pre_allocation_blockchain()` (nonce=0, balance=0, code empty). See [SYSTEM_ADDRESS lifecycle](#system_address-lifecycle) for the full rationale. ## System transactions @@ -20,8 +84,28 @@ System transactions are special EVM calls made by `SYSTEM_ADDRESS` that bypass n - If the call reverts or runs out of gas, the block MUST be invalid - For withdrawals only: if no contract is deployed at `DEPOSIT_CONTRACT_ADDRESS`, the system call is skipped and the block is still valid +## SYSTEM_ADDRESS lifecycle + +`SYSTEM_ADDRESS` (`0xfffffffffffffffffffffffffffffffffffffffe`) is the caller of all AuRa system transactions. + +**Pre-allocation (test fixtures):** `ConstantinopleFix.pre_allocation_blockchain()` includes `SYSTEM_ADDRESS` with nonce=0, balance=0, and empty code. Every blockchain test fixture from ConstantinopleFix onwards therefore has it in genesis before any block is executed. This ensures all four Gnosis clients (geth, Nethermind, Reth, Erigon) start from an agreed initial state. + ## Features by fork +### Pre-merge forks (Constantinople → London) + +| Feature | Con | ConstFix | Istn | Berlin | London | +|---|---|---|---|---|---| +| Block rewards system call | Yes | Yes | Yes | Yes | Yes | +| Base fee collection to `FEE_COLLECTOR_ADDRESS` | — | — | — | — | Yes | + +> **Con** = Constantinople, **ConstFix** = ConstantinopleFix (Petersburg), **Istn** = Istanbul +> +> Pre-merge block rewards replace Ethereum's PoW coinbase reward with a system call to `BLOCK_REWARDS_CONTRACT_ADDRESS`. +> London's `FEE_COLLECTOR_ADDRESS` is `0x1559000000000000000000000000000000000000` (same as all post-merge forks). + +### Post-merge forks (Paris → Osaka) + | Feature | Paris | Shanghai | Cancun | Prague | Osaka | |---|---|---|---|---|---| | Base fee collection to `FEE_COLLECTOR_ADDRESS` | Yes | Yes | Yes | Yes | Yes | @@ -41,27 +125,39 @@ BLOB_FEE_COLLECTOR = 0x1559000000000000000000000000000000000000 MAX_FAILED_WITHDRAWALS_TO_PROCESS = 4 ``` +Gnosis-specific blob limits (Osaka+, override Ethereum mainnet values): + +```text +BLOB_COUNT_LIMIT = 2 +MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +``` + +Prague and Cancun also override `MAX_BLOB_GAS_PER_BLOCK = U64(262144)`. + ## Block rewards (`process_block_rewards`) Called at the start of every block before user transactions. Calls `BLOCK_REWARDS_CONTRACT_ADDRESS` with selector `f91c2898` (`reward(address[],uint16[])`). Decodes the return as `(address[], uint256[])` and increases each address's balance by the corresponding amount. -Implementation: `fork.py:process_block_rewards` in Paris through Osaka. +If no contract is deployed at `BLOCK_REWARDS_CONTRACT_ADDRESS`, the call is silently skipped (allows tests with minimal pre-state). + +Implementation: `fork.py:process_block_rewards` in ConstantinopleFix through Osaka. ## Withdrawals (`process_withdrawals`) Called after all user transactions. Calls `DEPOSIT_CONTRACT_ADDRESS` with selector `79d0c0bc` (`executeSystemWithdrawals(uint256,uint64[],address[])`) passing `MAX_FAILED_WITHDRAWALS_TO_PROCESS`, withdrawal amounts (GWei), and withdrawal addresses. +The deposit contract is pre-allocated from Shanghai onwards. If no contract is deployed at `DEPOSIT_CONTRACT_ADDRESS`, the call is skipped and the block remains valid. + Implementation: `fork.py:process_withdrawals` in Shanghai through Osaka. ## Base fee collection After each user transaction, the base fee portion (`gas_used * base_fee_per_gas`) is sent to `FEE_COLLECTOR_ADDRESS` instead of being burned. This replaces Ethereum's EIP-1559 burn. +Implementation: `fork.py:process_transaction` in London through Osaka. + ## Blob fee collection (Prague+) After each user transaction with blobs, the blob gas fee is sent to `BLOB_FEE_COLLECTOR`. -## Gnosis-specific limits (Osaka+) - -- `BLOB_COUNT_LIMIT = 2` -- `MAX_BLOB_GAS_PER_BLOCK = 262144` +Implementation: `fork.py:process_transaction` in Prague through Osaka. diff --git a/Justfile b/Justfile index 2d1562c9f8a..9136f6c9fa0 100644 --- a/Justfile +++ b/Justfile @@ -11,7 +11,7 @@ root := justfile_directory() output_dir := root / ".just" xdist_workers := env("PYTEST_XDIST_AUTO_NUM_WORKERS", "6") evm_bin := env("EVM_BIN", "evm") -latest_fork := "Amsterdam" +latest_fork := "Osaka" # --- Static Analysis --- @@ -144,7 +144,7 @@ fill-pypy *args: --basetemp="{{ output_dir }}/fill-pypy/tmp" \ --log-to "{{ output_dir }}/fill-pypy/logs" \ --clean \ - --from Paris \ + --from ConstantinopleFix \ --until "{{ latest_fork }}" \ --ignore=tests/ported_static \ "$@" \ diff --git a/deposit_contract.bin b/deposit_contract.bin deleted file mode 100644 index 52d700cfbab..00000000000 --- a/deposit_contract.bin +++ /dev/null @@ -1 +0,0 @@ -608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220087c8f6d95dfb88f7f04a5b4428325c27952b8a5dd04a998cffab0d9291a1eb464736f6c634300081e0033 diff --git a/packages/testing/src/execution_testing/client_clis/clis/geth.py b/packages/testing/src/execution_testing/client_clis/clis/geth.py index 25f0e0244e9..383c697440b 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/geth.py +++ b/packages/testing/src/execution_testing/client_clis/clis/geth.py @@ -168,6 +168,9 @@ class GethExceptionMapper(ExceptionMapper): r"block access list exceeds gas limit" ), BlockException.GAS_USED_OVERFLOW: (r"gas limit reached"), + BlockException.SYSTEM_CONTRACT_CALL_FAILED: ( + r"execution reverted|invalid opcode: INVALID" + ), TransactionException.INTRINSIC_GAS_TOO_LOW: ( r"insufficient gas for floor data gas cost" ), diff --git a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py index 929fc139cbb..806647f3d3e 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/nethermind.py +++ b/packages/testing/src/execution_testing/client_clis/clis/nethermind.py @@ -436,10 +436,13 @@ class NethermindExceptionMapper(ExceptionMapper): r"calculated hash 0x[0-9a-f]+" ), BlockException.SYSTEM_CONTRACT_EMPTY: ( - r"(Withdrawals|Consolidations)Empty: Contract is not deployed\." + r"(BlockRewards|Withdrawals|Consolidations)Empty: " + r"Contract is not deployed\." ), BlockException.SYSTEM_CONTRACT_CALL_FAILED: ( - r"(Withdrawals|Consolidations)Failed: Contract execution failed\." + r"(BlockRewards|Withdrawals|Consolidations)Failed: " + r"Contract execution failed\.|" + r"execution reverted|invalid opcode: INVALID" ), # BAL Exceptions — specific exceptions have unique patterns, but # INVALID_BLOCK_ACCESS_LIST and INCORRECT_BLOCK_FORMAT intentionally diff --git a/packages/testing/src/execution_testing/client_clis/clis/reth.py b/packages/testing/src/execution_testing/client_clis/clis/reth.py index 454d5f9ffcb..62ab1727e3a 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/reth.py +++ b/packages/testing/src/execution_testing/client_clis/clis/reth.py @@ -81,7 +81,8 @@ class RethExceptionMapper(ExceptionMapper): r"transaction gas limit.*is greater than the cap" ), BlockException.SYSTEM_CONTRACT_CALL_FAILED: ( - r"failed to apply .* requests contract call" + r"failed to apply .* requests contract call|" + r"execution reverted|invalid opcode: INVALID" ), BlockException.INCORRECT_BLOB_GAS_USED: ( r"blob gas used mismatch|" diff --git a/packages/testing/src/execution_testing/fixtures/blockchain.py b/packages/testing/src/execution_testing/fixtures/blockchain.py index d1138fafa61..1e6445a4ab4 100644 --- a/packages/testing/src/execution_testing/fixtures/blockchain.py +++ b/packages/testing/src/execution_testing/fixtures/blockchain.py @@ -21,6 +21,7 @@ import ethereum_rlp as eth_rlp import pytest +from coincurve.keys import PrivateKey from ethereum_types.numeric import Uint from pydantic import ( AliasChoices, @@ -45,6 +46,7 @@ HeaderNonce, HexNumber, Number, + TestPrivateKey, ZeroPaddedHexNumber, unwrap_annotation, ) @@ -227,6 +229,15 @@ class FixtureHeader(CamelModel): fork: Fork | None = Field(None, exclude=True) + def set_fork(self, fork: Fork | None) -> None: + """ + Set the runtime-only fork reference and clear cached properties that + depend on fork-specific header encoding. + """ + object.__setattr__(self, "fork", fork) + for _prop in ("rlp_encode_list", "rlp", "block_hash"): + self.__dict__.pop(_prop, None) + def model_post_init(self, __context: Any) -> None: """ Model post init method used to check for required fields of a given @@ -264,17 +275,49 @@ def model_post_init(self, __context: Any) -> None: @cached_property def rlp_encode_list(self) -> List: """Compute the RLP of the header.""" - header_list = [] + # Gnosis only: non-zero difficulty signals an Aura-sealed block + aura = ( + self.fork is not None + and not self.fork.header_zero_difficulty_required() + ) + header_list: List[bytes | Uint] = [] for field in self.__class__.model_fields: if field == "fork": continue value = getattr(self, field) if value is not None: - header_list.append( - value if isinstance(value, bytes) else Uint(value) - ) + if aura and field == "prev_randao": + # AuRa: mixHash encodes the step (block number) + header_list.append(Uint(int(self.number))) + elif aura and field == "nonce": + # AuRa seal: 65-byte zero at genesis, ECDSA elsewhere + if int(self.number) == 0: + header_list.append(bytes(65)) + else: + header_list.append(self._aura_signature) + else: + header_list.append( + value if isinstance(value, bytes) else Uint(value) + ) return header_list + @cached_property + def _aura_signature(self) -> bytes: + """Return 65-byte r||s||v ECDSA seal over the unsealed header RLP.""" + sealing_list: List[bytes | Uint] = [] + for field in self.__class__.model_fields: + if field in ("fork", "prev_randao", "nonce"): + continue + value = getattr(self, field) + if value is None: + continue + sealing_list.append( + value if isinstance(value, bytes) else Uint(value) + ) + sealing_hash = Bytes(eth_rlp.encode(sealing_list)).keccak256() + privkey = PrivateKey(TestPrivateKey.to_bytes(32, "big")) + return privkey.sign_recoverable(bytes(sealing_hash), hasher=None) + @cached_property def rlp(self) -> Bytes: """Compute the RLP of the header.""" @@ -716,11 +759,16 @@ def with_rlp(self, txs: List[Transaction]) -> "FixtureBlock": if self.withdrawals is not None: block.append([w.to_serializable_list() for w in self.withdrawals]) - return FixtureBlock( + fixture_block = FixtureBlock( **self.model_dump(), rlp=eth_rlp.encode(block), ) + if self.header.fork is not None: + fixture_block.header.set_fork(self.header.fork) + + return fixture_block + class FixtureBlock(FixtureBlockBase): """Representation of an Ethereum block within a test Fixture.""" @@ -782,6 +830,13 @@ def config_defaults_for_backwards_compatibility(cls, data: Any) -> Any: data["config"]["chainid"] = "0x01" return data + @model_validator(mode="after") + def propagate_fork_to_genesis(self) -> Self: + """Restore genesis header's runtime fork context after JSON load.""" + if self.genesis.fork is None: + self.genesis.set_fork(self.fork.transitions_from()) + return self + def get_fork(self) -> Fork | TransitionFork | None: """Return fork of the fixture as a string.""" return self.fork diff --git a/packages/testing/src/execution_testing/forks/forks/contracts/block_reward_contract.bin b/packages/testing/src/execution_testing/forks/forks/contracts/block_reward_contract.bin index b84d2b67f34720f026a7b7b09f7b4ac040c6ff5b..42772ed081251ae2fabdd98fc9d846c8a15f1322 100644 GIT binary patch literal 880 zcmZ`%y=xRf6rZ;j(c+NHd3P!aWC@1|LJ-ZRGIEkaE1g|rH#p53E(wT&kwXLp*_pXb zun=cAMxvEiYiXlcY2km6MkIw`Wu=Xh58vEg1P|O{i<$Yo_xqTK3AV%Oq%K({MwaXd zjw3S_$xhL(g_2o00hMt;l(9c_ccQFWtY5TVu#VynrJiHj(W(!8oA-CyqB1pj+*+ zk{Z>zaf=FV0Gsxh}}|L3)$`vjmv!12`TSBhl7DG)@?(N|-NlR4oZNBrItO zWKOc5kw|o5BID>As$2ocd1_qCM@13(DF~w~bn-S%S`>w9sG5XV#kHXfasxR?$jSWr z6Yf4oPOoUvQkCj93#e}GOIEJ`_dx^ltROuiVYfIS4zK)I<*>li30!poy{Q6^eh=2T z&^?mqEyku`c|qwpo!->}Iq6&@pv{10q7{k0P%;hwsPaq!m)_%4uaK#Wk;ph7JRQBe z4ozS+C>tWPE*p#318anG5qY0uH&e8Tzu~g!bLNmCfb`zD@i3}{ezF3Y&B8QDOqeN` zIW=NMlhU!6hIF|0H`QiO*Zc7fP0^YCDcXIxaD92HJ3m?Vzdd+uue`f=XZ75t@?F(! f*7f0y?XS}Z!w)C6rxwer3*B2cJ9F&NBs=>D185^& literal 1008 zcmb7@&uddb5XWbCdr%RH(Wr+KL&e{hq9%xV2-Y6#X%k^nSPDBNXcfU=z?=H^y@nQ% z`d)ru1r_lR5KBD>D&7S3q8ED;PYR+3Q4j@x%qD3}trdKSH|%`peP=$yKI55eexH{> zh!qTY-?cP-nHa)uI;G9)ey{kof5*&vgu#Mt=?EjH&&vqQLWJQcL^h%{0xE5?IfT&~ zr9{v=d65V|X=A8G&SY)g7?bi@-hj!rgK@#LRO31?^9s!72^L4VTR@mYxU97H)1f^6 zv-8-sH2ez^pCdF#G^v0^GN4vGU{3o$+Ixhnq}60Clr$T79apxhfNbS5u53Gr+y3s# zhDbZ~rz;toY;{t^6Ua(bP(-M@k)X=biw0&ssTScPsmP`${V9fUL+OTWNNG|_%4ezk z&O-UacKK)Jc%-Z~qXtEXWpkm7+JwHJciRqSEs||5Bx9H86jT-#*c<%~T^;#=kL-)m zoec6l7Wqb{{e0UH`QacyzLOf$%6~Un)CKuCxjdsQ!q3<$vX@HNCGv9tvbRcm26SL! z3FNm6Hix`9lhZqk~Z0h9@N0xB7A0m|23IhSlqqy!` zjJegj9Br3!vvvZ-R+p>OPNe#At8}7#tTH+fPtEM|p00bMGDn+hlIPz&+A^1%KY1;j Zeo($}>E6Net2d>}=~KlaSdoOizX1IJd_4dF diff --git a/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_4895.py b/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_4895.py index 9577621e400..175f4446058 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_4895.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/shanghai/eip_4895.py @@ -7,8 +7,19 @@ https://eips.ethereum.org/EIPS/eip-4895 """ +from pathlib import Path +from typing import List, Mapping + +from execution_testing.base_types import Address + from ....base_fork import BaseFork +CONTRACTS_DIR = Path(__file__).parent.parent.parent / "contracts" +DEPOSIT_CONTRACT_ADDRESS = 0xBABE2BED00000000000000000000000000000003 +DEPOSIT_CONTRACT_BYTECODE = ( + CONTRACTS_DIR / "deposit_contract.bin" +).read_bytes() + class EIP4895( BaseFork, @@ -22,3 +33,23 @@ class EIP4895( def header_withdrawals_required(cls) -> bool: """Withdrawals are required.""" return True + + @classmethod + def system_contracts(cls) -> List[Address]: + """Deposit contract is present from Shanghai onwards.""" + return [ + Address( + DEPOSIT_CONTRACT_ADDRESS, + label="DEPOSIT_CONTRACT_ADDRESS", + ), + ] + super(EIP4895, cls).system_contracts() + + @classmethod + def pre_allocation_blockchain(cls) -> Mapping: + """Pre-allocate the Gnosis deposit contract.""" + return { + DEPOSIT_CONTRACT_ADDRESS: { + "nonce": 1, + "code": DEPOSIT_CONTRACT_BYTECODE, + }, + } | super(EIP4895, cls).pre_allocation_blockchain() # type: ignore diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 8c578a22c61..4e5a1f9622b 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -43,15 +43,9 @@ CONTRACTS_DIR = Path(realpath(__file__)).parent / "contracts" SYSTEM_ADDRESS = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE BLOCK_REWARDS_CONTRACT_ADDRESS = 0x2000000000000000000000000000000000000001 -DEPOSIT_CONTRACT_ADDRESS = 0xBABE2BED00000000000000000000000000000003 -BLOCK_REWARDS_CONTRACT_BYTECODE_FILE = ( - CONTRACTS_DIR / "block_reward_contract.bin" -) -DEPOSIT_CONTRACT_BYTECODE_FILE = CONTRACTS_DIR / "deposit_contract.bin" BLOCK_REWARDS_CONTRACT_BYTECODE = ( - BLOCK_REWARDS_CONTRACT_BYTECODE_FILE.read_bytes() -) -DEPOSIT_CONTRACT_BYTECODE = DEPOSIT_CONTRACT_BYTECODE_FILE.read_bytes() + CONTRACTS_DIR / "block_reward_contract.bin" +).read_bytes() # All forks must be listed here !!! in the order they were introduced !!! @@ -1044,17 +1038,8 @@ def precompiles(cls) -> List[Address]: @classmethod def system_contracts(cls) -> List[Address]: - """At Genesis, block rewards and deposit contract are present.""" - return [ - Address( - 0x2000000000000000000000000000000000000001, - label="BLOCK_REWARDS_CONTRACT_ADDRESS", - ), - Address( - 0xBABE2BED00000000000000000000000000000003, - label="DEPOSIT_CONTRACT_ADDRESS", - ), - ] + """At Genesis, no system contracts are present.""" + return [] @classmethod def deterministic_factory_predeploy_address(cls) -> Address | None: @@ -1261,24 +1246,9 @@ def pre_allocation_blockchain(cls) -> Mapping: """ Return whether the fork expects pre-allocation of accounts. - Frontier pre-allocates block rewards and deposit contracts. + Frontier does not require pre-allocated accounts """ - return { - BLOCK_REWARDS_CONTRACT_ADDRESS: { - "nonce": 1, - "code": BLOCK_REWARDS_CONTRACT_BYTECODE, - }, - DEPOSIT_CONTRACT_ADDRESS: { - "nonce": 1, - "code": DEPOSIT_CONTRACT_BYTECODE, - }, - SYSTEM_ADDRESS: { - "nonce": 0, - "balance": 0, - "code": b"", - "storage": {}, - }, - } + return {} @classmethod def build_default_block_header( @@ -1404,9 +1374,29 @@ class ConstantinopleFix( solc_name="constantinople", ruleset_name="PETERSBURG", ): - """Constantinople Fix fork.""" + """Constantinople Fix fork — first active Gnosis mainnet fork.""" - pass + @classmethod + def system_contracts(cls) -> List[Address]: + """Block rewards contract is present from ConstantinopleFix onwards.""" + return [ + Address( + BLOCK_REWARDS_CONTRACT_ADDRESS, + label="BLOCK_REWARDS_CONTRACT_ADDRESS", + ), + ] + super().system_contracts() + + @classmethod + def pre_allocation_blockchain(cls) -> Mapping: + """ + Pre-allocates the block rewards contract. + """ + return { + BLOCK_REWARDS_CONTRACT_ADDRESS: { + "nonce": 1, + "code": BLOCK_REWARDS_CONTRACT_BYTECODE, + } + } class Istanbul( diff --git a/packages/testing/src/execution_testing/forks/forks/src_contracts/block_reward_contract.sol b/packages/testing/src/execution_testing/forks/forks/src_contracts/block_reward_contract.sol index 4ba85e5a87e..a581f915634 100644 --- a/packages/testing/src/execution_testing/forks/forks/src_contracts/block_reward_contract.sol +++ b/packages/testing/src/execution_testing/forks/forks/src_contracts/block_reward_contract.sol @@ -1,22 +1,44 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +// Compiled with: solc --bin-runtime --optimize --optimize-runs 1 --evm-version constantinople +/** + * Minimum viable test implementation of the BlockRewardAuRa reward contract. + * + * Implements the reward(address[], uint16[]) interface called once per block + * as a system transaction from SYSTEM_ADDRESS (0xffff...fffe) with + * benefactors=[coinbase] and kind=[0] (RewardAuthor kind). + * + * Mirrors the guard logic from BlockRewardAuRaBase.reward(): invalid inputs + * return empty arrays without reverting. Valid inputs also return empty arrays, + * simulating the real contract's behaviour when validatorSetContract is unset + * (as it is in test pre-allocations). + * + * Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + * Real contract: https://github.com/gnosischain/posdao-contracts/blob/master/contracts/base/BlockRewardAuRaBase.sol + */ contract TestBlockReward { - function reward(address[] calldata, uint16[] calldata) - external pure returns(address[] memory, uint256[] memory) + function reward( + address[] memory benefactors, + uint16[] memory kind + ) + external + pure + returns ( + address[] memory receiversNative, + uint256[] memory rewardsNative + ) { - assembly { - // Get free memory pointer - let ptr := mload(0x40) - - // Build ABI-encoded return data for two empty arrays - mstore(ptr, 0x40) // Offset to first array (64 bytes) - mstore(add(ptr, 0x20), 0x60) // Offset to second array (96 bytes) - mstore(add(ptr, 0x40), 0) // First array length = 0 - mstore(add(ptr, 0x60), 0) // Second array length = 0 - - // Return 128 bytes (4 words) - return(ptr, 0x80) + // Mirror BlockRewardAuRaBase guard: invalid args → return empty (no revert) + if ( + benefactors.length != kind.length + || benefactors.length != 1 + || kind[0] != 0 + ) { + return (new address[](0), new uint256[](0)); } + + // validatorSetContract unset in test environment → return empty + return (new address[](0), new uint256[](0)); } -} \ No newline at end of file +} diff --git a/packages/testing/src/execution_testing/specs/blockchain.py b/packages/testing/src/execution_testing/specs/blockchain.py index 57f9ba45de8..eeea4294021 100644 --- a/packages/testing/src/execution_testing/specs/blockchain.py +++ b/packages/testing/src/execution_testing/specs/blockchain.py @@ -622,10 +622,15 @@ def discard_fixture_format_by_marks( def get_genesis_environment(self) -> Environment: """Get the genesis environment for pre-allocation groups.""" - modified_values = self.genesis_environment.set_fork_requirements( + # Apply GENESIS_ENVIRONMENT_DEFAULTS first so set_fork_requirements + # treats this as genesis (number = 0). Otherwise, default number = 1 + # triggers fork overrides, non-zero coinbase, and hash mismatch (AuRa + # genesis expects miner = 0x0). + explicit = self.genesis_environment.model_dump(exclude_unset=True) + payload = GENESIS_ENVIRONMENT_DEFAULTS | explicit + return Environment(**payload).set_fork_requirements( self.fork.transitions_from() - ).model_dump(exclude_unset=True) - return Environment(**(GENESIS_ENVIRONMENT_DEFAULTS | modified_values)) + ) def make_genesis( self, *, apply_pre_allocation_blockchain: bool diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_invalid_filled.json b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_invalid_filled.json index 9f3aa325227..4c9ee62a089 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_invalid_filled.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_invalid_filled.json @@ -662,7 +662,7 @@ "sealEngine": "NoProof", "_info": { "hash": "0x6e42f77408e60c3e36fa2e84a95fe0d885b013138c10dd90ca340e49343bafdd", - "fixture_format": "blockchain_test" + "fixture-format": "blockchain_test" } } -} \ No newline at end of file +} diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_valid_filled.json b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_valid_filled.json index 3dd67a53a2b..14e77b40a67 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_valid_filled.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_london_valid_filled.json @@ -518,7 +518,7 @@ "sealEngine": "NoProof", "_info": { "hash": "0x620a13e96b3eb731834fad810d11e7c1ce83353cf2fdd5a2548e730d960a3951", - "fixture_format": "blockchain_test" + "fixture-format": "blockchain_test" } } -} \ No newline at end of file +} diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_invalid_filled_engine.json b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_invalid_filled_engine.json index 76c70718182..4cc99583417 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_invalid_filled_engine.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_invalid_filled_engine.json @@ -1,28 +1,22 @@ { "000/my_blockchain_test/Shanghai": { "network": "Shanghai", - "lastblockhash": "0x3d161fc63931929e3ed9a44a2731348b51e3f2e5e90d4c0ae78f00d16e10ad15", + "lastblockhash": "0xe89b8bfbf199282a6d7b3fea125337e6b6c8d23fdf47e88daf0b11815a898926", "config": { "network": "Shanghai", "chainid": "0x01" }, "pre": { - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { @@ -66,7 +60,7 @@ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2eef6450527569580f3a230348ec8d69858676c2b37b4aaa1395392348743029", + "stateRoot": "0x79363990c99aa64864da10c1cc1cfb1b110bb676a0f9cc2ee443fdecc5a278b3", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -80,25 +74,19 @@ "nonce": "0x0000000000000000", "baseFeePerGas": "0x03e8", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "hash": "0xaf509b91322e732a830e9d86f61d4b8e9955a4044c0af75053efc1e4b285535c" + "hash": "0x08d5f6dcf8acd6cdf8e9b907854d3cc874509d27240ad68172f2d7de3fb9ac42" }, "postState": { - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { @@ -180,6 +168,12 @@ "0x2004": "0x01ffffffd000" } }, + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x", + "storage": {} + }, "0xba5e000000000000000000000000000000000000": { "nonce": "0x00", "balance": "0x04315222d1", @@ -197,9 +191,9 @@ { "params": [ { - "parentHash": "0xaf509b91322e732a830e9d86f61d4b8e9955a4044c0af75053efc1e4b285535c", + "parentHash": "0x08d5f6dcf8acd6cdf8e9b907854d3cc874509d27240ad68172f2d7de3fb9ac42", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0xc4b89d310fe828dc67f86711ea88c58f05cb5bfb1de3ecc1e50da6927ff1aa10", + "stateRoot": "0xdb2a51bb5c1cc9e5461b7ef043897e027d7069cf56132686b01dd0f49c8e62ea", "receiptsRoot": "0x29b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1", @@ -209,7 +203,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x36b", - "blockHash": "0xb512f4ea799e2a04deb311f025d33bdbf20767ed5f820d84f946beb80ca05376", + "blockHash": "0xd8ba99af8fe86e3ecc397ff9416a8b35da22b93b4cded82cb31b230432cdae18", "transactions": [ "0x02f8650180018203e8830f424094cccccccccccccccccccccccccccccccccccccccc8001c080a03351b6993208fc7b03fd770c8c06440cfb0d75b29aafee0a4c64c8ba20a80e58a067817fdb3058e75c5d26e51a33d1e338346bc7d406e115447a4bb5f7ab01625b" ], @@ -222,9 +216,9 @@ { "params": [ { - "parentHash": "0xb512f4ea799e2a04deb311f025d33bdbf20767ed5f820d84f946beb80ca05376", + "parentHash": "0xd8ba99af8fe86e3ecc397ff9416a8b35da22b93b4cded82cb31b230432cdae18", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0x2c639782acf29c1f777e70a17dfad332ce710274c58180662626d7c2ed732d00", + "stateRoot": "0x1f9ec452742cdbe3218d58dd407b768cbe6578c6e905b81b09fc66428c3d095e", "receiptsRoot": "0xabecd0c0c929d8339a0f55a2be4c3cdcb66f9de91de87109f351a7bd56a664e0", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x2", @@ -234,7 +228,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x2fe", - "blockHash": "0x09ae2bb98118f3ad763161b7050bc0295b45a4575b8b7906eb56e2a353c48776", + "blockHash": "0xc4dffba44f8ee037283a89931d2e65dc754be0229efd3ed0e1fcad6c71dbc94f", "transactions": [ "0x02f86701010a8203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820201c080a06ea285a870a051df2b8c80c462b7d3517f984815e09c4748efc8548a40434050a052f635268c1b9e1538ac76b37cb69c7b897595744d6de2dda9507b6624d352d0", "0x02f8670102648203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820202c080a0218549e818b36b3823c3f11a65ab5c1e16f6886469c385503cc2f1af1f53825da058b082850f55fd61290a99add11b7af6356ac8d55fbe4d513f06bf648824a64d", @@ -249,9 +243,9 @@ { "params": [ { - "parentHash": "0x09ae2bb98118f3ad763161b7050bc0295b45a4575b8b7906eb56e2a353c48776", + "parentHash": "0xc4dffba44f8ee037283a89931d2e65dc754be0229efd3ed0e1fcad6c71dbc94f", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0x60389c943f1a787ff145b42e4a7dab8cef2f14a59b2d5429233d78d543bfed29", + "stateRoot": "0x7bab64126f6c6bc60d7c37c1a9e345db84b5831061a4791f66791af75fe40bbd", "receiptsRoot": "0x976beb67b634171d419ef326220dfdda98074e3495940240a105e17643f0a4ef", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x3", @@ -261,7 +255,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x29f", - "blockHash": "0x17d95707ef330bf84a1396c12f6bb7a8afb58ba2ae5bf0b997fd1e4d291e92c8", + "blockHash": "0xa2bcb4f3899cd2cc7f4c45d236498fa30af2b4262f6c3ca0f374e1eb1e3bf71d", "transactions": [ "0x02f86901048203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820301c001a0720e2870881f8b0e285b7ec02c169f1165847bcb5f36ea5f33f3db6079854f63a04448266b715d7d99acd1e31dcab50d7119faa620d44c69b3f64f97d636634169", "0x02f86a0105830186a08203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820302c080a06c7fb2be7e001a210d72480522b9ebecade52d721360ce5242e34a6c05a02715a01220e3cb7418cd6294443b38d05f5ed9f2967b182d25c784e11e7863454b8f9b" @@ -276,9 +270,9 @@ { "params": [ { - "parentHash": "0x09ae2bb98118f3ad763161b7050bc0295b45a4575b8b7906eb56e2a353c48776", + "parentHash": "0xc4dffba44f8ee037283a89931d2e65dc754be0229efd3ed0e1fcad6c71dbc94f", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0x0f4f012abd9c5791d21ef68908fa4c8432975d36c7cfbb389f831a24d504dbac", + "stateRoot": "0x5cfe23921d17ab9015485580727c086c5bbdca6f7c8745f91295d0caef08ef11", "receiptsRoot": "0x2b276cfe779f83fc50afea9262628cfe97b3175ce1822a1871aba93000cc5061", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x3", @@ -288,7 +282,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x29f", - "blockHash": "0x9639ee4effc55eb3d8ffc842d4f1d1e5238e05ecd756930edf8a4ca5fe47ca88", + "blockHash": "0x3fca0bfec99fe6c0138fce3066dd67e3576de6106dc3f4df64943e9a23398364", "transactions": [ "0x02f86901048203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820301c001a0720e2870881f8b0e285b7ec02c169f1165847bcb5f36ea5f33f3db6079854f63a04448266b715d7d99acd1e31dcab50d7119faa620d44c69b3f64f97d636634169", "0x02f8670105648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820303c080a09c8531a41f9281633470c5e12b6c72c8930409a6433f26bf7b394a703d18512ea07a0c6151fde75f10a7e4efdd17a21f1f25206559bd4b8cf7880e5bc30e1cfe33", @@ -303,9 +297,9 @@ { "params": [ { - "parentHash": "0x9639ee4effc55eb3d8ffc842d4f1d1e5238e05ecd756930edf8a4ca5fe47ca88", + "parentHash": "0x3fca0bfec99fe6c0138fce3066dd67e3576de6106dc3f4df64943e9a23398364", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0xcd0858918a5307607b108bbb6e0ddd8652a4b3327b28dc20b54bce6a8a4737cd", + "stateRoot": "0x5c0a289bfe5a6c359a1c850cdb5574cbb0652869e4e6d6581c401912592ceccf", "receiptsRoot": "0x976beb67b634171d419ef326220dfdda98074e3495940240a105e17643f0a4ef", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x4", @@ -315,7 +309,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x24c", - "blockHash": "0xa2e8199b5611a4acdb53fcb9701805764204db41234a0a3ad50761076c3d3c75", + "blockHash": "0x04319fc65e4404535bcc2792eb4e15d041ac58de4918c56332730214be3e2e7b", "transactions": [ "0x02f86901078203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820401c001a0113c54f83e1b1e5c689ba86d288ec0ce2877f350b71821c4c7a3f7073b46602ca0548848e711b86ceeb657fd0a0bf44b792f6665ed18ec8a04f498471e811f8f97", "0x02f86a0108830186a08203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820402c001a0ebc8ad530ec3d510998aa2485763fcd1c6958c900c8d8ae6eaf86e1eddde8b23a0341e4a021f7b77da28d853c07d11253b92331ab640ad3f28f5d7b2cdbc7ceca7" @@ -330,9 +324,9 @@ { "params": [ { - "parentHash": "0x9639ee4effc55eb3d8ffc842d4f1d1e5238e05ecd756930edf8a4ca5fe47ca88", + "parentHash": "0x3fca0bfec99fe6c0138fce3066dd67e3576de6106dc3f4df64943e9a23398364", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0xdaa4a7c7da17ec6ae721acbe2091c1ffaac741a5e6b8f34a463aa7743c579b33", + "stateRoot": "0xd40a636a033f4a453518b6e07e2f6026c775a249e1ce12b789b74b1cf655c6f8", "receiptsRoot": "0x2b276cfe779f83fc50afea9262628cfe97b3175ce1822a1871aba93000cc5061", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x4", @@ -342,7 +336,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x24c", - "blockHash": "0x3d161fc63931929e3ed9a44a2731348b51e3f2e5e90d4c0ae78f00d16e10ad15", + "blockHash": "0xe89b8bfbf199282a6d7b3fea125337e6b6c8d23fdf47e88daf0b11815a898926", "transactions": [ "0x02f86901078203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820401c001a0113c54f83e1b1e5c689ba86d288ec0ce2877f350b71821c4c7a3f7073b46602ca0548848e711b86ceeb657fd0a0bf44b792f6665ed18ec8a04f498471e811f8f97", "0x02f8670108648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820403c080a08d7ec1116399aab6e1297b09302b291d73c5898a0338fb62a46c74b037d15a15a03cacc1a12eb47c261394443d490b8436f53a99d2109dac9ca5018cf531e6b29d", @@ -356,8 +350,8 @@ } ], "_info": { - "hash": "0xf3568960f1244cecce417cfa798bd1186b85c51621ed6e669a91da5a0b011871", - "fixture_format": "blockchain_test_engine" + "hash": "0x9ae846bff86ce656fa9914a8efe5712630705965d5afa1405b2efcb968a8520a", + "fixture-format": "blockchain_test_engine" } } } \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_valid_filled_engine.json b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_valid_filled_engine.json index 63e651c6818..ae24c6bf9de 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_valid_filled_engine.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/blockchain_shanghai_valid_filled_engine.json @@ -1,28 +1,22 @@ { "000/my_blockchain_test/Shanghai": { "network": "Shanghai", - "lastblockhash": "0x3d161fc63931929e3ed9a44a2731348b51e3f2e5e90d4c0ae78f00d16e10ad15", + "lastblockhash": "0xe89b8bfbf199282a6d7b3fea125337e6b6c8d23fdf47e88daf0b11815a898926", "config": { "network": "Shanghai", "chainid": "0x01" }, "pre": { - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { @@ -66,7 +60,7 @@ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2eef6450527569580f3a230348ec8d69858676c2b37b4aaa1395392348743029", + "stateRoot": "0x79363990c99aa64864da10c1cc1cfb1b110bb676a0f9cc2ee443fdecc5a278b3", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -80,25 +74,19 @@ "nonce": "0x0000000000000000", "baseFeePerGas": "0x03e8", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "hash": "0xaf509b91322e732a830e9d86f61d4b8e9955a4044c0af75053efc1e4b285535c" + "hash": "0x08d5f6dcf8acd6cdf8e9b907854d3cc874509d27240ad68172f2d7de3fb9ac42" }, "postState": { - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { @@ -180,6 +168,12 @@ "0x2004": "0x01ffffffd000" } }, + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x", + "storage": {} + }, "0xba5e000000000000000000000000000000000000": { "nonce": "0x00", "balance": "0x04315222d1", @@ -197,9 +191,9 @@ { "params": [ { - "parentHash": "0xaf509b91322e732a830e9d86f61d4b8e9955a4044c0af75053efc1e4b285535c", + "parentHash": "0x08d5f6dcf8acd6cdf8e9b907854d3cc874509d27240ad68172f2d7de3fb9ac42", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0xc4b89d310fe828dc67f86711ea88c58f05cb5bfb1de3ecc1e50da6927ff1aa10", + "stateRoot": "0xdb2a51bb5c1cc9e5461b7ef043897e027d7069cf56132686b01dd0f49c8e62ea", "receiptsRoot": "0x29b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1", @@ -209,7 +203,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x36b", - "blockHash": "0xb512f4ea799e2a04deb311f025d33bdbf20767ed5f820d84f946beb80ca05376", + "blockHash": "0xd8ba99af8fe86e3ecc397ff9416a8b35da22b93b4cded82cb31b230432cdae18", "transactions": [ "0x02f8650180018203e8830f424094cccccccccccccccccccccccccccccccccccccccc8001c080a03351b6993208fc7b03fd770c8c06440cfb0d75b29aafee0a4c64c8ba20a80e58a067817fdb3058e75c5d26e51a33d1e338346bc7d406e115447a4bb5f7ab01625b" ], @@ -222,9 +216,9 @@ { "params": [ { - "parentHash": "0xb512f4ea799e2a04deb311f025d33bdbf20767ed5f820d84f946beb80ca05376", + "parentHash": "0xd8ba99af8fe86e3ecc397ff9416a8b35da22b93b4cded82cb31b230432cdae18", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0x2c639782acf29c1f777e70a17dfad332ce710274c58180662626d7c2ed732d00", + "stateRoot": "0x1f9ec452742cdbe3218d58dd407b768cbe6578c6e905b81b09fc66428c3d095e", "receiptsRoot": "0xabecd0c0c929d8339a0f55a2be4c3cdcb66f9de91de87109f351a7bd56a664e0", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x2", @@ -234,7 +228,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x2fe", - "blockHash": "0x09ae2bb98118f3ad763161b7050bc0295b45a4575b8b7906eb56e2a353c48776", + "blockHash": "0xc4dffba44f8ee037283a89931d2e65dc754be0229efd3ed0e1fcad6c71dbc94f", "transactions": [ "0x02f86701010a8203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820201c080a06ea285a870a051df2b8c80c462b7d3517f984815e09c4748efc8548a40434050a052f635268c1b9e1538ac76b37cb69c7b897595744d6de2dda9507b6624d352d0", "0x02f8670102648203e8830f424094cccccccccccccccccccccccccccccccccccccccd80820202c080a0218549e818b36b3823c3f11a65ab5c1e16f6886469c385503cc2f1af1f53825da058b082850f55fd61290a99add11b7af6356ac8d55fbe4d513f06bf648824a64d", @@ -249,9 +243,9 @@ { "params": [ { - "parentHash": "0x09ae2bb98118f3ad763161b7050bc0295b45a4575b8b7906eb56e2a353c48776", + "parentHash": "0xc4dffba44f8ee037283a89931d2e65dc754be0229efd3ed0e1fcad6c71dbc94f", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0x0f4f012abd9c5791d21ef68908fa4c8432975d36c7cfbb389f831a24d504dbac", + "stateRoot": "0x5cfe23921d17ab9015485580727c086c5bbdca6f7c8745f91295d0caef08ef11", "receiptsRoot": "0x2b276cfe779f83fc50afea9262628cfe97b3175ce1822a1871aba93000cc5061", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x3", @@ -261,7 +255,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x29f", - "blockHash": "0x9639ee4effc55eb3d8ffc842d4f1d1e5238e05ecd756930edf8a4ca5fe47ca88", + "blockHash": "0x3fca0bfec99fe6c0138fce3066dd67e3576de6106dc3f4df64943e9a23398364", "transactions": [ "0x02f86901048203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820301c001a0720e2870881f8b0e285b7ec02c169f1165847bcb5f36ea5f33f3db6079854f63a04448266b715d7d99acd1e31dcab50d7119faa620d44c69b3f64f97d636634169", "0x02f8670105648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820303c080a09c8531a41f9281633470c5e12b6c72c8930409a6433f26bf7b394a703d18512ea07a0c6151fde75f10a7e4efdd17a21f1f25206559bd4b8cf7880e5bc30e1cfe33", @@ -276,9 +270,9 @@ { "params": [ { - "parentHash": "0x9639ee4effc55eb3d8ffc842d4f1d1e5238e05ecd756930edf8a4ca5fe47ca88", + "parentHash": "0x3fca0bfec99fe6c0138fce3066dd67e3576de6106dc3f4df64943e9a23398364", "feeRecipient": "0xba5e000000000000000000000000000000000000", - "stateRoot": "0xdaa4a7c7da17ec6ae721acbe2091c1ffaac741a5e6b8f34a463aa7743c579b33", + "stateRoot": "0xd40a636a033f4a453518b6e07e2f6026c775a249e1ce12b789b74b1cf655c6f8", "receiptsRoot": "0x2b276cfe779f83fc50afea9262628cfe97b3175ce1822a1871aba93000cc5061", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x4", @@ -288,7 +282,7 @@ "extraData": "0x", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x24c", - "blockHash": "0x3d161fc63931929e3ed9a44a2731348b51e3f2e5e90d4c0ae78f00d16e10ad15", + "blockHash": "0xe89b8bfbf199282a6d7b3fea125337e6b6c8d23fdf47e88daf0b11815a898926", "transactions": [ "0x02f86901078203e88203e8830f424094cccccccccccccccccccccccccccccccccccccccc80820401c001a0113c54f83e1b1e5c689ba86d288ec0ce2877f350b71821c4c7a3f7073b46602ca0548848e711b86ceeb657fd0a0bf44b792f6665ed18ec8a04f498471e811f8f97", "0x02f8670108648203e8830f424094ccccccccccccccccccccccccccccccccccccccce80820403c080a08d7ec1116399aab6e1297b09302b291d73c5898a0338fb62a46c74b037d15a15a03cacc1a12eb47c261394443d490b8436f53a99d2109dac9ca5018cf531e6b29d", @@ -302,8 +296,8 @@ } ], "_info": { - "hash": "0xb5298c9ec93a2abea398c455f153bc1f122b406eb9bc4f3564e2b3e613549ac5", - "fixture_format": "blockchain_test_engine" + "hash": "0x383de5a72fecb75ca729bf90379b8ab079f1ffa64c0407f5040ec367baa10cd0", + "fixture-format": "blockchain_test_engine" } } } \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_engine_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_engine_tx_type_0.json index fa61bd0b219..c1387b03893 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_engine_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_engine_tx_type_0.json @@ -1,7 +1,7 @@ { "000/my_chain_id_test/Cancun/tx_type_0": { "network": "Cancun", - "lastblockhash": "0xf70291ca243cf4accd64f3ef19abe503bc0989abd32d5318507273d391c94f36", + "lastblockhash": "0xa1a2a7016aedc7c10af284a5e6f73fc9c63aab38afe350290072621f7da018f9", "config": { "network": "Cancun", "chainid": "0x01", @@ -20,22 +20,16 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": {} }, - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -55,7 +49,7 @@ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x47028797acaba203b226a50b14d8550000310433e5d137569f7cd68ddad4b16a", + "stateRoot": "0x5d2cb837d58a04b69e7606729136e068785f8f303933c83f93da2b76bbd2d660", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -72,7 +66,7 @@ "blobGasUsed": "0x00", "excessBlobGas": "0x00", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "hash": "0x5f1be79dcdc16fee9d4ab1d3d4897cc4b5c83cd9d8fa5ae386c6c946a7ef6fbd" + "hash": "0x75a4d8212bde5c7f1b8244a3b67f8d861ac8e8853fff7b49df9b39a9ebb35f8e" }, "postState": { "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { @@ -83,22 +77,16 @@ "0x03e8": "0x03e8" } }, - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -115,6 +103,12 @@ "code": "0x", "storage": {} }, + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x", + "storage": {} + }, "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { "nonce": "0x00", "balance": "0x020229", @@ -132,9 +126,9 @@ { "params": [ { - "parentHash": "0x5f1be79dcdc16fee9d4ab1d3d4897cc4b5c83cd9d8fa5ae386c6c946a7ef6fbd", + "parentHash": "0x75a4d8212bde5c7f1b8244a3b67f8d861ac8e8853fff7b49df9b39a9ebb35f8e", "feeRecipient": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "stateRoot": "0xb9a55a1802de0027ec09c5986ca69fe72b8c4aa9adbc730bccbcdb756cea583d", + "stateRoot": "0x9b05669ff84a53f8b25cef1ceb583d5f42516b19b5af9f8216b42c07f8243e36", "receiptsRoot": "0x4b93b3c0006d672c5dfd4094132d3e8acd463e7cb018f86df29136c9a399d0b6", "logsBloom": "0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000", "blockNumber": "0x1", @@ -146,7 +140,7 @@ "baseFeePerGas": "0x7", "blobGasUsed": "0x0", "excessBlobGas": "0x0", - "blockHash": "0xf70291ca243cf4accd64f3ef19abe503bc0989abd32d5318507273d391c94f36", + "blockHash": "0xa1a2a7016aedc7c10af284a5e6f73fc9c63aab38afe350290072621f7da018f9", "transactions": [ "0xf861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b" ], @@ -160,8 +154,8 @@ } ], "_info": { - "hash": "0xfc54740833e3bcbca0167fe7a27406e290d84f21456707940733807baa1d10b5", - "fixture_format": "blockchain_test_engine" + "hash": "0xc8ef17ce97556be219e1c8bc5651bf7de348cb84becc440cad39654482a1b196", + "fixture-format": "blockchain_test_engine" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_tx_type_0.json index 96e00fc455f..20c3720de67 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_blockchain_test_tx_type_0.json @@ -5,7 +5,7 @@ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x47028797acaba203b226a50b14d8550000310433e5d137569f7cd68ddad4b16a", + "stateRoot": "0x5d2cb837d58a04b69e7606729136e068785f8f303933c83f93da2b76bbd2d660", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -22,7 +22,7 @@ "blobGasUsed": "0x00", "excessBlobGas": "0x00", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "hash": "0x5f1be79dcdc16fee9d4ab1d3d4897cc4b5c83cd9d8fa5ae386c6c946a7ef6fbd" + "hash": "0x75a4d8212bde5c7f1b8244a3b67f8d861ac8e8853fff7b49df9b39a9ebb35f8e" }, "pre": { "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { @@ -31,22 +31,16 @@ "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": {} }, - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -71,22 +65,16 @@ "0x03e8": "0x03e8" } }, - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -103,6 +91,12 @@ "code": "0x", "storage": {} }, + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x", + "storage": {} + }, "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { "nonce": "0x00", "balance": "0x020229", @@ -116,7 +110,7 @@ "storage": {} } }, - "lastblockhash": "0xf70291ca243cf4accd64f3ef19abe503bc0989abd32d5318507273d391c94f36", + "lastblockhash": "0xa1a2a7016aedc7c10af284a5e6f73fc9c63aab38afe350290072621f7da018f9", "config": { "network": "Cancun", "chainid": "0x01", @@ -128,14 +122,14 @@ } } }, - "genesisRLP": "0xf9023df90237a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a047028797acaba203b226a50b14d8550000310433e5d137569f7cd68ddad4b16aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000c0c0c0", + "genesisRLP": "0xf9023df90237a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a05d2cb837d58a04b69e7606729136e068785f8f303933c83f93da2b76bbd2d660a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000c0c0c0", "blocks": [ { "blockHeader": { - "parentHash": "0x5f1be79dcdc16fee9d4ab1d3d4897cc4b5c83cd9d8fa5ae386c6c946a7ef6fbd", + "parentHash": "0x75a4d8212bde5c7f1b8244a3b67f8d861ac8e8853fff7b49df9b39a9ebb35f8e", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "stateRoot": "0xb9a55a1802de0027ec09c5986ca69fe72b8c4aa9adbc730bccbcdb756cea583d", + "stateRoot": "0x9b05669ff84a53f8b25cef1ceb583d5f42516b19b5af9f8216b42c07f8243e36", "transactionsRoot": "0x8151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcb", "receiptsRoot": "0x4b93b3c0006d672c5dfd4094132d3e8acd463e7cb018f86df29136c9a399d0b6", "logsBloom": "0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000", @@ -152,7 +146,7 @@ "blobGasUsed": "0x00", "excessBlobGas": "0x00", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "hash": "0xf70291ca243cf4accd64f3ef19abe503bc0989abd32d5318507273d391c94f36" + "hash": "0xa1a2a7016aedc7c10af284a5e6f73fc9c63aab38afe350290072621f7da018f9" }, "transactions": [ { @@ -191,14 +185,14 @@ "rlp": "0xf901430182ab63b9010004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000f83af838941000000000000000000000000000000000000000e1a0000000000000000000000000000000000000000000000000000000000000000200" } ], - "rlp": "0xf902a5f9023ba05f1be79dcdc16fee9d4ab1d3d4897cc4b5c83cd9d8fa5ae386c6c946a7ef6fbda01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa0b9a55a1802de0027ec09c5986ca69fe72b8c4aa9adbc730bccbcdb756cea583da08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba04b93b3c0006d672c5dfd4094132d3e8acd463e7cb018f86df29136c9a399d0b6b901000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000080018502540be40082ab638203e800a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0c0", + "rlp": "0xf902a5f9023ba075a4d8212bde5c7f1b8244a3b67f8d861ac8e8853fff7b49df9b39a9ebb35f8ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa09b05669ff84a53f8b25cef1ceb583d5f42516b19b5af9f8216b42c07f8243e36a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba04b93b3c0006d672c5dfd4094132d3e8acd463e7cb018f86df29136c9a399d0b6b901000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000080018502540be40082ab638203e800a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0c0", "blocknumber": "1" } ], "sealEngine": "NoProof", "_info": { - "hash": "0x146e88fc9227a989608c555e205c9f27e5e44c1830339370d2a1a6b74aeb4955", - "fixture_format": "blockchain_test" + "hash": "0xfdbdced77f3303f51cbeeacc810a76649e5e2e291904dc1c83d66a8bbcec9137", + "fixture-format": "blockchain_test" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_0.json index 05734ebb0b8..344bc943907 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_0.json @@ -111,7 +111,7 @@ }, "_info": { "hash": "0xb58e509f61be2d5f339749a1ec8972af7ac414628f48cd54d5e34976a8c30936", - "fixture_format": "state_test" + "fixture-format": "state_test" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_1.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_1.json index 8e337c8fa9b..38275ce0fbc 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_1.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_cancun_state_test_tx_type_1.json @@ -122,7 +122,7 @@ }, "_info": { "hash": "0x4d0b9098cadad7f8f25595c08763f677a8c6a4d0b8d3e2dcbd3ba6943fc93cca", - "fixture_format": "state_test" + "fixture-format": "state_test" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_istanbul_blockchain_test_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_istanbul_blockchain_test_tx_type_0.json index 024b092b1c7..87d39d3aeb6 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_istanbul_blockchain_test_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_istanbul_blockchain_test_tx_type_0.json @@ -124,7 +124,7 @@ "sealEngine": "NoProof", "_info": { "hash": "0x57a6f950bef3a44741ac3617e53f37bb55b124ce2e26d02508b217e6d351eba8", - "fixture_format": "blockchain_test" + "fixture-format": "blockchain_test" } } -} \ No newline at end of file +} diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_london_blockchain_test_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_london_blockchain_test_tx_type_0.json index 6ea499bbc59..8cba96de04c 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_london_blockchain_test_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_london_blockchain_test_tx_type_0.json @@ -126,7 +126,7 @@ "sealEngine": "NoProof", "_info": { "hash": "0xc2da7ab682d573a2ff88b987526c1ae2d5abac2c738b575294b7976c5358078b", - "fixture_format": "blockchain_test" + "fixture-format": "blockchain_test" } } -} \ No newline at end of file +} diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_blockchain_test_engine_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_blockchain_test_engine_tx_type_0.json index 43ec7fa05c4..31e310add56 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_blockchain_test_engine_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_blockchain_test_engine_tx_type_0.json @@ -1,7 +1,7 @@ { "000/my_chain_id_test/Paris/tx_type_0": { "network": "Paris", - "lastblockhash": "0x362beffce981f639df5ffe88b7ab93a31c82c2b06de09d91d04584c9d8af7445", + "lastblockhash": "0xd6e5b3f7b2720ab2347ee0d6c199304c367806fc285c5dca46414a459ada37eb", "config": { "network": "Paris", "chainid": "0x01" @@ -10,19 +10,7 @@ "0x2000000000000000000000000000000000000001": { "nonce": "0x01", "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, - "0xbabe2bed00000000000000000000000000000003": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", - "storage": {} - }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", - "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -42,7 +30,7 @@ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xca9c5568ade9b987822c889d34c2edb5297b5920379a0bed04a08d5a7eff2d12", + "stateRoot": "0x099bdebe7a4c999459d48e5d664f15343d10948d2ee9616b7bf597163735c0fa", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -55,25 +43,13 @@ "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", "baseFeePerGas": "0x07", - "hash": "0x9faba6a4a272baf830f60caf8780bc79af6b58eada90454897aa4e0b0b00a05a" + "hash": "0x22fe81f7301e8ddb27ecc5f31eda2982af3d450e3d59e4d01f76e19c8ef20930" }, "postState": { "0x2000000000000000000000000000000000000001": { "nonce": "0x01", "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, - "0xbabe2bed00000000000000000000000000000003": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", - "storage": {} - }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", - "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -90,6 +66,12 @@ "code": "0x", "storage": {} }, + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x", + "storage": {} + }, "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { "nonce": "0x00", "balance": "0x020229", @@ -107,9 +89,9 @@ { "params": [ { - "parentHash": "0x9faba6a4a272baf830f60caf8780bc79af6b58eada90454897aa4e0b0b00a05a", + "parentHash": "0x22fe81f7301e8ddb27ecc5f31eda2982af3d450e3d59e4d01f76e19c8ef20930", "feeRecipient": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "stateRoot": "0xdfa28587a5343f55aed898f2d84daec28bf2f449bbbc8eec003525e6d660d75e", + "stateRoot": "0xc310470978f6327b545ee1fecdd5ea8ee904f0d864a640108f1f4b5f803184db", "receiptsRoot": "0x4b93b3c0006d672c5dfd4094132d3e8acd463e7cb018f86df29136c9a399d0b6", "logsBloom": "0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000", "blockNumber": "0x1", @@ -119,7 +101,7 @@ "extraData": "0x00", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x7", - "blockHash": "0x362beffce981f639df5ffe88b7ab93a31c82c2b06de09d91d04584c9d8af7445", + "blockHash": "0xd6e5b3f7b2720ab2347ee0d6c199304c367806fc285c5dca46414a459ada37eb", "transactions": [ "0xf861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b" ] @@ -130,8 +112,8 @@ } ], "_info": { - "hash": "0x7ea1ffaf32adb73116ef65759d75c5f819cdc0fc9eb4cf591e63bbaa2f7b4c7b", - "fixture_format": "blockchain_test_engine" + "hash": "0x3c977c86585f56f5f2b48d9a887e7774bf09eebe10243be6662e52707174f7a2", + "fixture-format": "blockchain_test_engine" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_state_test_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_state_test_tx_type_0.json index 1b65ae01a27..f7807f33b16 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_state_test_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_paris_state_test_tx_type_0.json @@ -103,7 +103,7 @@ }, "_info": { "hash": "0xf36639a4c77a212cffb234afced994bab0286aeddc136371f1e48831dc7fd2e2", - "fixture_format": "state_test" + "fixture-format": "state_test" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_blockchain_test_engine_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_blockchain_test_engine_tx_type_0.json index a37f9fea4b2..7986e518b49 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_blockchain_test_engine_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_blockchain_test_engine_tx_type_0.json @@ -1,28 +1,22 @@ { "000/my_chain_id_test/Shanghai/tx_type_0": { "network": "Shanghai", - "lastblockhash": "0x43fa72a356b61dae7028432054a5b40b4e42a9d1a17dee73dba48edfc9e23f49", + "lastblockhash": "0xc0b7de455f5a94d519ba5907d6a7d36300839f638dfbf3de3741ea3ee29bfe27", "config": { "network": "Shanghai", "chainid": "0x01" }, "pre": { - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -42,7 +36,7 @@ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xca9c5568ade9b987822c889d34c2edb5297b5920379a0bed04a08d5a7eff2d12", + "stateRoot": "0x93c4929c2c98a3a69468e26283ed7f847a0d5e091c9fb70b4832a47fa8c1ecb4", "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -56,25 +50,19 @@ "nonce": "0x0000000000000000", "baseFeePerGas": "0x07", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "hash": "0x33a0f59218d39524f9b0548be4dcb86485810bba4102f6543e8ef7919baa0d51" + "hash": "0xfaec90aebaf8cc749e844dfd7fc990878bf23160985b676521efac9b17cfb16a" }, "postState": { - "0x2000000000000000000000000000000000000001": { - "nonce": "0x01", - "balance": "0x00", - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004a6004803603810190610045919061014a565b610061565b604051610058929190610383565b60405180910390f35b60608060405160408152606060208201526000604082015260006060820152608081f35b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126100b4576100b361008f565b5b8235905067ffffffffffffffff8111156100d1576100d0610094565b5b6020830191508360208202830111156100ed576100ec610099565b5b9250929050565b60008083601f84011261010a5761010961008f565b5b8235905067ffffffffffffffff81111561012757610126610094565b5b60208301915083602082028301111561014357610142610099565b5b9250929050565b6000806000806040858703121561016457610163610085565b5b600085013567ffffffffffffffff8111156101825761018161008a565b5b61018e8782880161009e565b9450945050602085013567ffffffffffffffff8111156101b1576101b061008a565b5b6101bd878288016100f4565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610222826101f7565b9050919050565b61023281610217565b82525050565b60006102448383610229565b60208301905092915050565b6000602082019050919050565b6000610268826101cb565b61027281856101d6565b935061027d836101e7565b8060005b838110156102ae5781516102958882610238565b97506102a083610250565b925050600181019050610281565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6102fa816102e7565b82525050565b600061030c83836102f1565b60208301905092915050565b6000602082019050919050565b6000610330826102bb565b61033a81856102c6565b9350610345836102d7565b8060005b8381101561037657815161035d8882610300565b975061036883610318565b925050600181019050610349565b5085935050505092915050565b6000604082019050818103600083015261039d818561025d565b905081810360208301526103b18184610325565b9050939250505056fea2646970667358221220982a80ca13c9563653950e1e7eeabf23b31ed76a9c908ebc707f8cb83c70dee664736f6c634300081e0033", - "storage": {} - }, "0xbabe2bed00000000000000000000000000000003": { "nonce": "0x01", "balance": "0x00", "code": "0x608060405260043610610049575f3560e01c806301ffc9a71461004d5780632289511814610081578063621fd1301461009657806379d0c0bc146100b7578063c5f2892f146100d8575b5f5ffd5b348015610058575f5ffd5b5061006c610067366004610cbe565b6100fa565b60405190151581526020015b60405180910390f35b61009461008f366004610d31565b610130565b005b3480156100a1575f5ffd5b506100aa610941565b6040516100789190610e06565b3480156100c2575f5ffd5b506100946100d1366004610e59565b5050505050565b3480156100e3575f5ffd5b506100ec610953565b604051908152602001610078565b5f6001600160e01b031982166301ffc9a760e01b148061012a57506001600160e01b03198216638564090760e01b145b92915050565b603086146101945760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084015b60405180910390fd5b602084146102035760405162461bcd60e51b815260206004820152603660248201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616044820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606482015260840161018b565b606082146102655760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b606482015260840161018b565b670de0b6b3a76400003410156102cc5760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b606482015260840161018b565b6102da633b9aca0034610ee6565b156103435760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b606482015260840161018b565b5f610352633b9aca0034610f0d565b905067ffffffffffffffff8111156103bc5760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b606482015260840161018b565b5f6103c682610b14565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6103fb602054610b14565b60405161040f989796959493929190610f48565b60405180910390a15f60028a8a5f60801b60405160200161043293929190610fba565b60408051601f198184030181529082905261044c91610ff8565b602060405180830381855afa158015610467573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061048a9190611003565b90505f60028061049d6040848a8c61101a565b6040516020016104ae929190611041565b60408051601f19818403018152908290526104c891610ff8565b602060405180830381855afa1580156104e3573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105069190611003565b6002610515896040818d61101a565b6040516105289291905f90602001611050565b60408051601f198184030181529082905261054291610ff8565b602060405180830381855afa15801561055d573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105809190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526105ac91610ff8565b602060405180830381855afa1580156105c7573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906105ea9190611003565b90505f600280848c8c60405160200161060593929190611062565b60408051601f198184030181529082905261061f91610ff8565b602060405180830381855afa15801561063a573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061065d9190611003565b6040516002906106759088905f90889060200161107b565b60408051601f198184030181529082905261068f91610ff8565b602060405180830381855afa1580156106aa573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cd9190611003565b60408051602081019390935282015260600160408051601f19818403018152908290526106f991610ff8565b602060405180830381855afa158015610714573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107379190611003565b90508581146107cb5760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a40161018b565b60016107d960206002611188565b6107e39190611193565b6020541061083d5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b606482015260840161018b565b600160205f82825461084f91906111a6565b90915550506020545f5b6020811015610928578160011660010361088f57825f8260208110610880576108806111b9565b01555061093895505050505050565b60025f82602081106108a3576108a36111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526108d391610ff8565b602060405180830381855afa1580156108ee573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109119190611003565b925061091e600283610f0d565b9150600101610859565b506109316111cd565b5050505050505b50505050505050565b606061094e602054610b14565b905090565b6020545f908190815b6020811015610a9357816001166001036109f95760025f8260208110610984576109846111b9565b0154604080516020810192909252810185905260600160408051601f19818403018152908290526109b491610ff8565b602060405180830381855afa1580156109cf573d5f5f3e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109f29190611003565b9250610a7e565b60028360218360208110610a0f57610a0f6111b9565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a3d91610ff8565b602060405180830381855afa158015610a58573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610a7b9190611003565b92505b610a89600283610f0d565b915060010161095c565b50600282610aa2602054610b14565b604051610ab59291905f906020016111e1565b60408051601f1981840301815290829052610acf91610ff8565b602060405180830381855afa158015610aea573d5f5f3e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610b0d9190611003565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b825f81518110610b5357610b536111b9565b60200101906001600160f81b03191690815f1a9053508060061a60f81b82600181518110610b8357610b836111b9565b60200101906001600160f81b03191690815f1a9053508060051a60f81b82600281518110610bb357610bb36111b9565b60200101906001600160f81b03191690815f1a9053508060041a60f81b82600381518110610be357610be36111b9565b60200101906001600160f81b03191690815f1a9053508060031a60f81b82600481518110610c1357610c136111b9565b60200101906001600160f81b03191690815f1a9053508060021a60f81b82600581518110610c4357610c436111b9565b60200101906001600160f81b03191690815f1a9053508060011a60f81b82600681518110610c7357610c736111b9565b60200101906001600160f81b03191690815f1a905350805f1a60f81b82600781518110610ca257610ca26111b9565b60200101906001600160f81b03191690815f1a90535050919050565b5f60208284031215610cce575f5ffd5b81356001600160e01b031981168114610ce5575f5ffd5b9392505050565b5f5f83601f840112610cfc575f5ffd5b50813567ffffffffffffffff811115610d13575f5ffd5b602083019150836020828501011115610d2a575f5ffd5b9250929050565b5f5f5f5f5f5f5f6080888a031215610d47575f5ffd5b873567ffffffffffffffff811115610d5d575f5ffd5b610d698a828b01610cec565b909850965050602088013567ffffffffffffffff811115610d88575f5ffd5b610d948a828b01610cec565b909650945050604088013567ffffffffffffffff811115610db3575f5ffd5b610dbf8a828b01610cec565b989b979a50959894979596606090950135949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610ce56020830184610dd8565b5f5f83601f840112610e28575f5ffd5b50813567ffffffffffffffff811115610e3f575f5ffd5b6020830191508360208260051b8501011115610d2a575f5ffd5b5f5f5f5f5f60608688031215610e6d575f5ffd5b85359450602086013567ffffffffffffffff811115610e8a575f5ffd5b610e9688828901610e18565b909550935050604086013567ffffffffffffffff811115610eb5575f5ffd5b610ec188828901610e18565b969995985093965092949392505050565b634e487b7160e01b5f52601260045260245ffd5b5f82610ef457610ef4610ed2565b500690565b634e487b7160e01b5f52601160045260245ffd5b5f82610f1b57610f1b610ed2565b500490565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60a081525f610f5b60a083018a8c610f20565b8281036020840152610f6e81898b610f20565b90508281036040840152610f828188610dd8565b90508281036060840152610f97818688610f20565b90508281036080840152610fab8185610dd8565b9b9a5050505050505050505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b5f81518060208401855e5f93019283525090919050565b5f610ce58284610fe1565b5f60208284031215611013575f5ffd5b5051919050565b5f5f85851115611028575f5ffd5b83861115611034575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b82848237909101908152602001919050565b838152818360208301375f910160200190815292915050565b5f6110868286610fe1565b67ffffffffffffffff1994909416845250506018820152603801919050565b6001815b60018411156110e0578085048111156110c4576110c4610ef9565b60018416156110d257908102905b60019390931c9280026110a9565b935093915050565b5f826110f65750600161012a565b8161110257505f61012a565b816001811461111857600281146111225761113e565b600191505061012a565b60ff84111561113357611133610ef9565b50506001821b61012a565b5060208310610133831016604e8410600b8410161715611161575081810a61012a565b61116d5f1984846110a5565b805f190482111561118057611180610ef9565b029392505050565b5f610ce583836110e8565b8181038181111561012a5761012a610ef9565b8082018082111561012a5761012a610ef9565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6111f26020830185610fe1565b67ffffffffffffffff1993909316835250506018019291505056fea2646970667358221220d5419cc0e0a5f606255d3c6c49ccb84f3b8e6072b7752ee97b0638739de3963664736f6c634300081e003313838361119f565b8181038181111561013657610136610fb0565b8082018082111561013657610136610fb0565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52600160045260245ffd5b8381525f6112a96020830185611098565b67ffffffffffffffff1993909316835250506018019291505056fea264697066735822122051f5c50d19b9f3881ca9e6b0c05a3db947d64a57f60ca5ae395a5bbd192cee4e64736f6c634300081e0033363130393834363131316239353635623031353436303430383035313630323038313031393239303932353238313031383539303532363036303031363034303830353136303166313938313834303330313831353239303832393035323631303962343931363130666638353635623630323036303430353138303833303338313835356166613135383031353631303963663537336435663566336533643566666435623530353035303630343035313364363031663139363031663832303131363832303138303630343035323530383130313930363130396632393139303631313030333536356239323530363130613765353635623630303238333630323138333630323038313130363130613066353736313061306636313131623935363562303135343630343038303531363032303831303139333930393335323832303135323630363030313630343038303531363031663139383138343033303138313532393038323930353236313061336439313631306666383536356236303230363034303531383038333033383138353561666131353830313536313061353835373364356635663365336435666664356235303530353036303430353133643630316631393630316638323031313638323031383036303430353235303831303139303631306137623931393036313130303335363562393235303562363130613839363030323833363130663064353635623931353036303031303136313039356335363562353036303032383236313061613236303230353436313062313435363562363034303531363130616235393239313930356639303630323030313631313165313536356236303430383035313630316631393831383430333031383135323930383239303532363130616366393136313066663835363562363032303630343035313830383330333831383535616661313538303135363130616561353733643566356633653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313062306439313930363131303033353635623932353035303530393035363562363034303830353136303038383038323532383138333031393039323532363036303931363032303832303138313830333638333337303139303530353039303530363063303832393031623830363030373161363066383162383235663831353138313130363130623533353736313062353336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303631613630663831623832363030313831353138313130363130623833353736313062383336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303531613630663831623832363030323831353138313130363130626233353736313062623336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303431613630663831623832363030333831353138313130363130626533353736313062653336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303331613630663831623832363030343831353138313130363130633133353736313063313336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303231613630663831623832363030353831353138313130363130633433353736313063343336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303630303131613630663831623832363030363831353138313130363130633733353736313063373336313131623935363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353038303566316136306638316238323630303738313531383131303631306361323537363130636132363131316239353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530353039313930353035363562356636303230383238343033313231353631306363653537356635666664356238313335363030313630303136306530316230333139383131363831313436313063653535373566356666643562393339323530353035303536356235663566383336303166383430313132363130636663353735663566666435623530383133353637666666666666666666666666666666663831313131353631306431333537356635666664356236303230383330313931353038333630323038323835303130313131313536313064326135373566356666643562393235303932393035303536356235663566356635663566356635663630383038383861303331323135363130643437353735663566666435623837333536376666666666666666666666666666666638313131313536313064356435373566356666643562363130643639386138323862303136313063656335363562393039383530393635303530363032303838303133353637666666666666666666666666666666663831313131353631306438383537356635666664356236313064393438613832386230313631306365633536356239303936353039343530353036303430383830313335363766666666666666666666666666666666383131313135363130646233353735663566666435623631306462663861383238623031363130636563353635623938396239373961353039353938393439373935393636303630393039353031333539343933353035303530353035363562356638313531383038343532383036303230383430313630323038363031356535663630323038323836303130313532363032303630316631393630316638333031313638353031303139313530353039323931353035303536356236303230383135323566363130636535363032303833303138343631306464383536356235663566383336303166383430313132363130653238353735663566666435623530383133353637666666666666666666666666666666663831313131353631306533663537356635666664356236303230383330313931353038333630323038323630303531623835303130313131313536313064326135373566356666643562356635663566356635663630363038363838303331323135363130653664353735663566666435623835333539343530363032303836303133353637666666666666666666666666666666663831313131353631306538613537356635666664356236313065393638383832383930313631306531383536356239303935353039333530353036303430383630313335363766666666666666666666666666666666383131313135363130656235353735663566666435623631306563313838383238393031363130653138353635623936393939353938353039333936353039323934393339323530353035303536356236333465343837623731363065303162356635323630313236303034353236303234356666643562356638323631306566343537363130656634363130656432353635623530303639303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562356638323631306631623537363130663162363130656432353635623530303439303536356238313833353238313831363032303835303133373530356638323832303136303230393038313031393139303931353236303166393039313031363031663139313639303931303130313930353635623630613038313532356636313066356236306130383330313861386336313066323035363562383238313033363032303834303135323631306636653831383938623631306632303536356239303530383238313033363034303834303135323631306638323831383836313064643835363562393035303832383130333630363038343031353236313066393738313836383836313066323035363562393035303832383130333630383038343031353236313066616238313835363130646438353635623962396135303530353035303530353035303530353035303530353635623832383438323337366666666666666666666666666666666666666666666666666666666666666666663139393139303931313639313031393038313532363031303031393139303530353635623566383135313830363032303834303138353565356639333031393238333532353039303931393035303536356235663631306365353832383436313066653135363562356636303230383238343033313231353631313031333537356635666664356235303531393139303530353635623566356638353835313131353631313032383537356635666664356238333836313131353631313033343537356635666664356235303530383230313933393139303932303339313530353635623831383338323337356639313031393038313532393139303530353635623832383438323337393039313031393038313532363032303031393139303530353635623833383135323831383336303230383330313337356639313031363032303031393038313532393239313530353035363562356636313130383638323836363130666531353635623637666666666666666666666666666666663139393439303934313638343532353035303630313838323031353236303338303139313930353035363562363030313831356236303031383431313135363131306530353738303835303438313131313536313130633435373631313063343631306566393536356236303031383431363135363131306432353739303831303239303562363030313933393039333163393238303032363131306139353635623933353039333931353035303536356235663832363131306636353735303630303136313031326135363562383136313131303235373530356636313031326135363562383136303031383131343631313131383537363030323831313436313131323235373631313133653536356236303031393135303530363130313261353635623630666638343131313536313131333335373631313133333631306566393536356235303530363030313832316236313031326135363562353036303230383331303631303133333833313031363630346538343130363030623834313031363137313536313131363135373530383138313061363130313261353635623631313136643566313938343834363131306135353635623830356631393034383231313135363131313830353736313131383036313065663935363562303239333932353035303530353635623566363130636535383338333631313065383536356238313831303338313831313131353631303132613537363130313261363130656639353635623830383230313830383231313135363130313261353736313031326136313065663935363562363334653438376237313630653031623566353236303332363030343532363032343566666435623633346534383762373136306530316235663532363030313630303435323630323435666664356238333831353235663631313166323630323038333031383536313066653135363562363766666666666666666666666666666666313939333930393331363833353235303530363031383031393239313530353035366665613236343639373036363733353832323132323032363164656233353031313939323139653161336235666130303961313561396237313331383261613731376266326563353736343165323638396235643263363437333666366336333433303030383165303033330a", "storage": {} }, - "0xfffffffffffffffffffffffffffffffffffffffe": { - "nonce": "0x00", + "0x2000000000000000000000000000000000000001": { + "nonce": "0x01", "balance": "0x00", - "code": "0x", + "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f91c289814610030575b600080fd5b61004361003e3660046101c4565b61005a565b604051610051929190610299565b60405180910390f35b6060808251845114158061007057508351600114155b8061009a57508260008151811061008957610089610324565b602002602001015161ffff16600014155b156100bd57505060408051600080825260208201908152818301909252906100d7565b505060408051600080825260208201908152818301909252905b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561011c5761011c6100de565b604052919050565b60006001600160401b0382111561013d5761013d6100de565b5060051b60200190565b600082601f83011261015857600080fd5b813561016b61016682610124565b6100f4565b8082825260208201915060208360051b86010192508583111561018d57600080fd5b602085015b838110156101ba57803561ffff811681146101ac57600080fd5b835260209283019201610192565b5095945050505050565b600080604083850312156101d757600080fd5b82356001600160401b038111156101ed57600080fd5b8301601f810185136101fe57600080fd5b803561020c61016682610124565b8082825260208201915060208360051b85010192508783111561022e57600080fd5b6020840193505b828410156102655783356001600160a01b038116811461025457600080fd5b825260209384019390910190610235565b945050505060208301356001600160401b0381111561028357600080fd5b61028f85828601610147565b9150509250929050565b6040808252835190820181905260009060208501906060840190835b818110156102dc5783516001600160a01b03168352602093840193909201916001016102b5565b50508381036020808601919091528551808352918101925085019060005b818110156103185782518452602093840193909201916001016102fa565b50919695505050505050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220e77ead904fbb7a75873cc80c7781732415820e98fce4340752c326fc2e650c8764736f6c63430008220033", "storage": {} }, "0x1000000000000000000000000000000000000000": { @@ -91,6 +79,12 @@ "code": "0x", "storage": {} }, + "0xfffffffffffffffffffffffffffffffffffffffe": { + "nonce": "0x00", + "balance": "0x00", + "code": "0x", + "storage": {} + }, "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": { "nonce": "0x00", "balance": "0x020229", @@ -108,9 +102,9 @@ { "params": [ { - "parentHash": "0x33a0f59218d39524f9b0548be4dcb86485810bba4102f6543e8ef7919baa0d51", + "parentHash": "0xfaec90aebaf8cc749e844dfd7fc990878bf23160985b676521efac9b17cfb16a", "feeRecipient": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "stateRoot": "0xdfa28587a5343f55aed898f2d84daec28bf2f449bbbc8eec003525e6d660d75e", + "stateRoot": "0x46164412f49cb2af8c1549b669dab500dfc878e048cabb466c5d4d6c56566877", "receiptsRoot": "0x4b93b3c0006d672c5dfd4094132d3e8acd463e7cb018f86df29136c9a399d0b6", "logsBloom": "0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000", "blockNumber": "0x1", @@ -120,7 +114,7 @@ "extraData": "0x00", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "baseFeePerGas": "0x7", - "blockHash": "0x43fa72a356b61dae7028432054a5b40b4e42a9d1a17dee73dba48edfc9e23f49", + "blockHash": "0xc0b7de455f5a94d519ba5907d6a7d36300839f638dfbf3de3741ea3ee29bfe27", "transactions": [ "0xf861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b" ], @@ -132,8 +126,8 @@ } ], "_info": { - "hash": "0xdf52517806ed1d45acc613db1163680878b14019dd8861317d00eaaa27e1b839", - "fixture_format": "blockchain_test_engine" + "hash": "0xd7f7c6bde7262f05e550b9983a72b210e583b2258cb6f2b0c1622e18ece59205", + "fixture-format": "blockchain_test_engine" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_state_test_tx_type_0.json b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_state_test_tx_type_0.json index 866bc7a0a79..f79fa582002 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_state_test_tx_type_0.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/chainid_shanghai_state_test_tx_type_0.json @@ -103,7 +103,7 @@ }, "_info": { "hash": "0xc857c3dc8f5567871b869b41d0f4ddf481a2d923e87df18b0b2e39dad42aedbe", - "fixture_format": "state_test" + "fixture-format": "state_test" } } -} +} \ No newline at end of file diff --git a/packages/testing/src/execution_testing/specs/tests/fixtures/tx_simple_type_0_shanghai.json b/packages/testing/src/execution_testing/specs/tests/fixtures/tx_simple_type_0_shanghai.json index 4dfc66a72ce..d6da0eb446c 100644 --- a/packages/testing/src/execution_testing/specs/tests/fixtures/tx_simple_type_0_shanghai.json +++ b/packages/testing/src/execution_testing/specs/tests/fixtures/tx_simple_type_0_shanghai.json @@ -1,16 +1,16 @@ { "fixture": { - "_info" : { - "hash" : "0x3c588e18802a3c0c875da0e7bc8f9066369572c30d11e2568a516650216a33e7", + "_info": { + "hash": "0x3c588e18802a3c0c875da0e7bc8f9066369572c30d11e2568a516650216a33e7", "fixture_format": "transaction_test" }, - "result" : { - "Shanghai" : { - "hash" : "0x1997251035c9109e5cad5b146251579be13bbd91a17bf628b7cbb5f25dad73e2", - "intrinsicGas" : "0x5208", - "sender" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" + "result": { + "Shanghai": { + "hash": "0x1997251035c9109e5cad5b146251579be13bbd91a17bf628b7cbb5f25dad73e2", + "intrinsicGas": "0x5208", + "sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" } }, - "txbytes" : "0xf85f800a8252089400000000000000000000000000000000000000aa808026a0cc61d852649c34cc0b71803115f38036ace257d2914f087bf885e6806a664fbda02020cb35f5d7731ab540d62614503a7f2344301a86342f67daf011c1341551ff" + "txbytes": "0xf85f800a8252089400000000000000000000000000000000000000aa808026a0cc61d852649c34cc0b71803115f38036ace257d2914f087bf885e6806a664fbda02020cb35f5d7731ab540d62614503a7f2344301a86342f67daf011c1341551ff" } -} \ No newline at end of file +} diff --git a/packages/testing/src/execution_testing/specs/tests/test_fixtures.py b/packages/testing/src/execution_testing/specs/tests/test_fixtures.py index 2e0cbf32783..39a24196144 100644 --- a/packages/testing/src/execution_testing/specs/tests/test_fixtures.py +++ b/packages/testing/src/execution_testing/specs/tests/test_fixtures.py @@ -53,11 +53,11 @@ def fixture_hash(fork: Fork) -> bytes: """Set the fixture hash based on the fork.""" if fork == Berlin: - return bytes.fromhex("ffeca9eaa3") + return bytes.fromhex("036e606aae") elif fork == London: - return bytes.fromhex("d8d065b255") + return bytes.fromhex("1c0cb097a4") elif fork == Cancun: - return bytes.fromhex("506ca77260") + return bytes.fromhex("c54a8f4a30") raise ValueError(f"Unexpected fork: {fork}") diff --git a/packages/testing/src/execution_testing/test_types/block_types.py b/packages/testing/src/execution_testing/test_types/block_types.py index 44b8b735b2e..c5284bc5b29 100644 --- a/packages/testing/src/execution_testing/test_types/block_types.py +++ b/packages/testing/src/execution_testing/test_types/block_types.py @@ -18,6 +18,7 @@ Hash, HexNumber, NumberBoundTypeVar, + TestAddress, ZeroPaddedHexNumber, ) from execution_testing.forks import Fork @@ -204,6 +205,13 @@ def set_fork_requirements(self, fork: Fork) -> "Environment": if fork.header_slot_number_required() and self.slot_number is None: updated_values["slot_number"] = 0 + if ( + not fork.header_zero_difficulty_required() + and int(self.number) != 0 + ): + updated_values["fee_recipient"] = TestAddress + updated_values["difficulty"] = (1 << 128) - 2 + return self.copy(**updated_values) def __hash__(self) -> int: diff --git a/src/ethereum/forks/arrow_glacier/fork.py b/src/ethereum/forks/arrow_glacier/fork.py index d83e3fdffb4..c8fe30eb440 100644 --- a/src/ethereum/forks/arrow_glacier/fork.py +++ b/src/ethereum/forks/arrow_glacier/fork.py @@ -14,6 +14,7 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint @@ -30,6 +31,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -46,14 +48,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -67,17 +71,26 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 10700000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +FEE_COLLECTOR_ADDRESS = hex_to_address( + "0x1559000000000000000000000000000000000000" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -198,7 +211,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -563,10 +575,76 @@ def make_receipt( return encode_receipt(tx, receipt) +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + index_in_block=None, + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[LegacyTransaction | Bytes, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -584,9 +662,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -596,11 +671,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -680,46 +755,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -836,6 +871,18 @@ def process_transaction( elif account_exists_and_is_empty(tx_state, block_env.coinbase): destroy_account(tx_state, block_env.coinbase) + # transfer base fee to fee collector address + base_fee = U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) + if base_fee != 0: + fee_collector_balance = get_account( + tx_state, FEE_COLLECTOR_ADDRESS + ).balance + set_account_balance( + tx_state, + FEE_COLLECTOR_ADDRESS, + fee_collector_balance + base_fee, + ) + for address in tx_output.accounts_to_delete: destroy_account(tx_state, address) @@ -861,6 +908,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/arrow_glacier/vm/interpreter.py b/src/ethereum/forks/arrow_glacier/vm/interpreter.py index a57203fdefe..5d5a9b49b1f 100644 --- a/src/ethereum/forks/arrow_glacier/vm/interpreter.py +++ b/src/ethereum/forks/arrow_glacier/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -77,6 +77,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -85,6 +86,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -117,6 +119,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -147,6 +150,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/berlin/fork.py b/src/ethereum/forks/berlin/fork.py index c97256fddec..b754340f765 100644 --- a/src/ethereum/forks/berlin/fork.py +++ b/src/ethereum/forks/berlin/fork.py @@ -14,6 +14,7 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint @@ -30,6 +31,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -42,14 +44,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -62,15 +66,21 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 9000000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -190,7 +200,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -456,10 +465,76 @@ def make_receipt( return encode_receipt(tx, receipt) +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=Uint(0), + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + index_in_block=None, + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[LegacyTransaction | Bytes, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -477,9 +552,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -489,11 +561,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -573,46 +645,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -746,6 +778,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/berlin/vm/interpreter.py b/src/ethereum/forks/berlin/vm/interpreter.py index 9efc07bc5b4..ca83f636ed3 100644 --- a/src/ethereum/forks/berlin/vm/interpreter.py +++ b/src/ethereum/forks/berlin/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -76,6 +76,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -84,6 +85,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -116,6 +118,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -146,6 +149,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index fc2e22e040f..43defe78997 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -37,6 +37,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -59,12 +60,14 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, destroy_account, extract_block_diff, get_account, get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -808,7 +811,9 @@ def process_transaction( tx_state, FEE_COLLECTOR_ADDRESS ).balance set_account_balance( - tx_state, FEE_COLLECTOR_ADDRESS, fee_collector_balance + base_fee + tx_state, + FEE_COLLECTOR_ADDRESS, + fee_collector_balance + base_fee, ) for address in tx_output.accounts_to_delete: @@ -845,6 +850,14 @@ def process_withdrawals( Spec: https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md """ + wd_state = TransactionState(parent=block_env.state) + deposit_contract = get_account(wd_state, DEPOSIT_CONTRACT_ADDRESS) + if deposit_contract.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(wd_state, SYSTEM_ADDRESS): + set_account(wd_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + amounts = [] addresses = [] for i, wd in enumerate(withdrawals): @@ -869,6 +882,8 @@ def process_withdrawals( if out.error: raise InvalidBlock(f"Withdrawal system call failed: {out.error}") + incorporate_tx_into_block(wd_state) + def process_block_rewards( block_env: vm.BlockEnvironment, @@ -879,15 +894,26 @@ def process_block_rewards( Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 """ - # reward(address[],uint16[]) with empty lists - data = bytes.fromhex( - "f91c2898" - "0000000000000000000000000000000000000000000000000000000000000040" - "0000000000000000000000000000000000000000000000000000000000000060" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) ) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -896,11 +922,6 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - reward_state = TransactionState(parent=block_env.state) - account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) - if account.code_hash == EMPTY_CODE_HASH: - return - if len(out.return_data) == 0: return @@ -909,6 +930,7 @@ def process_block_rewards( address = hex_to_address(addr) balance = get_account(reward_state, address).balance + U256(amount) set_account_balance(reward_state, address, balance) + incorporate_tx_into_block(reward_state) diff --git a/src/ethereum/forks/constantinople/fork.py b/src/ethereum/forks/constantinople/fork.py index 855faf3acb4..fe811d81300 100644 --- a/src/ethereum/forks/constantinople/fork.py +++ b/src/ethereum/forks/constantinople/fork.py @@ -14,7 +14,9 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp +from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint from ethereum.crypto.hash import Hash32, keccak256 @@ -29,6 +31,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -41,14 +44,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -57,15 +62,21 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 5000000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -185,7 +196,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -448,10 +458,72 @@ def make_receipt( return receipt +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=Uint(0), + gas=SYSTEM_TRANSACTION_GAS, + state=system_tx_state, + index_in_block=Uint(0), + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[Transaction, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -469,9 +541,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -481,11 +550,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -565,46 +634,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -723,6 +752,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/constantinople/vm/interpreter.py b/src/ethereum/forks/constantinople/vm/interpreter.py index af3266e95c4..91fc1a6cb28 100644 --- a/src/ethereum/forks/constantinople/vm/interpreter.py +++ b/src/ethereum/forks/constantinople/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -75,6 +75,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -83,6 +84,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -115,6 +117,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -145,6 +148,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/gray_glacier/fork.py b/src/ethereum/forks/gray_glacier/fork.py index 9d44f903b3e..1bd91ff493c 100644 --- a/src/ethereum/forks/gray_glacier/fork.py +++ b/src/ethereum/forks/gray_glacier/fork.py @@ -14,6 +14,7 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint @@ -30,6 +31,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -46,14 +48,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -67,17 +71,26 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 11400000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +FEE_COLLECTOR_ADDRESS = hex_to_address( + "0x1559000000000000000000000000000000000000" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -198,7 +211,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -563,10 +575,76 @@ def make_receipt( return encode_receipt(tx, receipt) +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + index_in_block=None, + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[LegacyTransaction | Bytes, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -584,9 +662,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -596,11 +671,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -680,46 +755,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -836,6 +871,18 @@ def process_transaction( elif account_exists_and_is_empty(tx_state, block_env.coinbase): destroy_account(tx_state, block_env.coinbase) + # transfer base fee to fee collector address + base_fee = U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) + if base_fee != 0: + fee_collector_balance = get_account( + tx_state, FEE_COLLECTOR_ADDRESS + ).balance + set_account_balance( + tx_state, + FEE_COLLECTOR_ADDRESS, + fee_collector_balance + base_fee, + ) + for address in tx_output.accounts_to_delete: destroy_account(tx_state, address) @@ -861,6 +908,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/gray_glacier/vm/interpreter.py b/src/ethereum/forks/gray_glacier/vm/interpreter.py index 945f839fa45..05282fc0063 100644 --- a/src/ethereum/forks/gray_glacier/vm/interpreter.py +++ b/src/ethereum/forks/gray_glacier/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -77,6 +77,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -85,6 +86,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -117,6 +119,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -147,6 +150,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/istanbul/fork.py b/src/ethereum/forks/istanbul/fork.py index 3738b0bfc6e..b7fbdfed040 100644 --- a/src/ethereum/forks/istanbul/fork.py +++ b/src/ethereum/forks/istanbul/fork.py @@ -14,7 +14,9 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp +from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint from ethereum.crypto.hash import Hash32, keccak256 @@ -29,6 +31,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -41,14 +44,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -57,15 +62,21 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 5000000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -185,7 +196,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -448,10 +458,72 @@ def make_receipt( return receipt +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=Uint(0), + gas=SYSTEM_TRANSACTION_GAS, + state=system_tx_state, + index_in_block=Uint(0), + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[Transaction, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -469,9 +541,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -481,11 +550,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -565,46 +634,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -723,6 +752,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/istanbul/vm/interpreter.py b/src/ethereum/forks/istanbul/vm/interpreter.py index f812a5139be..31b93277a25 100644 --- a/src/ethereum/forks/istanbul/vm/interpreter.py +++ b/src/ethereum/forks/istanbul/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -76,6 +76,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -84,6 +85,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -116,6 +118,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -146,6 +149,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/london/fork.py b/src/ethereum/forks/london/fork.py index 2bf18f3e413..6f831484532 100644 --- a/src/ethereum/forks/london/fork.py +++ b/src/ethereum/forks/london/fork.py @@ -14,6 +14,7 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint @@ -31,6 +32,7 @@ from ethereum.fork_criteria import ByBlockNumber from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -47,14 +49,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -68,11 +72,12 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) MINIMUM_DIFFICULTY = Uint(131072) @@ -80,6 +85,14 @@ MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 9700000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +FEE_COLLECTOR_ADDRESS = hex_to_address( + "0x1559000000000000000000000000000000000000" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -200,7 +213,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -572,10 +584,76 @@ def make_receipt( return encode_receipt(tx, receipt) +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=block_env.base_fee_per_gas, + gas=SYSTEM_TRANSACTION_GAS, + access_list_addresses=set(), + access_list_storage_keys=set(), + state=system_tx_state, + index_in_block=None, + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + accessed_addresses=set(), + accessed_storage_keys=set(), + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[LegacyTransaction | Bytes, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -593,9 +671,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -605,11 +680,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -689,46 +764,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -845,6 +880,20 @@ def process_transaction( elif account_exists_and_is_empty(tx_state, block_env.coinbase): destroy_account(tx_state, block_env.coinbase) + # transfer base fee to fee collector address + # FEE_COLLECTOR_ADDRESS is intentionally excluded from touched_accounts + # to prevent it from being destroyed by destroy_touched_empty_accounts. + base_fee = U256(tx_gas_used_after_refund * block_env.base_fee_per_gas) + if base_fee != 0: + fee_collector_balance = get_account( + tx_state, FEE_COLLECTOR_ADDRESS + ).balance + set_account_balance( + tx_state, + FEE_COLLECTOR_ADDRESS, + fee_collector_balance + base_fee, + ) + for address in tx_output.accounts_to_delete: destroy_account(tx_state, address) @@ -870,6 +919,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/london/vm/interpreter.py b/src/ethereum/forks/london/vm/interpreter.py index 5f32151ff55..12723cada58 100644 --- a/src/ethereum/forks/london/vm/interpreter.py +++ b/src/ethereum/forks/london/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -77,6 +77,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -85,6 +86,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -117,6 +119,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -147,6 +150,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/muir_glacier/fork.py b/src/ethereum/forks/muir_glacier/fork.py index 451d36a80de..4b88f29fe14 100644 --- a/src/ethereum/forks/muir_glacier/fork.py +++ b/src/ethereum/forks/muir_glacier/fork.py @@ -14,7 +14,9 @@ from dataclasses import dataclass from typing import List, Optional, Set, Tuple +from eth_abi import decode from ethereum_rlp import rlp +from ethereum_types.bytes import Bytes from ethereum_types.numeric import U64, U256, Uint from ethereum.crypto.hash import Hash32, keccak256 @@ -29,6 +31,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -41,14 +44,16 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, destroy_touched_empty_accounts, extract_block_diff, get_account, + get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -57,15 +62,21 @@ recover_sender, validate_transaction, ) +from .utils.hexadecimal import hex_to_address from .utils.message import prepare_message +from .vm import Message from .vm.gas import GasCosts -from .vm.interpreter import process_message_call +from .vm.interpreter import MessageCallOutput, process_message_call -BLOCK_REWARD = U256(2 * 10**18) MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 9000000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) +SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +SYSTEM_TRANSACTION_GAS = Uint(30000000) @dataclass @@ -185,7 +196,6 @@ def state_transition(chain: BlockChain, block: Block) -> None: block_output = apply_body( block_env=block_env, transactions=block.transactions, - ommers=block.ommers, ) block_diff = extract_block_diff(block_state) block_state_root, _ = chain.state.compute_state_root_and_trie_changes( @@ -450,10 +460,72 @@ def make_receipt( return receipt +def process_unchecked_system_transaction( + block_env: vm.BlockEnvironment, + target_address: Address, + data: Bytes, +) -> MessageCallOutput: + """ + Process a system transaction without checking if the contract contains + code or if the transaction fails. + + Parameters + ---------- + block_env : + The block scoped environment. + target_address : + Address of the contract to call. + data : + Data to pass to the contract. + + Returns + ------- + system_tx_output : `MessageCallOutput` + Output of processing the system transaction. + + """ + system_tx_state = TransactionState(parent=block_env.state) + system_contract_code = get_code( + system_tx_state, + get_account(system_tx_state, target_address).code_hash, + ) + + tx_env = vm.TransactionEnvironment( + origin=SYSTEM_ADDRESS, + gas_price=Uint(0), + gas=SYSTEM_TRANSACTION_GAS, + state=system_tx_state, + index_in_block=Uint(0), + tx_hash=None, + ) + + system_tx_message = Message( + block_env=block_env, + tx_env=tx_env, + caller=SYSTEM_ADDRESS, + target=target_address, + current_target=target_address, + gas=SYSTEM_TRANSACTION_GAS, + value=U256(0), + data=data, + code=system_contract_code, + depth=Uint(0), + code_address=target_address, + should_transfer_value=False, + is_static=False, + parent_evm=None, + ) + + system_tx_output = process_message_call(system_tx_message) + + incorporate_tx_into_block(system_tx_state) + + return system_tx_output + + def apply_body( block_env: vm.BlockEnvironment, transactions: Tuple[Transaction, ...], - ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ Executes a block. @@ -471,9 +543,6 @@ def apply_body( The block scoped environment. transactions : Transactions included in the block. - ommers : - Headers of ancestor blocks which are not direct parents (formerly - uncles.) Returns ------- @@ -483,11 +552,11 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + for i, tx in enumerate(transactions): process_transaction(block_env, block_output, tx, Uint(i)) - pay_rewards(block_env, ommers) - return block_output @@ -567,46 +636,6 @@ def validate_ommers( raise InvalidBlock -def pay_rewards( - block_env: vm.BlockEnvironment, - ommers: Tuple[Header, ...], -) -> None: - """ - Pay rewards to the block miner as well as the ommers miners. - - The miner of the canonical block is rewarded with the predetermined - block reward, ``BLOCK_REWARD``, plus a variable award based off of the - number of ommer blocks that were mined around the same time, and included - in the canonical block's header. An ommer block is a block that wasn't - added to the canonical blockchain because it wasn't validated as fast as - the accepted block but was mined at the same time. Although not all blocks - that are mined are added to the canonical chain, miners are still paid a - reward for their efforts. This reward is called an ommer reward and is - calculated based on the number associated with the ommer block that they - mined. - - Parameters - ---------- - block_env : - The block scoped environment. - ommers : - List of ommers mentioned in the current block. - - """ - rewards_state = TransactionState(parent=block_env.state) - ommer_count = U256(len(ommers)) - miner_reward = BLOCK_REWARD + (ommer_count * (BLOCK_REWARD // U256(32))) - create_ether(rewards_state, block_env.coinbase, miner_reward) - - for ommer in ommers: - # Ommer age with respect to the current block. - ommer_age = U256(block_env.number - ommer.number) - ommer_miner_reward = ((U256(8) - ommer_age) * BLOCK_REWARD) // U256(8) - create_ether(rewards_state, ommer.coinbase, ommer_miner_reward) - - incorporate_tx_into_block(rewards_state) - - def process_transaction( block_env: vm.BlockEnvironment, block_output: vm.BlockOutput, @@ -725,6 +754,55 @@ def process_transaction( incorporate_tx_into_block(tx_state) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) + ) + + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + if len(out.return_data) == 0: + return + + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block(reward_state) + + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. diff --git a/src/ethereum/forks/muir_glacier/vm/interpreter.py b/src/ethereum/forks/muir_glacier/vm/interpreter.py index 684e677145a..e24d35e567f 100644 --- a/src/ethereum/forks/muir_glacier/vm/interpreter.py +++ b/src/ethereum/forks/muir_glacier/vm/interpreter.py @@ -14,7 +14,7 @@ from dataclasses import dataclass from typing import Optional, Set, Tuple -from ethereum_types.bytes import Bytes0 +from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U256, Uint, ulen from ethereum.exceptions import EthereumException @@ -76,6 +76,7 @@ class MessageCallOutput: 4. `accounts_to_delete`: Contracts which have self-destructed. 5. `touched_accounts`: Accounts that have been touched. 6. `error`: The error from the execution if any. + 7. `return_data`: The output bytes of the execution. """ gas_left: Uint @@ -84,6 +85,7 @@ class MessageCallOutput: accounts_to_delete: Set[Address] touched_accounts: Set[Address] error: Optional[EthereumException] + return_data: Bytes def process_message_call(message: Message) -> MessageCallOutput: @@ -116,6 +118,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=set(), touched_accounts=set(), error=AddressCollision(), + return_data=Bytes(b""), ) else: evm = process_create_message(message) @@ -146,6 +149,7 @@ def process_message_call(message: Message) -> MessageCallOutput: accounts_to_delete=accounts_to_delete, touched_accounts=touched_accounts, error=evm.error, + return_data=evm.output, ) diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index c3f7f4c98d5..d7da8fb15f7 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -38,6 +38,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -69,12 +70,14 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, destroy_account, extract_block_diff, get_account, get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -1044,6 +1047,14 @@ def process_withdrawals( Spec: https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md """ + wd_state = TransactionState(parent=block_env.state) + deposit_contract = get_account(wd_state, DEPOSIT_CONTRACT_ADDRESS) + if deposit_contract.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(wd_state, SYSTEM_ADDRESS): + set_account(wd_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + amounts = [] addresses = [] for i, wd in enumerate(withdrawals): @@ -1068,6 +1079,8 @@ def process_withdrawals( if out.error: raise InvalidBlock(f"Withdrawal system call failed: {out.error}") + incorporate_tx_into_block(wd_state) + def process_block_rewards( block_env: vm.BlockEnvironment, @@ -1078,15 +1091,26 @@ def process_block_rewards( Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 """ - # reward(address[],uint16[]) with empty lists - data = bytes.fromhex( - "f91c2898" - "0000000000000000000000000000000000000000000000000000000000000040" - "0000000000000000000000000000000000000000000000000000000000000060" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) ) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -1095,11 +1119,6 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - reward_state = TransactionState(parent=block_env.state) - account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) - if account.code_hash == EMPTY_CODE_HASH: - return - if len(out.return_data) == 0: return diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 7eaa6565799..4800677666a 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -36,6 +36,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -52,12 +53,14 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, destroy_account, extract_block_diff, get_account, get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -743,15 +746,26 @@ def process_block_rewards( Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 """ - # reward(address[],uint16[]) with empty lists - data = bytes.fromhex( - "f91c2898" - "0000000000000000000000000000000000000000000000000000000000000040" - "0000000000000000000000000000000000000000000000000000000000000060" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) ) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -760,11 +774,6 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - reward_state = TransactionState(parent=block_env.state) - account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) - if account.code_hash == EMPTY_CODE_HASH: - return - if len(out.return_data) == 0: return diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index 4bb4eae2ec8..7e23ecfcaaf 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -38,6 +38,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -68,12 +69,14 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, destroy_account, extract_block_diff, get_account, get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -1029,6 +1032,14 @@ def process_withdrawals( Spec: https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md """ + wd_state = TransactionState(parent=block_env.state) + deposit_contract = get_account(wd_state, DEPOSIT_CONTRACT_ADDRESS) + if deposit_contract.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(wd_state, SYSTEM_ADDRESS): + set_account(wd_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + amounts = [] addresses = [] for i, wd in enumerate(withdrawals): @@ -1053,6 +1064,8 @@ def process_withdrawals( if out.error: raise InvalidBlock(f"Withdrawal system call failed: {out.error}") + incorporate_tx_into_block(wd_state) + def process_block_rewards( block_env: vm.BlockEnvironment, @@ -1063,15 +1076,26 @@ def process_block_rewards( Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 """ - # reward(address[],uint16[]) with empty lists - data = bytes.fromhex( - "f91c2898" - "0000000000000000000000000000000000000000000000000000000000000040" - "0000000000000000000000000000000000000000000000000000000000000060" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) ) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -1080,11 +1104,6 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - reward_state = TransactionState(parent=block_env.state) - account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) - if account.code_hash == EMPTY_CODE_HASH: - return - if len(out.return_data) == 0: return diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 955f7aa3817..895f56cff02 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -37,6 +37,7 @@ ) from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, State, @@ -53,12 +54,14 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, destroy_account, extract_block_diff, get_account, get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -718,7 +721,9 @@ def process_transaction( tx_state, FEE_COLLECTOR_ADDRESS ).balance set_account_balance( - tx_state, FEE_COLLECTOR_ADDRESS, fee_collector_balance + base_fee + tx_state, + FEE_COLLECTOR_ADDRESS, + fee_collector_balance + base_fee, ) for address in tx_output.accounts_to_delete: @@ -754,6 +759,14 @@ def process_withdrawals( Spec: https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md """ + wd_state = TransactionState(parent=block_env.state) + deposit_contract = get_account(wd_state, DEPOSIT_CONTRACT_ADDRESS) + if deposit_contract.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(wd_state, SYSTEM_ADDRESS): + set_account(wd_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + amounts = [] addresses = [] for i, wd in enumerate(withdrawals): @@ -778,6 +791,8 @@ def process_withdrawals( if out.error: raise InvalidBlock(f"Withdrawal system call failed: {out.error}") + incorporate_tx_into_block(wd_state) + def process_block_rewards( block_env: vm.BlockEnvironment, @@ -788,15 +803,26 @@ def process_block_rewards( Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 """ - # reward(address[],uint16[]) with empty lists - data = bytes.fromhex( - "f91c2898" - "0000000000000000000000000000000000000000000000000000000000000040" - "0000000000000000000000000000000000000000000000000000000000000060" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) ) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -805,11 +831,6 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - reward_state = TransactionState(parent=block_env.state) - account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) - if account.code_hash == EMPTY_CODE_HASH: - return - if len(out.return_data) == 0: return diff --git a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py index 9f471e45b45..7164a3a955c 100644 --- a/src/ethereum_spec_tools/evm_tools/t8n/__init__.py +++ b/src/ethereum_spec_tools/evm_tools/t8n/__init__.py @@ -519,7 +519,10 @@ def _run_blockchain_test(self, block_env: Any, block_output: Any) -> None: self.fork.BlockAccessIndex(Uint(num_txs) + Uint(1)) ) - if not self.fork.proof_of_stake: + if ( + not self.fork.proof_of_stake + and not self.fork.has_process_block_rewards + ): if self.options.state_reward is None: self.pay_block_rewards(self.fork.BLOCK_REWARD, block_env) elif self.options.state_reward != -1: diff --git a/tests/paris/block_rewards/__init__.py b/tests/constantinople/block_rewards/__init__.py similarity index 100% rename from tests/paris/block_rewards/__init__.py rename to tests/constantinople/block_rewards/__init__.py diff --git a/tests/paris/block_rewards/conftest.py b/tests/constantinople/block_rewards/conftest.py similarity index 100% rename from tests/paris/block_rewards/conftest.py rename to tests/constantinople/block_rewards/conftest.py diff --git a/tests/paris/block_rewards/test_block_rewards.py b/tests/constantinople/block_rewards/test_block_rewards.py similarity index 65% rename from tests/paris/block_rewards/test_block_rewards.py rename to tests/constantinople/block_rewards/test_block_rewards.py index bf9cfa3ce11..3904e0ae375 100644 --- a/tests/paris/block_rewards/test_block_rewards.py +++ b/tests/constantinople/block_rewards/test_block_rewards.py @@ -21,7 +21,7 @@ from execution_testing.exceptions import BlockException pytestmark = [ - pytest.mark.valid_from("Paris"), + pytest.mark.valid_from("ConstantinopleFix"), pytest.mark.pre_alloc_mutable, ] @@ -50,6 +50,31 @@ def get_minimal_rewards_contract_code() -> Bytecode: ) +def get_distributing_rewards_contract_code( + recipient: int, amount: int +) -> Bytecode: + """ + Return bytecode that returns ([recipient], [amount]) for reward(). + + ABI-encodes (address[], uint256[]) with one element each: + 0x00: offset of address[] = 0x40 + 0x20: offset of uint256[] = 0x80 + 0x40: length of address[] = 1 + 0x60: address[0] (left-padded to 32 bytes) + 0x80: length of uint256[] = 1 + 0xa0: uint256[0] + """ + return ( + Op.MSTORE(0x00, 0x40) + + Op.MSTORE(0x20, 0x80) + + Op.MSTORE(0x40, 0x01) + + Op.MSTORE(0x60, recipient) + + Op.MSTORE(0x80, 0x01) + + Op.MSTORE(0xA0, amount) + + Op.RETURN(0, 0xC0) + ) + + def test_block_rewards_system_call_succeeds( blockchain_test: BlockchainTestFiller, pre: Alloc, @@ -148,7 +173,6 @@ def test_block_rewards_system_call_with_no_contract( @pytest.mark.exception_test -@pytest.mark.blockchain_test_engine_only def test_block_rewards_system_call_with_revert( blockchain_test: BlockchainTestFiller, pre: Alloc, @@ -171,7 +195,6 @@ def test_block_rewards_system_call_with_revert( @pytest.mark.exception_test -@pytest.mark.blockchain_test_engine_only def test_block_rewards_system_call_invalid_opcode( blockchain_test: BlockchainTestFiller, pre: Alloc, @@ -192,3 +215,62 @@ def test_block_rewards_system_call_invalid_opcode( ] blockchain_test(pre=pre, post={}, blocks=blocks) + + +REWARD_RECIPIENT = Address(0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) +REWARD_AMOUNT = 10**18 + + +def test_block_rewards_accumulates_on_existing_balance( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test that block rewards add to an already-funded recipient's balance. + + REWARD_RECIPIENT starts with REWARD_AMOUNT; the contract returns the same + amount again, so the final balance must be 2 * REWARD_AMOUNT. + """ + pre[REWARD_RECIPIENT] = Account(balance=REWARD_AMOUNT) + pre[BLOCK_REWARDS_CONTRACT] = Account( + code=get_distributing_rewards_contract_code( + int.from_bytes(REWARD_RECIPIENT, "big"), REWARD_AMOUNT + ), + nonce=1, + balance=0, + ) + + blockchain_test( + pre=pre, + post={ + REWARD_RECIPIENT: Account(balance=2 * REWARD_AMOUNT), + }, + blocks=[Block()], + ) + + +def test_block_rewards_distributes_to_recipients( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + Test that balances returned by the block rewards contract are credited. + + The contract returns ([REWARD_RECIPIENT], [REWARD_AMOUNT]); the + recipient's balance must increase by that amount after the block. + """ + pre[BLOCK_REWARDS_CONTRACT] = Account( + code=get_distributing_rewards_contract_code( + int.from_bytes(REWARD_RECIPIENT, "big"), REWARD_AMOUNT + ), + nonce=1, + balance=0, + ) + + blockchain_test( + pre=pre, + post={ + REWARD_RECIPIENT: Account(balance=REWARD_AMOUNT), + }, + blocks=[Block()], + ) diff --git a/tests/frontier/scenarios/test_scenarios.py b/tests/frontier/scenarios/test_scenarios.py index f5cd856e97a..71b82eb519b 100644 --- a/tests/frontier/scenarios/test_scenarios.py +++ b/tests/frontier/scenarios/test_scenarios.py @@ -228,15 +228,21 @@ def test_scenarios( tx_max_gas *= 2 tx_gasprice: int = 10 + block_number = len(blocks) + 1 + block_fee_recipient = ( + Environment(number=block_number) + .set_fork_requirements(fork) + .fee_recipient + ) exec_env = ExecutionEnvironment( fork=fork, origin=tx_origin, gasprice=tx_gasprice, timestamp=tx_env.timestamp, # we can't know timestamp before head, # use gas hash - number=len(blocks) + 1, + number=block_number, gaslimit=tx_env.gas_limit, - coinbase=tx_env.fee_recipient, + coinbase=block_fee_recipient, ) def make_result( diff --git a/tests/london/fee_collection/__init__.py b/tests/london/fee_collection/__init__.py new file mode 100644 index 00000000000..59b1542b0be --- /dev/null +++ b/tests/london/fee_collection/__init__.py @@ -0,0 +1 @@ +"""Gnosis fee collection tests for London fork.""" diff --git a/tests/london/fee_collection/test_fee_collection.py b/tests/london/fee_collection/test_fee_collection.py new file mode 100644 index 00000000000..ed3720d77c3 --- /dev/null +++ b/tests/london/fee_collection/test_fee_collection.py @@ -0,0 +1,138 @@ +""" +Tests for Gnosis fee collection to FEE_COLLECTOR_ADDRESS. + +From London onwards, the base fee portion of each transaction is sent to +FEE_COLLECTOR_ADDRESS instead of being burned as in Ethereum mainnet. + +Spec: https://github.com/gnosischain/specs/blob/master/network-upgrades/london.md +""" + +import pytest +from execution_testing import ( + Account, + Address, + Alloc, + Block, + BlockchainTestFiller, + Environment, + Fork, + Transaction, +) + +FEE_COLLECTOR_ADDRESS = Address("0x1559000000000000000000000000000000000000") + +pytestmark = [pytest.mark.valid_from("London")] + +BASE_FEE_PER_GAS = 10**9 # 1 gwei + + +@pytest.fixture +def env() -> Environment: + """Block environment with a non-zero base fee.""" + return Environment(base_fee_per_gas=BASE_FEE_PER_GAS) + + +def test_base_fee_sent_to_fee_collector( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + env: Environment, + fork: Fork, +) -> None: + """ + Test that the base fee is sent to FEE_COLLECTOR_ADDRESS rather than + burned. + + A simple ETH transfer uses 21000 gas, so with base_fee_per_gas = 1 gwei, + the fee collector should receive exactly 21000 * 1 gwei = 21000 gwei. + """ + gas_limit = 21000 + sender = pre.fund_eoa(amount=10**18) + receiver = pre.fund_eoa(amount=0) + + tx = Transaction( + sender=sender, + to=receiver, + value=0, + gas_limit=gas_limit, + max_fee_per_gas=BASE_FEE_PER_GAS * 2, + max_priority_fee_per_gas=0, + ) + + base_fee_per_gas = fork.base_fee_per_gas_calculator()( + parent_base_fee_per_gas=BASE_FEE_PER_GAS, + parent_gas_used=0, + parent_gas_limit=env.gas_limit, + ) + expected_fee = gas_limit * base_fee_per_gas + + blockchain_test( + pre=pre, + post={ + FEE_COLLECTOR_ADDRESS: Account(balance=expected_fee), + }, + blocks=[Block(txs=[tx])], + genesis_environment=env, + ) + + +def test_fee_collector_accumulates_across_txs( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + env: Environment, + fork: Fork, +) -> None: + """ + Test that FEE_COLLECTOR_ADDRESS accumulates fees across multiple + transactions in the same block. + """ + gas_limit = 21000 + sender = pre.fund_eoa(amount=10**18) + receiver = pre.fund_eoa(amount=0) + + txs = [ + Transaction( + sender=sender, + to=receiver, + value=0, + gas_limit=gas_limit, + max_fee_per_gas=BASE_FEE_PER_GAS * 2, + max_priority_fee_per_gas=0, + nonce=i, + ) + for i in range(3) + ] + + base_fee_per_gas = fork.base_fee_per_gas_calculator()( + parent_base_fee_per_gas=BASE_FEE_PER_GAS, + parent_gas_used=0, + parent_gas_limit=env.gas_limit, + ) + expected_fee = gas_limit * base_fee_per_gas * len(txs) + + blockchain_test( + pre=pre, + post={ + FEE_COLLECTOR_ADDRESS: Account(balance=expected_fee), + }, + blocks=[Block(txs=txs)], + genesis_environment=env, + ) + + +def test_fee_collector_receives_zero_when_no_txs( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + env: Environment, +) -> None: + """ + Test that FEE_COLLECTOR_ADDRESS has no balance change when a block + has no transactions. + """ + blockchain_test( + pre=pre, + post={ + FEE_COLLECTOR_ADDRESS: Account.NONEXISTENT, + }, + blocks=[Block()], + genesis_environment=env, + ) diff --git a/tests/london/system_address_state/__init__.py b/tests/london/system_address_state/__init__.py new file mode 100644 index 00000000000..f26b8a39b3d --- /dev/null +++ b/tests/london/system_address_state/__init__.py @@ -0,0 +1 @@ +"""Regression tests for SYSTEM_ADDRESS state persistence across system call.""" diff --git a/tests/london/system_address_state/test_system_address_in_state.py b/tests/london/system_address_state/test_system_address_in_state.py new file mode 100644 index 00000000000..eb59704dadd --- /dev/null +++ b/tests/london/system_address_state/test_system_address_in_state.py @@ -0,0 +1,140 @@ +""" +Regression test: SYSTEM_ADDRESS must remain in the state trie after +every block that executes a system call (block-rewards or fee-collection). + +Background +---------- +geth PR #33741 "core/vm: disable the value transfer in syscall" removed the +zero-value Context.Transfer that historically journaled SYSTEM_ADDRESS as +dirty, causing it to survive ``Finalise`` (which skips the SystemAddress +exclusion). Without that transfer, a full sync from genesis never writes +SYSTEM_ADDRESS into the state trie. + +On Gnosis mainnet this first manifests at block 1301, the block after the +AuRa safeContract multi-transition at block 1300. The execution-spec +reference implementation always journals SYSTEM_ADDRESS through the +system-call path; any client that diverges will produce a different trie +root and fail to import block 1301. + +What this test checks +--------------------- +1. After the *first* block (which triggers a system call via + ``process_block_rewards``), SYSTEM_ADDRESS must exist in the post-state + as a zero-value account. + +2. A second block (simulating the transition) must still find SYSTEM_ADDRESS + in the trie and produce an identical root. A client that silently + dropped SYSTEM_ADDRESS after block 1 will diverge here. + +The test is intentionally minimal: no user transactions, no reward +distribution, just the system-call side-effect on SYSTEM_ADDRESS. + +References +---------- +- https://github.com/ethereum/go-ethereum/pull/33741 +- https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + +""" + +import pytest +from execution_testing import ( + Account, + Address, + Alloc, + Block, + BlockchainTestFiller, + Bytecode, + Op, +) + +pytestmark = [ + pytest.mark.valid_from("ConstantinopleFix"), + pytest.mark.valid_before("Paris"), + pytest.mark.pre_alloc_mutable, +] + +SYSTEM_ADDRESS = Address(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) +BLOCK_REWARDS_CONTRACT = Address(0x2000000000000000000000000000000000000001) + + +def _no_op_rewards_bytecode() -> Bytecode: + """ + Minimal block-rewards contract: returns empty (address[], uint256[]). + + The system call succeeds, no balances are changed, but SYSTEM_ADDRESS + is still journaled as the call origin. + """ + return ( + Op.MSTORE(0x00, 0x40) + + Op.MSTORE(0x20, 0x60) + + Op.MSTORE(0x40, 0x00) + + Op.MSTORE(0x60, 0x00) + + Op.RETURN(0, 128) + ) + + +def test_system_address_persists_after_system_call( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + SYSTEM_ADDRESS must be present in the state trie after a block that + executes a system call, even when no value is transferred. + + A client implementing geth PR #33741 without the Gnosis-specific + MakeAuraSyscall fix will omit the zero-value transfer, never journal + SYSTEM_ADDRESS, and drop it from the trie during Finalise. The + resulting stateRoot diverges from the canonical value starting with the + first block that runs a system call, which on Gnosis mainnet is block 1. + """ + pre[BLOCK_REWARDS_CONTRACT] = Account( + code=_no_op_rewards_bytecode(), + nonce=1, + balance=0, + ) + + # SYSTEM_ADDRESS is not pre-allocated in genesis; touch_account inside + # process_block_rewards creates the leaf on the first system call. + # We verify it is present — zero-value — after block execution. + blocks = [Block()] + + post = { + SYSTEM_ADDRESS: Account(nonce=0, balance=0), + } + + blockchain_test(pre=pre, post=post, blocks=blocks) + + +def test_system_address_persists_across_validator_set_transition( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +) -> None: + """ + SYSTEM_ADDRESS must survive two consecutive system-call blocks. + + This models the Gnosis mainnet scenario around block 1300→1301: + - Block N triggers the AuRa safeContract transition (system call). + - Block N+1 must find SYSTEM_ADDRESS in the trie and produce the + canonical stateRoot. + + A buggy client drops SYSTEM_ADDRESS after block N, so its trie root + for block N+1 diverges from the canonical value — exactly the + "invalid merkle root" error observed at block 1301 during full sync + with unpatched geth v1.17.1-gc. + """ + pre[BLOCK_REWARDS_CONTRACT] = Account( + code=_no_op_rewards_bytecode(), + nonce=1, + balance=0, + ) + + # Two consecutive blocks, each triggering a system call. + # Block 1 corresponds to the transition block (e.g. block 1300). + # Block 2 corresponds to the first block after the transition (block 1301). + blocks = [Block(), Block()] + + post = { + SYSTEM_ADDRESS: Account(nonce=0, balance=0), + } + + blockchain_test(pre=pre, post=post, blocks=blocks) diff --git a/tests/shanghai/eip4895_withdrawals/test_withdrawals.py b/tests/shanghai/eip4895_withdrawals/test_withdrawals.py index 0bfc6f80a70..6fa26d6900d 100644 --- a/tests/shanghai/eip4895_withdrawals/test_withdrawals.py +++ b/tests/shanghai/eip4895_withdrawals/test_withdrawals.py @@ -131,7 +131,6 @@ def test_store_withdrawal_values_in_contract( @pytest.mark.exception_test -@pytest.mark.blockchain_test_engine_only @pytest.mark.pre_alloc_mutable def test_withdrawal_system_call_with_revert( blockchain_test: BlockchainTestFiller, @@ -166,14 +165,13 @@ def test_withdrawal_system_call_with_revert( @pytest.mark.exception_test -@pytest.mark.blockchain_test_engine_only @pytest.mark.pre_alloc_mutable -def test_withdrawal_system_call_out_of_gas( +def test_withdrawal_system_call_invalid_opcode( blockchain_test: BlockchainTestFiller, pre: Alloc, ) -> None: """ - Test behavior when deposit contract runs out of gas. + Test behavior when deposit contract hits the INVALID opcode. """ # Deploy contract that uses INVALID opcode pre[DEPOSIT_CONTRACT] = Account( From bbacd741a9d893585d974a0b4eaee6abc31189cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 20 May 2026 14:34:23 +0200 Subject: [PATCH 106/186] feat(tests): EIP-7981 reject in access-list-byte floor gap with exact-balance sender (#2880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EIP-7981 charges every access-list byte (20 per address, 32 per storage key) at the floor token cost. A transaction whose `gas_limit` lies in `[Amsterdam_floor_without_AL_term, Amsterdam_floor)` must reject at pre-validate with `INTRINSIC_GAS_BELOW_FLOOR_GAS_COST`; an implementation that omits the access-list-byte term from its floor computes a smaller floor and accepts. This test pins `gas_limit` at the midpoint of that uplift gap for Type-1 and Type-2 transactions carrying 1000 / 2000 nonzero data bytes plus a 1-address / 10-storage-key access list. The sender is funded with exactly `gas_limit * gas_price`, so a buggy implementation cannot fall back to a silent "accept and execute" — any acceptance produces a divergent post-state. Complements `test_insufficient_gas_for_access_list` and `test_floor_cost_validation_with_access_list`, which exercise this boundary at `gas_limit = floor - 1` with default sender funding. --- .../test_floor_boundary_exact_balance.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/amsterdam/eip7981_increase_access_list_cost/test_floor_boundary_exact_balance.py diff --git a/tests/amsterdam/eip7981_increase_access_list_cost/test_floor_boundary_exact_balance.py b/tests/amsterdam/eip7981_increase_access_list_cost/test_floor_boundary_exact_balance.py new file mode 100644 index 00000000000..10c15ec10a3 --- /dev/null +++ b/tests/amsterdam/eip7981_increase_access_list_cost/test_floor_boundary_exact_balance.py @@ -0,0 +1,87 @@ +""" +abstract: Tests for floor-boundary rejection with exact-balance funding in [EIP-7981: Increase Access List Cost](https://eips.ethereum.org/EIPS/eip-7981). +""" # noqa: E501 + +import pytest +from execution_testing import ( + AccessList, + Address, + Alloc, + Bytes, + Fork, + Hash, + StateTestFiller, + Transaction, + TransactionException, +) + +from .spec import ref_spec_7981 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7981.git_path +REFERENCE_SPEC_VERSION = ref_spec_7981.version + +pytestmark = pytest.mark.valid_at("EIP7981") + + +@pytest.mark.exception_test +@pytest.mark.parametrize( + "tx_type", + [pytest.param(1, id="type_1"), pytest.param(2, id="type_2")], +) +@pytest.mark.parametrize( + "nonzero_bytes", + [ + pytest.param(1000, id="1000_nonzero_bytes"), + pytest.param(2000, id="2000_nonzero_bytes"), + ], +) +def test_below_amsterdam_floor_with_access_list_exact_balance( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + tx_type: int, + nonzero_bytes: int, +) -> None: + """Reject when gas_limit sits in EIP-7981 access-list-byte floor gap.""" + access_list = [ + AccessList( + address=Address(1), + storage_keys=[Hash(k) for k in range(10)], + ) + ] + tx_data = Bytes(b"\x01" * nonzero_bytes) + intrinsic_regular = fork.transaction_intrinsic_cost_calculator()( + calldata=tx_data, + access_list=access_list, + return_cost_deducted_prior_execution=True, + ) + floor_calc = fork.transaction_data_floor_cost_calculator() + amsterdam_floor = floor_calc(data=tx_data, access_list=access_list) + amsterdam_floor_no_al = floor_calc(data=tx_data) + # Pin gas_limit inside the access-list-byte uplift gap so an + # implementation that omits this term from its floor accepts. + gas_limit = (amsterdam_floor_no_al + amsterdam_floor) // 2 + assert intrinsic_regular <= gas_limit < amsterdam_floor + assert gas_limit >= amsterdam_floor_no_al + + gas_price = 10 + sender = pre.fund_eoa(amount=gas_limit * gas_price) + if tx_type == 1: + fee_args: dict = {"gas_price": gas_price} + else: + fee_args = { + "max_fee_per_gas": gas_price, + "max_priority_fee_per_gas": 0, + } + tx = Transaction( + ty=tx_type, + sender=sender, + to=pre.fund_eoa(amount=0), + data=tx_data, + gas_limit=gas_limit, + access_list=access_list, + error=TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST, + **fee_args, + ) + + state_test(pre=pre, post={}, tx=tx) From c3a7b6b6cf5d806bdb20da8a3464d824bdefb81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 20 May 2026 15:36:15 +0200 Subject: [PATCH 107/186] feat(tests): EIP-7976 reject exact-balance tx in Prague/Amsterdam floor gap (#2878) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(tests): EIP-7976 reject in Prague/Amsterdam floor gap with exact-balance sender EIP-7976 raises the per-byte calldata floor cost. A transaction whose `gas_limit` lies in `[Prague_floor, Amsterdam_floor)` must reject at pre-validate with `INTRINSIC_GAS_BELOW_FLOOR_GAS_COST`. This test pins gas_limit at the midpoint of that gap for 100 and 1000 zero-byte calldata transactions. Sender balance equals `gas_limit * gas_price`, so an implementation that defaults to the Prague floor cannot fall through to a silent "accept and execute" — any pre-validate divergence produces a different post-state. * refactor(tests): use `valid_at` marker and improve docstring consistency --------- Co-authored-by: Felix H --- .../test_floor_boundary_exact_balance.py | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tests/amsterdam/eip7976_increase_calldata_floor_cost/test_floor_boundary_exact_balance.py diff --git a/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_floor_boundary_exact_balance.py b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_floor_boundary_exact_balance.py new file mode 100644 index 00000000000..b913e674f4d --- /dev/null +++ b/tests/amsterdam/eip7976_increase_calldata_floor_cost/test_floor_boundary_exact_balance.py @@ -0,0 +1,78 @@ +""" +abstract: Tests for floor-boundary rejection with exact-balance funding in [EIP-7976: Increase Calldata Floor Cost](https://eips.ethereum.org/EIPS/eip-7976). +""" # noqa: E501 + +import pytest +from execution_testing import ( + Alloc, + Bytes, + Fork, + StateTestFiller, + Transaction, + TransactionException, +) + +from ...prague.eip7623_increase_calldata_cost.spec import Spec as Spec7623 +from .spec import ref_spec_7976 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7976.git_path +REFERENCE_SPEC_VERSION = ref_spec_7976.version + +pytestmark = pytest.mark.valid_at("EIP7976") + + +@pytest.mark.exception_test +@pytest.mark.parametrize( + "zero_bytes", + [ + pytest.param(100, id="100_zero_bytes"), + pytest.param(1000, id="1000_zero_bytes"), + ], +) +def test_below_amsterdam_floor_with_exact_balance_sender( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, + zero_bytes: int, +) -> None: + """ + Reject when gas_limit sits between Prague and Amsterdam floor. + + EIP-7976 raises the per-byte calldata floor cost. A transaction + with `gas_limit` in `[Prague_floor, Amsterdam_floor)` must reject + with `INTRINSIC_GAS_BELOW_FLOOR_GAS_COST`. The sender is funded + with exactly `gas_limit * gas_price` so an implementation that + uses the Prague floor cannot fall back to silent execution. + + Type-0 only on purpose; broader type-1/2/3/4 coverage lives in + `test_transaction_validity.py`. + """ + tx_data = Bytes(b"\x00" * zero_bytes) + intrinsic_regular = fork.transaction_intrinsic_cost_calculator()( + calldata=tx_data, + return_cost_deducted_prior_execution=True, + ) + amsterdam_floor = fork.transaction_data_floor_cost_calculator()( + data=tx_data, + ) + # Prague counts each zero byte as one token at TX_DATA_TOKEN_FLOOR + # gas/token. Cannot be derived from amsterdam_floor because EIP-7976 + # changes both the per-token rate (10->16) and the floor tokenization + # (zero/nonzero both weighted by 4). + prague_floor = 21000 + Spec7623.TX_DATA_TOKEN_FLOOR * zero_bytes + gas_limit = (prague_floor + amsterdam_floor) // 2 + assert intrinsic_regular <= gas_limit + assert prague_floor <= gas_limit < amsterdam_floor + + gas_price = 10 + sender = pre.fund_eoa(amount=gas_limit * gas_price) + tx = Transaction( + sender=sender, + to=pre.fund_eoa(amount=0), + data=tx_data, + gas_limit=gas_limit, + gas_price=gas_price, + error=TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST, + ) + + state_test(pre=pre, post={}, tx=tx) From 89c133e07db3468a10acf664dcce99df23513723 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Wed, 20 May 2026 07:37:50 -0700 Subject: [PATCH 108/186] chore(specs): add missing type annotations (#2868) --- src/ethereum/forks/amsterdam/fork.py | 6 +- src/ethereum/forks/amsterdam/vm/gas.py | 270 +++++++++--------- .../forks/amsterdam/vm/instructions/log.py | 11 +- .../forks/amsterdam/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/arrow_glacier/vm/gas.py | 216 +++++++------- .../arrow_glacier/vm/instructions/log.py | 11 +- .../arrow_glacier/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/berlin/vm/gas.py | 216 +++++++------- .../forks/berlin/vm/instructions/log.py | 11 +- .../forks/berlin/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/bpo1/fork.py | 6 +- src/ethereum/forks/bpo1/vm/gas.py | 260 ++++++++--------- .../forks/bpo1/vm/instructions/log.py | 11 +- .../forks/bpo1/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/bpo2/fork.py | 6 +- src/ethereum/forks/bpo2/vm/gas.py | 260 ++++++++--------- .../forks/bpo2/vm/instructions/log.py | 11 +- .../forks/bpo2/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/bpo3/fork.py | 6 +- src/ethereum/forks/bpo3/vm/gas.py | 260 ++++++++--------- .../forks/bpo3/vm/instructions/log.py | 11 +- .../forks/bpo3/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/bpo4/fork.py | 6 +- src/ethereum/forks/bpo4/vm/gas.py | 260 ++++++++--------- .../forks/bpo4/vm/instructions/log.py | 11 +- .../forks/bpo4/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/bpo5/fork.py | 6 +- src/ethereum/forks/bpo5/vm/gas.py | 260 ++++++++--------- .../forks/bpo5/vm/instructions/log.py | 11 +- .../forks/bpo5/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/byzantium/vm/gas.py | 202 ++++++------- .../forks/byzantium/vm/instructions/log.py | 11 +- .../forks/byzantium/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/cancun/fork.py | 4 +- src/ethereum/forks/cancun/vm/gas.py | 236 +++++++-------- .../forks/cancun/vm/instructions/log.py | 11 +- .../forks/cancun/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/constantinople/vm/gas.py | 210 +++++++------- .../constantinople/vm/instructions/log.py | 11 +- .../constantinople/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/dao_fork/vm/gas.py | 184 ++++++------ .../forks/dao_fork/vm/instructions/log.py | 11 +- .../forks/dao_fork/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/frontier/vm/gas.py | 184 ++++++------ .../forks/frontier/vm/instructions/log.py | 11 +- .../forks/frontier/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/gray_glacier/vm/gas.py | 216 +++++++------- .../forks/gray_glacier/vm/instructions/log.py | 11 +- .../gray_glacier/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/homestead/vm/gas.py | 184 ++++++------ .../forks/homestead/vm/instructions/log.py | 11 +- .../forks/homestead/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/istanbul/vm/gas.py | 216 +++++++------- .../forks/istanbul/vm/instructions/log.py | 11 +- .../forks/istanbul/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/london/vm/gas.py | 216 +++++++------- .../forks/london/vm/instructions/log.py | 11 +- .../forks/london/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/muir_glacier/vm/gas.py | 216 +++++++------- .../forks/muir_glacier/vm/instructions/log.py | 11 +- .../muir_glacier/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/osaka/fork.py | 6 +- src/ethereum/forks/osaka/vm/gas.py | 260 ++++++++--------- .../forks/osaka/vm/instructions/log.py | 11 +- .../forks/osaka/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/paris/vm/gas.py | 216 +++++++------- .../forks/paris/vm/instructions/log.py | 11 +- .../forks/paris/vm/instructions/stack.py | 133 ++++----- src/ethereum/forks/prague/fork.py | 4 +- src/ethereum/forks/prague/vm/gas.py | 250 ++++++++-------- .../forks/prague/vm/instructions/log.py | 11 +- .../forks/prague/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/shanghai/vm/gas.py | 220 +++++++------- .../forks/shanghai/vm/instructions/log.py | 11 +- .../forks/shanghai/vm/instructions/stack.py | 135 ++++----- src/ethereum/forks/spurious_dragon/vm/gas.py | 188 ++++++------ .../spurious_dragon/vm/instructions/log.py | 11 +- .../spurious_dragon/vm/instructions/stack.py | 133 ++++----- .../forks/tangerine_whistle/vm/gas.py | 188 ++++++------ .../tangerine_whistle/vm/instructions/log.py | 11 +- .../vm/instructions/stack.py | 133 ++++----- tests/json_loader/test_tools_new_fork.py | 14 +- 82 files changed, 4495 insertions(+), 4433 deletions(-) diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index 531c086a9f7..8f68e76cb0a 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -115,7 +115,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" GWEI_TO_WEI = U256(10**9) diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index 14ad5d09203..f8ad377ff73 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -33,168 +33,168 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(14) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(21) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(14) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(21) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(11684671) # Block Access Lists - BLOCK_ACCESS_LIST_ITEM = Uint(2000) + BLOCK_ACCESS_LIST_ITEM: Final[Uint] = Uint(2000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_SLOTNUM = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW - OPCODE_DUPN = VERY_LOW - OPCODE_SWAPN = VERY_LOW - OPCODE_EXCHANGE = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_SLOTNUM: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW + OPCODE_DUPN: Final[Uint] = VERY_LOW + OPCODE_SWAPN: Final[Uint] = VERY_LOW + OPCODE_EXCHANGE: Final[Uint] = VERY_LOW # Dynamic Opcode Components - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/amsterdam/vm/instructions/log.py b/src/ethereum/forks/amsterdam/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/log.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/stack.py b/src/ethereum/forks/amsterdam/vm/instructions/stack.py index 6e2886493a0..0e72bd01f31 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/stack.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U8, U256, Uint @@ -143,73 +144,73 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) def dupn(evm: Evm) -> None: diff --git a/src/ethereum/forks/arrow_glacier/vm/gas.py b/src/ethereum/forks/arrow_glacier/vm/gas.py index fb6225cd856..2842b80b4d2 100644 --- a/src/ethereum/forks/arrow_glacier/vm/gas.py +++ b/src/ethereum/forks/arrow_glacier/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/log.py b/src/ethereum/forks/arrow_glacier/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py b/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/berlin/vm/gas.py b/src/ethereum/forks/berlin/vm/gas.py index 6ffec083550..672dc2fd026 100644 --- a/src/ethereum/forks/berlin/vm/gas.py +++ b/src/ethereum/forks/berlin/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/berlin/vm/instructions/log.py b/src/ethereum/forks/berlin/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/berlin/vm/instructions/log.py +++ b/src/ethereum/forks/berlin/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/berlin/vm/instructions/stack.py b/src/ethereum/forks/berlin/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/berlin/vm/instructions/stack.py +++ b/src/ethereum/forks/berlin/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/bpo1/fork.py b/src/ethereum/forks/bpo1/fork.py index 66832bf3a20..d84cee05378 100644 --- a/src/ethereum/forks/bpo1/fork.py +++ b/src/ethereum/forks/bpo1/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -103,7 +103,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/bpo1/vm/gas.py b/src/ethereum/forks/bpo1/vm/gas.py index 51c35efee77..2cd628097bc 100644 --- a/src/ethereum/forks/bpo1/vm/gas.py +++ b/src/ethereum/forks/bpo1/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,161 +32,161 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(10) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(15) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(8346193) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(10) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(15) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(8346193) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/bpo1/vm/instructions/log.py b/src/ethereum/forks/bpo1/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/log.py +++ b/src/ethereum/forks/bpo1/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/bpo1/vm/instructions/stack.py b/src/ethereum/forks/bpo1/vm/instructions/stack.py index 366cf79f5e4..ce94af6ce8e 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo1/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -142,70 +143,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/bpo2/fork.py b/src/ethereum/forks/bpo2/fork.py index 66832bf3a20..d84cee05378 100644 --- a/src/ethereum/forks/bpo2/fork.py +++ b/src/ethereum/forks/bpo2/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -103,7 +103,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/bpo2/vm/gas.py b/src/ethereum/forks/bpo2/vm/gas.py index 34ac7c66389..f2488b8e20a 100644 --- a/src/ethereum/forks/bpo2/vm/gas.py +++ b/src/ethereum/forks/bpo2/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,161 +32,161 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(14) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(21) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(14) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(21) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(11684671) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/bpo2/vm/instructions/log.py b/src/ethereum/forks/bpo2/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/log.py +++ b/src/ethereum/forks/bpo2/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/bpo2/vm/instructions/stack.py b/src/ethereum/forks/bpo2/vm/instructions/stack.py index d7b3df986b0..eff50ac73c9 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo2/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,70 +140,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/bpo3/fork.py b/src/ethereum/forks/bpo3/fork.py index 66832bf3a20..d84cee05378 100644 --- a/src/ethereum/forks/bpo3/fork.py +++ b/src/ethereum/forks/bpo3/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -103,7 +103,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/bpo3/vm/gas.py b/src/ethereum/forks/bpo3/vm/gas.py index 34ac7c66389..f2488b8e20a 100644 --- a/src/ethereum/forks/bpo3/vm/gas.py +++ b/src/ethereum/forks/bpo3/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,161 +32,161 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(14) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(21) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(14) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(21) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(11684671) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/bpo3/vm/instructions/log.py b/src/ethereum/forks/bpo3/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/log.py +++ b/src/ethereum/forks/bpo3/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/bpo3/vm/instructions/stack.py b/src/ethereum/forks/bpo3/vm/instructions/stack.py index d7b3df986b0..eff50ac73c9 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo3/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,70 +140,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/bpo4/fork.py b/src/ethereum/forks/bpo4/fork.py index 66832bf3a20..d84cee05378 100644 --- a/src/ethereum/forks/bpo4/fork.py +++ b/src/ethereum/forks/bpo4/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -103,7 +103,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/bpo4/vm/gas.py b/src/ethereum/forks/bpo4/vm/gas.py index 34ac7c66389..f2488b8e20a 100644 --- a/src/ethereum/forks/bpo4/vm/gas.py +++ b/src/ethereum/forks/bpo4/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,161 +32,161 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(14) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(21) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(14) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(21) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(11684671) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/bpo4/vm/instructions/log.py b/src/ethereum/forks/bpo4/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/log.py +++ b/src/ethereum/forks/bpo4/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/bpo4/vm/instructions/stack.py b/src/ethereum/forks/bpo4/vm/instructions/stack.py index 366cf79f5e4..ce94af6ce8e 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo4/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -142,70 +143,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/bpo5/fork.py b/src/ethereum/forks/bpo5/fork.py index 66832bf3a20..d84cee05378 100644 --- a/src/ethereum/forks/bpo5/fork.py +++ b/src/ethereum/forks/bpo5/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -103,7 +103,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/bpo5/vm/gas.py b/src/ethereum/forks/bpo5/vm/gas.py index 34ac7c66389..f2488b8e20a 100644 --- a/src/ethereum/forks/bpo5/vm/gas.py +++ b/src/ethereum/forks/bpo5/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,161 +32,161 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(14) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(21) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(11684671) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(14) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(21) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(11684671) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/bpo5/vm/instructions/log.py b/src/ethereum/forks/bpo5/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/log.py +++ b/src/ethereum/forks/bpo5/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/bpo5/vm/instructions/stack.py b/src/ethereum/forks/bpo5/vm/instructions/stack.py index 366cf79f5e4..ce94af6ce8e 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo5/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -142,70 +143,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/byzantium/vm/gas.py b/src/ethereum/forks/byzantium/vm/gas.py index 26cee8b14af..0395403db01 100644 --- a/src/ethereum/forks/byzantium/vm/gas.py +++ b/src/ethereum/forks/byzantium/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,128 +30,128 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(200) + SLOAD: Final[Uint] = Uint(200) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_ECADD = Uint(500) - PRECOMPILE_ECMUL = Uint(40000) - PRECOMPILE_ECPAIRING_BASE = Uint(100000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(80000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_ECADD: Final[Uint] = Uint(500) + PRECOMPILE_ECMUL: Final[Uint] = Uint(40000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(100000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(80000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) - OPCODE_EXTERNAL_BASE = Uint(700) - OPCODE_BALANCE = Uint(400) - OPCODE_CALL_BASE = Uint(700) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(700) + OPCODE_BALANCE: Final[Uint] = Uint(400) + OPCODE_CALL_BASE: Final[Uint] = Uint(700) @dataclass diff --git a/src/ethereum/forks/byzantium/vm/instructions/log.py b/src/ethereum/forks/byzantium/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/log.py +++ b/src/ethereum/forks/byzantium/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/byzantium/vm/instructions/stack.py b/src/ethereum/forks/byzantium/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/stack.py +++ b/src/ethereum/forks/byzantium/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index 19afbffcbc4..7f4be088993 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -92,7 +92,7 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = U64(786432) +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = U64(786432) VERSIONED_HASH_VERSION_KZG = b"\x01" diff --git a/src/ethereum/forks/cancun/vm/gas.py b/src/ethereum/forks/cancun/vm/gas.py index 90cda5fe5ad..89ad479051f 100644 --- a/src/ethereum/forks/cancun/vm/gas.py +++ b/src/ethereum/forks/cancun/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,147 +32,147 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_TARGET_GAS_PER_BLOCK = U64(393216) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(3338477) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = U64(393216) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(3338477) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/cancun/vm/instructions/log.py b/src/ethereum/forks/cancun/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/cancun/vm/instructions/log.py +++ b/src/ethereum/forks/cancun/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/cancun/vm/instructions/stack.py b/src/ethereum/forks/cancun/vm/instructions/stack.py index 366cf79f5e4..ce94af6ce8e 100644 --- a/src/ethereum/forks/cancun/vm/instructions/stack.py +++ b/src/ethereum/forks/cancun/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -142,70 +143,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/constantinople/vm/gas.py b/src/ethereum/forks/constantinople/vm/gas.py index 37b2d29f865..770c5212461 100644 --- a/src/ethereum/forks/constantinople/vm/gas.py +++ b/src/ethereum/forks/constantinople/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,132 +30,132 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(200) + SLOAD: Final[Uint] = Uint(200) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_ECADD = Uint(500) - PRECOMPILE_ECMUL = Uint(40000) - PRECOMPILE_ECPAIRING_BASE = Uint(100000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(80000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_ECADD: Final[Uint] = Uint(500) + PRECOMPILE_ECMUL: Final[Uint] = Uint(40000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(100000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(80000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_EXTCODEHASH = Uint(400) - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_EXTCODEHASH: Final[Uint] = Uint(400) + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) - OPCODE_EXTERNAL_BASE = Uint(700) - OPCODE_BALANCE = Uint(400) - OPCODE_CALL_BASE = Uint(700) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(700) + OPCODE_BALANCE: Final[Uint] = Uint(400) + OPCODE_CALL_BASE: Final[Uint] = Uint(700) @dataclass diff --git a/src/ethereum/forks/constantinople/vm/instructions/log.py b/src/ethereum/forks/constantinople/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/log.py +++ b/src/ethereum/forks/constantinople/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/constantinople/vm/instructions/stack.py b/src/ethereum/forks/constantinople/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/stack.py +++ b/src/ethereum/forks/constantinople/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/dao_fork/vm/gas.py b/src/ethereum/forks/dao_fork/vm/gas.py index 1fc39a94593..cb663624a36 100644 --- a/src/ethereum/forks/dao_fork/vm/gas.py +++ b/src/ethereum/forks/dao_fork/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -32,119 +32,119 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(50) + SLOAD: Final[Uint] = Uint(50) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = Uint(24000) + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[Uint] = Uint(24000) # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(10) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_EXTERNAL_BASE = Uint(20) - OPCODE_BALANCE = Uint(20) - OPCODE_CALL_BASE = Uint(40) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(10) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(20) + OPCODE_BALANCE: Final[Uint] = Uint(20) + OPCODE_CALL_BASE: Final[Uint] = Uint(40) @dataclass diff --git a/src/ethereum/forks/dao_fork/vm/instructions/log.py b/src/ethereum/forks/dao_fork/vm/instructions/log.py index e3e3ebd7e76..3cfb69c194c 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/log.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -76,8 +77,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/stack.py b/src/ethereum/forks/dao_fork/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/stack.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/frontier/vm/gas.py b/src/ethereum/forks/frontier/vm/gas.py index e73c9b2e925..1974386b1c3 100644 --- a/src/ethereum/forks/frontier/vm/gas.py +++ b/src/ethereum/forks/frontier/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -32,117 +32,117 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(50) + SLOAD: Final[Uint] = Uint(50) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = Uint(24000) + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[Uint] = Uint(24000) # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) # Transactions - TX_BASE = Uint(21000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW - - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(10) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_EXTERNAL_BASE = Uint(20) - OPCODE_BALANCE = Uint(20) - OPCODE_CALL_BASE = Uint(40) + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW + + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(10) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(20) + OPCODE_BALANCE: Final[Uint] = Uint(20) + OPCODE_CALL_BASE: Final[Uint] = Uint(40) @dataclass diff --git a/src/ethereum/forks/frontier/vm/instructions/log.py b/src/ethereum/forks/frontier/vm/instructions/log.py index e3e3ebd7e76..3cfb69c194c 100644 --- a/src/ethereum/forks/frontier/vm/instructions/log.py +++ b/src/ethereum/forks/frontier/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -76,8 +77,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/frontier/vm/instructions/stack.py b/src/ethereum/forks/frontier/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/frontier/vm/instructions/stack.py +++ b/src/ethereum/forks/frontier/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/gray_glacier/vm/gas.py b/src/ethereum/forks/gray_glacier/vm/gas.py index fb6225cd856..2842b80b4d2 100644 --- a/src/ethereum/forks/gray_glacier/vm/gas.py +++ b/src/ethereum/forks/gray_glacier/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/log.py b/src/ethereum/forks/gray_glacier/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/stack.py b/src/ethereum/forks/gray_glacier/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/homestead/vm/gas.py b/src/ethereum/forks/homestead/vm/gas.py index 1fc39a94593..cb663624a36 100644 --- a/src/ethereum/forks/homestead/vm/gas.py +++ b/src/ethereum/forks/homestead/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -32,119 +32,119 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(50) + SLOAD: Final[Uint] = Uint(50) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = Uint(24000) + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[Uint] = Uint(24000) # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(10) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_EXTERNAL_BASE = Uint(20) - OPCODE_BALANCE = Uint(20) - OPCODE_CALL_BASE = Uint(40) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(10) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(20) + OPCODE_BALANCE: Final[Uint] = Uint(20) + OPCODE_CALL_BASE: Final[Uint] = Uint(40) @dataclass diff --git a/src/ethereum/forks/homestead/vm/instructions/log.py b/src/ethereum/forks/homestead/vm/instructions/log.py index e3e3ebd7e76..3cfb69c194c 100644 --- a/src/ethereum/forks/homestead/vm/instructions/log.py +++ b/src/ethereum/forks/homestead/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -76,8 +77,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/homestead/vm/instructions/stack.py b/src/ethereum/forks/homestead/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/homestead/vm/instructions/stack.py +++ b/src/ethereum/forks/homestead/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/istanbul/vm/gas.py b/src/ethereum/forks/istanbul/vm/gas.py index 43cad92d739..25ff304ae00 100644 --- a/src/ethereum/forks/istanbul/vm/gas.py +++ b/src/ethereum/forks/istanbul/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(800) + SLOAD: Final[Uint] = Uint(800) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_EXTCODEHASH = Uint(700) - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_EXTCODEHASH: Final[Uint] = Uint(700) + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) - OPCODE_EXTERNAL_BASE = Uint(700) - OPCODE_BALANCE = Uint(700) - OPCODE_CALL_BASE = Uint(700) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(700) + OPCODE_BALANCE: Final[Uint] = Uint(700) + OPCODE_CALL_BASE: Final[Uint] = Uint(700) @dataclass diff --git a/src/ethereum/forks/istanbul/vm/instructions/log.py b/src/ethereum/forks/istanbul/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/log.py +++ b/src/ethereum/forks/istanbul/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/istanbul/vm/instructions/stack.py b/src/ethereum/forks/istanbul/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/stack.py +++ b/src/ethereum/forks/istanbul/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/london/vm/gas.py b/src/ethereum/forks/london/vm/gas.py index fb6225cd856..2842b80b4d2 100644 --- a/src/ethereum/forks/london/vm/gas.py +++ b/src/ethereum/forks/london/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/london/vm/instructions/log.py b/src/ethereum/forks/london/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/london/vm/instructions/log.py +++ b/src/ethereum/forks/london/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/london/vm/instructions/stack.py b/src/ethereum/forks/london/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/london/vm/instructions/stack.py +++ b/src/ethereum/forks/london/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/muir_glacier/vm/gas.py b/src/ethereum/forks/muir_glacier/vm/gas.py index 43cad92d739..25ff304ae00 100644 --- a/src/ethereum/forks/muir_glacier/vm/gas.py +++ b/src/ethereum/forks/muir_glacier/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(800) + SLOAD: Final[Uint] = Uint(800) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_EXTCODEHASH = Uint(700) - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_EXTCODEHASH: Final[Uint] = Uint(700) + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) - OPCODE_EXTERNAL_BASE = Uint(700) - OPCODE_BALANCE = Uint(700) - OPCODE_CALL_BASE = Uint(700) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(700) + OPCODE_BALANCE: Final[Uint] = Uint(700) + OPCODE_CALL_BASE: Final[Uint] = Uint(700) @dataclass diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/log.py b/src/ethereum/forks/muir_glacier/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/stack.py b/src/ethereum/forks/muir_glacier/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index 66832bf3a20..d84cee05378 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -103,7 +103,9 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = ( + GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB +) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/osaka/vm/gas.py b/src/ethereum/forks/osaka/vm/gas.py index db5a2a3d669..1d49b46098c 100644 --- a/src/ethereum/forks/osaka/vm/gas.py +++ b/src/ethereum/forks/osaka/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,161 +32,161 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_P256VERIFY = Uint(6900) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_SCHEDULE_TARGET = U64(6) - BLOB_TARGET_GAS_PER_BLOCK = PER_BLOB * BLOB_SCHEDULE_TARGET - BLOB_BASE_COST = Uint(2**13) - BLOB_SCHEDULE_MAX = U64(9) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_SCHEDULE_TARGET: Final[U64] = U64(6) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET + BLOB_BASE_COST: Final[Uint] = Uint(2**13) + BLOB_SCHEDULE_MAX: Final[U64] = U64(9) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(5007716) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_CLZ = LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_CLZ: Final[Uint] = LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/osaka/vm/instructions/log.py b/src/ethereum/forks/osaka/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/osaka/vm/instructions/log.py +++ b/src/ethereum/forks/osaka/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/osaka/vm/instructions/stack.py b/src/ethereum/forks/osaka/vm/instructions/stack.py index 366cf79f5e4..ce94af6ce8e 100644 --- a/src/ethereum/forks/osaka/vm/instructions/stack.py +++ b/src/ethereum/forks/osaka/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -142,70 +143,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/paris/vm/gas.py b/src/ethereum/forks/paris/vm/gas.py index 9dbf5fab377..b4b9ab1e402 100644 --- a/src/ethereum/forks/paris/vm/gas.py +++ b/src/ethereum/forks/paris/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,135 +30,135 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/paris/vm/instructions/log.py b/src/ethereum/forks/paris/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/paris/vm/instructions/log.py +++ b/src/ethereum/forks/paris/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/paris/vm/instructions/stack.py b/src/ethereum/forks/paris/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/paris/vm/instructions/stack.py +++ b/src/ethereum/forks/paris/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index e39016d12db..486ed9861e6 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple +from typing import Final, List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -102,7 +102,7 @@ "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) SYSTEM_TRANSACTION_GAS = Uint(30000000) -MAX_BLOB_GAS_PER_BLOCK = U64(1179648) +MAX_BLOB_GAS_PER_BLOCK: Final[U64] = U64(1179648) VERSIONED_HASH_VERSION_KZG = b"\x01" WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( diff --git a/src/ethereum/forks/prague/vm/gas.py b/src/ethereum/forks/prague/vm/gas.py index 226163494a3..e6cc23df1b8 100644 --- a/src/ethereum/forks/prague/vm/gas.py +++ b/src/ethereum/forks/prague/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U64, U256, Uint, ulen @@ -32,156 +32,156 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Authorization - AUTH_PER_EMPTY_ACCOUNT = 25000 + AUTH_PER_EMPTY_ACCOUNT: Final[int] = 25000 # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_POINT_EVALUATION = Uint(50000) - PRECOMPILE_BLS_G1ADD = Uint(375) - PRECOMPILE_BLS_G1MUL = Uint(12000) - PRECOMPILE_BLS_G1MAP = Uint(5500) - PRECOMPILE_BLS_G2ADD = Uint(600) - PRECOMPILE_BLS_G2MUL = Uint(22500) - PRECOMPILE_BLS_G2MAP = Uint(23800) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000) + PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375) + PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000) + PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500) + PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600) + PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500) + PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Blobs - PER_BLOB = U64(2**17) - BLOB_TARGET_GAS_PER_BLOCK = U64(786432) - BLOB_MIN_GASPRICE = Uint(1) - BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716) + PER_BLOB: Final[U64] = U64(2**17) + BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = U64(786432) + BLOB_MIN_GASPRICE: Final[Uint] = Uint(1) + BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(5007716) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_TOKEN_STANDARD = Uint(4) - TX_DATA_TOKEN_FLOOR = Uint(10) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4) + TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(10) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_BLOBBASEFEE = BASE - OPCODE_BLOBHASH = Uint(3) - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_BLOBBASEFEE: Final[Uint] = BASE + OPCODE_BLOBHASH: Final[Uint] = Uint(3) + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MCOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/prague/vm/instructions/log.py b/src/ethereum/forks/prague/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/prague/vm/instructions/log.py +++ b/src/ethereum/forks/prague/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/prague/vm/instructions/stack.py b/src/ethereum/forks/prague/vm/instructions/stack.py index 366cf79f5e4..ce94af6ce8e 100644 --- a/src/ethereum/forks/prague/vm/instructions/stack.py +++ b/src/ethereum/forks/prague/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -142,70 +143,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/shanghai/vm/gas.py b/src/ethereum/forks/shanghai/vm/gas.py index b0447492ef5..f7b597f700f 100644 --- a/src/ethereum/forks/shanghai/vm/gas.py +++ b/src/ethereum/forks/shanghai/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,137 +30,137 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - WARM_ACCESS = Uint(100) - COLD_ACCOUNT_ACCESS = Uint(2600) - COLD_STORAGE_ACCESS = Uint(2100) + WARM_ACCESS: Final[Uint] = Uint(100) + COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(2600) + COLD_STORAGE_ACCESS: Final[Uint] = Uint(2100) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) - CODE_INIT_PER_WORD = Uint(2) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) + CODE_INIT_PER_WORD: Final[Uint] = Uint(2) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) - FAST_STEP = Uint(5) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) + FAST_STEP: Final[Uint] = Uint(5) # Refunds - REFUND_STORAGE_CLEAR = 4800 + REFUND_STORAGE_CLEAR: Final[int] = 4800 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) - PRECOMPILE_BLAKE2F_PER_ROUND = Uint(1) - PRECOMPILE_ECADD = Uint(150) - PRECOMPILE_ECMUL = Uint(6000) - PRECOMPILE_ECPAIRING_BASE = Uint(45000) - PRECOMPILE_ECPAIRING_PER_POINT = Uint(34000) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) + PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1) + PRECOMPILE_ECADD: Final[Uint] = Uint(150) + PRECOMPILE_ECMUL: Final[Uint] = Uint(6000) + PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000) + PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(16) - TX_ACCESS_LIST_ADDRESS = Uint(2400) - TX_ACCESS_LIST_STORAGE_KEY = Uint(1900) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(16) + TX_ACCESS_LIST_ADDRESS: Final[Uint] = Uint(2400) + TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = Uint(1900) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_SHL = VERY_LOW - OPCODE_SHR = VERY_LOW - OPCODE_SAR = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_PREVRANDAO = BASE - OPCODE_RETURNDATASIZE = BASE - OPCODE_CHAINID = BASE - OPCODE_BASEFEE = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_PUSH0 = BASE - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_SHL: Final[Uint] = VERY_LOW + OPCODE_SHR: Final[Uint] = VERY_LOW + OPCODE_SAR: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_PREVRANDAO: Final[Uint] = BASE + OPCODE_RETURNDATASIZE: Final[Uint] = BASE + OPCODE_CHAINID: Final[Uint] = BASE + OPCODE_BASEFEE: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_PUSH0: Final[Uint] = BASE + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_RETURNDATACOPY_BASE = VERY_LOW - OPCODE_RETURNDATACOPY_PER_WORD = Uint(3) - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) + OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) @dataclass diff --git a/src/ethereum/forks/shanghai/vm/instructions/log.py b/src/ethereum/forks/shanghai/vm/instructions/log.py index bd5e652db22..695f4de735c 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/log.py +++ b/src/ethereum/forks/shanghai/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -79,8 +80,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/shanghai/vm/instructions/stack.py b/src/ethereum/forks/shanghai/vm/instructions/stack.py index d7b3df986b0..eff50ac73c9 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/stack.py +++ b/src/ethereum/forks/shanghai/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,70 +140,70 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push0 = partial(push_n, num_bytes=0) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push0: Callable[[Evm], None] = partial(push_n, num_bytes=0) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/spurious_dragon/vm/gas.py b/src/ethereum/forks/spurious_dragon/vm/gas.py index 3f5f8d58b04..c4cd3ce528f 100644 --- a/src/ethereum/forks/spurious_dragon/vm/gas.py +++ b/src/ethereum/forks/spurious_dragon/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,121 +30,121 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(200) + SLOAD: Final[Uint] = Uint(200) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(50) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) - OPCODE_EXTERNAL_BASE = Uint(700) - OPCODE_BALANCE = Uint(400) - OPCODE_CALL_BASE = Uint(700) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(700) + OPCODE_BALANCE: Final[Uint] = Uint(400) + OPCODE_CALL_BASE: Final[Uint] = Uint(700) @dataclass diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/log.py b/src/ethereum/forks/spurious_dragon/vm/instructions/log.py index e3e3ebd7e76..3cfb69c194c 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/log.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -76,8 +77,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py b/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/src/ethereum/forks/tangerine_whistle/vm/gas.py b/src/ethereum/forks/tangerine_whistle/vm/gas.py index 9cc32869503..93c81fae94d 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/gas.py +++ b/src/ethereum/forks/tangerine_whistle/vm/gas.py @@ -12,7 +12,7 @@ """ from dataclasses import dataclass -from typing import List, Tuple +from typing import Final, List, Tuple from ethereum_types.numeric import U256, Uint, ulen @@ -30,121 +30,121 @@ class GasCosts: """ # Tiers - BASE = Uint(2) - VERY_LOW = Uint(3) - LOW = Uint(5) - MID = Uint(8) - HIGH = Uint(10) + BASE: Final[Uint] = Uint(2) + VERY_LOW: Final[Uint] = Uint(3) + LOW: Final[Uint] = Uint(5) + MID: Final[Uint] = Uint(8) + HIGH: Final[Uint] = Uint(10) # Access - SLOAD = Uint(200) + SLOAD: Final[Uint] = Uint(200) # Storage - STORAGE_SET = Uint(20000) - COLD_STORAGE_WRITE = Uint(5000) + STORAGE_SET: Final[Uint] = Uint(20000) + COLD_STORAGE_WRITE: Final[Uint] = Uint(5000) # Call - CALL_VALUE = Uint(9000) - CALL_STIPEND = Uint(2300) - NEW_ACCOUNT = Uint(25000) + CALL_VALUE: Final[Uint] = Uint(9000) + CALL_STIPEND: Final[Uint] = Uint(2300) + NEW_ACCOUNT: Final[Uint] = Uint(25000) # Contract Creation - CODE_DEPOSIT_PER_BYTE = Uint(200) + CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200) # Utility - ZERO = Uint(0) - MEMORY_PER_WORD = Uint(3) + ZERO: Final[Uint] = Uint(0) + MEMORY_PER_WORD: Final[Uint] = Uint(3) # Refunds - REFUND_STORAGE_CLEAR = 15000 - REFUND_SELF_DESTRUCT = 24000 + REFUND_STORAGE_CLEAR: Final[int] = 15000 + REFUND_SELF_DESTRUCT: Final[int] = 24000 # Precompiles - PRECOMPILE_ECRECOVER = Uint(3000) - PRECOMPILE_SHA256_BASE = Uint(60) - PRECOMPILE_SHA256_PER_WORD = Uint(12) - PRECOMPILE_RIPEMD160_BASE = Uint(600) - PRECOMPILE_RIPEMD160_PER_WORD = Uint(120) - PRECOMPILE_IDENTITY_BASE = Uint(15) - PRECOMPILE_IDENTITY_PER_WORD = Uint(3) + PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000) + PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60) + PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12) + PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600) + PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120) + PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15) + PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3) # Transactions - TX_BASE = Uint(21000) - TX_CREATE = Uint(32000) - TX_DATA_PER_ZERO = Uint(4) - TX_DATA_PER_NON_ZERO = Uint(68) + TX_BASE: Final[Uint] = Uint(21000) + TX_CREATE: Final[Uint] = Uint(32000) + TX_DATA_PER_ZERO: Final[Uint] = Uint(4) + TX_DATA_PER_NON_ZERO: Final[Uint] = Uint(68) # Block - LIMIT_ADJUSTMENT_FACTOR = Uint(1024) - LIMIT_MINIMUM = Uint(5000) + LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024) + LIMIT_MINIMUM: Final[Uint] = Uint(5000) # Static Opcodes - OPCODE_ADD = VERY_LOW - OPCODE_SUB = VERY_LOW - OPCODE_MUL = LOW - OPCODE_DIV = LOW - OPCODE_SDIV = LOW - OPCODE_MOD = LOW - OPCODE_SMOD = LOW - OPCODE_ADDMOD = MID - OPCODE_MULMOD = MID - OPCODE_SIGNEXTEND = LOW - OPCODE_LT = VERY_LOW - OPCODE_GT = VERY_LOW - OPCODE_SLT = VERY_LOW - OPCODE_SGT = VERY_LOW - OPCODE_EQ = VERY_LOW - OPCODE_ISZERO = VERY_LOW - OPCODE_AND = VERY_LOW - OPCODE_OR = VERY_LOW - OPCODE_XOR = VERY_LOW - OPCODE_NOT = VERY_LOW - OPCODE_BYTE = VERY_LOW - OPCODE_JUMP = MID - OPCODE_JUMPI = HIGH - OPCODE_JUMPDEST = Uint(1) - OPCODE_CALLDATALOAD = VERY_LOW - OPCODE_BLOCKHASH = Uint(20) - OPCODE_COINBASE = BASE - OPCODE_POP = BASE - OPCODE_MSIZE = BASE - OPCODE_PC = BASE - OPCODE_GAS = BASE - OPCODE_ADDRESS = BASE - OPCODE_ORIGIN = BASE - OPCODE_CALLER = BASE - OPCODE_CALLVALUE = BASE - OPCODE_CALLDATASIZE = BASE - OPCODE_CODESIZE = BASE - OPCODE_GASPRICE = BASE - OPCODE_TIMESTAMP = BASE - OPCODE_NUMBER = BASE - OPCODE_GASLIMIT = BASE - OPCODE_DIFFICULTY = BASE - OPCODE_PUSH = VERY_LOW - OPCODE_DUP = VERY_LOW - OPCODE_SWAP = VERY_LOW + OPCODE_ADD: Final[Uint] = VERY_LOW + OPCODE_SUB: Final[Uint] = VERY_LOW + OPCODE_MUL: Final[Uint] = LOW + OPCODE_DIV: Final[Uint] = LOW + OPCODE_SDIV: Final[Uint] = LOW + OPCODE_MOD: Final[Uint] = LOW + OPCODE_SMOD: Final[Uint] = LOW + OPCODE_ADDMOD: Final[Uint] = MID + OPCODE_MULMOD: Final[Uint] = MID + OPCODE_SIGNEXTEND: Final[Uint] = LOW + OPCODE_LT: Final[Uint] = VERY_LOW + OPCODE_GT: Final[Uint] = VERY_LOW + OPCODE_SLT: Final[Uint] = VERY_LOW + OPCODE_SGT: Final[Uint] = VERY_LOW + OPCODE_EQ: Final[Uint] = VERY_LOW + OPCODE_ISZERO: Final[Uint] = VERY_LOW + OPCODE_AND: Final[Uint] = VERY_LOW + OPCODE_OR: Final[Uint] = VERY_LOW + OPCODE_XOR: Final[Uint] = VERY_LOW + OPCODE_NOT: Final[Uint] = VERY_LOW + OPCODE_BYTE: Final[Uint] = VERY_LOW + OPCODE_JUMP: Final[Uint] = MID + OPCODE_JUMPI: Final[Uint] = HIGH + OPCODE_JUMPDEST: Final[Uint] = Uint(1) + OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW + OPCODE_BLOCKHASH: Final[Uint] = Uint(20) + OPCODE_COINBASE: Final[Uint] = BASE + OPCODE_POP: Final[Uint] = BASE + OPCODE_MSIZE: Final[Uint] = BASE + OPCODE_PC: Final[Uint] = BASE + OPCODE_GAS: Final[Uint] = BASE + OPCODE_ADDRESS: Final[Uint] = BASE + OPCODE_ORIGIN: Final[Uint] = BASE + OPCODE_CALLER: Final[Uint] = BASE + OPCODE_CALLVALUE: Final[Uint] = BASE + OPCODE_CALLDATASIZE: Final[Uint] = BASE + OPCODE_CODESIZE: Final[Uint] = BASE + OPCODE_GASPRICE: Final[Uint] = BASE + OPCODE_TIMESTAMP: Final[Uint] = BASE + OPCODE_NUMBER: Final[Uint] = BASE + OPCODE_GASLIMIT: Final[Uint] = BASE + OPCODE_DIFFICULTY: Final[Uint] = BASE + OPCODE_PUSH: Final[Uint] = VERY_LOW + OPCODE_DUP: Final[Uint] = VERY_LOW + OPCODE_SWAP: Final[Uint] = VERY_LOW # Dynamic Opcodes - OPCODE_CALLDATACOPY_BASE = VERY_LOW - OPCODE_CODECOPY_BASE = VERY_LOW - OPCODE_MLOAD_BASE = VERY_LOW - OPCODE_MSTORE_BASE = VERY_LOW - OPCODE_MSTORE8_BASE = VERY_LOW - OPCODE_COPY_PER_WORD = Uint(3) - OPCODE_CREATE_BASE = Uint(32000) - OPCODE_EXP_BASE = Uint(10) - OPCODE_EXP_PER_BYTE = Uint(10) - OPCODE_KECCAK256_BASE = Uint(30) - OPCODE_KECCACK256_PER_WORD = Uint(6) - OPCODE_LOG_BASE = Uint(375) - OPCODE_LOG_DATA_PER_BYTE = Uint(8) - OPCODE_LOG_TOPIC = Uint(375) - OPCODE_SELFDESTRUCT_BASE = Uint(5000) - OPCODE_SELFDESTRUCT_NEW_ACCOUNT = Uint(25000) - OPCODE_EXTERNAL_BASE = Uint(700) - OPCODE_BALANCE = Uint(400) - OPCODE_CALL_BASE = Uint(700) + OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW + OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW + OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW + OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3) + OPCODE_CREATE_BASE: Final[Uint] = Uint(32000) + OPCODE_EXP_BASE: Final[Uint] = Uint(10) + OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(10) + OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30) + OPCODE_KECCACK256_PER_WORD: Final[Uint] = Uint(6) + OPCODE_LOG_BASE: Final[Uint] = Uint(375) + OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8) + OPCODE_LOG_TOPIC: Final[Uint] = Uint(375) + OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000) + OPCODE_SELFDESTRUCT_NEW_ACCOUNT: Final[Uint] = Uint(25000) + OPCODE_EXTERNAL_BASE: Final[Uint] = Uint(700) + OPCODE_BALANCE: Final[Uint] = Uint(400) + OPCODE_CALL_BASE: Final[Uint] = Uint(700) @dataclass diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py index e3e3ebd7e76..3cfb69c194c 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import Uint @@ -76,8 +77,8 @@ def log_n(evm: Evm, num_topics: int) -> None: evm.pc += Uint(1) -log0 = partial(log_n, num_topics=0) -log1 = partial(log_n, num_topics=1) -log2 = partial(log_n, num_topics=2) -log3 = partial(log_n, num_topics=3) -log4 = partial(log_n, num_topics=4) +log0: Callable[[Evm], None] = partial(log_n, num_topics=0) +log1: Callable[[Evm], None] = partial(log_n, num_topics=1) +log2: Callable[[Evm], None] = partial(log_n, num_topics=2) +log3: Callable[[Evm], None] = partial(log_n, num_topics=3) +log4: Callable[[Evm], None] = partial(log_n, num_topics=4) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py index 9104c1e9749..901bff4ed3b 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py @@ -12,6 +12,7 @@ """ from functools import partial +from typing import Callable from ethereum_types.numeric import U256, Uint @@ -139,69 +140,69 @@ def swap_n(evm: Evm, item_number: int) -> None: evm.pc += Uint(1) -push1 = partial(push_n, num_bytes=1) -push2 = partial(push_n, num_bytes=2) -push3 = partial(push_n, num_bytes=3) -push4 = partial(push_n, num_bytes=4) -push5 = partial(push_n, num_bytes=5) -push6 = partial(push_n, num_bytes=6) -push7 = partial(push_n, num_bytes=7) -push8 = partial(push_n, num_bytes=8) -push9 = partial(push_n, num_bytes=9) -push10 = partial(push_n, num_bytes=10) -push11 = partial(push_n, num_bytes=11) -push12 = partial(push_n, num_bytes=12) -push13 = partial(push_n, num_bytes=13) -push14 = partial(push_n, num_bytes=14) -push15 = partial(push_n, num_bytes=15) -push16 = partial(push_n, num_bytes=16) -push17 = partial(push_n, num_bytes=17) -push18 = partial(push_n, num_bytes=18) -push19 = partial(push_n, num_bytes=19) -push20 = partial(push_n, num_bytes=20) -push21 = partial(push_n, num_bytes=21) -push22 = partial(push_n, num_bytes=22) -push23 = partial(push_n, num_bytes=23) -push24 = partial(push_n, num_bytes=24) -push25 = partial(push_n, num_bytes=25) -push26 = partial(push_n, num_bytes=26) -push27 = partial(push_n, num_bytes=27) -push28 = partial(push_n, num_bytes=28) -push29 = partial(push_n, num_bytes=29) -push30 = partial(push_n, num_bytes=30) -push31 = partial(push_n, num_bytes=31) -push32 = partial(push_n, num_bytes=32) - -dup1 = partial(dup_n, item_number=0) -dup2 = partial(dup_n, item_number=1) -dup3 = partial(dup_n, item_number=2) -dup4 = partial(dup_n, item_number=3) -dup5 = partial(dup_n, item_number=4) -dup6 = partial(dup_n, item_number=5) -dup7 = partial(dup_n, item_number=6) -dup8 = partial(dup_n, item_number=7) -dup9 = partial(dup_n, item_number=8) -dup10 = partial(dup_n, item_number=9) -dup11 = partial(dup_n, item_number=10) -dup12 = partial(dup_n, item_number=11) -dup13 = partial(dup_n, item_number=12) -dup14 = partial(dup_n, item_number=13) -dup15 = partial(dup_n, item_number=14) -dup16 = partial(dup_n, item_number=15) - -swap1 = partial(swap_n, item_number=1) -swap2 = partial(swap_n, item_number=2) -swap3 = partial(swap_n, item_number=3) -swap4 = partial(swap_n, item_number=4) -swap5 = partial(swap_n, item_number=5) -swap6 = partial(swap_n, item_number=6) -swap7 = partial(swap_n, item_number=7) -swap8 = partial(swap_n, item_number=8) -swap9 = partial(swap_n, item_number=9) -swap10 = partial(swap_n, item_number=10) -swap11 = partial(swap_n, item_number=11) -swap12 = partial(swap_n, item_number=12) -swap13 = partial(swap_n, item_number=13) -swap14 = partial(swap_n, item_number=14) -swap15 = partial(swap_n, item_number=15) -swap16 = partial(swap_n, item_number=16) +push1: Callable[[Evm], None] = partial(push_n, num_bytes=1) +push2: Callable[[Evm], None] = partial(push_n, num_bytes=2) +push3: Callable[[Evm], None] = partial(push_n, num_bytes=3) +push4: Callable[[Evm], None] = partial(push_n, num_bytes=4) +push5: Callable[[Evm], None] = partial(push_n, num_bytes=5) +push6: Callable[[Evm], None] = partial(push_n, num_bytes=6) +push7: Callable[[Evm], None] = partial(push_n, num_bytes=7) +push8: Callable[[Evm], None] = partial(push_n, num_bytes=8) +push9: Callable[[Evm], None] = partial(push_n, num_bytes=9) +push10: Callable[[Evm], None] = partial(push_n, num_bytes=10) +push11: Callable[[Evm], None] = partial(push_n, num_bytes=11) +push12: Callable[[Evm], None] = partial(push_n, num_bytes=12) +push13: Callable[[Evm], None] = partial(push_n, num_bytes=13) +push14: Callable[[Evm], None] = partial(push_n, num_bytes=14) +push15: Callable[[Evm], None] = partial(push_n, num_bytes=15) +push16: Callable[[Evm], None] = partial(push_n, num_bytes=16) +push17: Callable[[Evm], None] = partial(push_n, num_bytes=17) +push18: Callable[[Evm], None] = partial(push_n, num_bytes=18) +push19: Callable[[Evm], None] = partial(push_n, num_bytes=19) +push20: Callable[[Evm], None] = partial(push_n, num_bytes=20) +push21: Callable[[Evm], None] = partial(push_n, num_bytes=21) +push22: Callable[[Evm], None] = partial(push_n, num_bytes=22) +push23: Callable[[Evm], None] = partial(push_n, num_bytes=23) +push24: Callable[[Evm], None] = partial(push_n, num_bytes=24) +push25: Callable[[Evm], None] = partial(push_n, num_bytes=25) +push26: Callable[[Evm], None] = partial(push_n, num_bytes=26) +push27: Callable[[Evm], None] = partial(push_n, num_bytes=27) +push28: Callable[[Evm], None] = partial(push_n, num_bytes=28) +push29: Callable[[Evm], None] = partial(push_n, num_bytes=29) +push30: Callable[[Evm], None] = partial(push_n, num_bytes=30) +push31: Callable[[Evm], None] = partial(push_n, num_bytes=31) +push32: Callable[[Evm], None] = partial(push_n, num_bytes=32) + +dup1: Callable[[Evm], None] = partial(dup_n, item_number=0) +dup2: Callable[[Evm], None] = partial(dup_n, item_number=1) +dup3: Callable[[Evm], None] = partial(dup_n, item_number=2) +dup4: Callable[[Evm], None] = partial(dup_n, item_number=3) +dup5: Callable[[Evm], None] = partial(dup_n, item_number=4) +dup6: Callable[[Evm], None] = partial(dup_n, item_number=5) +dup7: Callable[[Evm], None] = partial(dup_n, item_number=6) +dup8: Callable[[Evm], None] = partial(dup_n, item_number=7) +dup9: Callable[[Evm], None] = partial(dup_n, item_number=8) +dup10: Callable[[Evm], None] = partial(dup_n, item_number=9) +dup11: Callable[[Evm], None] = partial(dup_n, item_number=10) +dup12: Callable[[Evm], None] = partial(dup_n, item_number=11) +dup13: Callable[[Evm], None] = partial(dup_n, item_number=12) +dup14: Callable[[Evm], None] = partial(dup_n, item_number=13) +dup15: Callable[[Evm], None] = partial(dup_n, item_number=14) +dup16: Callable[[Evm], None] = partial(dup_n, item_number=15) + +swap1: Callable[[Evm], None] = partial(swap_n, item_number=1) +swap2: Callable[[Evm], None] = partial(swap_n, item_number=2) +swap3: Callable[[Evm], None] = partial(swap_n, item_number=3) +swap4: Callable[[Evm], None] = partial(swap_n, item_number=4) +swap5: Callable[[Evm], None] = partial(swap_n, item_number=5) +swap6: Callable[[Evm], None] = partial(swap_n, item_number=6) +swap7: Callable[[Evm], None] = partial(swap_n, item_number=7) +swap8: Callable[[Evm], None] = partial(swap_n, item_number=8) +swap9: Callable[[Evm], None] = partial(swap_n, item_number=9) +swap10: Callable[[Evm], None] = partial(swap_n, item_number=10) +swap11: Callable[[Evm], None] = partial(swap_n, item_number=11) +swap12: Callable[[Evm], None] = partial(swap_n, item_number=12) +swap13: Callable[[Evm], None] = partial(swap_n, item_number=13) +swap14: Callable[[Evm], None] = partial(swap_n, item_number=14) +swap15: Callable[[Evm], None] = partial(swap_n, item_number=15) +swap16: Callable[[Evm], None] = partial(swap_n, item_number=16) diff --git a/tests/json_loader/test_tools_new_fork.py b/tests/json_loader/test_tools_new_fork.py index 0f009afeac5..45e76591af5 100644 --- a/tests/json_loader/test_tools_new_fork.py +++ b/tests/json_loader/test_tools_new_fork.py @@ -75,19 +75,19 @@ def test_end_to_end(template_fork: str) -> None: source = f.read() expected = [ - "BLOB_TARGET_GAS_PER_BLOCK = U64(199)", - "PER_BLOB = U64(1)", - "BLOB_MIN_GASPRICE = Uint(2)", - "BLOB_BASE_FEE_UPDATE_FRACTION = Uint(750)", - "BLOB_SCHEDULE_TARGET = U64(88)", - "BLOB_SCHEDULE_MAX = U64(77)", + "BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = U64(199)", + "PER_BLOB: Final[U64] = U64(1)", + "BLOB_MIN_GASPRICE: Final[Uint] = Uint(2)", + "BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(750)", + "BLOB_SCHEDULE_TARGET: Final[U64] = U64(88)", + "BLOB_SCHEDULE_MAX: Final[U64] = U64(77)", ] for needle in expected: assert needle in source with (fork_dir / "fork.py").open("r") as f: - assert "MAX_BLOB_GAS_PER_BLOCK = U64(99)" in f.read() + assert "MAX_BLOB_GAS_PER_BLOCK: Final[U64] = U64(99)" in f.read() # TODO: Remove this condition once trie.py is removed from all # forks (i.e. fork-agnostic Trie is ported to pre-amsterdam forks). From 1de389b6177788dfa1df35c71b643e46b82029d1 Mon Sep 17 00:00:00 2001 From: felipe Date: Wed, 20 May 2026 16:33:22 -0600 Subject: [PATCH 109/186] feat(tests): extend BALs coverage (#2854) * test(tests): extend BALs coverage for edge cases * test(tests): closes #1910 - parametrize memory for call_opcode tests * test(tests): expand BAL coverage for insufficient-funds boundaries Add a combined outer-REVERT + inner-insufficient-funds test (CALL and CREATE), and layer EIP-7928-gated BAL expectations onto three existing cross-fork insufficient-funds tests (EIP-7708, EIP-2929 frontier CALL). * feat(tests): add some more parallelization test scenarios for BALs * chore(tests): add SSTORE to CREATE2 + SD + re-create as sanity check * cleanups from comments on PR #2854 * feat(tests): add parallelization BAL tests for collision / OOG create chain * chore: audit * update ``test_cases.md`` after suggestions and PR #2882 * fix(tests): update expected exception(s) for transition tests --- .../test_block_access_lists.py | 458 ++++++++++++++++++ .../test_block_access_lists_eip7702.py | 97 ++-- .../test_block_access_lists_opcodes.py | 247 +++++++--- .../test_cases.md | 34 +- .../test_fork_transition.py | 13 +- .../eip2929_gas_cost_increases/test_create.py | 65 ++- .../test_journal_revert.py | 18 + 7 files changed, 808 insertions(+), 124 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index e7d99ad0935..5b22e2e77a2 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -28,11 +28,13 @@ Header, Initcode, Op, + StateTestFiller, Transaction, TransactionException, add_kzg_version, compute_create_address, ) +from execution_testing import Macros as Om from .spec import ref_spec_7928 @@ -581,6 +583,118 @@ def test_bal_block_rewards( ) +@pytest.mark.parametrize( + "same_tx", [False, True], ids=["pre_deploy", "same_tx"] +) +def test_bal_selfdestruct_to_coinbase( + pre: Alloc, + state_test: StateTestFiller, + fork: Fork, + same_tx: bool, +) -> None: + """ + Ensure BAL records SELFDESTRUCT when the beneficiary is the coinbase. + + Post-Cancun (EIP-6780) the contract is only actually destroyed when + created in the same tx; the pre-deployed path only transfers balance + and preserves the contract. Both shapes must appear in BAL. + """ + alice = pre.fund_eoa() + coinbase = pre.fund_eoa(amount=0) + victim_balance = 100 + victim_code = Op.SELFDESTRUCT(Op.COINBASE) + + # Match gas_price to base_fee so the priority-fee tip is zero; + # coinbase's BAL entry then carries only the SELFDESTRUCT transfer. + base_fee_per_gas = 7 + env = Environment( + base_fee_per_gas=base_fee_per_gas, fee_recipient=coinbase + ) + + tx_gas_limit = fork.transaction_gas_limit_cap() + account_expectations: dict[Address, BalAccountExpectation] + + if same_tx: + initcode = Initcode(deploy_code=victim_code) + factory_code = Om.MSTORE(initcode, 0) + Op.CALL( + gas=Op.GAS, + address=Op.CREATE( + value=victim_balance, offset=0, size=len(initcode) + ), + ) + factory = pre.deploy_contract( + code=factory_code, balance=victim_balance + ) + victim = compute_create_address(address=factory, nonce=1) + tx_target = factory + post = { + factory: Account(balance=0), + victim: Account.NONEXISTENT, + coinbase: Account(balance=victim_balance), + } + account_expectations = { + factory: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=2) + ], + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0) + ], + ), + # Created and destroyed in the same tx — empty changes. + victim: BalAccountExpectation.empty(), + coinbase: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=victim_balance + ) + ], + ), + } + else: + victim = pre.deploy_contract(code=victim_code, balance=victim_balance) + tx_target = victim + # Pre-deployed and not same-tx: post-Cancun preserves the contract. + post = { + victim: Account(balance=0, code=victim_code), + coinbase: Account(balance=victim_balance), + } + account_expectations = { + victim: BalAccountExpectation( + balance_changes=[ + BalBalanceChange(block_access_index=1, post_balance=0) + ], + ), + coinbase: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, post_balance=victim_balance + ) + ], + ), + } + + tx = Transaction( + sender=alice, + to=tx_target, + gas_limit=tx_gas_limit, + gas_price=base_fee_per_gas, + ) + + state_test( + env=env, + pre=pre, + post=post, + tx=tx, + blockchain_test_header_verify=Header( + base_fee_per_gas=base_fee_per_gas + ), + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations, + ), + ) + + def test_bal_2930_account_listed_but_untouched( pre: Alloc, blockchain_test: BlockchainTestFiller, @@ -1239,6 +1353,188 @@ def test_bal_aborted_account_access( ) +@pytest.mark.parametrize( + "inner_action", + ["sstore", "sload", "balance", "extcodesize"], +) +@pytest.mark.parametrize( + "outer_abort", + [ + pytest.param(Op.REVERT(0, 0), id="outer_revert"), + pytest.param(Op.INVALID, id="outer_invalid"), + ], +) +def test_bal_parent_revert_state_access( + pre: Alloc, + state_test: StateTestFiller, + fork: Fork, + inner_action: str, + outer_abort: Op, +) -> None: + """Ensure BAL captures child-frame state access when the parent reverts.""" + alice = pre.fund_eoa() + extra_target = pre.deploy_contract(code=Op.STOP) + + if inner_action == "sstore": + # Write demoted to read by parent revert; pre-set 0xDEAD so the + # post-state confirms the slot was unchanged. + inner = pre.deploy_contract( + code=Op.SSTORE(1, 0x42) + Op.STOP, + storage={1: 0xDEAD}, + ) + elif inner_action == "sload": + inner = pre.deploy_contract( + code=Op.POP(Op.SLOAD(1)) + Op.STOP, + storage={1: 0xDEAD}, + ) + elif inner_action == "balance": + inner = pre.deploy_contract( + code=Op.POP(Op.BALANCE(extra_target)) + Op.STOP + ) + elif inner_action == "extcodesize": + inner = pre.deploy_contract( + code=Op.POP(Op.EXTCODESIZE(extra_target)) + Op.STOP + ) + else: + raise ValueError(f"unknown inner_action: {inner_action}") + outer = pre.deploy_contract( + code=Op.CALL(gas=Op.GAS, address=inner) + outer_abort + ) + + tx = Transaction( + sender=alice, to=outer, gas_limit=fork.transaction_gas_limit_cap() + ) + + account_expectations: dict[Address, BalAccountExpectation] + if inner_action in ("sstore", "sload"): + account_expectations = { + inner: BalAccountExpectation(storage_reads=[1]), + } + elif inner_action in ("balance", "extcodesize"): + account_expectations = { + inner: BalAccountExpectation.empty(), + extra_target: BalAccountExpectation.empty(), + } + else: + raise ValueError(f"unknown inner_action: {inner_action}") + + post: dict = {alice: Account(nonce=1)} + if inner_action in ("sstore", "sload"): + # Slot 1 stays at its pre-state value: SSTORE demoted to read, + # SLOAD never mutates. + post[inner] = Account(storage={1: 0xDEAD}) + + state_test( + pre=pre, + post=post, + tx=tx, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations, + ), + ) + + +@pytest.mark.parametrize( + "inner_op", + [pytest.param("call", id="call"), pytest.param("create", id="create")], +) +def test_bal_outer_revert_with_inner_insufficient_funds( + pre: Alloc, + state_test: StateTestFiller, + fork: Fork, + inner_op: str, +) -> None: + """ + Outer REVERT + inner CALL/CREATE that fails on insufficient funds. + + Inner writes two slots and then attempts a value-bearing CALL or + CREATE that fails (balance=0 < value). The opcode's state-touching + costs are charged before the balance check, so the failed CALL's + target stays in BAL with empty changes, while CREATE fails before + `track_address` and the would-be address does not appear at all. + Inner's writes demote to reads under outer's REVERT; the post-state + checks confirm none of the rolled-back state leaked through. + """ + alice = pre.fund_eoa() + slot_a, slot_b = 1, 2 + insufficient_value = 100 + + if inner_op == "call": + target = pre.deploy_contract(code=Op.STOP) + inner = pre.deploy_contract( + code=( + Op.SSTORE(slot_a, 0x42) + + Op.SSTORE( + slot_b, + Op.CALL( + gas=100_000, + address=target, + value=insufficient_value, + ), + ) + + Op.STOP + ), + balance=0, + ) + extra_account = target + extra_bal: BalAccountExpectation | None = BalAccountExpectation.empty() + extra_post: Account | None = Account(balance=0) + elif inner_op == "create": + initcode_bytes = bytes(Initcode(deploy_code=Op.STOP)) + inner = pre.deploy_contract( + code=( + Op.MSTORE(0, Op.PUSH32(initcode_bytes)) + + Op.SSTORE(slot_a, 0x42) + + Op.SSTORE( + slot_b, + Op.CREATE( + value=insufficient_value, + offset=32 - len(initcode_bytes), + size=len(initcode_bytes), + ), + ) + + Op.STOP + ), + balance=0, + ) + extra_account = compute_create_address(address=inner, nonce=1) + extra_bal = None + extra_post = Account.NONEXISTENT + else: + raise ValueError(f"unknown inner_op: {inner_op}") + + outer = pre.deploy_contract( + code=Op.CALL(gas=Op.GAS, address=inner) + Op.REVERT(0, 0) + ) + + tx = Transaction( + sender=alice, to=outer, gas_limit=fork.transaction_gas_limit_cap() + ) + + state_test( + pre=pre, + post={ + alice: Account(nonce=1), + outer: Account(balance=0, storage={}), + inner: Account(balance=0, storage={}), + extra_account: extra_post, + }, + tx=tx, + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + outer: BalAccountExpectation.empty(), + inner: BalAccountExpectation(storage_reads=[slot_a, slot_b]), + extra_account: extra_bal, + }, + ), + ) + + def test_bal_fully_unmutated_account( pre: Alloc, blockchain_test: BlockchainTestFiller, @@ -2379,6 +2675,168 @@ def test_bal_cross_tx_deploy_then_call( ) +@pytest.mark.parametrize( + "failure_mode", + [ + pytest.param("none", id="no_failure"), + pytest.param("collision", id="mid_chain_collision"), + pytest.param("oog", id="mid_chain_oog"), + ], +) +@pytest.mark.pre_alloc_mutable() +def test_bal_cross_tx_factory_nonce_create_chain( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + fork: Fork, + failure_mode: str, +) -> None: + """ + Cross-tx CREATE chain: 8 senders share a factory whose CREATE + address derives solely from `factory.nonce`. `collision` and `oog` + test opposite parallelization hazards mid-chain — collision still + bumps factory.nonce (later txs slide forward), OOG does not (later + txs slide backward, reusing the OOG'd slot). + """ + chain_length = 8 + failure_index = 3 if failure_mode in ("collision", "oog") else None + + factory_code = ( + Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + + Op.CREATE(0, 0, Op.CALLDATASIZE) + + Op.STOP + ) + factory = pre.deploy_contract(code=factory_code) + factory_pre_nonce = 1 + + deploy_code = Op.STOP + initcode = Initcode(deploy_code=deploy_code) + collision_code = Op.PUSH1(0x42) + Op.STOP + + targets = [ + compute_create_address(address=factory, nonce=factory_pre_nonce + k) + for k in range(chain_length) + ] + + if failure_mode == "collision": + assert failure_index is not None + pre[targets[failure_index]] = Account(code=collision_code) + + sequence: list[dict] = [] + factory_nonce = factory_pre_nonce + for i in range(chain_length): + block_idx = i + 1 + if failure_mode == "oog" and i == failure_index: + sequence.append( + {"block_idx": block_idx, "target_idx": None, "deployed": False} + ) + else: + target_idx = factory_nonce - factory_pre_nonce + factory_nonce += 1 + deployed = not (failure_mode == "collision" and i == failure_index) + sequence.append( + { + "block_idx": block_idx, + "factory_post_nonce": factory_nonce, + "target_idx": target_idx, + "deployed": deployed, + } + ) + + senders = [pre.fund_eoa() for _ in range(chain_length)] + # OOG tx: intrinsic + 1 — valid to include but no gas to run CREATE. + intrinsic = fork.transaction_intrinsic_cost_calculator()( + calldata=bytes(initcode), contract_creation=False, access_list=[] + ) + txs = [ + Transaction( + sender=senders[i], + to=factory, + data=initcode, + gas_limit=( + intrinsic + 1 + if failure_mode == "oog" and i == failure_index + else fork.transaction_gas_limit_cap() + ), + ) + for i in range(chain_length) + ] + + account_expectations: dict = { + senders[i]: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=i + 1, post_nonce=1) + ], + ) + for i in range(chain_length) + } + # Factory: only txs that bumped its nonce contribute entries. + account_expectations[factory] = BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=s["block_idx"], + post_nonce=s["factory_post_nonce"], + ) + for s in sequence + if s["target_idx"] is not None + ], + ) + for s in sequence: + if s["target_idx"] is None: + continue + target = targets[s["target_idx"]] + if s["deployed"]: + account_expectations[target] = BalAccountExpectation( + nonce_changes=[ + BalNonceChange( + block_access_index=s["block_idx"], post_nonce=1 + ) + ], + code_changes=[ + BalCodeChange( + block_access_index=s["block_idx"], + new_code=deploy_code, + ) + ], + ) + else: + # Collision: accessed during EIP-684 check, no state change. + account_expectations[target] = BalAccountExpectation.empty() + + touched_target_idxs = { + s["target_idx"] for s in sequence if s["target_idx"] is not None + } + final_factory_nonce = factory_pre_nonce + len(touched_target_idxs) + post: dict = { + factory: Account(nonce=final_factory_nonce), + **{sender: Account(nonce=1) for sender in senders}, + } + for s in sequence: + if s["target_idx"] is None: + continue + target = targets[s["target_idx"]] + post[target] = ( + Account(nonce=1, code=deploy_code) + if s["deployed"] + else Account(code=collision_code) + ) + for k, target in enumerate(targets): + if k not in touched_target_idxs: + post[target] = Account.NONEXISTENT + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=txs, + expected_block_access_list=BlockAccessListExpectation( + account_expectations=account_expectations + ), + ) + ], + post=post, + ) + + @pytest.mark.parametrize( "funding_method", ["direct_call", "selfdestruct"], diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py index 434c432c2cf..08ab12a9e79 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py @@ -133,70 +133,97 @@ def test_bal_7702_delegation_create( @pytest.mark.parametrize( - "self_funded", + "sender_pattern", [ - pytest.param(False, id="sponsored"), - pytest.param(True, id="self_funded"), + pytest.param("sponsored", id="sponsored"), + pytest.param("self_funded", id="self_funded"), + pytest.param("sponsored_cross_sender", id="sponsored_cross_sender"), ], ) def test_bal_7702_delegation_update( pre: Alloc, blockchain_test: BlockchainTestFiller, - self_funded: bool, + sender_pattern: str, ) -> None: - """Ensure BAL captures update of existing EOA delegation.""" + """ + Ensure BAL captures update of existing EOA delegation. The + `sponsored_cross_sender` variant uses a distinct relayer per tx so + the cross-tx auth-nonce dep can't be served by sender-nonce + serialization alone. + """ alice = pre.fund_eoa() bob = pre.fund_eoa(amount=0) - if not self_funded: - relayer = pre.fund_eoa() - sender = relayer - else: - sender = alice - oracle1 = pre.deploy_contract(code=Op.STOP) oracle2 = pre.deploy_contract(code=Op.STOP) - ## Perhaps create a pre-existing delegation, - ## see `test_bal_7702_delegated_storage_access` since - ## `test_bal_7702_delegation_create` already tests creation + if sender_pattern == "self_funded": + sender_create = alice + sender_update = alice + update_tx_nonce = 2 + create_auth_nonce = 1 + update_auth_nonce = 3 + alice_post_create = 2 + alice_post_update = 4 + elif sender_pattern == "sponsored": + relayer = pre.fund_eoa() + sender_create = relayer + sender_update = relayer + update_tx_nonce = 1 + create_auth_nonce = 0 + update_auth_nonce = 1 + alice_post_create = 1 + alice_post_update = 2 + elif sender_pattern == "sponsored_cross_sender": + relayer_create = pre.fund_eoa() + relayer_update = pre.fund_eoa() + sender_create = relayer_create + sender_update = relayer_update + update_tx_nonce = 0 + create_auth_nonce = 0 + update_auth_nonce = 1 + alice_post_create = 1 + alice_post_update = 2 + else: + raise ValueError(f"unknown sender_pattern: {sender_pattern}") + tx_create = Transaction( - sender=sender, + sender=sender_create, to=bob, value=10, gas_limit=1_000_000, authorization_list=[ AuthorizationTuple( address=oracle1, - nonce=1 if self_funded else 0, + nonce=create_auth_nonce, signer=alice, ) ], ) tx_update = Transaction( - nonce=2 if self_funded else 1, - sender=sender, + nonce=update_tx_nonce, + sender=sender_update, to=bob, value=10, gas_limit=1_000_000, authorization_list=[ AuthorizationTuple( address=oracle2, - nonce=3 if self_funded else 1, + nonce=update_auth_nonce, signer=alice, ) ], ) - account_expectations = { + account_expectations: dict = { alice: BalAccountExpectation( nonce_changes=[ BalNonceChange( - block_access_index=1, post_nonce=2 if self_funded else 1 + block_access_index=1, post_nonce=alice_post_create ), BalNonceChange( - block_access_index=2, post_nonce=4 if self_funded else 2 + block_access_index=2, post_nonce=alice_post_update ), ], code_changes=[ @@ -222,14 +249,24 @@ def test_bal_7702_delegation_update( oracle2: None, } - # For sponsored variant, relayer must also be included in BAL - if not self_funded: + if sender_pattern == "sponsored": account_expectations[relayer] = BalAccountExpectation( nonce_changes=[ BalNonceChange(block_access_index=1, post_nonce=1), BalNonceChange(block_access_index=2, post_nonce=2), ], ) + elif sender_pattern == "sponsored_cross_sender": + account_expectations[relayer_create] = BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1), + ], + ) + account_expectations[relayer_update] = BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=2, post_nonce=1), + ], + ) block = Block( txs=[tx_create, tx_update], @@ -238,19 +275,21 @@ def test_bal_7702_delegation_update( ), ) - post = { + post: dict = { # Finally Alice's account should be delegated to oracle2 alice: Account( - nonce=4 if self_funded else 2, + nonce=alice_post_update, code=Spec7702.delegation_designation(oracle2), ), # Bob receives 20 wei in total bob: Account(balance=20), } - # For sponsored variant, include relayer in post state - if not self_funded: - post.update({relayer: Account(nonce=2)}) + if sender_pattern == "sponsored": + post[relayer] = Account(nonce=2) + elif sender_pattern == "sponsored_cross_sender": + post[relayer_create] = Account(nonce=1) + post[relayer_update] = Account(nonce=1) blockchain_test( pre=pre, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index 671a84c6397..c7f0d49fcd4 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -466,7 +466,13 @@ def test_bal_extcodesize_and_oog( ) @pytest.mark.parametrize("value", [0, 1], ids=["no_value", "with_value"]) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_call_no_delegation_and_oog_before_target_access( pre: Alloc, @@ -476,13 +482,18 @@ def test_bal_call_no_delegation_and_oog_before_target_access( target_is_warm: bool, target_is_empty: bool, value: int, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ CALL without 7702 delegation - test SUCCESS and OOG before target access. When target_is_warm=True, we use EIP-2930 tx access list to warm the target. Access list warming does NOT add to BAL - only EVM access does. + + Memory expansion is parametrized independently for args (insize) and + ret (outsize) per #1910, surfacing client-impl asymmetry bugs in the + memory-cost calculator. """ alice = pre.fund_eoa() @@ -492,19 +503,21 @@ def test_bal_call_no_delegation_and_oog_before_target_access( else pre.deploy_contract(code=Op.STOP) ) - ret_size = 32 if memory_expansion else 0 + new_memory_size = max(args_size, ret_size) # Full gas metadata: includes create_cost when applicable call_code = Op.CALL( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=value > 0 and target_is_empty, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) caller = pre.deploy_contract(code=call_code, balance=value) @@ -524,12 +537,14 @@ def test_bal_call_no_delegation_and_oog_before_target_access( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) gas_limit = intrinsic_cost + call_static.gas_cost(fork) - 1 else: # SUCCESS @@ -602,7 +617,13 @@ def test_bal_call_no_delegation_and_oog_before_target_access( "target_is_warm", [False, True], ids=["cold_target", "warm_target"] ) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) @pytest.mark.eels_base_coverage def test_bal_call_no_delegation_oog_after_target_access( @@ -610,7 +631,8 @@ def test_bal_call_no_delegation_oog_after_target_access( blockchain_test: BlockchainTestFiller, fork: Fork, target_is_warm: bool, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ CALL without 7702 delegation - OOG after state access. @@ -629,6 +651,9 @@ def test_bal_call_no_delegation_oog_after_target_access( The create_cost (NEW_ACCOUNT = 25000) is charged only for value transfers to empty accounts, creating the gap tested here. + Memory expansion is parametrized independently for args (insize) and + ret (outsize) per #1910. + """ alice = pre.fund_eoa() @@ -637,8 +662,7 @@ def test_bal_call_no_delegation_oog_after_target_access( # value > 0 required for create_cost value = 1 - # memory expansion / no expansion - ret_size = 32 if memory_expansion else 0 + new_memory_size = max(args_size, ret_size) # Static gas (before state access): no create_cost # Pass static check, fail at second check due to create cost @@ -646,12 +670,14 @@ def test_bal_call_no_delegation_oog_after_target_access( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=True, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) caller = pre.deploy_contract(code=call_code, balance=value) @@ -717,7 +743,13 @@ def test_bal_call_no_delegation_oog_after_target_access( ) @pytest.mark.parametrize("value", [0, 1], ids=["no_value", "with_value"]) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_call_7702_delegation_and_oog( pre: Alloc, @@ -727,33 +759,37 @@ def test_bal_call_7702_delegation_and_oog( target_is_warm: bool, delegation_is_warm: bool, value: int, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ CALL with 7702 delegation - test all OOG boundaries. When target_is_warm or delegation_is_warm, we use EIP-2930 tx access list. Access list warming does NOT add targets to BAL - only EVM access does. + + Memory expansion is parametrized independently for args and ret per #1910. """ alice = pre.fund_eoa() delegation_target = pre.deploy_contract(code=Op.STOP) target = pre.fund_eoa(amount=0, delegation=delegation_target) - # memory expansion / no expansion - ret_size = 32 if memory_expansion else 0 + new_memory_size = max(args_size, ret_size) # Full gas metadata: includes delegation cost call_code = Op.CALL( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, delegated_address=True, delegated_address_warm=delegation_is_warm, ) @@ -777,12 +813,14 @@ def test_bal_call_7702_delegation_and_oog( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) if oog_boundary == OutOfGasBoundary.OOG_BEFORE_TARGET_ACCESS: @@ -877,7 +915,13 @@ def test_bal_call_7702_delegation_and_oog( "target_is_warm", [False, True], ids=["cold_target", "warm_target"] ) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_delegatecall_no_delegation_and_oog_before_target_access( pre: Alloc, @@ -885,28 +929,32 @@ def test_bal_delegatecall_no_delegation_and_oog_before_target_access( fork: Fork, oog_boundary: OutOfGasBoundary, target_is_warm: bool, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ DELEGATECALL without 7702 delegation - test SUCCESS and OOG boundaries. When target_is_warm=True, we use EIP-2930 tx access list to warm the target. Access list warming does NOT add to BAL - only EVM access does. + + Memory expansion is parametrized independently for args and ret per #1910. """ alice = pre.fund_eoa() target = pre.deploy_contract(code=Op.STOP) - ret_size = 32 if memory_expansion else 0 - ret_offset = 0 + new_memory_size = max(args_size, ret_size) delegatecall_code = Op.DELEGATECALL( address=target, gas=0, + args_size=args_size, + args_offset=0, ret_size=ret_size, - ret_offset=ret_offset, + ret_offset=0, address_warm=target_is_warm, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) caller = pre.deploy_contract(code=delegatecall_code) @@ -975,7 +1023,13 @@ def test_bal_delegatecall_no_delegation_and_oog_before_target_access( ids=["cold_delegation", "warm_delegation"], ) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_delegatecall_7702_delegation_and_oog( pre: Alloc, @@ -984,7 +1038,8 @@ def test_bal_delegatecall_7702_delegation_and_oog( oog_boundary: OutOfGasBoundary, target_is_warm: bool, delegation_is_warm: bool, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ DELEGATECALL with 7702 delegation - test all OOG boundaries. @@ -995,24 +1050,26 @@ def test_bal_delegatecall_7702_delegation_and_oog( For 7702 delegation, there's ALWAYS a gap between static gas and second check (delegation_cost) - all 3 scenarios produce distinct behaviors. + + Memory expansion is parametrized independently for args and ret per #1910. """ alice = pre.fund_eoa() delegation_target = pre.deploy_contract(code=Op.STOP) target = pre.fund_eoa(amount=0, delegation=delegation_target) - # memory expansion / no expansion - ret_size = 32 if memory_expansion else 0 - ret_offset = 0 + new_memory_size = max(args_size, ret_size) # Full gas metadata: includes delegation cost delegatecall_code = Op.DELEGATECALL( gas=0, address=target, + args_size=args_size, + args_offset=0, ret_size=ret_size, - ret_offset=ret_offset, + ret_offset=0, address_warm=target_is_warm, - new_memory_size=ret_size, + new_memory_size=new_memory_size, delegated_address=True, delegated_address_warm=delegation_is_warm, ) @@ -1036,10 +1093,12 @@ def test_bal_delegatecall_7702_delegation_and_oog( delegatecall_static = Op.DELEGATECALL( gas=0, address=target, + args_size=args_size, + args_offset=0, ret_size=ret_size, - ret_offset=ret_offset, + ret_offset=0, address_warm=target_is_warm, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) if oog_boundary == OutOfGasBoundary.OOG_BEFORE_TARGET_ACCESS: @@ -1112,7 +1171,13 @@ def test_bal_delegatecall_7702_delegation_and_oog( ) @pytest.mark.parametrize("value", [0, 1], ids=["no_value", "with_value"]) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_callcode_no_delegation_and_oog_before_target_access( pre: Alloc, @@ -1121,7 +1186,8 @@ def test_bal_callcode_no_delegation_and_oog_before_target_access( oog_boundary: OutOfGasBoundary, target_is_warm: bool, value: int, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ CALLCODE without 7702 delegation - test SUCCESS and OOG boundaries. @@ -1129,23 +1195,27 @@ def test_bal_callcode_no_delegation_and_oog_before_target_access( When target_is_warm=True, we use EIP-2930 tx access list to warm the target. Access list warming does NOT add to BAL - only EVM access does. CALLCODE has no balance transfer to target (runs in caller's context). + + Memory expansion is parametrized independently for args and ret per #1910. """ alice = pre.fund_eoa() target = pre.deploy_contract(code=Op.STOP) - ret_size = 32 if memory_expansion else 0 + new_memory_size = max(args_size, ret_size) callcode_code = Op.CALLCODE( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) caller = pre.deploy_contract(code=callcode_code, balance=value) @@ -1221,7 +1291,13 @@ def test_bal_callcode_no_delegation_and_oog_before_target_access( ) @pytest.mark.parametrize("value", [0, 1], ids=["no_value", "with_value"]) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_callcode_7702_delegation_and_oog( pre: Alloc, @@ -1231,7 +1307,8 @@ def test_bal_callcode_7702_delegation_and_oog( target_is_warm: bool, delegation_is_warm: bool, value: int, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ CALLCODE with 7702 delegation - test all OOG boundaries. @@ -1242,26 +1319,29 @@ def test_bal_callcode_7702_delegation_and_oog( For 7702 delegation, there's ALWAYS a gap between static gas and second check (delegation_cost) - all 3 scenarios produce distinct behaviors. + + Memory expansion is parametrized independently for args and ret per #1910. """ alice = pre.fund_eoa() delegation_target = pre.deploy_contract(code=Op.STOP) target = pre.fund_eoa(amount=0, delegation=delegation_target) - # memory expansion / no expansion - ret_size = 32 if memory_expansion else 0 + new_memory_size = max(args_size, ret_size) # Full gas metadata: includes delegation cost callcode_code = Op.CALLCODE( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, delegated_address=True, delegated_address_warm=delegation_is_warm, ) @@ -1285,12 +1365,14 @@ def test_bal_callcode_7702_delegation_and_oog( gas=0, address=target, value=value, + args_size=args_size, + args_offset=0, ret_size=ret_size, ret_offset=0, address_warm=target_is_warm, value_transfer=value > 0, account_new=False, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) if oog_boundary == OutOfGasBoundary.OOG_BEFORE_TARGET_ACCESS: @@ -1362,7 +1444,13 @@ def test_bal_callcode_7702_delegation_and_oog( "target_is_warm", [False, True], ids=["cold_target", "warm_target"] ) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_staticcall_no_delegation_and_oog_before_target_access( pre: Alloc, @@ -1370,7 +1458,8 @@ def test_bal_staticcall_no_delegation_and_oog_before_target_access( fork: Fork, oog_boundary: OutOfGasBoundary, target_is_warm: bool, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ STATICCALL without 7702 delegation - test SUCCESS and OOG boundaries. @@ -1382,16 +1471,17 @@ def test_bal_staticcall_no_delegation_and_oog_before_target_access( target = pre.deploy_contract(code=Op.STOP) - ret_size = 32 if memory_expansion else 0 - ret_offset = 0 + new_memory_size = max(args_size, ret_size) staticcall_code = Op.STATICCALL( address=target, gas=0, + args_size=args_size, + args_offset=0, ret_size=ret_size, - ret_offset=ret_offset, + ret_offset=0, address_warm=target_is_warm, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) caller = pre.deploy_contract(code=staticcall_code) @@ -1460,7 +1550,13 @@ def test_bal_staticcall_no_delegation_and_oog_before_target_access( ids=["cold_delegation", "warm_delegation"], ) @pytest.mark.parametrize( - "memory_expansion", [False, True], ids=["no_memory", "with_memory"] + "args_size,ret_size", + [ + pytest.param(0, 0, id="no_memory"), + pytest.param(4096, 0, id="args_large"), + pytest.param(0, 4096, id="ret_large"), + pytest.param(32, 32, id="both_small"), + ], ) def test_bal_staticcall_7702_delegation_and_oog( pre: Alloc, @@ -1469,7 +1565,8 @@ def test_bal_staticcall_7702_delegation_and_oog( oog_boundary: OutOfGasBoundary, target_is_warm: bool, delegation_is_warm: bool, - memory_expansion: bool, + args_size: int, + ret_size: int, ) -> None: """ STATICCALL with 7702 delegation - test all OOG boundaries. @@ -1486,25 +1583,23 @@ def test_bal_staticcall_7702_delegation_and_oog( delegation_target = pre.deploy_contract(code=Op.STOP) target = pre.fund_eoa(amount=0, delegation=delegation_target) - # memory expansion / no expansion - ret_size = 32 if memory_expansion else 0 - ret_offset = 0 + new_memory_size = max(args_size, ret_size) - # Full gas metadata: includes delegation cost staticcall_code = Op.STATICCALL( gas=0, address=target, + args_size=args_size, + args_offset=0, ret_size=ret_size, - ret_offset=ret_offset, + ret_offset=0, address_warm=target_is_warm, - new_memory_size=ret_size, + new_memory_size=new_memory_size, delegated_address=True, delegated_address_warm=delegation_is_warm, ) caller = pre.deploy_contract(code=staticcall_code) - # Build access list for warming access_list: list[AccessList] = [] if target_is_warm: access_list.append(AccessList(address=target, storage_keys=[])) @@ -1517,14 +1612,15 @@ def test_bal_staticcall_7702_delegation_and_oog( access_list=access_list ) - # Static gas (before state access): no delegation staticcall_static = Op.STATICCALL( gas=0, address=target, + args_size=args_size, + args_offset=0, ret_size=ret_size, - ret_offset=ret_offset, + ret_offset=0, address_warm=target_is_warm, - new_memory_size=ret_size, + new_memory_size=new_memory_size, ) if oog_boundary == OutOfGasBoundary.OOG_BEFORE_TARGET_ACCESS: @@ -3268,25 +3364,30 @@ def test_bal_create2_selfdestruct_then_recreate_same_block( pre_balance: int, ) -> None: """ - Tx1 CREATE2+SELFDESTRUCT, Tx2 CREATE2 resurrection at same address. + Tx1 CREATE2+SSTORE+SELFDESTRUCT, Tx2 CREATE2 resurrection at same + address. Two identical txs invoke the same factory with the same initcode (same hash => same CREATE2 address A). The factory branches on its own storage slot 1: on the first tx, the slot is 0 so the factory - CREATE2's then CALLs A (runtime SELFDESTRUCTs) and records the - CALL's return code in slot 1; on the second tx, slot 1 is non-zero - so only CREATE2 runs and A persists with the runtime code. + CREATE2's then CALLs A (runtime SSTOREs to a target slot then + SELFDESTRUCTs) and records the CALL's return code in slot 1; on the + second tx, slot 1 is non-zero so only CREATE2 runs and A persists + with the runtime code (its runtime is never executed). Per EIP-7928 SELFDESTRUCT-in-tx semantics, Tx1's destructed A has no `nonce_changes` or `code_changes`; only `balance_changes` if it was - pre-funded. Tx2's fresh A has `nonce_changes` (post=1) and - `code_changes` (post=runtime). + pre-funded. The SSTORE is demoted to `storage_reads` because the + contract is destroyed in the same tx. Tx2's fresh A has + `nonce_changes` (post=1), `code_changes` (post=runtime), and empty + storage. """ alice = pre.fund_eoa() beneficiary = pre.fund_eoa(amount=0) salt = 0 + target_slot = 0x07 - runtime = Op.SELFDESTRUCT(beneficiary) + runtime = Op.SSTORE(target_slot, 0xCAFE) + Op.SELFDESTRUCT(beneficiary) runtime_bytes = bytes(runtime) initcode_bytes = bytes(Initcode(deploy_code=runtime)) @@ -3298,7 +3399,7 @@ def test_bal_create2_selfdestruct_then_recreate_same_block( ) + Conditional( condition=Op.ISZERO(Op.SLOAD(1)), - if_true=Op.SSTORE(1, Op.CALL(50_000, Op.SLOAD(0), 0, 0, 0, 0, 0)), + if_true=Op.SSTORE(1, Op.CALL(Op.GAS, Op.SLOAD(0), 0, 0, 0, 0, 0)), if_false=Op.STOP, ) + Op.STOP @@ -3349,8 +3450,10 @@ def test_bal_create2_selfdestruct_then_recreate_same_block( expected_block_access_list=BlockAccessListExpectation( account_expectations={ target_a: BalAccountExpectation( - # Tx1 destruction (EIP-7928 #165): no nonce/code changes. - # Tx2 resurrection: fresh contract with nonce=1, runtime. + # Tx1 destruction (EIP-7928 #165): no nonce/code changes; + # the SSTORE is demoted to a storage_read because A is + # destroyed same-tx. Tx2 resurrection: fresh contract + # with nonce=1, runtime, and untouched storage. nonce_changes=[ BalNonceChange(block_access_index=2, post_nonce=1), ], @@ -3361,7 +3464,7 @@ def test_bal_create2_selfdestruct_then_recreate_same_block( ], balance_changes=target_a_balance_changes, storage_changes=[], - storage_reads=[], + storage_reads=[target_slot], ), beneficiary: beneficiary_expectation, } @@ -3372,7 +3475,9 @@ def test_bal_create2_selfdestruct_then_recreate_same_block( pre=pre, blocks=[block], post={ - target_a: Account(nonce=1, balance=0, code=runtime_bytes), + target_a: Account( + nonce=1, balance=0, code=runtime_bytes, storage={} + ), beneficiary: Account(balance=pre_balance) if pre_balance > 0 else Account.NONEXISTENT, diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index c67ca1eaf3e..76f282706e6 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -13,13 +13,14 @@ | `test_selfdestruct_to_system_contract` (Cancun) | Ensure BAL captures SELFDESTRUCT success boundary for system contract beneficiaries | Victim executes `SELFDESTRUCT(system_contract)` at exact gas boundary. System contracts are always warm (no cold access charge) and always have code (no G_NEW_ACCOUNT charge). Gas = G_VERY_LOW + G_SELF_DESTRUCT. Parametrized: is_success (exact_gas/exact_gas_minus_1), all system contracts via `@pytest.mark.with_all_system_contracts`, same_tx (pre_deploy/same_tx), originator_balance (0/1). File: `tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py`. | exact_gas: System contract in BAL with `balance_changes` if originator had balance, victim destroyed (same_tx) or balance=0 (pre-existing). exact_gas_minus_1: OOG, system contract not in BAL (no state access). | ✅ Completed | | `test_initcode_selfdestruct_to_self` (TangerineWhistle) | Ensure BAL captures SELFDESTRUCT during initcode where beneficiary is self | Initcode executes `SELFDESTRUCT(ADDRESS)` during CREATE, before any code is deployed. Contract has nonce=1 (post-EIP-161), making it non-empty. Always warm (executing contract), no G_NEW_ACCOUNT (nonce > 0). Gas boundary testing not possible (CREATE uses all available gas). Parametrized: originator_balance (0/1). File: `tests/tangerine_whistle/eip150_operation_gas_costs/test_eip150_selfdestruct.py`. | Contract created and destroyed in same tx - victim has empty BAL changes. Caller has `nonce_changes` (incremented by CREATE) and `balance_changes` if originator had balance. Victim is NONEXISTENT in post state. | ✅ Completed | | `test_bal_account_access_target` | Ensure BAL captures target addresses of account access opcodes | Alice calls `Oracle` contract which uses account access opcodes (`BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) on `TargetContract`. | BAL MUST include Alice, `Oracle`, and `TargetContract` with empty changes for `TargetContract` and nonce changes for Alice. | ✅ Completed | -| `test_bal_call_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated CALL | Parametrized: target warm/cold, target empty/existing, value 0/1, memory expansion, OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL with balance changes when value > 0. | ✅ Completed | -| `test_bal_call_no_delegation_oog_after_target_access` | Ensure BAL includes target but excludes value transfer when OOG after target access | Hardcoded: empty target, value=1 (required for create_cost gap). Parametrized: warm/cold, memory expansion. | Target always in BAL. No balance changes (value transfer fails after G_NEW_ACCOUNT check). | ✅ Completed | -| `test_bal_call_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for CALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, value 0/1, memory expansion, OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | +| `test_bal_call_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated CALL | Parametrized: target warm/cold, target empty/existing, value 0/1, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL with balance changes when value > 0. | ✅ Completed | +| `test_bal_call_no_delegation_oog_after_target_access` | Ensure BAL includes target but excludes value transfer when OOG after target access | Hardcoded: empty target, value=1 (required for create_cost gap). Parametrized: warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)). | Target always in BAL. No balance changes (value transfer fails after G_NEW_ACCOUNT check). | ✅ Completed | +| `test_bal_call_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for CALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, value 0/1, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | | `test_bal_callcode_nested_value_transfer` | Ensure BAL captures balance changes from nested value transfers when CALLCODE executes target code that itself makes CALL with value | Alice calls `Oracle` contract (200 wei balance) which uses `CALLCODE` to execute `TargetContract`'s code; that code makes a nested CALL transferring 100 wei to Bob. | BAL MUST include Alice (nonce changes), `Oracle` (balance change to 100 wei), Bob (balance change to 100 wei), and `TargetContract` (empty changes). | ✅ Completed | | `test_bal_delegated_storage_writes` | Ensure BAL captures delegated storage writes via `DELEGATECALL` and `CALLCODE` | Alice calls `Oracle` contract which uses `DELEGATECALL`/`CALLCODE` to `TargetContract` that writes `0x42` to slot `0x01`. | BAL MUST include Alice (nonce changes), `Oracle` (storage changes for slot `0x01` = `0x42`), and `TargetContract` (empty changes). | ✅ Completed | | `test_bal_delegated_storage_reads` | Ensure BAL captures delegated storage reads via `DELEGATECALL` and `CALLCODE` | Alice calls `Oracle` contract (with slot `0x01` = `0x42`) which uses `DELEGATECALL`/`CALLCODE` to `TargetContract` that reads from slot `0x01`. | BAL MUST include Alice (nonce changes), `Oracle` (storage reads for slot `0x01`), and `TargetContract` (empty changes). | ✅ Completed | | `test_bal_block_rewards` | BAL tracks fee recipient balance changes from block rewards | Alice sends 100 wei to Bob with Charlie as fee recipient | BAL MUST include fee recipient Charlie with `balance_changes` reflecting transaction fees collected from the block. | ✅ Completed | +| `test_bal_selfdestruct_to_coinbase` | Ensure BAL records SELFDESTRUCT when the beneficiary is the coinbase address. Parametrized over `same_tx ∈ [False, True]`. Coinbase pre-funded with amount=0 (empty per EIP-161). `gas_price = base_fee_per_gas` so the priority-fee tip is zero and coinbase's entry carries only the SELFDESTRUCT transfer. | `pre_deploy`: pre-existing victim contract (balance 100) executes `SELFDESTRUCT(Op.COINBASE)`; post-Cancun (EIP-6780) the contract is preserved with balance 0. `same_tx`: factory creates victim with `CREATE(value=100, ...)` and CALLs it; victim's runtime SELFDESTRUCT runs in the same tx so the contract is actually destroyed. | `pre_deploy`: BAL MUST include victim with `balance_changes` 100→0 and coinbase with `balance_changes` 0→100. `same_tx`: BAL MUST include factory with `nonce_changes` (CREATE bumped nonce) + `balance_changes` 100→0, victim with empty changes (created+destroyed same-tx), and coinbase with `balance_changes` 0→100. | ✅ Completed | | `test_bal_2930_account_listed_but_untouched` | Ensure BAL excludes listed but untouched account | Alice sends a simple eth transfer tx to Bob with EIP-2930 access list including `Oracle` | BAL MUST NOT include any entry for `Oracle` because it wasn't accessed. | ✅ Completed | | `test_bal_2930_slot_listed_but_untouched` | Ensure BAL excludes listed but untouched storage slots | Alice sends tx with EIP-2930 access list including `(PureCalculator, slot=0x01)`; PureCalculator executes pure arithmetic (adding two numbers) without touching slot `0x01` | BAL MUST NOT include any entry for PureCalculator's slot `0x01` because it doesn't access state | ✅ Completed | | `test_bal_2930_slot_listed_and_unlisted_writes` | Ensure BAL includes storage writes regardless of access list presence | Alice sends tx with EIP-2930 access list including `(StorageWriter, slot=0x01)`; StorageWriter executes `SSTORE` to slots `0x01` and `0x02` | BAL MUST include `storage_changes` for StorageWriter's slots `0x01` and `0x02` | ✅ Completed | @@ -36,13 +37,17 @@ | `test_bal_system_contract_noop_filtering` | Ensure system contract post-execution calls filter net-zero storage writes | Simple transfer that doesn't interact with system contracts. Post-execution system calls read withdrawal/consolidation contract slots 0-3 but don't modify them. | Withdrawal and consolidation system contracts **MUST** have `storage_reads` for slots 0x00-0x03 but **MUST NOT** have `storage_changes` (no actual modifications occurred). | ✅ Completed | | `test_bal_aborted_storage_access` | Ensure BAL captures storage access in aborted transactions correctly | Alice calls contract that reads storage slot `0x01`, writes to slot `0x02`, then aborts with `REVERT`/`INVALID` | BAL MUST include storage_reads for slots `0x01` and `0x02` (aborted writes become reads), empty storage_changes. Only nonce changes for Alice. | ✅ Completed | | `test_bal_aborted_account_access` | Ensure BAL captures account access in aborted transactions for all account accessing opcodes | Alice calls `AbortContract` that performs account access operations (`BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) on `TargetContract` and aborts via `REVERT`/`INVALID` | BAL MUST include Alice, `TargetContract`, and `AbortContract` in account_changes and nonce changes for Alice. | ✅ Completed | +| `test_bal_parent_revert_state_access` | Ensure BAL captures child-frame state access when the parent frame reverts (write-demoted-to-read across frame boundary). Parametrized: `inner_action ∈ [sstore, sload, balance, extcodesize]`, `outer_abort ∈ [REVERT, INVALID]`. | Outer contract CALLs an inner contract that performs one state-access op (SSTORE/SLOAD against its own storage, or BALANCE/EXTCODESIZE against a separate target). Inner's slot 1 is pre-set to `0xDEAD` so the post-state confirms the demoted SSTORE didn't overwrite it. Inner returns successfully; outer then aborts. | BAL MUST include inner with `storage_reads=[1]` (SSTORE/SLOAD cases — write demoted to read), or empty changes plus the separate target in BAL with empty changes (BALANCE/EXTCODESIZE cases). Post-state: `inner.storage[1] == 0xDEAD` for SSTORE/SLOAD cases. | ✅ Completed | +| `test_selfdestruct_balance_transfer_reverted` (Cancun) | Ensure BAL records SELFDESTRUCT touches even when the containing sub-call reverts. Multi-fork via `state_test`; BAL expectations gated on `fork.is_eip_enabled(7928)`. File: `tests/cancun/eip6780_selfdestruct/test_journal_revert.py`. | Outer → controller (CALL) → victim (CALL); victim executes `SELFDESTRUCT(beneficiary)`, controller REVERTs (rolling back the balance transfer), outer continues and observes balances. | When EIP-7928 is enabled, BAL MUST include victim and beneficiary with empty changes (touched in the reverted sub-call's SELFDESTRUCT plus outer's BALANCE reads; net balances unchanged). | ✅ Completed | +| `test_bal_outer_revert_with_inner_insufficient_funds` | Combine outer-frame REVERT with inner-frame insufficient-funds CALL or CREATE. Parametrized `inner_op ∈ [call, create]`. | Outer → inner (CALL). Inner does `SSTORE(slot_a, 0x42)`, then attempts CALL/CREATE with `value > balance=0`. Inner returns successfully (insufficient-balance check happens after the opcode's state-touching costs are charged, not via a REVERT). Outer then REVERTs. | Inner's two SSTOREs demote to `storage_reads`. For `call`: the failed call's target appears in BAL with empty changes (cold access charged before balance check). For `create`: the would-be address is NOT in BAL (early failure precedes `track_address`). | ✅ Completed | +| `test_create_insufficient_balance` (Berlin) | Ensure BAL records that a failed CREATE does NOT itself add the would-be address; only a subsequent BALANCE call does. Multi-fork via `state_test`; BAL gated on `fork.is_eip_enabled(7928)`. File: `tests/berlin/eip2929_gas_cost_increases/test_create.py`. | Entry → creator (CREATE with `value=1`, creator balance 0 → fails) → checker (cold BALANCE on the would-be address, measures gas). | Creator has real `storage_changes` (slot 0 = `1 → 0`). Checker has `storage_changes` (slot 1 = cold BALANCE gas cost). Would-be address appears in BAL with empty changes — accessed only via the BALANCE in the checker contract, NOT via the failed CREATE. | ✅ Completed | | `test_bal_pure_contract_call` | Ensure BAL captures contract access for pure computation calls | Alice calls `PureContract` that performs pure arithmetic (ADD operation) without storage or balance changes | BAL MUST include Alice and `PureContract` in `account_changes`, and `nonce_changes` for Alice. | ✅ Completed | | `test_bal_create_storage_op_then_selfdestruct_same_tx` | BAL correctly demotes ephemeral storage operations to `storage_reads` when a contract is created and destroyed in the same tx (combined coverage for `read` and `write` storage_op cases — replaces `test_bal_create2_to_A_read_then_selfdestruct` and `test_bal_create2_to_A_write_then_selfdestruct`). Parametrized: `@pytest.mark.with_all_create_opcodes` + `storage_op ∈ ["read", "write"]`. | Address A is pre-funded via `pre.fund_address`. Alice sends a single tx calling a factory that deploys a contract at A via the parametrized create opcode; init code is either `SLOAD(B)+SELFDESTRUCT` or `SSTORE(B, v)+SELFDESTRUCT` (beneficiary = separate EOA). | BAL **MUST** include **A** with `balance_changes` `[(1, 0)]` (outflow to beneficiary on destruction). Slot **B** **MUST** appear under `storage_reads`, **NOT** `storage_changes` (write demoted to read because the contract is destroyed same-tx). A **MUST NOT** have `nonce_changes` or `code_changes`. Beneficiary has `balance_changes` reflecting receipt of `fund` at index 1. | ✅ Completed | | `test_bal_precompile_funded` | BAL records precompile value transfer with or without balance change | Alice sends value to precompile (all precompiles) via direct transaction. Parameterized: (1) with value (1 ETH), (2) without value (0 ETH). | For with_value: BAL **MUST** include precompile with `balance_changes`. For no_value: BAL **MUST** include precompile with empty `balance_changes`. No `storage_changes` or `code_changes` in either case. | ✅ Completed | | `test_bal_precompile_call_opcode` | BAL records the precompile address regardless of call opcode. | Parametrized: `@pytest.mark.with_all_precompiles × @pytest.mark.with_all_call_opcodes`. Alice calls Oracle which invokes the precompile via the parametrized call opcode. For DELEGATECALL/CALLCODE the precompile provides the code but is not the call target, so its access has to be recorded explicitly rather than incidentally. | BAL **MUST** include the precompile address with empty changes for all four call opcodes. Oracle has empty changes (called but no state mutation), Alice has `nonce_changes`. | ✅ Completed | | `test_bal_7702_delegated_create` | BAL tracks EIP-7702 delegation indicator write and contract creation | Alice sends a type-4 (7702) tx authorizing herself to delegate to `Deployer` code which executes `CREATE` | BAL MUST include for **Alice**: `code_changes` (delegation indicator), `nonce_changes` (increment from 7702 processing), and `balance_changes` (post-gas). For **Child**: `code_changes` (runtime bytecode) and `nonce_changes = 1`. | ✅ Completed | | `test_bal_7702_delegation_create` | Ensure BAL captures creation of EOA delegation | Alice authorizes delegation to contract `Oracle`. Transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends 7702 tx herself. (2) Sponsored: `Relayer` sends 7702 tx on Alice's behalf. | BAL **MUST** include Alice: `code_changes` (delegation designation `0xef0100\|\|address(Oracle)`),`nonce_changes` (increment). Bob: `balance_changes` (receives 10 wei). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes`.`Oracle` **MUST NOT** be present in BAL - the account is never accessed. | ✅ Completed | -| `test_bal_7702_delegation_update` | Ensure BAL captures update of existing EOA delegation | Alice first delegates to `Oracle1`, then in second tx updates delegation to `Oracle2`. Each transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends both 7702 txs herself. (2) Sponsored: `Relayer` sends both 7702 txs on Alice's behalf. | BAL **MUST** include Alice: first tx has `code_changes` (delegation designation `0xef0100\|\|address(Oracle1)`),`nonce_changes`. Second tx has`code_changes` (delegation designation `0xef0100\|\|address(Oracle2)`),`nonce_changes`. Bob:`balance_changes` (receives 10 wei on each tx). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes` for both transactions. `Oracle1` and `Oracle2` **MUST NOT** be present in BAL - accounts are never accessed. | ✅ Completed | +| `test_bal_7702_delegation_update` | Ensure BAL captures update of existing EOA delegation. Three variants: (1) Self-funded: Alice sends both 7702 txs herself. (2) Sponsored: a single `Relayer` sends both txs on Alice's behalf. (3) `sponsored_cross_sender`: a distinct relayer per tx — exercises the cross-tx auth-nonce-chain dependency since sender-nonce serialization no longer trivializes the test. A client that parallel-verifies auth signatures must consult Alice's BAL `nonce_changes` to validate the second auth against her post-tx-1 nonce. | Alice first delegates to `Oracle1`, then in second tx updates delegation to `Oracle2`. Each transaction sends 10 wei to Bob. | BAL **MUST** include Alice: first tx has `code_changes` (delegation designation `0xef0100\|\|address(Oracle1)`),`nonce_changes`. Second tx has`code_changes` (delegation designation `0xef0100\|\|address(Oracle2)`),`nonce_changes`. Bob:`balance_changes` (receives 10 wei on each tx). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes` for both transactions; for `sponsored_cross_sender`, each relayer has one `nonce_changes` at its tx index. `Oracle1` and `Oracle2` **MUST NOT** be present in BAL - accounts are never accessed. | ✅ Completed | | `test_bal_7702_delegation_clear` | Ensure BAL captures clearing of EOA delegation | Alice first delegates to `Oracle`, then in second tx clears delegation by authorizing to `0x0` address. Each transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends both 7702 txs herself. (2) Sponsored: `Relayer` sends both 7702 txs on Alice's behalf. | BAL **MUST** include Alice: first tx has `code_changes` (delegation designation `0xef0100\|\|address(Oracle)`), `nonce_changes`. Second tx has `code_changes` (empty code - delegation cleared), `nonce_changes`. Bob: `balance_changes` (receives 10 wei on each tx). For sponsored variant, BAL **MUST** also include `Relayer`: `nonce_changes` for both transactions. `Oracle` and `0x0` address **MUST NOT** be present in BAL - accounts are never accessed. | ✅ Completed | | `test_bal_7702_delegated_storage_access` | Ensure BAL captures storage operations when calling a delegated EIP-7702 account | Alice has delegated her account to `Oracle`. `Oracle` contract contains code that reads from storage slot `0x01` and writes to storage slot `0x02`. Bob sends 10 wei to Alice (the delegated account), which executes `Oracle`'s code. | BAL **MUST** include Alice: `balance_changes` (receives 10 wei), `storage_changes` for slot `0x02` (write operation performed in Alice's storage), `storage_reads` for slot `0x01` (read operation from Alice's storage). Bob: `nonce_changes` (sender), `balance_changes` (loses 10 wei plus gas costs). `Oracle` (account access). | ✅ Completed | | `test_bal_7702_invalid_nonce_authorization` | Ensure BAL handles failed authorization due to wrong nonce | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect nonce, causing silent authorization failure | BAL **MUST** include Alice with empty changes (account access), Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include `Oracle` (authorization failed, no delegation) | ✅ Completed | @@ -64,12 +69,12 @@ | `test_bal_balance_and_oog` | Ensure BAL handles OOG during BALANCE opcode execution correctly | Alice calls contract that attempts `BALANCE` opcode on cold target account. Parameterized: (1) OOG at BALANCE opcode (insufficient gas), (2) Successful BALANCE execution. | For OOG case: BAL **MUST NOT** include target account (wasn't accessed). For success case: BAL **MUST** include target account in `account_changes`. | ✅ Completed | | `test_bal_account_touch_system_address` | Ensure BAL includes `SYSTEM_ADDRESS` when a regular transaction touches it via any account-accessing opcode | Alice calls a contract that executes one of `BALANCE`, `EXTCODESIZE`, `EXTCODEHASH`, `EXTCODECOPY`, `CALL`, or `STATICCALL` against `SYSTEM_ADDRESS`. Parametrized over the six opcodes. | BAL **MUST** include `SYSTEM_ADDRESS` as an account-only entry for every opcode because the address experienced a real EVM state access. This is distinct from excluding the synthetic system-operation caller. | ✅ Completed | | `test_bal_extcodesize_and_oog` | Ensure BAL handles OOG during EXTCODESIZE opcode execution correctly | Alice calls contract that attempts `EXTCODESIZE` opcode on cold target contract. Parameterized: (1) OOG at EXTCODESIZE opcode (insufficient gas), (2) Successful EXTCODESIZE execution. | For OOG case: BAL **MUST NOT** include target contract (wasn't accessed). For success case: BAL **MUST** include target contract in `account_changes`. | ✅ Completed | -| `test_bal_delegatecall_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated DELEGATECALL | Parametrized: target warm/cold, memory expansion, OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | -| `test_bal_delegatecall_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for DELEGATECALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, memory expansion, OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | -| `test_bal_callcode_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated CALLCODE | Parametrized: target warm/cold, value 0/1, memory expansion, OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | -| `test_bal_callcode_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for CALLCODE to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, value 0/1, memory expansion, OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | -| `test_bal_staticcall_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated STATICCALL | Parametrized: target warm/cold, memory expansion, OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | -| `test_bal_staticcall_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for STATICCALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, memory expansion, OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | +| `test_bal_delegatecall_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated DELEGATECALL | Parametrized: target warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | +| `test_bal_delegatecall_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for DELEGATECALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | +| `test_bal_callcode_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated CALLCODE | Parametrized: target warm/cold, value 0/1, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | +| `test_bal_callcode_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for CALLCODE to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, value 0/1, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | +| `test_bal_staticcall_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated STATICCALL | Parametrized: target warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | +| `test_bal_staticcall_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for STATICCALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | | `test_bal_extcodecopy_and_oog` | Ensure BAL handles OOG during EXTCODECOPY at various failure points | Alice calls contract that attempts `EXTCODECOPY` from cold target contract. Parameterized: (1) Successful EXTCODECOPY, (2) OOG at cold access (insufficient gas for account access), (3) OOG at memory expansion with large offset (64KB offset, gas covers cold access + copy but NOT memory expansion), (4) OOG at memory expansion boundary (256 byte offset, gas is exactly 1 less than needed). | For success case: BAL **MUST** include target contract. For all OOG cases: BAL **MUST NOT** include target contract. Gas for ALL components (cold access + copy + memory expansion) must be checked BEFORE recording account access. | ✅ Completed | | `test_bal_multiple_balance_changes_same_account` | Ensure BAL tracks multiple balance changes to same account across transactions | Alice funds Bob (starts at 0) in tx0 with exact amount needed. Bob spends everything in tx1 to Charlie. Bob's balance: 0 → funding_amount → 0 | BAL **MUST** include Bob with two `balance_changes`: one at txIndex=1 (receives funds) and one at txIndex=2 (balance returns to 0). This tests balance tracking across two transactions. | ✅ Completed | | `test_bal_multiple_storage_writes_same_slot` | Ensure BAL tracks multiple writes to same storage slot across transactions | Alice calls contract 3 times in same block. Contract increments slot 1 on each call: 0 → 1 → 2 → 3 | BAL **MUST** include contract with slot 1 having three `slot_changes`: txIndex=1 (value 1), txIndex=2 (value 2), txIndex=3 (value 3). Each transaction's write must be recorded separately. | ✅ Completed | @@ -77,6 +82,7 @@ | `test_bal_cross_tx_storage_revert_to_zero` | Ensure BAL captures storage changes when tx2 reverts slot back to original value (blobhash regression test) | Alice sends tx1 writing slot 0=0xABCD (from 0x0), then tx2 writing slot 0=0x0 (back to original) | BAL **MUST** include contract with slot 0 having two `slot_changes`: txIndex=1 (0xABCD) and txIndex=2 (0x0). Cross-transaction net-zero **MUST NOT** be filtered. | ✅ Completed | | `test_bal_cross_tx_storage_chain` | Verify clients apply BAL state changes from prior transactions before executing later transactions in the same block. Each later Tx depends on the two preceding writes (Fibonacci-style), so any tx skipped or run against pre-block state cascades into a wrong slot value and a different state root. | Fixed `chain_length=8`. Single branching contract: Tx i with `i<2` seeds slot i with `1`; Tx i with `i>=2` writes `slot[i] = SLOAD(i-1) + SLOAD(i-2)`. | BAL **MUST** include the contract with `storage_changes` for each slot i (post=`fib(i)` at `block_access_index=i+1`). Post-state: slots 0-7 equal `[1, 1, 2, 3, 5, 8, 13, 21]`. | ✅ Completed | | `test_bal_cross_tx_deploy_then_call` | Verify clients apply Tx1's CREATE to their state view before executing Tx2's CALL in the same block. A client that parallelizes Tx2 without applying Tx1's `code_changes` would hit an empty account, the CALL would no-op, and slot 0 would remain 0. Parametrized over `@pytest.mark.with_all_create_opcodes` (CREATE and CREATE2). | Tx1 (Alice) calls a factory which CREATE/CREATE2s a contract whose runtime is `SSTORE(0, 0x42) + STOP` at a deterministic address. Tx2 (Bob) CALLs that address directly. | BAL **MUST** include the target contract with `nonce_changes` and `code_changes` at `block_access_index=1` (the deployment) and `storage_changes` for slot 0 (post=`0x42`) at `block_access_index=2` (Tx2's CALL through the deployed runtime). Post-state: target contract has runtime code and `slot[0] == 0x42`. | ✅ Completed | +| `test_bal_cross_tx_factory_nonce_create_chain` | Verify clients propagate `factory.nonce_changes` across txs when later CREATE addresses derive from the factory's current nonce. The cross-tx dependency signal is solely `nonce_changes` — no storage or balance mutations exist anywhere. A scheduler that deprioritizes nonce_changes (or schedules CREATE-family txs by their resulting distinct addresses) would speculatively derive `addr(factory, N+1)` for every tx and produce only one successful deployment. Parametrized: `failure_mode ∈ ["none", "collision", "oog"]` — `collision` pre-populates the mid-chain target (factory.nonce still bumps; chain slides forward); `oog` gives the mid-chain tx `intrinsic+1` gas so CREATE never fires (factory.nonce does not bump; chain slides backward, reusing the slot). | 8 txs from 8 distinct senders each call a shared factory that does CREATE with identical minimal initcode (deploys `Op.STOP` as runtime). | `none`: factory has 8 sequential `nonce_changes` (post=`N+1`..`N+8`); each address has `nonce_changes`/`code_changes` at its `block_access_index`. `collision`: factory still has 8 sequential `nonce_changes`; the colliding target appears with `BalAccountExpectation.empty()` (accessed under EIP-684, no state change) and its pre-state code is preserved. `oog`: factory has only 7 `nonce_changes` (the OOG tx contributes none); subsequent post_nonce values are shifted -1; the OOG'd tx's would-be address slot is filled by the next tx; the final chain address is never touched (`NONEXISTENT`). Post-state: senders all `nonce=1`; factory `nonce=N+(7 or 8)` depending on mode. | ✅ Completed | | `test_bal_cross_tx_balance_dependency` | Verify clients apply Tx1's balance change before executing Tx2 in the same block. A client that parallelizes Tx2 without applying Tx1's `balance_changes` would record the pre-block balance via `SELFBALANCE`, yielding a different state root. Parametrized over `direct_call` and `selfdestruct` funding paths so a client can't tie balance tracking to recipient-code execution. | Tx1 (Alice) routes `1` wei into a branching contract (empty calldata → STOP). In `direct_call`, alice sends value directly; in `selfdestruct`, alice calls a pre-funded killer contract that `SELFDESTRUCT`s to the recipient (recipient bytecode never runs in Tx1). Tx2 (Bob) calls the contract with non-empty calldata, taking the `SSTORE(0, SELFBALANCE)` path. | BAL **MUST** include the contract with `balance_changes` at `block_access_index=1` (post=`1`) and `storage_changes` for slot 0 (post=`1`) at `block_access_index=2`. In `selfdestruct`, BAL also includes the killer with `balance_changes` (post=`0`) at index 1. Post-state: `contract.balance == contract.storage[0] == 1` proves Tx2 observed Tx1's balance change. | ✅ Completed | | `test_bal_7702_cross_tx_delegation_then_call` | Verify clients apply Tx1's EIP-7702 delegation before later txs CALL the now-delegated EOA. Three-tx chain forces clients to apply both the code-install and each intermediate storage increment for the final value to be correct. | Tx1 (Relayer): sponsors an EIP-7702 auth that delegates Alice to a `SSTORE(0, SLOAD(0) + 1)` counter contract. Tx2 (Bob) and Tx3 (Charlie): both CALL Alice, which dispatches to the counter and increments her slot 0. | BAL **MUST** include Alice with `code_changes` at `block_access_index=1` (delegation designator), `nonce_changes` at index 1, and two `storage_changes` for slot 0 (post=1 at index 2, post=2 at index 3). Post-state: Alice has the delegation code and `slot[0] == 2`. | ✅ Completed | | `test_bal_cross_tx_funding_chain` | Verify clients apply each tx's BAL `balance_changes` to the next sender's funds check. Five-tx chain across distinct senders, each intermediate starts empty and depends on the prior tx to be solvent. A parallelizing client validating any later tx against pre-block state would see zero balance on its sender and wrongly reject the block. Parametrized over `success`, `oog_minus_1` (eunice's tx OOGs at exact gas minus one), and `insufficient_funds` (dan forwards one wei short so eunice's upfront balance check fails, block rejected with `INSUFFICIENT_ACCOUNT_FUNDS`). | Tx1 alice→bob, Tx2 bob→charlie, Tx3 charlie→dan, Tx4 dan→eunice. Each forwards exactly the next sender's upfront cost. Tx5 eunice→target with runtime `SSTORE(0, 0xC0FFEE)`. | For `success`/`oog_minus_1`: BAL **MUST** include nonce/balance changes for each EOA at its tx's `block_access_index`, plus target's `storage_changes` at index 5 (`success`) or `storage_reads=[0]` (`oog_minus_1`). Post-state: all five EOAs end with `balance=0`; target has `slot[0]==0xC0FFEE` in `success` and empty storage in `oog_minus_1`. For `insufficient_funds`: block **MUST** be rejected with `TransactionException.INSUFFICIENT_ACCOUNT_FUNDS`. | ✅ Completed | @@ -122,7 +128,7 @@ | `test_bal_create2_collision` | Ensure BAL handles CREATE2 address collision correctly | Factory contract (nonce=1, storage slot 0=0xDEAD) executes `CREATE2(salt=0, initcode)` targeting address that already has `code=STOP, nonce=1`. Pre-deploy contract at calculated CREATE2 target address before factory deployment. | BAL **MUST** include: (1) Factory with `nonce_changes` (1→2, incremented even on failed CREATE2), `storage_changes` for slot 0 (0xDEAD→0, stores failure). (2) Collision address with empty changes (accessed during collision check, no state changes). CREATE2 returns 0. Collision address **MUST NOT** have `nonce_changes` or `code_changes`. | ✅ Completed | | `test_bal_create_selfdestruct_to_self_with_call` | Ensure BAL handles init code that calls external contract then selfdestructs to itself | Factory executes `CREATE2` with endowment=100. Init code (embedded in factory via CODECOPY): (1) `CALL(Oracle, 0)` - Oracle writes to its storage slot 0x01. (2) `SSTORE(0x01, 0x42)` - write to own storage. (3) `SELFDESTRUCT(SELF)` - selfdestruct to own address. Contract created and destroyed in same tx. | BAL **MUST** include: (1) Factory with `nonce_changes`, `balance_changes` (loses 100). (2) Oracle with `storage_changes` for slot 0x01 (external call succeeded). (3) Created address with `storage_reads` for slot 0x01 (aborted write becomes read) - **MUST NOT** have `nonce_changes`, `code_changes`, `storage_changes`, or `balance_changes` (ephemeral contract, balance burned via SELFDESTRUCT to self). | ✅ Completed | | `test_bal_selfdestruct_to_7702_delegation` | Ensure BAL correctly handles SELFDESTRUCT to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Tx2: Victim contract (balance=100) executes `SELFDESTRUCT(Alice)`. Two separate transactions in same block. Note: Alice starts with initial balance which accumulates with selfdestruct. | BAL **MUST** include: (1) Alice at block_access_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at block_access_index=2 with `balance_changes` (receives selfdestruct). (3) Victim at block_access_index=2 with `balance_changes` (100→0). **Oracle MUST NOT appear in tx2** - per EVM spec, SELFDESTRUCT transfers balance without executing recipient code, so delegation target is never accessed. | ✅ Completed | -| `test_bal_call_revert_insufficient_funds` | Ensure BAL handles value-transferring call failure due to insufficient balance (not OOG), with and without 7702 delegation | Caller contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), call_opcode(target, value=1000), SSTORE(0x02, result)`. The call fails because 1000 > 100. Parametrized: (1) `call_opcode` over CALL and CALLCODE via `with_all_call_opcodes(selector=...)`, (2) `delegated` (target is plain EOA vs. 7702-delegated EOA pointing to `delegation_target`=STOP), (3) `target_is_warm` (cold/warm via EIP-2930 access list), (4) `delegation_is_warm` (only when delegated). | BAL **MUST** include: (1) Caller with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, call returned failure). (2) Target with empty changes - accessed before balance check fails. (3) When delegated: `delegation_target` with empty changes - delegation is loaded before balance check fails (unlike the OOG cases in `test_bal_call_7702_delegation_and_oog` where the static-check optimization avoids the delegation load). Access-list warming does NOT add to BAL on its own, so the BAL is identical across warm/cold variants. | ✅ Completed | +| `test_bal_call_revert_insufficient_funds` | Ensure BAL handles value-transferring call failure due to insufficient balance (not OOG), with and without 7702 delegation | Caller contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), call_opcode(target, value=1000), SSTORE(0x02, result)`. The call fails because 1000 > 100. Parametrized: (1) `call_opcode` over CALL and CALLCODE via `with_all_call_opcodes(selector=...)`, (2) `delegated` (target is plain EOA vs. 7702-delegated EOA pointing to `delegation_target`=STOP), (3) `target_is_warm` (cold/warm via EIP-2930 access list), (4) `delegation_is_warm` (only when delegated). | BAL **MUST** include: (1) Caller with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, call returned failure). (2) Target with empty changes — accessed before the balance check fails. (3) When delegated: `delegation_target` **MUST NOT** appear in the BAL — the balance check fails before `generic_call` runs, so the delegation target's account is never read. Access-list warming does NOT add to BAL on its own, so the BAL is identical across warm/cold variants. | ✅ Completed | | `test_bal_lexicographic_address_ordering` | Ensure BAL enforces strict lexicographic byte-wise ordering | Pre-fund three addresses with specific byte patterns: `addr_low = 0x0000...0001`, `addr_mid = 0x0000...0100`, `addr_high = 0x0100...0000`. Contract touches them in reverse order: `BALANCE(addr_high), BALANCE(addr_low), BALANCE(addr_mid)`. Additionally, include two endian-trap addresses that are byte-reversals of each other: `addr_endian_low = 0x0100000000000000000000000000000000000002`, `addr_endian_high = 0x0200000000000000000000000000000000000001`. Note: `reverse(addr_endian_low) = addr_endian_high`. Correct lexicographic order: `addr_endian_low < addr_endian_high` (0x01 < 0x02 at byte 0). If implementation incorrectly reverses bytes before comparing, it would get `addr_endian_low > addr_endian_high` (wrong). | BAL account list **MUST** be sorted lexicographically by address bytes: `addr_low` < `addr_mid` < `addr_high` < `addr_endian_low` < `addr_endian_high`, regardless of access order. The endian-trap addresses specifically catch byte-reversal bugs where addresses are compared with wrong byte order. Complements `test_bal_invalid_account_order` which tests rejection; this tests correct generation. | ✅ Completed | | `test_bal_gas_limit_boundary` | Ensure BAL max items gas limit boundary is enforced for empty blocks | Empty block with gas limit set to the exact boundary where `bal_items <= block_gas_limit // GAS_BLOCK_ACCESS_LIST_ITEM`. Parameterized: (1) at_boundary (gas limit = exact minimum, passes), (2) below_boundary (gas limit = exact minimum - 1, fails). | At boundary: block **MUST** be accepted. Below boundary: block **MUST** be rejected with `BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED` exception. | ✅ Completed | | `test_bal_transient_storage_not_tracked` | Ensure BAL excludes EIP-1153 transient storage operations | Contract executes: `TSTORE(0x01, 0x42)` (transient write), `TLOAD(0x01)` (transient read), `SSTORE(0x02, result)` (persistent write using transient value). | BAL **MUST** include slot 0x02 in `storage_changes` (persistent storage was modified). BAL **MUST NOT** include slot 0x01 in `storage_reads` or `storage_changes` (transient storage is not persisted, not needed for stateless execution). This verifies TSTORE/TLOAD don't pollute BAL. | ✅ Completed | @@ -163,7 +169,7 @@ | `test_bal_2935_query` | Ensure BAL captures storage reads when querying EIP-2935 historical block hashes (valid and invalid queries) with optional value transfer | Parameterized test: Block 1 (empty, stores genesis hash via system call). Block 2: Oracle contract queries `HISTORY_STORAGE_ADDRESS` with block number. Two block number scenarios (valid=0 genesis hash, invalid=1042 out of range) and value (0 or 100 wei). Valid query (block_number=0): reads genesis hash slot, oracle writes returned value. If value > 0, history storage contract receives balance. Invalid query (block_number=1042, out of range): reverts before storage access, oracle has implicit SLOAD recorded, value stays in oracle (not transferred to history storage). | Block 2 BAL **MUST** include: Valid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with `storage_reads` [slot 0] and `balance_changes` if value > 0, oracle with `storage_changes` (empty `slot_changes`). Invalid case at `block_access_index=1`: `HISTORY_STORAGE_ADDRESS` with NO `storage_reads` (reverts before access) and NO `balance_changes`, oracle with `storage_reads` [0], NO `storage_changes`, and `balance_changes` if value > 0 (value stays in oracle). Alice with `nonce_changes` at `block_access_index=1`. | ✅ Completed | | `test_bal_2935_selfdestruct_to_history_storage` | Ensure BAL captures `SELFDESTRUCT` to EIP-2935 history storage address | Single block: Transaction where Alice calls contract (pre-funded with 100 wei) that selfdestructs with `HISTORY_STORAGE_ADDRESS` as beneficiary. | BAL **MUST** include at `block_access_index=1`: Alice with `nonce_changes`, contract with `balance_changes` (100→0), `HISTORY_STORAGE_ADDRESS` with `balance_changes` (receives 100 wei). | ✅ Completed | | `test_bal_2935_invalid_calldata_size` | Ensure BAL correctly handles EIP-2935 queries with invalid calldata size (reverts before any storage access) | Parameterized test: Block 1 stores genesis hash via system call. Block 2: Oracle contract calls `HISTORY_STORAGE_ADDRESS` with invalid calldata sizes (0, 31, 33 bytes). EIP-2935 requires exactly 32 bytes calldata; any other size causes immediate revert before storage access. Optional value transfer (0 or 100 wei). | Block 2 BAL **MUST** include: `HISTORY_STORAGE_ADDRESS` with NO `storage_reads` (calldata size check fails before any SLOAD) and NO `balance_changes` (call reverts). Oracle with `storage_reads` [0] (implicit SLOAD from no-op SSTORE), NO `storage_changes`, and `balance_changes` if value > 0 (value stays in oracle on revert). Alice with `nonce_changes`. | ✅ Completed | -| `test_bal_create2_selfdestruct_then_recreate_same_block` | Ensure BAL handles **(tx1) CREATE2+SELFDESTRUCT** then **(tx2) CREATE2 "resurrection"** of the *same address* in the same block. Parametrized over `pre_balance: [0, 100]`. | Two identical txs invoke the same factory with the same initcode (same hash → same CREATE2 address A). The factory branches on its own `storage[1]`: on the first tx, slot 1 is 0 so the factory CREATE2's then CALLs A (runtime SELFDESTRUCTs to beneficiary) and records the CALL's return code in slot 1; on the second tx, slot 1 is non-zero so only CREATE2 runs and A persists. When `pre_balance > 0`, A is pre-funded so Tx1's SELFDESTRUCT transfers a real balance. | At `block_access_index=1` (destructed A): **MUST NOT** include `nonce_changes` or `code_changes` for A (EIP-7928 SELFDESTRUCT-in-tx semantics). `balance_changes` for A appears only when pre-funded. Beneficiary appears with `balance_changes` if pre-funded, otherwise `empty()` (SELFDESTRUCT touches the beneficiary even with 0 value). At `block_access_index=2` (resurrection): A has `nonce_changes` (post=1) and `code_changes` (post=runtime). Factory's `storage[1] = 1` confirms the Tx1 CALL went through. | ✅ Completed | +| `test_bal_create2_selfdestruct_then_recreate_same_block` | Ensure BAL handles **(tx1) CREATE2+SSTORE+SELFDESTRUCT** then **(tx2) CREATE2 "resurrection"** of the *same address* in the same block. Parametrized over `pre_balance: [0, 100]`. | Two identical txs invoke the same factory with the same initcode (same hash → same CREATE2 address A). The factory branches on its own `storage[1]`: on the first tx, slot 1 is 0 so the factory CREATE2's then CALLs A (runtime SSTOREs to a target slot then SELFDESTRUCTs to beneficiary) and records the CALL's return code in slot 1; on the second tx, slot 1 is non-zero so only CREATE2 runs and A persists with the runtime code (its runtime is never executed). When `pre_balance > 0`, A is pre-funded so Tx1's SELFDESTRUCT transfers a real balance. | At `block_access_index=1` (destructed A): **MUST NOT** include `nonce_changes` or `code_changes` for A (EIP-7928 SELFDESTRUCT-in-tx semantics); the SSTORE is demoted to `storage_reads` for the target slot (write demoted because A is destroyed same-tx). `balance_changes` for A appears only when pre-funded. Beneficiary appears with `balance_changes` if pre-funded, otherwise `empty()` (SELFDESTRUCT touches the beneficiary even with 0 value). At `block_access_index=2` (resurrection): A has `nonce_changes` (post=1) and `code_changes` (post=runtime). Post-state: A has empty `storage={}` (the tx1 SSTORE was wiped; tx2 never executed the runtime). Factory's `storage[1] = 1` confirms the Tx1 CALL went through. | ✅ Completed | | `test_bal_call_with_value_in_static_context` | CALL with nonzero value in static context: target NOT in BAL | Parametrized: `target_is_warm` (cold/warm via access list), `target_has_code` (EOA/contract). Static check must fire before account access. | `target` **MUST NOT** appear in BAL. Balances unchanged. | ✅ Completed | | `test_bal_create_in_static_context` | CREATE/CREATE2 in static context: created address NOT in BAL | Parametrized: `@pytest.mark.with_all_create_opcodes`, `value` (0/1). Static check must fire before balance check, address computation, or nonce increment. | Created address **MUST NOT** appear in BAL. Factory nonce unchanged. | ✅ Completed | | `test_bal_selfdestruct_in_static_context` | SELFDESTRUCT in static context: beneficiary NOT in BAL | Parametrized: `beneficiary_is_warm` (cold/warm via access list), `caller_balance` (0/100). Static check must fire before beneficiary access or balance transfer. | `beneficiary` **MUST NOT** appear in BAL. Balances unchanged. | ✅ Completed | @@ -171,7 +177,7 @@ | `test_bal_callcode_with_value_in_static_context` | CALLCODE with nonzero value succeeds in static context | EIP-214 explicitly excludes CALLCODE from write-protection. Caller invokes `CALLCODE(value=1, target)` inside STATICCALL. | `target` **MUST** appear in BAL. Ensures clients don't apply CALL-with-value restriction to CALLCODE. | ✅ Completed | | `test_bal_create_and_oog` | CREATE/CREATE2 OOG boundary test at three gas levels | Parametrized: `@pytest.mark.with_all_create_opcodes`, `OutOfGasBoundary` (OOG_BEFORE_TARGET_ACCESS, OOG_AFTER_TARGET_ACCESS, SUCCESS). BEFORE and AFTER differ by 1 gas, proving the static cost boundary. | OOG_BEFORE: created address **MUST NOT** appear in BAL. OOG_AFTER: created address IS in BAL as `empty()` (accessed, state reverted). SUCCESS: created address in BAL with `nonce_changes`/`code_changes`. | ✅ Completed | | `test_bal_fork_transition_happy_path` | Verify a BAL is produced at the Amsterdam activation block and absent before it. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. Uses `@pytest.mark.valid_at_transition_to("Amsterdam")` to run across the `BPO2 -> Amsterdam` boundary. | Two blocks: pre-fork (`timestamp=14_999`) with a simple Alice→Bob transfer, then activation block (`timestamp=15_000`) with the same kind of transfer. | Pre-fork block header **MUST NOT** carry `block_access_list_hash`. Activation block **MUST** include `block_access_list_hash` correctly derived from the BAL body, and the BAL body **MUST** record Alice's `nonce_changes` and Bob's `balance_changes` at `block_access_index=1`. | ✅ Completed | -| `test_invalid_pre_fork_block_with_bal_hash_field` | Verify clients reject a pre-Amsterdam block whose header carries `block_access_list_hash`. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. | Single block at `timestamp=14_999` with a regular transfer, mutated via `rlp_modifier=Header(block_access_list_hash=Hash(0))` to inject the field into the pre-fork header schema. | Block **MUST** be rejected with `BlockException.INCORRECT_BLOCK_FORMAT` / `EngineAPIError.InvalidParams`. The new header / body field must not be accepted before activation. | ✅ Completed | -| `test_invalid_post_fork_block_without_bal_hash_field` | Verify clients reject an Amsterdam activation block whose header is missing `block_access_list_hash`. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. | Single block at `timestamp=15_000` with a regular transfer, mutated via `rlp_modifier=Header(block_access_list_hash=Header.REMOVE_FIELD)` so the field is dropped from the header. | Block **MUST** be rejected with `BlockException.INCORRECT_BLOCK_FORMAT` / `EngineAPIError.InvalidParams`. The new header field becomes mandatory from the activation block onward. | ✅ Completed | +| `test_invalid_pre_fork_block_with_bal_hash_field` | Verify clients reject a pre-Amsterdam block whose header carries `block_access_list_hash`. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. | Single block at `timestamp=14_999` with a regular transfer, mutated via `rlp_modifier=Header(block_access_list_hash=Hash(0))` to inject the field into the pre-fork header schema. | Block **MUST** be rejected with `BlockException.INVALID_BLOCK_HASH`: pre-fork clients compute the block hash without the injected field, mismatching the expected hash. | ✅ Completed | +| `test_invalid_post_fork_block_without_bal_hash_field` | Verify clients reject an Amsterdam activation block whose header is missing `block_access_list_hash`. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. | Single block at `timestamp=15_000` with a regular transfer, mutated via `rlp_modifier=Header(block_access_list_hash=Header.REMOVE_FIELD)` so the field is dropped from the header. | Block **MUST** be rejected with `BlockException.INVALID_BAL_HASH` or `BlockException.INVALID_BLOCK_HASH`: clients re-derive the BAL hash from execution and detect the mismatch either at the BAL hash check or the header hash check. | ✅ Completed | | `test_fork_transition_bal_size_constraint` | Verify the BAL size constraint (`bal_items <= gas_limit // BLOCK_ACCESS_LIST_ITEM`) applies only on/after Amsterdam. File: `tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py`. Parametrized over `exceeds_limit_at_fork`: `at_fork_within_budget` (`gas_limit == empty_block_bal_item_count() * BLOCK_ACCESS_LIST_ITEM`) and `at_fork_over_budget` (`gas_limit` one wei below that). | Two empty blocks: pre-fork (`timestamp=14_999`) and activation block (`timestamp=15_000`). The same low `gas_limit` is used for both via `genesis_environment=Environment(gas_limit=...)`. | Pre-fork block **MUST** be accepted under both budgets (constraint not yet enforced). Activation block **MUST** be accepted at the exact budget and **MUST** be rejected with `BlockException.BLOCK_ACCESS_LIST_GAS_LIMIT_EXCEEDED` one item over the budget. | ✅ Completed | diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py b/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py index 8e524c8e68e..6be8458434c 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_fork_transition.py @@ -12,7 +12,6 @@ BlockchainTestFiller, BlockException, EIPChecklist, - EngineAPIError, Environment, Hash, Header, @@ -94,9 +93,6 @@ def test_invalid_pre_fork_block_with_bal_hash_field( """ Reject a pre-Amsterdam block whose header carries `block_access_list_hash`. - - The field is not part of the pre-fork header schema; injecting it via the - Engine API must fail with `INCORRECT_BLOCK_FORMAT` / `InvalidParams`. """ sender = pre.fund_eoa() receiver = pre.fund_eoa(amount=0) @@ -111,8 +107,7 @@ def test_invalid_pre_fork_block_with_bal_hash_field( timestamp=FORK_TIMESTAMP - 1, txs=[tx], rlp_modifier=Header(block_access_list_hash=Hash(0)), - exception=BlockException.INCORRECT_BLOCK_FORMAT, - engine_api_error_code=EngineAPIError.InvalidParams, + exception=BlockException.INVALID_BLOCK_HASH, ), ], ) @@ -144,8 +139,10 @@ def test_invalid_post_fork_block_without_bal_hash_field( rlp_modifier=Header( block_access_list_hash=Header.REMOVE_FIELD, ), - exception=BlockException.INCORRECT_BLOCK_FORMAT, - engine_api_error_code=EngineAPIError.InvalidParams, + exception=[ + BlockException.INVALID_BAL_HASH, + BlockException.INVALID_BLOCK_HASH, + ], ), ], ) diff --git a/tests/berlin/eip2929_gas_cost_increases/test_create.py b/tests/berlin/eip2929_gas_cost_increases/test_create.py index 3e73407f5d9..f216a39242e 100644 --- a/tests/berlin/eip2929_gas_cost_increases/test_create.py +++ b/tests/berlin/eip2929_gas_cost_increases/test_create.py @@ -23,6 +23,11 @@ from execution_testing import ( Account, Alloc, + BalAccountExpectation, + BalNonceChange, + BalStorageChange, + BalStorageSlot, + BlockAccessListExpectation, CodeGasMeasure, Environment, Fork, @@ -100,10 +105,11 @@ def test_create_insufficient_balance( + Op.STOP ) + sender = pre.fund_eoa() tx = Transaction( to=entry_address, gas_limit=1_000_000, - sender=pre.fund_eoa(), + sender=sender, ) post = { @@ -111,8 +117,63 @@ def test_create_insufficient_balance( creator_address: Account(storage={0: 0}), # BALANCE gas cost matches cold access checker_address: Account(storage={1: cold_balance.gas_cost(fork)}), + # Fail-proofing: confirm CREATE never deposited a contract. + contract_address: Account.NONEXISTENT, } - state_test(env=env, pre=pre, post=post, tx=tx) + + # Under EIP-7928 (BAL): the failed CREATE itself does NOT add the + # would-be address to BAL (failure precedes `track_address`). The + # subsequent BALANCE call in `checker_address` is what brings it in, + # so it appears with empty changes. Creator/checker have real + # storage writes; entry is just a passthrough. + expected_bal = ( + BlockAccessListExpectation( + account_expectations={ + sender: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1) + ], + ), + entry_address: BalAccountExpectation.empty(), + creator_address: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange( + block_access_index=1, post_value=0 + ) + ], + ) + ], + ), + checker_address: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=1, + slot_changes=[ + BalStorageChange( + block_access_index=1, + post_value=cold_balance.gas_cost(fork), + ) + ], + ) + ], + ), + contract_address: BalAccountExpectation.empty(), + } + ) + if fork.is_eip_enabled(7928) + else None + ) + + state_test( + env=env, + pre=pre, + post=post, + tx=tx, + expected_block_access_list=expected_bal, + ) @pytest.mark.valid_from("Berlin") diff --git a/tests/cancun/eip6780_selfdestruct/test_journal_revert.py b/tests/cancun/eip6780_selfdestruct/test_journal_revert.py index 1ed5f267e5a..6dfe7fa5d57 100644 --- a/tests/cancun/eip6780_selfdestruct/test_journal_revert.py +++ b/tests/cancun/eip6780_selfdestruct/test_journal_revert.py @@ -6,6 +6,8 @@ from execution_testing import ( Account, Alloc, + BalAccountExpectation, + BlockAccessListExpectation, Environment, Fork, Op, @@ -74,6 +76,21 @@ def test_selfdestruct_balance_transfer_reverted( TransactionReceipt(logs=[]) if fork.is_eip_enabled(7708) else None ) + # Under EIP-7928 (BAL): victim and beneficiary are touched in the + # reverted sub-call's SELFDESTRUCT and again by outer's BALANCE reads. + # The balance transfer is undone, so they appear with empty changes + # (accessed but no net state change). + expected_bal = ( + BlockAccessListExpectation( + account_expectations={ + victim: BalAccountExpectation.empty(), + beneficiary: BalAccountExpectation.empty(), + } + ) + if fork.is_eip_enabled(7928) + else None + ) + state_test( env=env, pre=pre, @@ -90,4 +107,5 @@ def test_selfdestruct_balance_transfer_reverted( gas_limit=1_000_000, expected_receipt=expected_receipt, ), + expected_block_access_list=expected_bal, ) From 61d2edc92a1b256c29c46b4f480f993f8519c135 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 21 May 2026 17:10:23 +0530 Subject: [PATCH 110/186] chore: remove bpo lint --- src/ethereum/forks/london/fork.py | 2 +- .../lint/lints/glacier_forks_hygiene.py | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/ethereum/forks/london/fork.py b/src/ethereum/forks/london/fork.py index 6f831484532..2d889e47f46 100644 --- a/src/ethereum/forks/london/fork.py +++ b/src/ethereum/forks/london/fork.py @@ -80,8 +80,8 @@ BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8) ELASTICITY_MULTIPLIER = Uint(2) -MINIMUM_DIFFICULTY = Uint(131072) INITIAL_BASE_FEE = Uint(1000000000) +MINIMUM_DIFFICULTY = Uint(131072) MAX_OMMER_DEPTH = Uint(6) BOMB_DELAY_BLOCKS = 9700000 EMPTY_OMMER_HASH = keccak256(rlp.encode([])) diff --git a/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py b/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py index 55d58c6a264..7d2c34830af 100644 --- a/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py +++ b/src/ethereum_spec_tools/lint/lints/glacier_forks_hygiene.py @@ -57,11 +57,7 @@ def __init__(self) -> None: @staticmethod def _needs_lint(fork_name: str) -> bool: - return ( - fork_name == "dao_fork" - or fork_name.endswith("_glacier") - or fork_name.startswith("bpo") - ) + return fork_name == "dao_fork" or fork_name.endswith("_glacier") def lint( self, forks: List[Hardfork], position: int @@ -150,10 +146,6 @@ def compare( if fork_name.endswith("_glacier") and item == "BOMB_DELAY_BLOCKS": previous_item.value.value = self.delay_blocks[fork_name] - if fork_name.startswith("bpo"): - if item.startswith("GasCosts.BLOB_"): - continue - if not compare_ast(previous_item, current_item): add_diagnostic( diagnostics, From 55d774b5c5869d5f1ec6661b85b900aa1668a5e0 Mon Sep 17 00:00:00 2001 From: Ishika Choudhury <117741714+Rimeeeeee@users.noreply.github.com> Date: Thu, 21 May 2026 17:15:14 +0530 Subject: [PATCH 111/186] chore: updated error mapping for reth devnet 7 (#2890) --- .../src/execution_testing/client_clis/clis/reth.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/testing/src/execution_testing/client_clis/clis/reth.py b/packages/testing/src/execution_testing/client_clis/clis/reth.py index 454d5f9ffcb..c2193fcb996 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/reth.py +++ b/packages/testing/src/execution_testing/client_clis/clis/reth.py @@ -60,7 +60,8 @@ class RethExceptionMapper(ExceptionMapper): r"max fee per blob gas \(\d+\)" ), TransactionException.INTRINSIC_GAS_TOO_LOW: ( - r"call gas cost \(\d+\) exceeds the gas limit \(\d+\)" + r"call gas cost \(\d+\) exceeds the gas limit \(\d+\)|" + r"gas floor \(\d+\) exceeds the gas limit \(\d+\)" ), TransactionException.INTRINSIC_GAS_BELOW_FLOOR_GAS_COST: ( r"gas floor \(\d+\) exceeds the gas limit \(\d+\)" @@ -75,7 +76,8 @@ class RethExceptionMapper(ExceptionMapper): r"blob transactions present in pre-cancun payload|empty blobs" ), TransactionException.GAS_ALLOWANCE_EXCEEDED: ( - r"transaction gas limit \w+ is more than blocks available gas \w+" + r"transaction gas limit \w+ is more than blocks available gas \w+|" + r"caller gas limit exceeds the block gas limit" ), TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM: ( r"transaction gas limit.*is greater than the cap" @@ -112,10 +114,12 @@ class RethExceptionMapper(ExceptionMapper): # BAL Exceptions BlockException.INVALID_BAL_HASH: (r"block access list hash mismatch"), BlockException.INVALID_BLOCK_ACCESS_LIST: ( - r"block access list hash mismatch" + r"block access list hash mismatch|" + r"BAL rejection: FinalHashMismatch" ), BlockException.INCORRECT_BLOCK_FORMAT: ( - r"block access list hash mismatch" + r"block access list hash mismatch|" + r"BAL rejection: FinalHashMismatch" ), # Reth does not validate the sizes or offsets of the deposit # contract logs. As a workaround we have set From a20dd5dde119d26b9d00f895d526ce37817efcad Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 21 May 2026 17:28:39 +0530 Subject: [PATCH 112/186] chore: fix fixture url --- .github/workflows/hive-consume.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index f3eb93efad9..8d753f75197 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -64,7 +64,7 @@ concurrency: env: # Use direct URL instead of release spec (e.g., fusaka@v0.1.0) to avoid GitHub API rate limits - FIXTURES_URL: https://github.com/gnosischain/execution-spec-tests/releases/download/v0.1.0/fixtures_fusaka.tar.gz + FIXTURES_URL: https://github.com/gnosischain/execution-spec-tests/releases/download/fusaka@v0.1.0/fixtures_fusaka.tar.gz jobs: cache-docker-images: From c4f3294c1c9460bb7ae2bb7158e36354490ea94e Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 21 May 2026 17:52:09 +0530 Subject: [PATCH 113/186] chore: update default client --- .github/workflows/hive-consume.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 8d753f75197..5c55c4f0758 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -31,11 +31,11 @@ on: docker_images: description: "Space-separated list of Docker images to cache" required: false - default: "ghcr.io/gnosischain/reth_gnosis:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "docker.io/nethermind/nethermind:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., reth-gnosis, go-ethereum-gnosis)" + description: "Hive client to test (e.g., nethermind-gnosis, go-ethereum-gnosis)" required: false - default: "reth-gnosis" + default: "nethermind-gnosis" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -46,12 +46,12 @@ on: description: "Space-separated list of Docker images to cache" required: false type: string - default: "ghcr.io/gnosischain/reth_gnosis:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "docker.io/nethermind/nethermind:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., reth-gnosis, go-ethereum-gnosis)" + description: "Hive client to test (e.g., nethermind-gnosis, go-ethereum-gnosis)" required: false type: string - default: "reth-gnosis" + default: "nethermind-gnosis" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -77,14 +77,14 @@ jobs: - name: Cache Docker images uses: ./.github/actions/cache-docker-images with: - images: ${{ inputs.docker_images || 'ghcr.io/gnosischain/reth_gnosis:latest docker.io/alpine:latest docker.io/library/golang:1-alpine' }} + images: ${{ inputs.docker_images || 'docker.io/nethermind/nethermind:latest docker.io/alpine:latest docker.io/library/golang:1-alpine' }} test-hive: name: ${{ matrix.name }} needs: cache-docker-images runs-on: ubuntu-latest env: - CLIENT: ${{ inputs.client || 'reth-gnosis' }} + CLIENT: ${{ inputs.client || 'nethermind-gnosis' }} CLIENT_FILE: ${{ inputs.client_file || 'latest.yaml' }} strategy: fail-fast: true From fc41dc639e0f8a423b6c8f83afa63903d43afd2a Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 22 May 2026 02:21:25 +0530 Subject: [PATCH 114/186] chore: update workflows --- .github/configs/feature.yaml | 24 ++---------------------- .github/workflows/hive-consume.yaml | 16 ++++++++-------- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/.github/configs/feature.yaml b/.github/configs/feature.yaml index 2cb3430119d..42788e4e981 100644 --- a/.github/configs/feature.yaml +++ b/.github/configs/feature.yaml @@ -13,33 +13,13 @@ benchmark_fast: fill-params: --fork=Osaka --generate-all-formats --gas-benchmark-values 100 ./tests/benchmark/compute feature_only: true -merge: - evm-type: eels - fill-params: --fork=Paris tests/paris - feature_only: true - -shapella: - evm-type: eels - fill-params: --fork=Shanghai tests/shanghai - feature_only: true - -dencun: - evm-type: eels - fill-params: --fork=Cancun tests/cancun - feature_only: true - -pectra: - evm-type: eels - fill-params: --fork=Prague tests/prague - feature_only: true - fusaka: evm-type: eels - fill-params: --fork=Osaka tests/osaka + fill-params: --fork=Osaka feature_only: true bal: evm-type: eels - fill-params: --fork=Amsterdam tests/amsterdam + fill-params: --fork=Amsterdam feature_only: true diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 5c55c4f0758..377023bef33 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -31,11 +31,11 @@ on: docker_images: description: "Space-separated list of Docker images to cache" required: false - default: "docker.io/nethermind/nethermind:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., nethermind-gnosis, go-ethereum-gnosis)" + description: "Hive client to test (e.g., go-ethereum, reth)" required: false - default: "nethermind-gnosis" + default: "go-ethereum" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -46,12 +46,12 @@ on: description: "Space-separated list of Docker images to cache" required: false type: string - default: "docker.io/nethermind/nethermind:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., nethermind-gnosis, go-ethereum-gnosis)" + description: "Hive client to test (e.g., go-ethereum, reth)" required: false type: string - default: "nethermind-gnosis" + default: "go-ethereum" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -77,14 +77,14 @@ jobs: - name: Cache Docker images uses: ./.github/actions/cache-docker-images with: - images: ${{ inputs.docker_images || 'docker.io/nethermind/nethermind:latest docker.io/alpine:latest docker.io/library/golang:1-alpine' }} + images: ${{ inputs.docker_images || 'ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine' }} test-hive: name: ${{ matrix.name }} needs: cache-docker-images runs-on: ubuntu-latest env: - CLIENT: ${{ inputs.client || 'nethermind-gnosis' }} + CLIENT: ${{ inputs.client || 'go-ethereum' }} CLIENT_FILE: ${{ inputs.client_file || 'latest.yaml' }} strategy: fail-fast: true From 15b988ce332dff77d19f2ee12c9af93cf29ce5f4 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 22 May 2026 03:27:35 +0530 Subject: [PATCH 115/186] chore: update workflow --- .github/workflows/hive-consume.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 377023bef33..052a2924157 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -33,9 +33,9 @@ on: required: false default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., go-ethereum, reth)" + description: "Hive client to test (e.g., go-ethereum-gnosis, reth-gnosis)" required: false - default: "go-ethereum" + default: "go-ethereum-gnosis" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -48,10 +48,10 @@ on: type: string default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., go-ethereum, reth)" + description: "Hive client to test (e.g., go-ethereum-gnosis, reth-gnosis)" required: false type: string - default: "go-ethereum" + default: "go-ethereum-gnosis" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -84,7 +84,7 @@ jobs: needs: cache-docker-images runs-on: ubuntu-latest env: - CLIENT: ${{ inputs.client || 'go-ethereum' }} + CLIENT: ${{ inputs.client || 'go-ethereum-gnosis' }} CLIENT_FILE: ${{ inputs.client_file || 'latest.yaml' }} strategy: fail-fast: true From 876ff7a0ccfdf191591616679c956c2c7af3adc2 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 22 May 2026 16:43:15 +0530 Subject: [PATCH 116/186] chore: update workflow for testing --- .github/workflows/eest_hive_gnosis_multi_client.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index a20fa60c143..bbda1092293 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -68,7 +68,7 @@ jobs: path: fixtures/ - name: Clone Hive repository - run: git clone -b master https://github.com/gnosischain/hive.git + run: git clone -b fix/neth-client https://github.com/gnosischain/hive.git - name: Install Go (for Hive) uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 From 29473de937cf1071928a737110c06fbd4b13ce20 Mon Sep 17 00:00:00 2001 From: Edgar Date: Fri, 22 May 2026 19:17:14 +0200 Subject: [PATCH 117/186] feat(tests): EIP-7928 BAL withdrawal predeploy balance read across txs (#2883) * feat(tests): EIP-7928 BAL withdrawal predeploy balance read across txs Add a cross-tx test in eip7928_block_level_access_lists/test_block_access_lists_cross_index.py that verifies a transaction observing the BAL balance change of the WITHDRAWAL_REQUEST_PREDEPLOY recorded by a prior transaction within the same block. tx 0 pays the withdrawal fee (balance 0 -> fee, recorded as a BAL balance_change at index 1). tx 1 calls a contract that performs SSTORE(0, BALANCE(WITHDRAWAL_REQUEST_PREDEPLOY)); the assertion that slot 0 equals fee exercises that tx 1's pre-state for the predeploy includes tx 0's BAL prefix entry. * chore: add entry to ``test_cases.md`` * chore: unrelated cleanup to use Spec instead of hard-coding --------- Co-authored-by: fselmo --- .../test_block_access_lists_cross_index.py | 121 +++++++++++++++++- .../test_cases.md | 1 + 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py index 9d32fdf1231..86eadf5ec9d 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py @@ -15,6 +15,8 @@ Address, Alloc, BalAccountExpectation, + BalBalanceChange, + BalNonceChange, BalStorageChange, BalStorageSlot, Block, @@ -25,6 +27,8 @@ Transaction, ) +from ...prague.eip7002_el_triggerable_withdrawals.spec import Spec as Spec7002 +from ...prague.eip7251_consolidations.spec import Spec as Spec7251 from .spec import ref_spec_7928 REFERENCE_SPEC_GIT_PATH = ref_spec_7928.git_path @@ -33,10 +37,10 @@ pytestmark = pytest.mark.valid_from("Amsterdam") WITHDRAWAL_REQUEST_ADDRESS = Address( - 0x00000961EF480EB55E80D19AD83579A64C007002 + Spec7002.WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS ) CONSOLIDATION_REQUEST_ADDRESS = Address( - 0x0000BBDDC7CE488642FB579F8B00F3A590007251 + Spec7251.CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS ) @@ -316,3 +320,116 @@ def test_bal_system_contract_noop_filtering( receiver: Account(balance=100), }, ) + + +def test_bal_withdrawal_predeploy_balance_observed_cross_tx( + pre: Alloc, + blockchain_test: BlockchainTestFiller, +) -> None: + """ + Test that a subsequent transaction observes the post-state balance of the + withdrawal predeploy after a prior transaction in the same block paid the + withdrawal fee. + + Within one block: + - tx 0: EOA sends `fee` wei to WITHDRAWAL_REQUEST_PREDEPLOY with a valid + withdrawal-request calldata. The predeploy retains the fee, so its + balance transitions 0 -> fee (BAL balance_change at index 1). + - tx 1: calls a reader contract that performs + `SSTORE(0, BALANCE(WITHDRAWAL_REQUEST_PREDEPLOY))`. + + Per EIP-7928, the BAL prefix consumed by tx 1's execution must include + tx 0's balance change for the predeploy, so the BALANCE opcode returns + `fee` and slot 0 of the reader ends at `fee`. The predeploy is also + touched by the prepare-block system call (storage reads at slots 0-3), + making its address one whose pre-block snapshot would otherwise mask the + BAL overlay if consulted ahead of the BAL prefix. + """ + fee = 1 # Spec7002.get_fee(0) is 1 when excess == 0; one request fits. + withdrawal_calldata = ( + (b"\x01" + b"\x00" * 47) # 48-byte validator pubkey + + (b"\x00" * 8) # 8-byte amount + ) + + sender_0 = pre.fund_eoa() + sender_1 = pre.fund_eoa() + + reader = pre.deploy_contract( + code=Bytecode( + Op.SSTORE( + 0, + Op.BALANCE(WITHDRAWAL_REQUEST_ADDRESS), + ) + + Op.STOP + ), + ) + + tx_pay_fee = Transaction( + sender=sender_0, + to=WITHDRAWAL_REQUEST_ADDRESS, + value=fee, + data=withdrawal_calldata, + gas_limit=1_000_000, + ) + + tx_read_balance = Transaction( + sender=sender_1, + to=reader, + gas_limit=100_000, + ) + + expected_block_access_list = BlockAccessListExpectation( + account_expectations={ + # Predeploy: tx 0 records the fee as a BAL balance_change at + # index 1; the framework also verifies the system-call storage + # behaviour through its own post-execution invariants. + WITHDRAWAL_REQUEST_ADDRESS: BalAccountExpectation( + balance_changes=[ + BalBalanceChange( + block_access_index=1, + post_balance=fee, + ), + ], + ), + # Reader: tx 1 stores the predeploy balance at slot 0. + # If the consumed BAL prefix did not surface tx 0's balance + # change to BALANCE, post_value would be 0 and the assertion + # below would fail. + reader: BalAccountExpectation( + storage_changes=[ + BalStorageSlot( + slot=0, + slot_changes=[ + BalStorageChange( + block_access_index=2, + post_value=fee, + ), + ], + ), + ], + ), + sender_0: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1), + ], + ), + sender_1: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=2, post_nonce=1), + ], + ), + } + ) + + blockchain_test( + pre=pre, + blocks=[ + Block( + txs=[tx_pay_fee, tx_read_balance], + expected_block_access_list=expected_block_access_list, + ), + ], + post={ + reader: Account(storage={0: fee}), + }, + ) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index 76f282706e6..ea2b7ae8cd3 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -86,6 +86,7 @@ | `test_bal_cross_tx_balance_dependency` | Verify clients apply Tx1's balance change before executing Tx2 in the same block. A client that parallelizes Tx2 without applying Tx1's `balance_changes` would record the pre-block balance via `SELFBALANCE`, yielding a different state root. Parametrized over `direct_call` and `selfdestruct` funding paths so a client can't tie balance tracking to recipient-code execution. | Tx1 (Alice) routes `1` wei into a branching contract (empty calldata → STOP). In `direct_call`, alice sends value directly; in `selfdestruct`, alice calls a pre-funded killer contract that `SELFDESTRUCT`s to the recipient (recipient bytecode never runs in Tx1). Tx2 (Bob) calls the contract with non-empty calldata, taking the `SSTORE(0, SELFBALANCE)` path. | BAL **MUST** include the contract with `balance_changes` at `block_access_index=1` (post=`1`) and `storage_changes` for slot 0 (post=`1`) at `block_access_index=2`. In `selfdestruct`, BAL also includes the killer with `balance_changes` (post=`0`) at index 1. Post-state: `contract.balance == contract.storage[0] == 1` proves Tx2 observed Tx1's balance change. | ✅ Completed | | `test_bal_7702_cross_tx_delegation_then_call` | Verify clients apply Tx1's EIP-7702 delegation before later txs CALL the now-delegated EOA. Three-tx chain forces clients to apply both the code-install and each intermediate storage increment for the final value to be correct. | Tx1 (Relayer): sponsors an EIP-7702 auth that delegates Alice to a `SSTORE(0, SLOAD(0) + 1)` counter contract. Tx2 (Bob) and Tx3 (Charlie): both CALL Alice, which dispatches to the counter and increments her slot 0. | BAL **MUST** include Alice with `code_changes` at `block_access_index=1` (delegation designator), `nonce_changes` at index 1, and two `storage_changes` for slot 0 (post=1 at index 2, post=2 at index 3). Post-state: Alice has the delegation code and `slot[0] == 2`. | ✅ Completed | | `test_bal_cross_tx_funding_chain` | Verify clients apply each tx's BAL `balance_changes` to the next sender's funds check. Five-tx chain across distinct senders, each intermediate starts empty and depends on the prior tx to be solvent. A parallelizing client validating any later tx against pre-block state would see zero balance on its sender and wrongly reject the block. Parametrized over `success`, `oog_minus_1` (eunice's tx OOGs at exact gas minus one), and `insufficient_funds` (dan forwards one wei short so eunice's upfront balance check fails, block rejected with `INSUFFICIENT_ACCOUNT_FUNDS`). | Tx1 alice→bob, Tx2 bob→charlie, Tx3 charlie→dan, Tx4 dan→eunice. Each forwards exactly the next sender's upfront cost. Tx5 eunice→target with runtime `SSTORE(0, 0xC0FFEE)`. | For `success`/`oog_minus_1`: BAL **MUST** include nonce/balance changes for each EOA at its tx's `block_access_index`, plus target's `storage_changes` at index 5 (`success`) or `storage_reads=[0]` (`oog_minus_1`). Post-state: all five EOAs end with `balance=0`; target has `slot[0]==0xC0FFEE` in `success` and empty storage in `oog_minus_1`. For `insufficient_funds`: block **MUST** be rejected with `TransactionException.INSUFFICIENT_ACCOUNT_FUNDS`. | ✅ Completed | +| `test_bal_withdrawal_predeploy_balance_observed_cross_tx` | Verify Tx2 observes Tx1's balance change on the EIP-7002 withdrawal predeploy via the `BALANCE` opcode. Exercises cross-tx visibility through a system address that is also touched by the prepare-block system call, so a client snapshotting the predeploy ahead of the BAL prefix would mask the overlay. Companion to `test_bal_cross_tx_balance_dependency`, which uses `SELFBALANCE` on a regular contract. File: `tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_cross_index.py`. | Tx1 (`sender_0`) sends `1` wei (the fee at `excess=0`) to `WITHDRAWAL_REQUEST_PREDEPLOY` with a valid 56-byte withdrawal-request calldata; the predeploy retains the fee. Tx2 (`sender_1`) calls a reader contract whose runtime is `SSTORE(0, BALANCE(WITHDRAWAL_REQUEST_PREDEPLOY))`. | BAL **MUST** include `WITHDRAWAL_REQUEST_PREDEPLOY` with `balance_changes` at `block_access_index=1` (post=`1`) and the reader with `storage_changes` for slot 0 at `block_access_index=2` (post=`1`). Post-state: `reader.storage[0] == 1` proves Tx2's `BALANCE` opcode returned the post-Tx1 balance. | ✅ Completed | | `test_bal_intra_tx_multiple_sstores_same_slot` | Ensure BAL coalesces consecutive SSTOREs to the same slot within one tx into a single storage change with the final post-value | Contract executes `SSTORE(0x01, 0xAA) + SSTORE(0x01, 0xBB) + SSTORE(0x01, 0xCC)` in one tx. Parametrized by `pre_value`: `slot_starts_empty` (0x00), `slot_starts_nonzero` (0x11), `intermediate_equals_pre` (0xBB, where the second write transiently matches the pre-state). | BAL **MUST** include contract with slot `0x01` having exactly one `slot_changes` entry: `txIndex=1, post_value=0xCC`. Intermediate values `0xAA` and `0xBB` **MUST NOT** appear as separate entries (enforced via `absent_values`). | ✅ Completed | | `test_bal_intra_tx_sstores_same_slot_net_zero` | Ensure BAL filters net-zero result when multiple SSTOREs to the same slot occur within one tx | Parametrized: `nonzero_pre_returns_to_pre` (pre=0xCC, writes 0xAA→0xBB→0xCC) and `empty_pre_ephemeral_writes` (pre=0x00, writes 0xAA→0xBB→0x00). Final value equals pre-state in both cases. | BAL **MUST** include contract with slot `0x01` in `storage_reads` (slot was accessed) and **MUST NOT** include slot `0x01` in `storage_changes` (net-zero). | ✅ Completed | | `test_bal_create_contract_init_revert` | Ensure BAL correctly handles CREATE when parent call reverts | Caller calls factory, factory executes CREATE (succeeds), then factory REVERTs rolling back the CREATE | BAL **MUST** include Alice with `nonce_changes`. Caller and factory with no changes (reverted). Created contract address appears in BAL but **MUST NOT** have `nonce_changes` or `code_changes` (CREATE was rolled back). Contract address **MUST NOT** exist in post-state. | ✅ Completed | From 810c184219ebbde038c7c0144c13cae141701827 Mon Sep 17 00:00:00 2001 From: milen <94537774+taratorio@users.noreply.github.com> Date: Sat, 23 May 2026 03:19:12 +1000 Subject: [PATCH 118/186] feat(tests): EIP-7928 self destruct to system address with 0 value (#2893) * feat(tests): EIP-7928 self destruct to system address with 0 value * chore: some cleanup and add test case to ``tests_cases.md`` * chore: move test to more appropriate location --------- Co-authored-by: fselmo --- .../test_block_access_lists_opcodes.py | 49 +++++++++++++++++++ .../test_cases.md | 1 + 2 files changed, 50 insertions(+) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py index c7f0d49fcd4..5a8dd849139 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py @@ -386,6 +386,55 @@ def test_bal_account_touch_system_address( ) +def test_bal_selfdestruct_to_system_address_zero_balance( + pre: Alloc, + blockchain_test: BlockchainTestFiller, + fork: Fork, +) -> None: + """ + Ensure `SYSTEM_ADDRESS` is in BAL when accessed via `SELFDESTRUCT`, + even with zero balance transferred. Companion to + `test_bal_account_touch_system_address`, which covers the + `BALANCE`/`EXTCODE*`/`CALL`/`STATICCALL` opcodes. + """ + alice = pre.fund_eoa() + + init_code = Op.SELFDESTRUCT(SYSTEM_ADDRESS) + new_contract = compute_create_address(address=alice, nonce=0) + + tx = Transaction( + sender=alice, + to=None, # CREATE + value=0, # zero contract balance at SELFDESTRUCT time + data=init_code, + gas_limit=fork.transaction_gas_limit_cap(), + gas_price=10, + ) + + block = Block( + txs=[tx], + expected_block_access_list=BlockAccessListExpectation( + account_expectations={ + alice: BalAccountExpectation( + nonce_changes=[ + BalNonceChange(block_access_index=1, post_nonce=1), + ], + ), + SYSTEM_ADDRESS: BalAccountExpectation.empty(), + } + ), + ) + + blockchain_test( + pre=pre, + blocks=[block], + post={ + alice: Account(nonce=1), + new_contract: Account.NONEXISTENT, + }, + ) + + @pytest.mark.parametrize( "fails_at_extcodesize", [True, False], diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md index ea2b7ae8cd3..f814e9840ea 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_cases.md @@ -68,6 +68,7 @@ | `test_bal_sload_and_oog` | Ensure BAL handles OOG during SLOAD execution correctly | Alice calls contract that attempts `SLOAD` from cold slot `0x01`. Parameterized: (1) OOG at SLOAD opcode (insufficient gas), (2) Successful SLOAD execution. | For OOG case: BAL **MUST NOT** contain slot `0x01` in `storage_reads` since storage wasn't accessed. For success case: BAL **MUST** contain slot `0x01` in `storage_reads`. | ✅ Completed | | `test_bal_balance_and_oog` | Ensure BAL handles OOG during BALANCE opcode execution correctly | Alice calls contract that attempts `BALANCE` opcode on cold target account. Parameterized: (1) OOG at BALANCE opcode (insufficient gas), (2) Successful BALANCE execution. | For OOG case: BAL **MUST NOT** include target account (wasn't accessed). For success case: BAL **MUST** include target account in `account_changes`. | ✅ Completed | | `test_bal_account_touch_system_address` | Ensure BAL includes `SYSTEM_ADDRESS` when a regular transaction touches it via any account-accessing opcode | Alice calls a contract that executes one of `BALANCE`, `EXTCODESIZE`, `EXTCODEHASH`, `EXTCODECOPY`, `CALL`, or `STATICCALL` against `SYSTEM_ADDRESS`. Parametrized over the six opcodes. | BAL **MUST** include `SYSTEM_ADDRESS` as an account-only entry for every opcode because the address experienced a real EVM state access. This is distinct from excluding the synthetic system-operation caller. | ✅ Completed | +| `test_bal_selfdestruct_to_system_address_zero_balance` | Ensure BAL includes `SYSTEM_ADDRESS` as the SELFDESTRUCT beneficiary even when no value is transferred. Companion to `test_bal_account_touch_system_address` (which covers `BALANCE`/`EXTCODE*`/`CALL`/`STATICCALL`); SELFDESTRUCT is the missing opcode in that parametrize list. File: `tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py`. | CREATE transaction whose init code is `SELFDESTRUCT(SYSTEM_ADDRESS)`; the new contract carries no value, so the beneficiary receives 0 wei. Per EIP-6780 the contract is deleted (creation and destruction in the same tx). | BAL **MUST** include `SYSTEM_ADDRESS` with every change-set empty — the SELFDESTRUCT is the only access on `SYSTEM_ADDRESS` in this block. Post-state: created contract is `NONEXISTENT` (proves SELFDESTRUCT fired); Alice has `nonce=1`. | ✅ Completed | | `test_bal_extcodesize_and_oog` | Ensure BAL handles OOG during EXTCODESIZE opcode execution correctly | Alice calls contract that attempts `EXTCODESIZE` opcode on cold target contract. Parameterized: (1) OOG at EXTCODESIZE opcode (insufficient gas), (2) Successful EXTCODESIZE execution. | For OOG case: BAL **MUST NOT** include target contract (wasn't accessed). For success case: BAL **MUST** include target contract in `account_changes`. | ✅ Completed | | `test_bal_delegatecall_no_delegation_and_oog_before_target_access` | Ensure BAL handles OOG before target access and success for non-delegated DELEGATECALL | Parametrized: target warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/success). | OOG: target in BAL ONLY if pre-warmed. Success: target always in BAL. | ✅ Completed | | `test_bal_delegatecall_7702_delegation_and_oog` | Ensure BAL handles OOG at all 4 boundaries for DELEGATECALL to 7702 delegated accounts | Parametrized: target warm/cold, delegation warm/cold, `(args_size, ret_size)` pair (covers in-only and out-only expansion per [#1910](https://github.com/ethereum/execution-specs/issues/1910)), OOG boundary (before_target_access/after_target_access/success_minus_1/success). | OOG before: neither in BAL. OOG after & success_minus_1: target in BAL, delegation NOT in BAL (static check optimization). Success: all in BAL. | ✅ Completed | From d819b53cef82a437c7fe2ca13ff173076a139f0f Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 15:29:16 +0530 Subject: [PATCH 119/186] chore: update geth image --- .github/workflows/hive-consume.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 052a2924157..6e96f2ed890 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -31,7 +31,7 @@ on: docker_images: description: "Space-separated list of Docker images to cache" required: false - default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "ghcr.io/chetna-mittal/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: description: "Hive client to test (e.g., go-ethereum-gnosis, reth-gnosis)" required: false @@ -46,7 +46,7 @@ on: description: "Space-separated list of Docker images to cache" required: false type: string - default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "ghcr.io/chetna-mittal/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: description: "Hive client to test (e.g., go-ethereum-gnosis, reth-gnosis)" required: false @@ -77,7 +77,7 @@ jobs: - name: Cache Docker images uses: ./.github/actions/cache-docker-images with: - images: ${{ inputs.docker_images || 'ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine' }} + images: ${{ inputs.docker_images || 'ghcr.io/chetna-mittal/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine' }} test-hive: name: ${{ matrix.name }} From da47893c486dc5fc60a964aa18012d8894181bb3 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 15:32:06 +0530 Subject: [PATCH 120/186] chore: update geth image in workflow --- .github/actions/cache-docker-images/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cache-docker-images/action.yaml b/.github/actions/cache-docker-images/action.yaml index 493764a16c0..19cc98eb425 100644 --- a/.github/actions/cache-docker-images/action.yaml +++ b/.github/actions/cache-docker-images/action.yaml @@ -5,7 +5,7 @@ inputs: images: description: "Space-separated list of Docker images to cache" required: true - default: "ghcr.io/gnosischain/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + default: "ghcr.io/chetna-mittal/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" cache-key-prefix: description: "Prefix for the cache key" required: false From 704d3dc059b964f3f2ac9246e13293a03ed1ce8f Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 15:37:25 +0530 Subject: [PATCH 121/186] chore: update hive branch --- .github/workflows/hive-consume.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 6e96f2ed890..4f85eccdcc6 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -138,7 +138,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: gnosischain/hive - ref: master + ref: fix/neth-client path: hive # Redirect Go's caches to a per-job temp dir so the setup-go cache From 8d8d645889b7405c398068087470bfbabc2abd22 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 15:51:36 +0530 Subject: [PATCH 122/186] chore: update latest.yaml --- .github/configs/hive/latest.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/configs/hive/latest.yaml b/.github/configs/hive/latest.yaml index 6eb2d6b215f..0ad950ce6dd 100644 --- a/.github/configs/hive/latest.yaml +++ b/.github/configs/hive/latest.yaml @@ -1,11 +1,11 @@ # Hive client configuration file with latest release images # Geth (Go-Ethereum) -# GHCR: https://ghcr.io/gnosischain/geth +# GHCR: https://ghcr.io/chetna-mittal/geth - client: go-ethereum-gnosis nametag: "" build_args: - baseimage: ghcr.io/gnosischain/geth + baseimage: ghcr.io/chetna-mittal/geth tag: latest # Nethermind From 1d5fa6b3a9edd52a811eb73ca3eef1c008f33acd Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 18:47:08 +0530 Subject: [PATCH 123/186] chore: update binary --- .github/workflows/release_fixture_feature.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_fixture_feature.yaml b/.github/workflows/release_fixture_feature.yaml index b82f4de9844..bcb890685dc 100644 --- a/.github/workflows/release_fixture_feature.yaml +++ b/.github/workflows/release_fixture_feature.yaml @@ -59,7 +59,7 @@ jobs: repo_name: solidity remote_name: solc-static-linux binary_name: solc - expected_sha256: fb03a29a517452b9f12bcf459ef37d0a543765bb3bbc911e70a87d6a37c30d5f + expected_sha256: 5294614a0d3ccfae8e7d3236e7f4e7c2e5e4a5b6c7d8e9f0a1b2c3d4e5f6a7b - uses: ./.github/actions/build-fixtures with: From 88425cfd3ed0918a548f27f66ec2370e4d849f11 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 18:52:12 +0530 Subject: [PATCH 124/186] chore: update binary --- .github/workflows/release_fixture_feature.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release_fixture_feature.yaml b/.github/workflows/release_fixture_feature.yaml index bcb890685dc..b82f4de9844 100644 --- a/.github/workflows/release_fixture_feature.yaml +++ b/.github/workflows/release_fixture_feature.yaml @@ -59,7 +59,7 @@ jobs: repo_name: solidity remote_name: solc-static-linux binary_name: solc - expected_sha256: 5294614a0d3ccfae8e7d3236e7f4e7c2e5e4a5b6c7d8e9f0a1b2c3d4e5f6a7b + expected_sha256: fb03a29a517452b9f12bcf459ef37d0a543765bb3bbc911e70a87d6a37c30d5f - uses: ./.github/actions/build-fixtures with: From 8512b60cab8aebfbef3dd4c0c67895a4d05596a3 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 21:11:58 +0530 Subject: [PATCH 125/186] chore: add defensive check --- src/ethereum/forks/cancun/fork.py | 3 +++ src/ethereum/forks/osaka/fork.py | 3 +++ src/ethereum/forks/paris/fork.py | 3 +++ src/ethereum/forks/prague/fork.py | 3 +++ src/ethereum/forks/shanghai/fork.py | 3 +++ 5 files changed, 15 insertions(+) diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index 564bedd7054..2fe2a96fb77 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -925,6 +925,9 @@ def process_block_rewards( if len(out.return_data) == 0: return + if len(out.return_data) == 0: + return + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index df0e02bc19f..12066bf17c0 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -1124,6 +1124,9 @@ def process_block_rewards( if len(out.return_data) == 0: return + if len(out.return_data) == 0: + return + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 4800677666a..484dec3ab0d 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -777,6 +777,9 @@ def process_block_rewards( if len(out.return_data) == 0: return + if len(out.return_data) == 0: + return + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index 1638f030721..f30f3e8deb2 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -1107,6 +1107,9 @@ def process_block_rewards( if len(out.return_data) == 0: return + if len(out.return_data) == 0: + return + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 895f56cff02..88d1f5120cc 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -834,6 +834,9 @@ def process_block_rewards( if len(out.return_data) == 0: return + if len(out.return_data) == 0: + return + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) From 4daf6d74ee327e619e39e3836b84da127f7aea90 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 10 Apr 2026 15:30:07 +0530 Subject: [PATCH 126/186] chore: fix lint issue --- packages/testing/src/execution_testing/forks/forks/forks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 4e5a1f9622b..9064d989118 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -1475,6 +1475,7 @@ class Paris( pass + class Shanghai( eips.EIP3855, eips.EIP3860, From 565d942e90cf673a3c6c94289706450f5e1259c8 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 10 Apr 2026 16:51:45 +0530 Subject: [PATCH 127/186] chore: add gnosis specs --- .github/configs/fork-ranges.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/configs/fork-ranges.yaml b/.github/configs/fork-ranges.yaml index dcb4ea65ba1..4195d3b853d 100644 --- a/.github/configs/fork-ranges.yaml +++ b/.github/configs/fork-ranges.yaml @@ -13,9 +13,6 @@ - label: osaka from: Osaka until: Osaka -- label: bpo - from: BPO1 - until: BPO2 - label: amsterdam from: Amsterdam until: Amsterdam From ffb2e83b26d559f5b89158680c19f92a9f4af6e8 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 10 Apr 2026 18:44:15 +0530 Subject: [PATCH 128/186] chore: add fork range --- Justfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Justfile b/Justfile index 9136f6c9fa0..05fcf143442 100644 --- a/Justfile +++ b/Justfile @@ -180,6 +180,8 @@ json-loader *args: test-tests *args: @mkdir -p "{{ output_dir }}/test-tests/tmp" cd packages/testing && uv run pytest \ + --from Paris \ + --until "{{ latest_fork }}" \ -n {{ xdist_workers }} \ --basetemp="{{ output_dir }}/test-tests/tmp" \ --ignore=src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_benchmarking.py \ @@ -192,6 +194,8 @@ test-tests-pypy *args: @mkdir -p "{{ output_dir }}/test-tests-pypy/tmp" cd packages/testing && uv run --python pypy3.11 pytest \ -n auto --maxprocesses 6 \ + --from Paris \ + --until "{{ latest_fork }}" \ --basetemp="{{ output_dir }}/test-tests-pypy/tmp" \ --ignore=src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_benchmarking.py \ "$@" \ From f8d1fbacc71f3d23e0a8fad3679ac12b86ca61f8 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 10 Apr 2026 19:00:38 +0530 Subject: [PATCH 129/186] chore: fix failure --- Justfile | 4 ---- tests/cancun/eip4844_blobs/test_blobhash_opcode.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Justfile b/Justfile index 05fcf143442..9136f6c9fa0 100644 --- a/Justfile +++ b/Justfile @@ -180,8 +180,6 @@ json-loader *args: test-tests *args: @mkdir -p "{{ output_dir }}/test-tests/tmp" cd packages/testing && uv run pytest \ - --from Paris \ - --until "{{ latest_fork }}" \ -n {{ xdist_workers }} \ --basetemp="{{ output_dir }}/test-tests/tmp" \ --ignore=src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_benchmarking.py \ @@ -194,8 +192,6 @@ test-tests-pypy *args: @mkdir -p "{{ output_dir }}/test-tests-pypy/tmp" cd packages/testing && uv run --python pypy3.11 pytest \ -n auto --maxprocesses 6 \ - --from Paris \ - --until "{{ latest_fork }}" \ --basetemp="{{ output_dir }}/test-tests-pypy/tmp" \ --ignore=src/execution_testing/cli/pytest_commands/plugins/filler/tests/test_benchmarking.py \ "$@" \ diff --git a/tests/cancun/eip4844_blobs/test_blobhash_opcode.py b/tests/cancun/eip4844_blobs/test_blobhash_opcode.py index fdf1d87e1b7..5c5ab8db7fc 100644 --- a/tests/cancun/eip4844_blobs/test_blobhash_opcode.py +++ b/tests/cancun/eip4844_blobs/test_blobhash_opcode.py @@ -346,7 +346,7 @@ def test_blobhash_invalid_blob_index( data=Hash(0), access_list=[], max_fee_per_blob_gas=( - fork.min_base_fee_per_blob_gas() * 10 + fork.min_base_fee_per_blob_gas() * 10**10 ), blob_versioned_hashes=blobs, ) From 6cda4af05701060f701be8aa2243dec15f9cec72 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 10 Apr 2026 19:18:56 +0530 Subject: [PATCH 130/186] chore: revert change --- tests/cancun/eip4844_blobs/test_blobhash_opcode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cancun/eip4844_blobs/test_blobhash_opcode.py b/tests/cancun/eip4844_blobs/test_blobhash_opcode.py index 5c5ab8db7fc..fdf1d87e1b7 100644 --- a/tests/cancun/eip4844_blobs/test_blobhash_opcode.py +++ b/tests/cancun/eip4844_blobs/test_blobhash_opcode.py @@ -346,7 +346,7 @@ def test_blobhash_invalid_blob_index( data=Hash(0), access_list=[], max_fee_per_blob_gas=( - fork.min_base_fee_per_blob_gas() * 10**10 + fork.min_base_fee_per_blob_gas() * 10 ), blob_versioned_hashes=blobs, ) From bcbb8afcfc9832e27980669e0c14ac45e4660eba Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 13 Apr 2026 14:28:09 +0530 Subject: [PATCH 131/186] chore: restore bpo label --- .github/configs/fork-ranges.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/configs/fork-ranges.yaml b/.github/configs/fork-ranges.yaml index 4195d3b853d..dcb4ea65ba1 100644 --- a/.github/configs/fork-ranges.yaml +++ b/.github/configs/fork-ranges.yaml @@ -13,6 +13,9 @@ - label: osaka from: Osaka until: Osaka +- label: bpo + from: BPO1 + until: BPO2 - label: amsterdam from: Amsterdam until: Amsterdam From 1964b033c422163f1d6853df13908559a45c258d Mon Sep 17 00:00:00 2001 From: Chetna Mittal Date: Wed, 18 Feb 2026 11:34:43 +0530 Subject: [PATCH 132/186] chore: update hive workflows with latest master branch --- .github/workflows/eest_hive_gnosis.yaml | 1 + .github/workflows/eest_hive_gnosis_multi_client.yaml | 1 + .github/workflows/eest_hive_matrix.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 042d05b04da..923d51d6f2d 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -35,6 +35,7 @@ jobs: - name: Build and install Hive run: | + git clone -b master https://github.com/gnosischain/hive.git cd hive go install ./... diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index bbda1092293..b24238d0bc7 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -78,6 +78,7 @@ jobs: - name: Build and install Hive run: | + git clone -b master https://github.com/gnosischain/hive.git cd hive go install ./... diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index 1d313420c1b..cb5afda5d2c 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -128,6 +128,7 @@ jobs: - name: Build and install Hive run: | + git clone -b master https://github.com/gnosischain/hive.git cd hive go install ./... From 8c5acc28533d3886e6f7ba7d62d493a72233cbe4 Mon Sep 17 00:00:00 2001 From: Chetna Mittal Date: Wed, 18 Feb 2026 17:07:50 +0530 Subject: [PATCH 133/186] chore: increase timeout --- .github/workflows/eest_hive_gnosis.yaml | 3 ++- .github/workflows/eest_hive_gnosis_multi_client.yaml | 1 + .github/workflows/eest_hive_matrix.yaml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 923d51d6f2d..9492bfe0d94 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -50,7 +50,8 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - + sleep 30 # Give Hive time to start + - name: Install wait-on utility run: npm install -g wait-on diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index b24238d0bc7..425d5556c4a 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -91,6 +91,7 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & + sleep 30 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index cb5afda5d2c..83eaa84f814 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -143,6 +143,7 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & + sleep 30 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on From f100061e4d2a278640aaa2e2762bda31719fb6c2 Mon Sep 17 00:00:00 2001 From: Chetna Mittal Date: Wed, 18 Feb 2026 18:27:52 +0530 Subject: [PATCH 134/186] Revert "chore: increase timeout" --- .github/workflows/eest_hive_gnosis.yaml | 2 +- .github/workflows/eest_hive_gnosis_multi_client.yaml | 2 +- .github/workflows/eest_hive_matrix.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 9492bfe0d94..7a446523a1e 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -50,7 +50,7 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - sleep 30 # Give Hive time to start + sleep 10 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index 425d5556c4a..ecb1ac790ad 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -91,7 +91,7 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - sleep 30 # Give Hive time to start + sleep 10 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index 83eaa84f814..07ac0dfb905 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -143,7 +143,7 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - sleep 30 # Give Hive time to start + sleep 10 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on From 4cec9db8c9439188d12704a1e3bc0f6b88dcb62c Mon Sep 17 00:00:00 2001 From: Chetna Mittal Date: Wed, 18 Feb 2026 18:48:03 +0530 Subject: [PATCH 135/186] chore: update hive workflows --- .github/workflows/eest_hive_gnosis.yaml | 1 - .github/workflows/eest_hive_gnosis_multi_client.yaml | 1 - .github/workflows/eest_hive_matrix.yaml | 1 - 3 files changed, 3 deletions(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 7a446523a1e..39ce82bd951 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -35,7 +35,6 @@ jobs: - name: Build and install Hive run: | - git clone -b master https://github.com/gnosischain/hive.git cd hive go install ./... diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index ecb1ac790ad..9d23e24e950 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -78,7 +78,6 @@ jobs: - name: Build and install Hive run: | - git clone -b master https://github.com/gnosischain/hive.git cd hive go install ./... diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index 07ac0dfb905..4d7168ee8af 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -128,7 +128,6 @@ jobs: - name: Build and install Hive run: | - git clone -b master https://github.com/gnosischain/hive.git cd hive go install ./... From cc5f186ac251f3e1ea96909111b330b8541978ae Mon Sep 17 00:00:00 2001 From: Chetna Mittal Date: Wed, 18 Feb 2026 19:07:37 +0530 Subject: [PATCH 136/186] chore: modify hive workflow --- .github/workflows/eest_hive_gnosis.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 39ce82bd951..c6764292a35 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -49,7 +49,6 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - sleep 10 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on From 81caafaec388edc55d1db86418dc08e63c0d9ddc Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 19 Feb 2026 16:42:54 +0530 Subject: [PATCH 137/186] chore: add rest files --- .github/workflows/eest_hive_gnosis_multi_client.yaml | 1 - .github/workflows/eest_hive_matrix.yaml | 1 - .../cancun/eip1153_tstore/test_tstorage_execution_contexts.py | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index 9d23e24e950..bbda1092293 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -90,7 +90,6 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - sleep 10 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index 4d7168ee8af..1d313420c1b 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -142,7 +142,6 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - sleep 10 # Give Hive time to start - name: Install wait-on utility run: npm install -g wait-on diff --git a/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py b/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py index 25708e81a15..3cfe8dc2418 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py @@ -192,9 +192,7 @@ def __new__( # noqa: D102 f"{call_opcode._name_} upon out of gas during TSTORE. " "Note: Gas passed to sub-call is capped." ), - "caller_bytecode": lambda fork, - call_opcode=call_opcode, - callee_bytecode=callee_bytecode: ( + "caller_bytecode": lambda fork, call_opcode=call_opcode, callee_bytecode=callee_bytecode: ( Op.TSTORE(0, 420) + Op.TSTORE(1, 420) + Op.SSTORE( From 875c08a1f98ba7fff296faa1a66051ada73c4557 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 19 Feb 2026 16:54:12 +0530 Subject: [PATCH 138/186] chore: fix lint issue --- .../cancun/eip1153_tstore/test_tstorage_execution_contexts.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py b/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py index 3cfe8dc2418..25708e81a15 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py @@ -192,7 +192,9 @@ def __new__( # noqa: D102 f"{call_opcode._name_} upon out of gas during TSTORE. " "Note: Gas passed to sub-call is capped." ), - "caller_bytecode": lambda fork, call_opcode=call_opcode, callee_bytecode=callee_bytecode: ( + "caller_bytecode": lambda fork, + call_opcode=call_opcode, + callee_bytecode=callee_bytecode: ( Op.TSTORE(0, 420) + Op.TSTORE(1, 420) + Op.SSTORE( From 9070f81848aa2633b896991fc271430a7ac0eb52 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 26 Feb 2026 14:26:20 +0530 Subject: [PATCH 139/186] chore: fix lint issue --- .../evm_tools/loaders/fixture_loader.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py index f67215aeee3..489733d3354 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py @@ -62,9 +62,13 @@ def json_to_state(self, raw: Any) -> Any: """Converts json state data to a state object.""" state = State() EMPTY_ACCOUNT = self.fork.EMPTY_ACCOUNT # noqa N806 - SYSTEM_ADDRESS = ( # noqa N806 - self.fork.SYSTEM_ADDRESS if self.fork.proof_of_stake else None - ) + SYSTEM_ADDRESS = self.fork.SYSTEM_ADDRESS # noqa N806 + + # TODO: backport to previous forks. + # block_state is only in amsterdam, so its a + # good proxy for check for code_hash + + uses_code_hash = self.fork.has_block_state for address_hex, account_state in raw.items(): address = self.fork.hex_to_address(address_hex) From e636ece94bac2dd59df1e80b75f5bbc0c8e0983c Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 2 Apr 2026 11:52:23 +0530 Subject: [PATCH 140/186] chore: guard system address with proof of stake check --- src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py index 489733d3354..589fb2bdda6 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py @@ -62,7 +62,7 @@ def json_to_state(self, raw: Any) -> Any: """Converts json state data to a state object.""" state = State() EMPTY_ACCOUNT = self.fork.EMPTY_ACCOUNT # noqa N806 - SYSTEM_ADDRESS = self.fork.SYSTEM_ADDRESS # noqa N806 + SYSTEM_ADDRESS = self.fork.SYSTEM_ADDRESS if self.fork.proof_of_stake else None # noqa N806 # TODO: backport to previous forks. # block_state is only in amsterdam, so its a From 77415d3b2272e61e6058c460aaddb54a73628db4 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 2 Apr 2026 12:04:44 +0530 Subject: [PATCH 141/186] chore: fix lint issue --- .../evm_tools/loaders/fixture_loader.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py index 589fb2bdda6..f67215aeee3 100644 --- a/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py +++ b/src/ethereum_spec_tools/evm_tools/loaders/fixture_loader.py @@ -62,13 +62,9 @@ def json_to_state(self, raw: Any) -> Any: """Converts json state data to a state object.""" state = State() EMPTY_ACCOUNT = self.fork.EMPTY_ACCOUNT # noqa N806 - SYSTEM_ADDRESS = self.fork.SYSTEM_ADDRESS if self.fork.proof_of_stake else None # noqa N806 - - # TODO: backport to previous forks. - # block_state is only in amsterdam, so its a - # good proxy for check for code_hash - - uses_code_hash = self.fork.has_block_state + SYSTEM_ADDRESS = ( # noqa N806 + self.fork.SYSTEM_ADDRESS if self.fork.proof_of_stake else None + ) for address_hex, account_state in raw.items(): address = self.fork.hex_to_address(address_hex) From 7ec89c3f1e86d6be24cbe803c6b1f74d13a67a33 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 2 Apr 2026 14:53:01 +0530 Subject: [PATCH 142/186] chore: update block rewards function --- src/ethereum/forks/shanghai/fork.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 88d1f5120cc..ddfe2e559fd 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -845,7 +845,6 @@ def process_block_rewards( incorporate_tx_into_block(reward_state) - def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. From b4fa4f76762812799f2fc0bbfccf40e505c2b177 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 2 Apr 2026 15:28:08 +0530 Subject: [PATCH 143/186] chore: fix lint issue --- src/ethereum/forks/shanghai/fork.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index ddfe2e559fd..88d1f5120cc 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -845,6 +845,7 @@ def process_block_rewards( incorporate_tx_into_block(reward_state) + def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: """ Validates the gas limit for a block. From 392e42dec41b70032a8d64e33f695a51dcc14e15 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 3 Apr 2026 12:11:55 +0530 Subject: [PATCH 144/186] chore: modify t8n tool for amsterdam --- src/ethereum/forks/amsterdam/fork.py | 102 +++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 13 deletions(-) diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index d546f651cff..bd9e44fc098 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -9,11 +9,20 @@ ------------ Entry point for the Ethereum specification. + +Gnosis diff +----------- + + - Added logic to collect base fee into a collector address + - Added system call into block rewards contract that may mint tokens + - Modified withdrawals processing to make a system call + - Added logic to collect blob fee into a collector address """ from dataclasses import dataclass from typing import Final, List, Optional, Tuple +from eth_abi import decode, encode from ethereum_rlp import rlp from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable @@ -119,8 +128,9 @@ GasCosts.BLOB_SCHEDULE_MAX * GasCosts.PER_BLOB ) VERSIONED_HASH_VERSION_KZG = b"\x01" -GWEI_TO_WEI = U256(10**9) - +BLOB_FEE_COLLECTOR = hex_to_address( + "0x1559000000000000000000000000000000000000" +) WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address( "0x00000961Ef480Eb55e80D19ad83579A64c007002" ) @@ -840,6 +850,8 @@ def apply_body( """ block_output = vm.BlockOutput() + process_block_rewards(block_env) + process_unchecked_system_transaction( block_env=block_env, target_address=BEACON_ROOTS_ADDRESS, @@ -855,12 +867,22 @@ def apply_body( for i, tx in enumerate(map(decode_transaction, transactions)): process_transaction(block_env, block_output, tx, Uint(i)) + # Gnosis: populate withdrawals trie here because + # process_withdrawals() is a system call that doesn't + # receive block_output (upstream does this internally). + for i, wd in enumerate(withdrawals): + trie_set( + block_output.withdrawals_trie, + rlp.encode(Uint(i)), + rlp.encode(wd), + ) + # EIP-7928: Post-execution operations use index N+1 block_env.block_access_list_builder.block_access_index = BlockAccessIndex( ulen(transactions) + Uint(1) ) - process_withdrawals(block_env, block_output, withdrawals) + process_withdrawals(block_env, withdrawals) process_general_purpose_requests( block_env=block_env, @@ -1124,24 +1146,78 @@ def process_transaction( def process_withdrawals( block_env: vm.BlockEnvironment, - block_output: vm.BlockOutput, withdrawals: Tuple[Withdrawal, ...], ) -> None: """ - Increase the balance of the withdrawing account. + Make a system call to the deposit contract to process withdrawals. + + Spec: https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md """ + amounts = [] + addresses = [] + for w in withdrawals: + amounts.append(int(w.amount)) + addresses.append(w.address) + + payload = encode( + ["uint256", "uint64[]", "address[]"], + [MAX_FAILED_WITHDRAWALS_TO_PROCESS, amounts, addresses], + ) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=DEPOSIT_CONTRACT_ADDRESS, + data=bytes.fromhex("79d0c0bc") + payload, + ) + if out.error: + raise InvalidBlock(f"Withdrawal system call failed: {out.error}") + wd_state = TransactionState(parent=block_env.state) + incorporate_tx_into_block( + wd_state, block_env.block_access_list_builder + ) - for i, wd in enumerate(withdrawals): - trie_set( - block_output.withdrawals_trie, - rlp.encode(Uint(i)), - rlp.encode(wd), - ) - create_ether(wd_state, wd.address, wd.amount * GWEI_TO_WEI) +def process_block_rewards( + block_env: vm.BlockEnvironment, +) -> None: + """ + Call BlockRewardAuRaBase contract reward function - incorporate_tx_into_block(wd_state, block_env.block_access_list_builder) + Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md + Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 + """ + # reward(address[],uint16[]) with empty lists + data = bytes.fromhex( + "f91c2898" + "0000000000000000000000000000000000000000000000000000000000000040" + "0000000000000000000000000000000000000000000000000000000000000060" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + ) + + out = process_unchecked_system_transaction( + block_env=block_env, + target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, + data=data, + ) + if out.error: + raise InvalidBlock(f"Block rewards system call failed: {out.error}") + + account = get_account(block_env.state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + reward_state = TransactionState(parent=block_env.state) + addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) + for addr, amount in zip(addresses, amounts, strict=True): + address = hex_to_address(addr) + balance = get_account(reward_state, address).balance + U256(amount) + set_account_balance(reward_state, address, balance) + + incorporate_tx_into_block( + reward_state, block_env.block_access_list_builder + ) def check_gas_limit(gas_limit: Uint, parent_gas_limit: Uint) -> bool: From 56418e161b3510e003e0ac3fd02baf25048970a8 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 6 Apr 2026 11:01:21 +0530 Subject: [PATCH 145/186] chore: fix filling issues for amsterdam tests --- src/ethereum/forks/amsterdam/fork.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index bd9e44fc098..bd177a52ca8 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -1158,12 +1158,12 @@ def process_withdrawals( for w in withdrawals: amounts.append(int(w.amount)) addresses.append(w.address) - + payload = encode( ["uint256", "uint64[]", "address[]"], [MAX_FAILED_WITHDRAWALS_TO_PROCESS, amounts, addresses], ) - + out = process_unchecked_system_transaction( block_env=block_env, target_address=DEPOSIT_CONTRACT_ADDRESS, @@ -1173,16 +1173,14 @@ def process_withdrawals( raise InvalidBlock(f"Withdrawal system call failed: {out.error}") wd_state = TransactionState(parent=block_env.state) - incorporate_tx_into_block( - wd_state, block_env.block_access_list_builder - ) + incorporate_tx_into_block(wd_state, block_env.block_access_list_builder) def process_block_rewards( block_env: vm.BlockEnvironment, ) -> None: """ - Call BlockRewardAuRaBase contract reward function + Call BlockRewardAuRaBase contract reward function. Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 @@ -1195,7 +1193,7 @@ def process_block_rewards( "0000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000" ) - + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -1204,11 +1202,11 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - account = get_account(block_env.state, BLOCK_REWARDS_CONTRACT_ADDRESS) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) if account.code_hash == EMPTY_CODE_HASH: return - reward_state = TransactionState(parent=block_env.state) addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) From 73b2ca1b7e8583fe5151b9f39144a730a84629e1 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 6 Apr 2026 23:00:29 +0530 Subject: [PATCH 146/186] chore: fix tests --- .../test_block_access_lists_eip7702.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py index 08ab12a9e79..1ad726f9007 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py @@ -1334,9 +1334,6 @@ def test_bal_selfdestruct_to_7702_delegation( ) -GWEI = 10**9 - - def test_bal_withdrawal_to_7702_delegation( pre: Alloc, blockchain_test: BlockchainTestFiller, @@ -1381,10 +1378,6 @@ def test_bal_withdrawal_to_7702_delegation( ], ) - alice_final_balance = alice_initial_balance + ( - withdrawal_amount_gwei * GWEI - ) - account_expectations = { alice: BalAccountExpectation( # tx1: nonce change for auth, code change for delegation @@ -1395,12 +1388,8 @@ def test_bal_withdrawal_to_7702_delegation( new_code=Spec7702.delegation_designation(oracle), ) ], - # tx2 (withdrawal): balance change - balance_changes=[ - BalBalanceChange( - block_access_index=2, post_balance=alice_final_balance - ) - ], + # NO balance_changes: on Gnosis, withdrawals go through a system + # contract call — there is no direct balance credit in the BAL. ), bob: BalAccountExpectation( balance_changes=[ @@ -1434,7 +1423,7 @@ def test_bal_withdrawal_to_7702_delegation( alice: Account( nonce=1, code=Spec7702.delegation_designation(oracle), - balance=alice_final_balance, + balance=alice_initial_balance, ), bob: Account(balance=10), relayer: Account(nonce=1), From 299a507988cdffbf9e1e37473fc3983457ee423f Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 6 Apr 2026 23:17:03 +0530 Subject: [PATCH 147/186] chore: fix tests --- .../eip7928_block_level_access_lists/test_block_access_lists.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py index 90af0443091..016849195d6 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py @@ -3352,7 +3352,7 @@ def test_bal_all_transaction_types( gas_limit=100_000, max_fee_per_gas=50, max_priority_fee_per_gas=5, - max_fee_per_blob_gas=10, + max_fee_per_blob_gas=10**10, blob_versioned_hashes=blob_hashes, data=Hash(0x04), ) From 6e3d304469ad9643a5131f85931b529e1ea0040d Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 7 Apr 2026 10:30:27 +0530 Subject: [PATCH 148/186] chore: update tests --- .../test_block_access_lists_eip4895.py | 114 ++++-------------- 1 file changed, 21 insertions(+), 93 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py index d72f262c240..5573409c6b6 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py @@ -61,13 +61,7 @@ def test_bal_withdrawal_empty_block( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=11 * GWEI - ) - ], - ), + charlie: BalAccountExpectation.empty(), } ), ) @@ -76,7 +70,7 @@ def test_bal_withdrawal_empty_block( pre=pre, blocks=[block], post={ - charlie: Account(balance=11 * GWEI), + charlie: Account(balance=1 * GWEI), }, ) @@ -128,13 +122,7 @@ def test_bal_withdrawal_and_transaction( BalBalanceChange(block_access_index=1, post_balance=5) ], ), - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=2, post_balance=10 * GWEI - ) - ], - ), + charlie: BalAccountExpectation.empty(), } ), ) @@ -145,7 +133,7 @@ def test_bal_withdrawal_and_transaction( post={ alice: Account(nonce=1), bob: Account(balance=5), - charlie: Account(balance=10 * GWEI), + charlie: Account.NONEXISTENT, }, ) @@ -175,13 +163,7 @@ def test_bal_withdrawal_to_nonexistent_account( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=10 * GWEI - ) - ], - ), + charlie: BalAccountExpectation.empty(), } ), ) @@ -190,7 +172,7 @@ def test_bal_withdrawal_to_nonexistent_account( pre=pre, blocks=[block], post={ - charlie: Account(balance=10 * GWEI), + charlie: Account.NONEXISTENT, }, ) @@ -224,15 +206,7 @@ def test_bal_withdrawal_no_evm_execution( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - oracle: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=10 * GWEI - ) - ], - storage_reads=[], - storage_changes=[], - ), + oracle: BalAccountExpectation.empty(), } ), ) @@ -242,7 +216,7 @@ def test_bal_withdrawal_no_evm_execution( blocks=[block], post={ oracle: Account( - balance=10 * GWEI, + balance=0, storage={0x01: 0x42}, ), }, @@ -303,11 +277,6 @@ def test_bal_withdrawal_and_state_access_same_account( ], ) ], - balance_changes=[ - BalBalanceChange( - block_access_index=2, post_balance=10 * GWEI - ) - ], ), } ), @@ -319,7 +288,7 @@ def test_bal_withdrawal_and_state_access_same_account( post={ alice: Account(nonce=1), oracle: Account( - balance=10 * GWEI, + balance=0, storage={0x01: 0x42, 0x02: 0x99}, ), }, @@ -370,9 +339,6 @@ def test_bal_withdrawal_and_value_transfer_same_address( BalBalanceChange( block_access_index=1, post_balance=5 * GWEI ), - BalBalanceChange( - block_access_index=2, post_balance=15 * GWEI - ), ], ), } @@ -384,7 +350,7 @@ def test_bal_withdrawal_and_value_transfer_same_address( blocks=[block], post={ alice: Account(nonce=1), - bob: Account(balance=15 * GWEI), + bob: Account(balance=5 * GWEI), }, ) @@ -410,13 +376,7 @@ def test_bal_multiple_withdrawals_same_address( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=30 * GWEI - ) - ], - ), + charlie: BalAccountExpectation.empty(), } ), ) @@ -425,7 +385,7 @@ def test_bal_multiple_withdrawals_same_address( pre=pre, blocks=[block], post={ - charlie: Account(balance=30 * GWEI), + charlie: Account.NONEXISTENT, }, ) @@ -483,9 +443,6 @@ def test_bal_withdrawal_and_selfdestruct( oracle: BalAccountExpectation( balance_changes=[ BalBalanceChange(block_access_index=1, post_balance=0), - BalBalanceChange( - block_access_index=2, post_balance=50 * GWEI - ), ], ), } @@ -498,7 +455,7 @@ def test_bal_withdrawal_and_selfdestruct( post={ alice: Account(nonce=1), bob: Account(balance=100 * GWEI), - oracle: Account(balance=50 * GWEI), + oracle: Account(balance=0), }, ) @@ -554,9 +511,6 @@ def test_bal_withdrawal_and_new_contract( BalBalanceChange( block_access_index=1, post_balance=5 * GWEI ), - BalBalanceChange( - block_access_index=2, post_balance=15 * GWEI - ), ], ), } @@ -568,7 +522,7 @@ def test_bal_withdrawal_and_new_contract( blocks=[block], post={ alice: Account(nonce=1), - oracle: Account(balance=15 * GWEI, code=code), + oracle: Account(balance=5 * GWEI, code=code), }, ) @@ -655,15 +609,7 @@ def test_bal_withdrawal_to_precompiles( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - precompile: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=10 * GWEI - ) - ], - storage_reads=[], - storage_changes=[], - ), + precompile: BalAccountExpectation.empty(), } ), ) @@ -672,7 +618,7 @@ def test_bal_withdrawal_to_precompiles( pre=pre, blocks=[block], post={ - precompile: Account(balance=10 * GWEI), + precompile: Account.NONEXISTENT, }, ) @@ -703,14 +649,7 @@ def test_bal_withdrawal_largest_amount( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, - post_balance=max_amount * GWEI, - ) - ], - ), + charlie: BalAccountExpectation.empty(), } ), ) @@ -719,7 +658,7 @@ def test_bal_withdrawal_largest_amount( pre=pre, blocks=[block], post={ - charlie: Account(balance=max_amount * GWEI), + charlie: Account.NONEXISTENT, }, ) @@ -760,7 +699,6 @@ def test_bal_withdrawal_to_coinbase( parent_gas_limit=genesis_env.gas_limit, ) tip_to_coinbase = (gas_price - base_fee_per_gas) * intrinsic_gas - coinbase_final_balance = tip_to_coinbase + (10 * GWEI) block = Block( txs=[tx], @@ -791,10 +729,6 @@ def test_bal_withdrawal_to_coinbase( BalBalanceChange( block_access_index=1, post_balance=tip_to_coinbase ), - BalBalanceChange( - block_access_index=2, - post_balance=coinbase_final_balance, - ), ], ), } @@ -807,7 +741,7 @@ def test_bal_withdrawal_to_coinbase( post={ alice: Account(nonce=1), bob: Account(balance=5), - coinbase: Account(balance=coinbase_final_balance), + coinbase: Account(balance=tip_to_coinbase), }, genesis_environment=genesis_env, ) @@ -838,13 +772,7 @@ def test_bal_withdrawal_to_coinbase_empty_block( ], expected_block_access_list=BlockAccessListExpectation( account_expectations={ - coinbase: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, post_balance=10 * GWEI - ) - ], - ), + coinbase: BalAccountExpectation.empty(), } ), ) @@ -853,6 +781,6 @@ def test_bal_withdrawal_to_coinbase_empty_block( pre=pre, blocks=[block], post={ - coinbase: Account(balance=10 * GWEI), + coinbase: Account.NONEXISTENT, }, ) From d359d1f802ddbbbb8d76e23ebc28c550d33504d0 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 7 Apr 2026 11:07:38 +0530 Subject: [PATCH 149/186] chore: fix tests --- .../test_block_access_lists_eip4895.py | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py index 5573409c6b6..0c20bf47c91 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py @@ -41,11 +41,11 @@ def test_bal_withdrawal_empty_block( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures withdrawal balance changes in empty block. + Ensure BAL produces no entry for withdrawal in an empty block. Charlie starts with 1 gwei balance (existing account). Block with 0 transactions and 1 withdrawal of 10 gwei to Charlie. - Charlie ends with 11 gwei balance. + Charlie does not appear in BAL and balance is not credited. """ charlie = pre.fund_eoa(amount=1 * GWEI) @@ -60,9 +60,7 @@ def test_bal_withdrawal_empty_block( ) ], expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - charlie: BalAccountExpectation.empty(), - } + account_expectations={} ), ) @@ -81,12 +79,12 @@ def test_bal_withdrawal_and_transaction( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures both transaction and withdrawal balance changes. + Ensure BAL captures transaction changes but not withdrawal. Alice starts with 1 ETH, Bob starts with 0, Charlie starts with 0. Alice sends 5 wei to Bob. - Charlie receives 10 gwei withdrawal. - Bob ends with 5 wei, Charlie ends with 10 gwei. + Charlie receives 10 gwei withdrawal but is not captured in BAL. + Bob ends with 5 wei, Charlie's balance remains unchanged. """ alice = pre.fund_eoa() bob = pre.fund_eoa(amount=0) @@ -122,7 +120,6 @@ def test_bal_withdrawal_and_transaction( BalBalanceChange(block_access_index=1, post_balance=5) ], ), - charlie: BalAccountExpectation.empty(), } ), ) @@ -133,7 +130,6 @@ def test_bal_withdrawal_and_transaction( post={ alice: Account(nonce=1), bob: Account(balance=5), - charlie: Account.NONEXISTENT, }, ) @@ -162,18 +158,14 @@ def test_bal_withdrawal_to_nonexistent_account( ) ], expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - charlie: BalAccountExpectation.empty(), - } + account_expectations={} ), ) blockchain_test( pre=pre, blocks=[block], - post={ - charlie: Account.NONEXISTENT, - }, + post={}, ) From 407fa002a4c2982f209d5e1c0de4a35951414a17 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 7 Apr 2026 12:31:09 +0530 Subject: [PATCH 150/186] chore: fix tests --- .../test_block_access_lists_eip4895.py | 105 ++++++------------ 1 file changed, 35 insertions(+), 70 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py index 0c20bf47c91..7975a73b657 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip4895.py @@ -59,9 +59,7 @@ def test_bal_withdrawal_empty_block( amount=10, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={} - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( @@ -157,9 +155,7 @@ def test_bal_withdrawal_to_nonexistent_account( amount=10, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={} - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( @@ -174,7 +170,7 @@ def test_bal_withdrawal_no_evm_execution( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures withdrawal without triggering EVM execution. + Ensure withdrawal does not trigger EVM or appear in BAL. Oracle contract starts with 0 balance and storage slot 0x01 = 0x42. Oracle's code writes 0xFF to slot 0x01 when called. @@ -196,11 +192,7 @@ def test_bal_withdrawal_no_evm_execution( amount=10, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - oracle: BalAccountExpectation.empty(), - } - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( @@ -220,12 +212,12 @@ def test_bal_withdrawal_and_state_access_same_account( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures both state access and withdrawal to same address. + Ensure BAL captures state access but not withdrawal to same address. Oracle contract starts with 0 balance and storage slot 0x01 = 0x42. Alice calls Oracle (reads slot 0x01, writes 0x99 to slot 0x02). Oracle receives withdrawal of 10 gwei. - Both state access and withdrawal are captured in BAL. + State access is captured in BAL but not withdrawal. """ alice = pre.fund_eoa() oracle = pre.deploy_contract( @@ -292,12 +284,12 @@ def test_bal_withdrawal_and_value_transfer_same_address( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures both value transfer and withdrawal to same address. + Ensure BAL captures value transfer but not withdrawal to same address. Alice starts with 1 ETH, Bob starts with 0. Alice sends 5 gwei to Bob. - Bob receives withdrawal of 10 gwei. - Bob ends with 15 gwei (5 from tx + 10 from withdrawal). + Bob receives withdrawal of 10 gwei but is not captured in BAL. + Bob ends with 5 gwei (tx only). """ alice = pre.fund_eoa() bob = pre.fund_eoa(amount=0) @@ -352,11 +344,11 @@ def test_bal_multiple_withdrawals_same_address( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL accumulates multiple withdrawals to same address. + Ensure multiple withdrawals to same address do not appear in BAL. Charlie starts with 0 balance. Block empty block with 3 withdrawals to Charlie: 5 gwei, 10 gwei, 15 gwei. - Charlie ends with 30 gwei balance (cumulative). + Charlie does not appear in BAL and balance is not credited. """ charlie = pre.fund_eoa(amount=0) @@ -366,19 +358,13 @@ def test_bal_multiple_withdrawals_same_address( Withdrawal(index=i, validator_index=i, address=charlie, amount=amt) for i, amt in enumerate([5, 10, 15]) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - charlie: BalAccountExpectation.empty(), - } - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( pre=pre, blocks=[block], - post={ - charlie: Account.NONEXISTENT, - }, + post={}, ) @@ -387,12 +373,12 @@ def test_bal_withdrawal_and_selfdestruct( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures withdrawal to self-destructed contract address. + Ensure BAL captures SELFDESTRUCT balance changes but not withdrawal. Oracle contract starts with 100 gwei balance. Alice triggers Oracle to self-destruct, sending balance to Bob. Oracle receives withdrawal of 50 gwei after self-destructing. - Oracle ends with 50 gwei (funded by withdrawal). + Oracle ends with 0 balance (withdrawal is not captured in BAL). """ alice = pre.fund_eoa() bob = pre.fund_eoa(amount=0) @@ -457,11 +443,11 @@ def test_bal_withdrawal_and_new_contract( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures withdrawal to newly created contract. + Ensure BAL captures contract creation with value but not withdrawal. Alice deploys Oracle contract with 5 gwei initial balance. Oracle receives withdrawal of 10 gwei in same block. - Oracle ends with 15 gwei (5 from deployment + 10 from withdrawal). + Oracle ends with 5 gwei (deployment only). """ alice = pre.fund_eoa() @@ -532,11 +518,11 @@ def test_bal_zero_withdrawal( initial_balance: int, ) -> None: """ - Ensure BAL handles zero-amount withdrawal correctly. + Ensure zero-amount withdrawal does not appear in BAL. Charlie either exists with initial balance or is non-existent. Block with 0 transactions and 1 zero-amount withdrawal to Charlie. - Charlie appears in BAL but with empty changes, balance unchanged. + Charlie does not appear in BAL and balance is unchanged. """ if initial_balance > 0: charlie = pre.fund_eoa(amount=initial_balance) @@ -553,11 +539,7 @@ def test_bal_zero_withdrawal( amount=0, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - charlie: BalAccountExpectation.empty(), - } - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( @@ -584,10 +566,10 @@ def test_bal_withdrawal_to_precompiles( precompile: Address, ) -> None: """ - Ensure BAL captures withdrawal to precompile addresses. + Ensure withdrawal to precompile address does not appear in BAL. Block with 0 transactions and 1 withdrawal of 10 gwei to precompile. - Precompile ends with 10 gwei balance. + Precompile does not appear in BAL and balance is not credited. """ block = Block( txs=[], @@ -599,19 +581,13 @@ def test_bal_withdrawal_to_precompiles( amount=10, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - precompile: BalAccountExpectation.empty(), - } - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( pre=pre, blocks=[block], - post={ - precompile: Account.NONEXISTENT, - }, + post={}, ) @@ -620,11 +596,11 @@ def test_bal_withdrawal_largest_amount( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures withdrawal with largest amount. + Ensure withdrawal with largest amount does not appear in BAL. Block with 0 transactions and 1 withdrawal of maximum uint64 value (2^64-1)Gwei to Charlie. - Charlie ends with (2^64-1) Gwei. + Charlie does not appear in BAL and balance is not credited. """ charlie = pre.fund_eoa(amount=0) max_amount = 2**64 - 1 @@ -639,19 +615,13 @@ def test_bal_withdrawal_largest_amount( amount=max_amount, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - charlie: BalAccountExpectation.empty(), - } - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( pre=pre, blocks=[block], - post={ - charlie: Account.NONEXISTENT, - }, + post={}, ) @@ -661,10 +631,11 @@ def test_bal_withdrawal_to_coinbase( fork: Fork, ) -> None: """ - Ensure BAL captures withdrawal to coinbase address. + Ensure BAL captures tx fee but not withdrawal to coinbase address. Block with 1 transaction and 1 withdrawal to coinbase/fee recipient. - Coinbase receives both transaction fees and withdrawal. + Coinbase receives both transaction fees. + Withdrawal is not captured in BAL and balance is not credited. """ alice = pre.fund_eoa() bob = pre.fund_eoa(amount=0) @@ -744,10 +715,10 @@ def test_bal_withdrawal_to_coinbase_empty_block( blockchain_test: BlockchainTestFiller, ) -> None: """ - Ensure BAL captures withdrawal to coinbase when there are no transactions. + Ensure withdrawal to coinbase does not appear in BAL. Empty block with 1 withdrawal of 10 gwei to coinbase/fee recipient. - Coinbase receives only withdrawal (no transaction fees). + Coinbase does not appear in BAL and balance is not credited. """ coinbase = pre.fund_eoa(amount=0) @@ -762,17 +733,11 @@ def test_bal_withdrawal_to_coinbase_empty_block( amount=10, ) ], - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - coinbase: BalAccountExpectation.empty(), - } - ), + expected_block_access_list=BlockAccessListExpectation(), ) blockchain_test( pre=pre, blocks=[block], - post={ - coinbase: Account.NONEXISTENT, - }, + post={}, ) From d079f07aae90c48c5693be09aaaf9fad22496d4c Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 7 Apr 2026 15:21:48 +0530 Subject: [PATCH 151/186] chore: enable amsterdam fork for py3 tests --- .github/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 168322671f7..d8edfb1d7b4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -94,9 +94,9 @@ jobs: - label: osaka from_fork: Osaka until_fork: Osaka - # - label: amsterdam - # from_fork: Amsterdam - # until_fork: Amsterdam + - label: amsterdam + from_fork: Amsterdam + until_fork: Amsterdam steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: From 190a7ae3037274bbe65e55ae60d1c06edbe6a43e Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 7 Apr 2026 18:28:18 +0530 Subject: [PATCH 152/186] chore: update workflow --- .github/workflows/eest_hive_gnosis.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index c6764292a35..be899a44d5b 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - name: Clone Hive repository - run: git clone -b master https://github.com/gnosischain/hive.git + run: git clone -b fix/nethermind-client https://github.com/gnosischain/hive.git - name: Install Go (for Hive) uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 From be3cc5e88add983569b027f42b7bea7313712045 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Tue, 7 Apr 2026 18:46:48 +0530 Subject: [PATCH 153/186] chore: update workflow --- .github/workflows/eest_hive_gnosis.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index be899a44d5b..f1b7fa98772 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - name: Clone Hive repository - run: git clone -b fix/nethermind-client https://github.com/gnosischain/hive.git + run: git clone -b fix/client-files https://github.com/gnosischain/hive.git - name: Install Go (for Hive) uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 From 0f22caa58b6199ea5a2a54bf5c9d855e8a9c7d43 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Sun, 12 Apr 2026 17:34:38 +0530 Subject: [PATCH 154/186] chore: update eip 7928 --- .../execution_testing/forks/forks/eips/amsterdam/eip_7928.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py index d4b1b9a6e17..30cbfd90e67 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py @@ -49,8 +49,10 @@ def empty_block_bal_item_count(cls) -> int: EIP-2935 history storage: 1 address + 1 write = 2 EIP-7002 withdrawal requests: 1 address + 4 reads = 5 EIP-7251 consolidation requests: 1 address + 4 reads = 5 + Withdrawal system call: 1 read = 1 + Block rewards system call: 1 read = 1 """ - return 15 + return 17 @classmethod def engine_execution_payload_block_access_list(cls) -> bool: From e1571b60f6522fbe1bd672205df4c19291a17dda Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Sun, 12 Apr 2026 17:35:35 +0530 Subject: [PATCH 155/186] chore: fix comment --- .../execution_testing/forks/forks/eips/amsterdam/eip_7928.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py index 30cbfd90e67..d6ce8384013 100644 --- a/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py +++ b/packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_7928.py @@ -44,7 +44,7 @@ def empty_block_bal_item_count(cls) -> int: """ Return the BAL item count for an empty EIP-7928 block. - Four system contracts produce 15 items: + Six system contracts produce 17 items: EIP-4788 beacon roots: 1 address + 1 write + 1 read = 3 EIP-2935 history storage: 1 address + 1 write = 2 EIP-7002 withdrawal requests: 1 address + 4 reads = 5 From 8411d05b9d785df9e0352916395039eec48570ea Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 13 Apr 2026 13:09:20 +0530 Subject: [PATCH 156/186] chore: modify tests --- .../test_block_access_lists_invalid.py | 45 ++++++------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index 52d366019d8..c30a788d8a4 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -655,19 +655,19 @@ def test_bal_invalid_missing_account( @pytest.mark.valid_from("Amsterdam") @pytest.mark.exception_test -def test_bal_invalid_missing_withdrawal_account( +def test_bal_invalid_missing_tx_account( blockchain_test: BlockchainTestFiller, pre: Alloc, ) -> None: """ Test that clients reject blocks where BAL is missing an account - that was modified only by a withdrawal. + that was modified by a transaction. Alice sends 5 wei to Bob (1 transaction). - Charlie receives 10 gwei withdrawal. - BAL is corrupted by removing Charlie's entry entirely. - Clients must detect that Charlie's balance was modified by the - withdrawal but has no corresponding BAL entry. + Charlie receives 10 gwei withdrawal but is not captured in BAL. + BAL is corrupted by removing Bob's entry (the tx-modified account). + Clients must detect that Bob's balance was modified by the tx but has no + corresponding BAL entry because Charlie's withdrawal is a no-op. """ alice = pre.fund_eoa() bob = pre.fund_eoa(amount=0) @@ -715,16 +715,8 @@ def test_bal_invalid_missing_withdrawal_account( ) ], ), - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=2, - post_balance=10 * 10**9, - ) - ], - ), } - ).modify(remove_accounts(charlie)), + ).modify(remove_accounts(bob)), ) ], ) @@ -737,11 +729,12 @@ def test_bal_invalid_missing_withdrawal_account_empty_block( pre: Alloc, ) -> None: """ - Test that clients reject blocks where BAL is missing an account - that was modified only by a withdrawal, in a block with no transactions. + Test that an empty block containing only a withdrawal produces + a valid block with an empty BAL. - Charlie receives 10 gwei withdrawal in an empty block. - BAL is corrupted by removing Charlie's entry entirely. + Charlie receives 10 gwei withdrawal in an empty block (no transactions). + Charlie is not captured in BAL because the withdrawal is a no-op. + The block is valid with an empty BAL. """ charlie = pre.fund_eoa(amount=0) @@ -761,19 +754,7 @@ def test_bal_invalid_missing_withdrawal_account_empty_block( amount=10, ) ], - exception=BlockException.INVALID_BLOCK_ACCESS_LIST, - expected_block_access_list=BlockAccessListExpectation( - account_expectations={ - charlie: BalAccountExpectation( - balance_changes=[ - BalBalanceChange( - block_access_index=1, - post_balance=10 * 10**9, - ) - ], - ), - } - ).modify(remove_accounts(charlie)), + expected_block_access_list=BlockAccessListExpectation(), ) ], ) From 2f25fa085be270eb1e852928acb6d3dc1042058c Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 13 Apr 2026 13:11:52 +0530 Subject: [PATCH 157/186] chore: fix test --- .../test_block_access_lists_invalid.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py index c30a788d8a4..608bda54039 100644 --- a/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py +++ b/tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_invalid.py @@ -723,7 +723,6 @@ def test_bal_invalid_missing_tx_account( @pytest.mark.valid_from("Amsterdam") -@pytest.mark.exception_test def test_bal_invalid_missing_withdrawal_account_empty_block( blockchain_test: BlockchainTestFiller, pre: Alloc, From f40371b56553810380ae7bb7816d1c7472e4f917 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 13 Apr 2026 14:19:47 +0530 Subject: [PATCH 158/186] chore: amsterdam related changes --- .github/workflows/eest_hive_gnosis.yaml | 2 +- .github/workflows/eest_hive_gnosis_multi_client.yaml | 2 +- .github/workflows/eest_hive_matrix.yaml | 8 ++++---- .../testing/src/execution_testing/forks/forks/forks.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index f1b7fa98772..04fb0943f41 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -6,7 +6,7 @@ on: fork: description: "Fork passed to --fork" required: true - default: "Osaka" + default: "Amsterdam" client: description: "Client passed to --client" required: true diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index bbda1092293..13942d8f335 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -6,7 +6,7 @@ on: fork: description: "Fork passed to --fork" required: true - default: "Osaka" + default: "Amsterdam" test_dir: description: "Optional test directory under tests/ (e.g. osaka). Leave empty to fill all tests." required: false diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index 1d313420c1b..cc2d21a77a3 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -6,16 +6,16 @@ on: fork: description: "Fork passed to --fork" required: true - default: "Osaka" + default: "Amsterdam" client: description: "Client passed to --client" required: true - default: "reth-gnosis" + default: "nethermind-gnosis" test_dirs: description: "Comma-separated list of EIP numbers or directory names" required: true - default: "osaka" - + default: "amsterdam" + jobs: # Prepare matrix from input prepare: diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 9064d989118..7da3e93d683 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -1611,7 +1611,7 @@ class BPO5( class Amsterdam( AmsterdamEIPs, - BPO2, + Osaka, deployed=False, ): """Amsterdam fork.""" From 2c61f5c54a7e2cc38448d10dcdf2fa7a60a833ac Mon Sep 17 00:00:00 2001 From: dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:08:51 +0200 Subject: [PATCH 159/186] Remove BPO transition forks, add OsakaToAmsterdam transition Gnosis Amsterdam inherits directly from Osaka (no BPO forks), so BPO transition forks (OsakaToBPO1, BPO1ToBPO2, BPO2ToAmsterdam) are not valid. Replace with OsakaToAmsterdamAtTime15k and update tests. Also revert Hive workflow refs from fix/client-files to master. --- .github/workflows/eest_hive_gnosis.yaml | 2 +- .../consume/simulators/helpers/ruleset.py | 4 +-- .../plugins/forks/tests/test_forks.py | 15 ++++----- .../src/execution_testing/forks/__init__.py | 8 ++--- .../forks/forks/transition.py | 24 ++------------ .../forks/tests/test_forks.py | 33 ++++++++----------- 6 files changed, 29 insertions(+), 57 deletions(-) diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index 04fb0943f41..fcdfe909907 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - name: Clone Hive repository - run: git clone -b fix/client-files https://github.com/gnosischain/hive.git + run: git clone -b master https://github.com/gnosischain/hive.git - name: Install Go (for Hive) uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py index 10593157fee..2fc17ca08bf 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py @@ -5,7 +5,7 @@ from execution_testing.forks import ( ALL_FORKS_WITH_TRANSITIONS, Amsterdam, - BPO2ToAmsterdamAtTime15k, + OsakaToAmsterdamAtTime15k, Byzantium, Fork, London, @@ -23,7 +23,7 @@ def ruleset_format(fork: Fork | TransitionFork) -> Dict[str, int]: if fork > London: default_values["HIVE_TERMINAL_TOTAL_DIFFICULTY"] = 0 entries = default_values | fork.ruleset() - if fork in [Amsterdam, BPO2ToAmsterdamAtTime15k]: + if fork in [Amsterdam, OsakaToAmsterdamAtTime15k]: entries.pop("HIVE_AMSTERDAM_BLOB_BASE_FEE_UPDATE_FRACTION") entries.pop("HIVE_AMSTERDAM_BLOB_MAX") entries.pop("HIVE_AMSTERDAM_BLOB_TARGET") diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py index 57697c6a8c1..a3d4e6090c0 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py @@ -17,8 +17,8 @@ get_forks, ) from execution_testing.forks.forks.transition import ( - BPO2ToAmsterdamAtTime15k, - OsakaToBPO1AtTime15k, + OsakaToAmsterdamAtTime15k, + PragueToOsakaAtTime15k, ) from execution_testing.specs import StateTest @@ -294,9 +294,9 @@ def test_fork_range({StateTest.pytest_parameter_name()}): "pytest-fill.ini", "-v", "--from", - "OsakaToBPO1AtTime15k", + "PragueToOsakaAtTime15k", "--until", - "BPO2ToAmsterdamAtTime15k", + "OsakaToAmsterdamAtTime15k", ) stdout = "\n".join(result.stdout.lines) # The header line lists the selected fork set; parse it. @@ -313,7 +313,6 @@ def test_fork_range({StateTest.pytest_parameter_name()}): # Strip ANSI codes from the last element. fork_names[-1] = fork_names[-1].split("\x1b")[0] assert Amsterdam.name() not in fork_names - assert BPO1.name() in fork_names - assert BPO2.name() in fork_names - assert BPO2ToAmsterdamAtTime15k.name() in fork_names - assert OsakaToBPO1AtTime15k.name() in fork_names + assert "Osaka" in fork_names + assert OsakaToAmsterdamAtTime15k.name() in fork_names + assert PragueToOsakaAtTime15k.name() in fork_names diff --git a/packages/testing/src/execution_testing/forks/__init__.py b/packages/testing/src/execution_testing/forks/__init__.py index cd333c559e8..5b49d2f6132 100644 --- a/packages/testing/src/execution_testing/forks/__init__.py +++ b/packages/testing/src/execution_testing/forks/__init__.py @@ -29,12 +29,10 @@ ) from .forks.transition import ( BerlinToLondonAt5, - BPO1ToBPO2AtTime15k, - BPO2ToAmsterdamAtTime15k, BPO2ToBPO3AtTime15k, BPO3ToBPO4AtTime15k, CancunToPragueAtTime15k, - OsakaToBPO1AtTime15k, + OsakaToAmsterdamAtTime15k, ParisToShanghaiAtTime15k, PragueToOsakaAtTime15k, ShanghaiToCancunAtTime15k, @@ -115,12 +113,10 @@ "Prague", "PragueToOsakaAtTime15k", "Osaka", - "OsakaToBPO1AtTime15k", + "OsakaToAmsterdamAtTime15k", "BPO1", - "BPO1ToBPO2AtTime15k", "BPO2", "BPO2ToBPO3AtTime15k", - "BPO2ToAmsterdamAtTime15k", "BPO3", "BPO3ToBPO4AtTime15k", "BPO4", diff --git a/packages/testing/src/execution_testing/forks/forks/transition.py b/packages/testing/src/execution_testing/forks/forks/transition.py index ac3e50786d4..2f35c4725af 100644 --- a/packages/testing/src/execution_testing/forks/forks/transition.py +++ b/packages/testing/src/execution_testing/forks/forks/transition.py @@ -53,27 +53,9 @@ class PragueToOsakaAtTime15k(TransitionBaseClass): pass -@transition_fork(to_fork=BPO1, from_fork=Osaka, at_timestamp=15_000) -class OsakaToBPO1AtTime15k(TransitionBaseClass): - """Osaka to BPO1 transition at Timestamp 15k.""" - - pass - - -@transition_fork(to_fork=BPO2, from_fork=BPO1, at_timestamp=15_000) -class BPO1ToBPO2AtTime15k(TransitionBaseClass): - """BPO1 to BPO2 transition at Timestamp 15k.""" - - pass - - -@transition_fork(to_fork=Amsterdam, from_fork=BPO2, at_timestamp=15_000) -class BPO2ToAmsterdamAtTime15k(TransitionBaseClass): - """BPO2 to Amsterdam transition at Timestamp 15k.""" - - # TODO: We may need to adjust which BPO Amsterdam inherits from as the - # related Amsterdam specs change over time, and before Amsterdam is - # live on mainnet. +@transition_fork(to_fork=Amsterdam, from_fork=Osaka, at_timestamp=15_000) +class OsakaToAmsterdamAtTime15k(TransitionBaseClass): + """Osaka to Amsterdam transition at Timestamp 15k.""" pass diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index e40f100b709..13116b3049a 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -28,12 +28,10 @@ ) from ..forks.transition import ( BerlinToLondonAt5, - BPO1ToBPO2AtTime15k, - BPO2ToAmsterdamAtTime15k, BPO2ToBPO3AtTime15k, BPO3ToBPO4AtTime15k, CancunToPragueAtTime15k, - OsakaToBPO1AtTime15k, + OsakaToAmsterdamAtTime15k, ParisToShanghaiAtTime15k, PragueToOsakaAtTime15k, ShanghaiToCancunAtTime15k, @@ -590,8 +588,7 @@ def test_bpo_fork() -> None: # noqa: D103 assert BPO2.bpo_fork() is True assert BPO3.bpo_fork() is True assert BPO4.bpo_fork() is True - assert OsakaToBPO1AtTime15k.fork_at().bpo_fork() is False - assert BPO1ToBPO2AtTime15k.fork_at().bpo_fork() is True + assert OsakaToAmsterdamAtTime15k.fork_at().bpo_fork() is False assert BPO2ToBPO3AtTime15k.fork_at().bpo_fork() is True assert BPO3ToBPO4AtTime15k.fork_at().bpo_fork() is True @@ -627,22 +624,21 @@ def test_transition_from_and_until(self) -> None: """Test range with transition forks as both boundaries.""" result = get_selected_fork_set( single_fork=set(), - forks_from={OsakaToBPO1AtTime15k}, # type: ignore[arg-type] - forks_until={BPO2ToAmsterdamAtTime15k}, # type: ignore[arg-type] + forks_from={PragueToOsakaAtTime15k}, # type: ignore[arg-type] + forks_until={OsakaToAmsterdamAtTime15k}, # type: ignore[arg-type] ) - assert self._normal_forks(result) == {BPO1, BPO2} + assert self._normal_forks(result) == {Osaka} assert self._transition_forks(result) == { - OsakaToBPO1AtTime15k, - BPO1ToBPO2AtTime15k, - BPO2ToAmsterdamAtTime15k, + PragueToOsakaAtTime15k, + OsakaToAmsterdamAtTime15k, } def test_transition_until_excludes_target(self) -> None: """Transition fork `--until` must not include `transitions_to()`.""" result = get_selected_fork_set( single_fork=set(), - forks_from={OsakaToBPO1AtTime15k}, # type: ignore[arg-type] - forks_until={BPO2ToAmsterdamAtTime15k}, # type: ignore[arg-type] + forks_from={PragueToOsakaAtTime15k}, # type: ignore[arg-type] + forks_until={OsakaToAmsterdamAtTime15k}, # type: ignore[arg-type] ) assert Amsterdam not in result @@ -675,13 +671,12 @@ def test_transition_from_normal_until(self) -> None: """Test transition `--from` with normal `--until`.""" result = get_selected_fork_set( single_fork=set(), - forks_from={OsakaToBPO1AtTime15k}, # type: ignore[arg-type] - forks_until={BPO2}, + forks_from={PragueToOsakaAtTime15k}, # type: ignore[arg-type] + forks_until={Osaka}, ) - assert self._normal_forks(result) == {BPO1, BPO2} - assert OsakaToBPO1AtTime15k in result - assert BPO1ToBPO2AtTime15k in result - assert BPO2ToAmsterdamAtTime15k not in result + assert self._normal_forks(result) == {Osaka} + assert PragueToOsakaAtTime15k in result + assert OsakaToAmsterdamAtTime15k not in result def test_blob_constants() -> None: # noqa: D103 From e55456f77b16b2efae8580ec78a21067f5025170 Mon Sep 17 00:00:00 2001 From: dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:12:10 +0200 Subject: [PATCH 160/186] Remove unused BPO1 import from transition.py --- packages/testing/src/execution_testing/forks/forks/transition.py | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/testing/src/execution_testing/forks/forks/transition.py b/packages/testing/src/execution_testing/forks/forks/transition.py index 2f35c4725af..806323939e9 100644 --- a/packages/testing/src/execution_testing/forks/forks/transition.py +++ b/packages/testing/src/execution_testing/forks/forks/transition.py @@ -2,7 +2,6 @@ from ..transition_base_fork import TransitionBaseClass, transition_fork from .forks import ( - BPO1, BPO2, BPO3, BPO4, From c0f536f37a45d000898ea78139c166fad2b5b30a Mon Sep 17 00:00:00 2001 From: dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:17:48 +0200 Subject: [PATCH 161/186] Fix lint: remove unused BPO imports, sort imports --- .../plugins/consume/simulators/helpers/ruleset.py | 2 +- .../cli/pytest_commands/plugins/forks/tests/test_forks.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py index 2fc17ca08bf..b7806f44cb0 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/consume/simulators/helpers/ruleset.py @@ -5,10 +5,10 @@ from execution_testing.forks import ( ALL_FORKS_WITH_TRANSITIONS, Amsterdam, - OsakaToAmsterdamAtTime15k, Byzantium, Fork, London, + OsakaToAmsterdamAtTime15k, TransitionFork, ) diff --git a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py index a3d4e6090c0..2a55a2c8bb5 100644 --- a/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/cli/pytest_commands/plugins/forks/tests/test_forks.py @@ -7,8 +7,6 @@ ) from execution_testing.fixtures import LabeledFixtureFormat from execution_testing.forks import ( - BPO1, - BPO2, Amsterdam, ArrowGlacier, Fork, From 09c47e52d39ba7eca4d15f6302d400fba536a3ca Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Sun, 19 Apr 2026 23:13:56 +0530 Subject: [PATCH 162/186] chore: remove dead code --- src/ethereum/forks/amsterdam/fork.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index bd177a52ca8..ce45f5bd6d2 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -1172,9 +1172,6 @@ def process_withdrawals( if out.error: raise InvalidBlock(f"Withdrawal system call failed: {out.error}") - wd_state = TransactionState(parent=block_env.state) - incorporate_tx_into_block(wd_state, block_env.block_access_list_builder) - def process_block_rewards( block_env: vm.BlockEnvironment, From 0be5b46dca52b537bbbf0c7e96afa061b8f8dfd6 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 20 Apr 2026 13:19:37 +0530 Subject: [PATCH 163/186] chore: add workflows for dashboard integration --- .github/configs/fork-ranges.yaml | 3 - .github/workflows/hive-bal.yaml | 188 ++++++++++++++++++++++++++++ .github/workflows/hive-generic.yaml | 172 +++++++++++++++++++++++++ 3 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/hive-bal.yaml create mode 100644 .github/workflows/hive-generic.yaml diff --git a/.github/configs/fork-ranges.yaml b/.github/configs/fork-ranges.yaml index dcb4ea65ba1..4195d3b853d 100644 --- a/.github/configs/fork-ranges.yaml +++ b/.github/configs/fork-ranges.yaml @@ -13,9 +13,6 @@ - label: osaka from: Osaka until: Osaka -- label: bpo - from: BPO1 - until: BPO2 - label: amsterdam from: Amsterdam until: Amsterdam diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml new file mode 100644 index 00000000000..e6d64ffe198 --- /dev/null +++ b/.github/workflows/hive-bal.yaml @@ -0,0 +1,188 @@ +name: Hive - BAL +on: + schedule: + - cron: '0 0 * * *' # Run every day at 00:00 UTC + workflow_dispatch: + inputs: + client: + type: string + default: '"go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"' + description: Comma-separated list of clients to test e.g. go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis + simulator: + type: string + default: >- + "gnosis/eels/consume-engine", + "gnosis/eels/consume-rlp" + description: >- + Comma-separated list of simulators to test + .e.g gnosis/eels/consume-engine, gnosis/eels/consume-rlp + hive_version: + type: string + default: gnosischain/hive@master + description: GitHub repository and tag for hive (repo@tag) + client_source: + type: choice + default: docker + description: >- + How client images should be sourced. + 'git' will use the github repo and tag (See client_repos). + 'docker' will use the docker registry and tag (See client_images). + options: + - docker + - git + common_client_tag: + type: string + description: >- + If provided, this tag will be used for all clients, overriding individual tags/branches in client_repos and client_images + default: "bal-devnet-3" + client_repos: + type: string + default: | + { + "geth": "gnosischain/go-ethereum@v1.16.8-gc", + "reth": "gnosischain/reth_gnosis@master", + "nethermind": "NethermindEth/nethermind@master", + "erigon": "erigontech/erigon@main" + } + description: 'JSON object containing client versions in format {"client": "repo@tag", ...}' + client_images: + type: string + default: | + { + "geth": "ghcr.io/gnosischain/geth:latest", + "reth": "ghcr.io/gnosischain/reth_gnosis:latest", + "nethermind": "nethermind/nethermind:1.36.1", + "erigon": "erigontech/erigon:latest" + } + description: 'JSON object containing client docker images in format {"client": "registry:tag", ...}' + +env: + # Proxy + GOPROXY: "${{ vars.GOPROXY }}" + # Hive action environment variables + GCS_BUCKET: gnosis-hive-ui-staging + GCS_PATH: bal + GCS_PUBLIC_URL: https://storage.googleapis.com/gnosis-hive-ui-staging/bal + INSTALL_RCLONE_VERSION: v1.68.2 + # Flags used for all simulators + GLOBAL_EXTRA_FLAGS: >- + --client.checktimelimit=300s + --docker.buildoutput + # Docker-specific flags (only used when client_source is 'docker') + DOCKER_AUTH_FLAGS: >- + --docker.auth + # Flags used for the gnosis/eels/consume-engine simulator + EELS_ENGINE_FLAGS: >- + --sim.parallelism=6 + --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} + --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} + --sim.limit='.*(8024|7708|7778|7843|7928|7954|8037).*' + --sim.limit.exact=false + --sim.loglevel=3 + # Flags used for the gnosis/eels/consume-rlp simulator + EELS_RLP_FLAGS: >- + --sim.parallelism=6 + --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} + --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} + --sim.limit='.*(8024|7708|7778|7843|7928|7954|8037).*' + --sim.limit.exact=false + --sim.loglevel=3 + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + hive_repo: ${{ steps.client_config.outputs.hive_repo }} + hive_tag: ${{ steps.client_config.outputs.hive_tag }} + client_config: ${{ steps.client_config.outputs.client_config }} + client_source: ${{ inputs.client_source || 'git' }} + fixtures_url: ${{ steps.latest.outputs.fixtures_url }} + eels_branch: ${{ steps.latest.outputs.eels_branch }} + steps: + - name: Get latest bal fixtures and branch + id: latest + env: + GH_TOKEN: ${{ github.token }} + run: | + # Get latest bal fixtures release from EEST + TAG=$(gh release list --repo gnosischain/execution-spec-tests --json tagName --limit 100 | jq -r '[.[] | select(.tagName | startswith("bal"))][0].tagName') + FIXTURES_URL="https://github.com/gnosischain/execution-spec-tests/releases/download/${TAG}/fixtures_bal.tar.gz" + echo "fixtures_url=$FIXTURES_URL" >> "$GITHUB_OUTPUT" + echo "Using fixtures from: $FIXTURES_URL" + + # Get latest devnets/bal/N branch from EELS (highest number) + BRANCH=$(gh api repos/gnosischain/execution-specs/branches --paginate -q '.[].name' | grep -E '^devnets/bal/[0-9]+$' | sort -t/ -k3 -n | tail -1) + echo "eels_branch=$BRANCH" >> "$GITHUB_OUTPUT" + echo "Using EELS branch: $BRANCH" + + - uses: gnosischain/hive-github-action/helpers/client-config@9f65ec1bd266757a681c38d38b7fc9e341b08f0a + name: "Client config" + id: client_config + with: + client_repos: ${{ inputs.client_repos }} + client_images: ${{ inputs.client_images }} + common_client_tag: ${{ inputs.common_client_tag || 'bal-devnet-3' }} + client_source: ${{ inputs.client_source || 'git' }} + hive_version: ${{ inputs.hive_version || 'gnosischain/hive@master' }} + goproxy: ${{ env.GOPROXY }} + + test: + timeout-minutes: 2160 + needs: prepare + env: + # BAL-specific environment variables + HIVE_PARALLEL_TX_PROCESSING_DISABLED: "true" + HIVE_AMSTERDAM_TIMESTAMP: "1759250952" + # Dynamic EELS build args from prepare job + EELS_BUILD_ARG_FIXTURES: ${{ needs.prepare.outputs.fixtures_url }} + EELS_BUILD_ARG_BRANCH: ${{ needs.prepare.outputs.eels_branch }} + runs-on: >- + ${{ + matrix.simulator == 'gnosis/rpc-compat' && 'ubuntu-latest' || + contains(matrix.simulator, 'gnosis/eels/') && 'self-hosted-ghr-size-ccx33-x64' || + 'ubuntu-latest' + }} + concurrency: + group: >- + ${{ github.head_ref || inputs }}-${{ matrix.client }}-${{ matrix.simulator }}-quick + strategy: + fail-fast: false + matrix: + client: >- + ${{ fromJSON(format('[{0}]', inputs.client || ' + "go-ethereum", + "nethermind", + "nimbus-el", + "erigon", + "besu", + "reth", + "ethrex" + '))}} + # TODO: add back "ethereum/eels/consume-rlp" when clients have bal-devnet-3 branch + simulator: >- + ${{ fromJSON(format('[{0}]', inputs.simulator || ' + "gnosis/eels/consume-engine" + '))}} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: gnosischain/hive-github-action@master + with: + hive_repository: ${{ needs.prepare.outputs.hive_repo }} + hive_version: ${{ needs.prepare.outputs.hive_tag }} + client: ${{ matrix.client }} + simulator: ${{ matrix.simulator }} + client_config: ${{ needs.prepare.outputs.client_config }} + extra_flags: >- + ${{ env.GLOBAL_EXTRA_FLAGS }} + ${{ needs.prepare.outputs.client_source == 'docker' && env.DOCKER_AUTH_FLAGS || '' }} + ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} + ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} + gcs_upload: true + gcs_bucket: ${{ env.GCS_BUCKET }} + gcs_path: ${{ env.GCS_PATH }} + gcs_public_url: ${{ env.GCS_PUBLIC_URL }} + rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} + rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} + workflow_artifact_upload: true + website_upload: true \ No newline at end of file diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml new file mode 100644 index 00000000000..94470d72e97 --- /dev/null +++ b/.github/workflows/hive-generic.yaml @@ -0,0 +1,172 @@ +name: Hive - Generic +on: + workflow_dispatch: + inputs: + client: + type: string + default: '["go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"]' + description: JSON array of clients to test .e.g go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis + client_matrix: + type: choice + options: + - "true" + - "false" + default: "true" + description: If "true", run each client in a separate matrix job. If "false", run all clients together in a single job. + simulator: + type: string + # Disabled for now: devp2p, gnosis/consensus, gnosis/graphql, gnosis/rpc-compat + default: >- + [ + "gnosis/eels/consume-engine", + "gnosis/eels/consume-rlp", + "gnosis/engine" + ] + description: JSON array of simulators to test .e.g gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp + hive_version: + type: string + default: gnosischain/hive@master + description: GitHub repository and tag for hive (repo@tag) + client_source: + type: choice + description: >- + How client images should be sourced. + 'git' will use the github repo and tag (See client_config repos). + 'docker' will use the docker registry and tag (See client_config images). + options: + - docker + - git + default: git + client_config: + type: string + default: | + { + "repos": { + "geth": "gnosischain/go-ethereum@release-1.17.1-gc", + "reth": "gnosischain/reth_gnosis@master", + "nethermind": "NethermindEth/nethermind@master", + "erigon": "erigontech/erigon@main" + }, + "images": { + "geth": "ghcr.io/gnosischain/geth:latest", + "reth": "ghcr.io/gnosischain/reth_gnosis:latest", + "nethermind": "nethermind/nethermind:latest", + "erigon": "erigontech/erigon:latest" + } + } + description: 'JSON object containing client configuration with "repos" and "images" objects for git and docker sources respectively' + extra_flags: + type: string + default: "" + description: Additional flags to append to the hive command + concurrency_group: + type: string + default: "default" + description: Concurrency group for the workflow + workflow_artifact_upload: + description: "Upload test results as an workflow artifact" + required: false + default: "false" + timeout_minutes: + type: string + default: "2880" + description: "Timeout in minutes for the test job (default: 2880 = 2 days)" + + +env: + # Proxy + GOPROXY: "${{ vars.GOPROXY }}" + # Hive action environment variables + GCS_BUCKET: gnosis-hive-ui-staging + GCS_PATH: generic + GCS_PUBLIC_URL: https://storage.googleapis.com/gnosis-hive-ui-staging/generic + INSTALL_RCLONE_VERSION: v1.68.2 + EELS_BUILD_ARG_FIXTURES: https://github.com/gnosischain/execution-spec-tests/releases/download/v0.1.0/fixtures_mainnet.tar.gz + EELS_BUILD_ARG_BRANCH: forks/amsterdam + # Flags used for all simulators + GLOBAL_EXTRA_FLAGS: >- + --client.checktimelimit=180s + --sim.parallelism=4 + --docker.auth + --docker.buildoutput + # Flags used for the gnosis/eels/consume-engine simulator + EELS_ENGINE_FLAGS: >- + --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} + --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} + --sim.loglevel=3 + # Flags used for the gnosis/eels/consume-rlp simulator + EELS_RLP_FLAGS: >- + --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} + --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} + --sim.loglevel=3 + # # Flags used for the gnosis/rpc-compat simulator + # RPC_COMPAT_FLAGS: >- + # --sim.loglevel=3 + # # Flags used for the gnosis/consensus simulator + # CONSENSUS_FLAGS: >- + # --sim.loglevel=3 + # # Flags used for the gnosis/graphql simulator + # GRAPHQL_FLAGS: >- + # --sim.loglevel=3 + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + # Hive version + hive_repo: ${{ steps.client_config.outputs.hive_repo }} + hive_tag: ${{ steps.client_config.outputs.hive_tag }} + # client_config contains the YAML client config for Hive + client_config: ${{ steps.client_config.outputs.client_config }} + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 + - uses: gnosischain/hive-github-action/helpers/client-config@9f65ec1bd266757a681c38d38b7fc9e341b08f0a + name: "Client config" + id: client_config + with: + client_repos: ${{ toJSON(fromJSON(inputs.client_config).repos) }} + client_images: ${{ toJSON(fromJSON(inputs.client_config).images) }} + client_source: ${{ inputs.client_source }} + hive_version: ${{ inputs.hive_version }} + goproxy: ${{ env.GOPROXY }} + + test: + timeout-minutes: ${{ fromJSON(inputs.timeout_minutes) }} + needs: prepare + runs-on: ubuntu-latest + concurrency: + group: >- + ${{ github.head_ref || inputs.concurrency_group }}-${{ matrix.client }}-${{ matrix.simulator }} + strategy: + fail-fast: false + matrix: + client: >- + ${{ + inputs.client_matrix == 'true' && fromJSON(inputs.client) || + fromJSON(format('["{0}"]', join(fromJSON(inputs.client), '-'))) + }} + simulator: ${{ fromJSON(inputs.simulator)}} + steps: + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 + + - uses: gnosischain/hive-github-action@master + with: + hive_repository: ${{ needs.prepare.outputs.hive_repo }} + hive_version: ${{ needs.prepare.outputs.hive_tag }} + client: ${{ inputs.client_matrix == 'true' && matrix.client || join(fromJSON(inputs.client), ',') }} + simulator: ${{ matrix.simulator }} + client_config: ${{ needs.prepare.outputs.client_config }} + extra_flags: >- + ${{ env.GLOBAL_EXTRA_FLAGS }} + ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} + ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} + ${{ inputs.extra_flags }} + gcs_upload: true + gcs_bucket: ${{ env.GCS_BUCKET }} + gcs_path: ${{ env.GCS_PATH }} + gcs_public_url: ${{ env.GCS_PUBLIC_URL }} + rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} + rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} + workflow_artifact_upload: ${{ inputs.workflow_artifact_upload }} + website_upload: false + website_index_generation: false From 0557a0b43c6cc85e9e061583880946560d3aa867 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 20 Apr 2026 13:54:45 +0530 Subject: [PATCH 164/186] chore: update workflows --- .github/workflows/hive-bal.yaml | 35 +++-- .github/workflows/hive-fusaka.yaml | 200 ---------------------------- .github/workflows/hive-generic.yaml | 2 +- 3 files changed, 17 insertions(+), 220 deletions(-) delete mode 100644 .github/workflows/hive-fusaka.yaml diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml index e6d64ffe198..f37eeee73c6 100644 --- a/.github/workflows/hive-bal.yaml +++ b/.github/workflows/hive-bal.yaml @@ -34,15 +34,15 @@ on: type: string description: >- If provided, this tag will be used for all clients, overriding individual tags/branches in client_repos and client_images - default: "bal-devnet-3" + default: "" client_repos: type: string default: | { - "geth": "gnosischain/go-ethereum@v1.16.8-gc", + "geth": "gnosischain/go-ethereum@release-1.17.1-gc", "reth": "gnosischain/reth_gnosis@master", - "nethermind": "NethermindEth/nethermind@master", - "erigon": "erigontech/erigon@main" + "nethermind": "NethermindEth/nethermind@bal-devnet-3", + "erigon": "erigontech/erigon@bal-devnet-3" } description: 'JSON object containing client versions in format {"client": "repo@tag", ...}' client_images: @@ -51,8 +51,8 @@ on: { "geth": "ghcr.io/gnosischain/geth:latest", "reth": "ghcr.io/gnosischain/reth_gnosis:latest", - "nethermind": "nethermind/nethermind:1.36.1", - "erigon": "erigontech/erigon:latest" + "nethermind": "nethermind/nethermind:bal-devnet-3", + "erigon": "erigontech/erigon:bal-devnet-3" } description: 'JSON object containing client docker images in format {"client": "registry:tag", ...}' @@ -110,18 +110,18 @@ jobs: echo "fixtures_url=$FIXTURES_URL" >> "$GITHUB_OUTPUT" echo "Using fixtures from: $FIXTURES_URL" - # Get latest devnets/bal/N branch from EELS (highest number) - BRANCH=$(gh api repos/gnosischain/execution-specs/branches --paginate -q '.[].name' | grep -E '^devnets/bal/[0-9]+$' | sort -t/ -k3 -n | tail -1) + # Get devnets/bal from EELS + BRANCH="devnets/bal" echo "eels_branch=$BRANCH" >> "$GITHUB_OUTPUT" echo "Using EELS branch: $BRANCH" - - uses: gnosischain/hive-github-action/helpers/client-config@9f65ec1bd266757a681c38d38b7fc9e341b08f0a + - uses: gnosischain/hive-github-action/helpers/client-config@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa name: "Client config" id: client_config with: client_repos: ${{ inputs.client_repos }} client_images: ${{ inputs.client_images }} - common_client_tag: ${{ inputs.common_client_tag || 'bal-devnet-3' }} + common_client_tag: ${{ inputs.common_client_tag }} client_source: ${{ inputs.client_source || 'git' }} hive_version: ${{ inputs.hive_version || 'gnosischain/hive@master' }} goproxy: ${{ env.GOPROXY }} @@ -150,18 +150,15 @@ jobs: matrix: client: >- ${{ fromJSON(format('[{0}]', inputs.client || ' - "go-ethereum", - "nethermind", - "nimbus-el", - "erigon", - "besu", - "reth", - "ethrex" + "go-ethereum-gnosis", + "reth-gnosis", + "nethermind-gnosis", + "erigon-gnosis" '))}} - # TODO: add back "ethereum/eels/consume-rlp" when clients have bal-devnet-3 branch simulator: >- ${{ fromJSON(format('[{0}]', inputs.simulator || ' - "gnosis/eels/consume-engine" + "gnosis/eels/consume-engine", + "gnosis/eels/consume-rlp" '))}} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/hive-fusaka.yaml b/.github/workflows/hive-fusaka.yaml deleted file mode 100644 index 49c16dfc543..00000000000 --- a/.github/workflows/hive-fusaka.yaml +++ /dev/null @@ -1,200 +0,0 @@ -name: Hive - Gnosis (Fusaka) - -on: - schedule: - - cron: '0 0 * * *' # Run every day at 00:00 UTC - workflow_dispatch: - inputs: - client: - type: string - default: '"go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"' - description: Comma-separated list of clients to test e.g. go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis - simulator: - type: string - default: >- - "gnosis/eels/consume-engine", - "gnosis/eels/consume-rlp", - "gnosis/eels/consume-sync" - description: >- - Comma-separated list of simulators to test - e.g. gnosis/eels/consume-engine, gnosis/eels/consume-rlp, gnosis/eels/consume-sync - hive_version: - type: string - default: gnosischain/hive@master - description: GitHub repository and tag for hive (repo@tag) - client_source: - type: choice - description: >- - How client images should be sourced. - 'git' will use the github repo and tag (See client_repos). - 'docker' will use the docker registry and tag (See client_images). - options: - - docker - - git - client_repos: - type: string - default: | - { - "geth": "gnosischain/go-ethereum@v1.16.8-gc", - "reth": "gnosischain/reth_gnosis@master", - "nethermind": "NethermindEth/nethermind@master", - "erigon": "erigontech/erigon@main" - } - description: 'JSON object containing client versions in format {"client": "repo@tag", ...}' - client_images: - type: string - default: | - { - "geth": "ghcr.io/gnosischain/geth:latest", - "reth": "ghcr.io/gnosischain/reth_gnosis:latest", - "nethermind": "nethermind/nethermind:1.36.1", - "erigon": "erigontech/erigon:latest" - } - description: 'JSON object containing client docker images in format {"client": "registry:tag", ...}' - -env: - GOPROXY: "${{ vars.GOPROXY }}" - GCS_BUCKET: gnosis-hive-ui-staging - GCS_PATH: fusaka - GCS_PUBLIC_URL: https://storage.googleapis.com/gnosis-hive-ui-staging/fusaka - INSTALL_RCLONE_VERSION: v1.68.2 - EELS_BUILD_ARG_FIXTURES: https://github.com/gnosischain/execution-spec-tests/releases/download/v0.1.0/fixtures_osaka.tar.gz - EELS_BUILD_ARG_BRANCH: forks/amsterdam - # Flags used for all simulators - GLOBAL_EXTRA_FLAGS: >- - --client.checktimelimit=300s - --docker.buildoutput - # Flags used for the gnosis/eels/consume-engine simulator - EELS_ENGINE_FLAGS: >- - --sim.parallelism=6 - --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} - --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} - --sim.loglevel=3 - --sim.limit=.*Osaka.* - # Flags used for the gnosis/eels/consume-rlp simulator - EELS_RLP_FLAGS: >- - --sim.parallelism=6 - --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} - --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} - --sim.loglevel=3 - --sim.limit=.*Osaka.* - -jobs: - prepare: - runs-on: ubuntu-latest - outputs: - hive_repo: >- - ${{ - steps.client_config_schedule.outputs.hive_repo || - steps.client_config_dispatch.outputs.hive_repo - }} - hive_tag: >- - ${{ - steps.client_config_schedule.outputs.hive_tag || - steps.client_config_dispatch.outputs.hive_tag - }} - client_config: >- - ${{ - steps.client_config_schedule.outputs.client_config || - steps.client_config_dispatch.outputs.client_config - }} - steps: - - uses: gnosischain/hive-github-action/helpers/client-config@9f65ec1bd266757a681c38d38b7fc9e341b08f0a - if: github.event_name == 'schedule' - name: 'Client config: schedule' - id: client_config_schedule - with: - client_source: 'git' - hive_version: 'gnosischain/hive@master' - goproxy: ${{ env.GOPROXY }} - - - uses: gnosischain/hive-github-action/helpers/client-config@9f65ec1bd266757a681c38d38b7fc9e341b08f0a - if: github.event_name == 'workflow_dispatch' - name: 'Client config: workflow_dispatch' - id: client_config_dispatch - with: - client_repos: ${{ inputs.client_repos }} - client_images: ${{ inputs.client_images }} - client_source: ${{ inputs.client_source }} - hive_version: ${{ inputs.hive_version }} - goproxy: ${{ env.GOPROXY }} - - test: - timeout-minutes: 2160 - needs: prepare - if: >- - github.event_name == 'schedule' || - !contains(inputs.simulator, 'consume-sync') || - (contains(inputs.simulator, 'consume-engine') || contains(inputs.simulator, 'consume-rlp')) - runs-on: ubuntu-latest - concurrency: - group: >- - ${{ github.head_ref || inputs }}-${{ matrix.client }}-${{ matrix.simulator }} - strategy: - fail-fast: false - matrix: - client: >- - ${{ fromJSON(format('[{0}]', inputs.client || ' - "go-ethereum-gnosis", - "reth-gnosis", - "nethermind-gnosis", - "erigon-gnosis" - '))}} - simulator: >- - ${{ fromJSON(format('[{0}]', inputs.simulator || ' - "gnosis/eels/consume-engine", - "gnosis/eels/consume-rlp" - '))}} - exclude: - - simulator: 'gnosis/eels/consume-sync' - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: gnosischain/hive-github-action@1d88652e508626aaefa085d830ea05f422384300 - with: - hive_repository: ${{ needs.prepare.outputs.hive_repo }} - hive_version: ${{ needs.prepare.outputs.hive_tag }} - client: ${{ matrix.client }} - simulator: ${{ matrix.simulator }} - client_config: ${{ needs.prepare.outputs.client_config }} - extra_flags: >- - ${{ env.GLOBAL_EXTRA_FLAGS }} - ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} - gcs_upload: true - gcs_bucket: ${{ env.GCS_BUCKET }} - gcs_path: ${{ env.GCS_PATH }} - gcs_public_url: ${{ env.GCS_PUBLIC_URL }} - rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} - rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} - workflow_artifact_upload: true - website_upload: true - - test-consume-sync-matrix: - timeout-minutes: 2160 - needs: prepare - runs-on: ubuntu-latest - concurrency: - group: ${{ github.head_ref || inputs }}-sync-matrix - if: contains(inputs.simulator || 'gnosis/eels/consume-sync', 'gnosis/eels/consume-sync') - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: gnosischain/hive-github-action@1d88652e508626aaefa085d830ea05f422384300 - with: - hive_repository: ${{ needs.prepare.outputs.hive_repo }} - hive_version: ${{ needs.prepare.outputs.hive_tag }} - client: >- - ${{ - inputs.client || '"go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"' - }} - simulator: 'gnosis/eels/consume-sync' - client_config: ${{ needs.prepare.outputs.client_config }} - extra_flags: >- - ${{ env.GLOBAL_EXTRA_FLAGS }} - gcs_upload: true - gcs_bucket: ${{ env.GCS_BUCKET }} - gcs_path: ${{ env.GCS_PATH }} - gcs_public_url: ${{ env.GCS_PUBLIC_URL }} - rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} - rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} - workflow_artifact_upload: true - website_upload: true diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 94470d72e97..cefb734073b 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -120,7 +120,7 @@ jobs: client_config: ${{ steps.client_config.outputs.client_config }} steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - - uses: gnosischain/hive-github-action/helpers/client-config@9f65ec1bd266757a681c38d38b7fc9e341b08f0a + - uses: gnosischain/hive-github-action/helpers/client-config@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa name: "Client config" id: client_config with: From 16cc98957e144803c5997aaf5ebdf3821b26a30d Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 15:41:48 +0530 Subject: [PATCH 165/186] chore: add rpc-compat simulator to hive generic workflow --- .github/workflows/hive-generic.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index cefb734073b..02f8e3a62a1 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -15,12 +15,13 @@ on: description: If "true", run each client in a separate matrix job. If "false", run all clients together in a single job. simulator: type: string - # Disabled for now: devp2p, gnosis/consensus, gnosis/graphql, gnosis/rpc-compat + # Disabled for now: devp2p, gnosis/consensus, gnosis/graphql default: >- [ "gnosis/eels/consume-engine", "gnosis/eels/consume-rlp", - "gnosis/engine" + "gnosis/engine", + "gnosis/rpc-compat" ] description: JSON array of simulators to test .e.g gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp hive_version: @@ -99,9 +100,9 @@ env: --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} --sim.loglevel=3 - # # Flags used for the gnosis/rpc-compat simulator - # RPC_COMPAT_FLAGS: >- - # --sim.loglevel=3 + # Flags used for the gnosis/rpc-compat simulator + RPC_COMPAT_FLAGS: >- + --sim.loglevel=3 # # Flags used for the gnosis/consensus simulator # CONSENSUS_FLAGS: >- # --sim.loglevel=3 @@ -160,6 +161,8 @@ jobs: ${{ env.GLOBAL_EXTRA_FLAGS }} ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} + ${{ matrix.simulator == 'gnosis/engine' && env.ENGINE_FLAGS || '' }} + ${{ matrix.simulator == 'gnosis/rpc-compat' && env.RPC_COMPAT_FLAGS || '' }} ${{ inputs.extra_flags }} gcs_upload: true gcs_bucket: ${{ env.GCS_BUCKET }} From c3b495019ba0c22b7f4491bc87ff9413bc1b6315 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 18:22:58 +0530 Subject: [PATCH 166/186] chore: update fixtures url --- .github/workflows/hive-generic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 02f8e3a62a1..2161077a621 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -82,7 +82,7 @@ env: GCS_PATH: generic GCS_PUBLIC_URL: https://storage.googleapis.com/gnosis-hive-ui-staging/generic INSTALL_RCLONE_VERSION: v1.68.2 - EELS_BUILD_ARG_FIXTURES: https://github.com/gnosischain/execution-spec-tests/releases/download/v0.1.0/fixtures_mainnet.tar.gz + EELS_BUILD_ARG_FIXTURES: https://github.com/gnosischain/execution-spec-tests/releases/download/mainnet@v0.1.0/fixtures_mainnet.tar.gz EELS_BUILD_ARG_BRANCH: forks/amsterdam # Flags used for all simulators GLOBAL_EXTRA_FLAGS: >- From b9c81deff1fecf3642fc987d49238f4047961979 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 18:35:12 +0530 Subject: [PATCH 167/186] chore: fix lint issue --- packages/testing/src/execution_testing/forks/forks/forks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index 7da3e93d683..41fbea35954 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -1475,7 +1475,6 @@ class Paris( pass - class Shanghai( eips.EIP3855, eips.EIP3860, From 5b13bd08c561ed90f8d644f7ba96f3c1e3c16a6f Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Wed, 22 Apr 2026 18:39:41 +0530 Subject: [PATCH 168/186] chore: minor fixes --- .github/workflows/hive-bal.yaml | 3 +-- .github/workflows/hive-generic.yaml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml index f37eeee73c6..4b909b30d5d 100644 --- a/.github/workflows/hive-bal.yaml +++ b/.github/workflows/hive-bal.yaml @@ -15,7 +15,7 @@ on: "gnosis/eels/consume-rlp" description: >- Comma-separated list of simulators to test - .e.g gnosis/eels/consume-engine, gnosis/eels/consume-rlp + e.g. gnosis/eels/consume-engine, gnosis/eels/consume-rlp hive_version: type: string default: gnosischain/hive@master @@ -162,7 +162,6 @@ jobs: '))}} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: gnosischain/hive-github-action@master with: hive_repository: ${{ needs.prepare.outputs.hive_repo }} diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 2161077a621..9b76681625a 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -23,7 +23,7 @@ on: "gnosis/engine", "gnosis/rpc-compat" ] - description: JSON array of simulators to test .e.g gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp + description: JSON array of simulators to test e.g. gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp hive_version: type: string default: gnosischain/hive@master @@ -149,7 +149,6 @@ jobs: simulator: ${{ fromJSON(inputs.simulator)}} steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - - uses: gnosischain/hive-github-action@master with: hive_repository: ${{ needs.prepare.outputs.hive_repo }} From 6ec10c5cbca59a1cb331c548634de29133b1ab9e Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 23 Apr 2026 00:05:16 +0530 Subject: [PATCH 169/186] chore: update sha pinned action --- .github/workflows/hive-bal.yaml | 2 +- .github/workflows/hive-generic.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml index 4b909b30d5d..010207fa886 100644 --- a/.github/workflows/hive-bal.yaml +++ b/.github/workflows/hive-bal.yaml @@ -162,7 +162,7 @@ jobs: '))}} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: gnosischain/hive-github-action@master + - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa with: hive_repository: ${{ needs.prepare.outputs.hive_repo }} hive_version: ${{ needs.prepare.outputs.hive_tag }} diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 9b76681625a..d2555acea36 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -149,7 +149,7 @@ jobs: simulator: ${{ fromJSON(inputs.simulator)}} steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - - uses: gnosischain/hive-github-action@master + - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa with: hive_repository: ${{ needs.prepare.outputs.hive_repo }} hive_version: ${{ needs.prepare.outputs.hive_tag }} From b49a4f99aaac77b25b592809bed3a5fcbbb471b3 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 23 Apr 2026 14:12:02 +0530 Subject: [PATCH 170/186] chore: update branch for geth --- .github/workflows/hive-generic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index d2555acea36..73aecf20db6 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -43,7 +43,7 @@ on: default: | { "repos": { - "geth": "gnosischain/go-ethereum@release-1.17.1-gc", + "geth": "gnosischain/go-ethereum@release-1.17.2-gc", "reth": "gnosischain/reth_gnosis@master", "nethermind": "NethermindEth/nethermind@master", "erigon": "erigontech/erigon@main" From c02bf3a675e6bb48874bfb79c9890b3854b2e32e Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 23 Apr 2026 14:18:02 +0530 Subject: [PATCH 171/186] chore: remove rpc-compat simulator --- .github/workflows/hive-generic.yaml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 73aecf20db6..53fb4fa1006 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -15,13 +15,12 @@ on: description: If "true", run each client in a separate matrix job. If "false", run all clients together in a single job. simulator: type: string - # Disabled for now: devp2p, gnosis/consensus, gnosis/graphql + # Disabled for now: devp2p, gnosis/consensus, gnosis/graphql, gnosis/rpc-compat default: >- [ "gnosis/eels/consume-engine", "gnosis/eels/consume-rlp", "gnosis/engine", - "gnosis/rpc-compat" ] description: JSON array of simulators to test e.g. gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp hive_version: @@ -100,9 +99,9 @@ env: --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} --sim.loglevel=3 - # Flags used for the gnosis/rpc-compat simulator - RPC_COMPAT_FLAGS: >- - --sim.loglevel=3 + # # Flags used for the gnosis/rpc-compat simulator + # RPC_COMPAT_FLAGS: >- + # --sim.loglevel=3 # # Flags used for the gnosis/consensus simulator # CONSENSUS_FLAGS: >- # --sim.loglevel=3 @@ -161,7 +160,6 @@ jobs: ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} ${{ matrix.simulator == 'gnosis/engine' && env.ENGINE_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/rpc-compat' && env.RPC_COMPAT_FLAGS || '' }} ${{ inputs.extra_flags }} gcs_upload: true gcs_bucket: ${{ env.GCS_BUCKET }} From 92cedc6c0f9b8d2ee4e162d4b670b8e85da0cd95 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 23 Apr 2026 14:18:56 +0530 Subject: [PATCH 172/186] chore: fix lint issue --- .github/workflows/hive-generic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 53fb4fa1006..136084a9049 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -20,7 +20,7 @@ on: [ "gnosis/eels/consume-engine", "gnosis/eels/consume-rlp", - "gnosis/engine", + "gnosis/engine" ] description: JSON array of simulators to test e.g. gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp hive_version: From 68b13ca836d1c58aa87f2f49aadf6793e8d40fb8 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Thu, 23 Apr 2026 17:24:07 +0530 Subject: [PATCH 173/186] chore: enable website upload --- .github/workflows/hive-generic.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 136084a9049..361d057b339 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -168,5 +168,5 @@ jobs: rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} workflow_artifact_upload: ${{ inputs.workflow_artifact_upload }} - website_upload: false - website_index_generation: false + website_upload: true + website_index_generation: true From 06ab9879652ff50305e2545795a370418a401608 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 00:02:31 +0530 Subject: [PATCH 174/186] chore: update parallelism --- .github/workflows/hive-generic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 361d057b339..52bed93f041 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -86,7 +86,7 @@ env: # Flags used for all simulators GLOBAL_EXTRA_FLAGS: >- --client.checktimelimit=180s - --sim.parallelism=4 + --sim.parallelism=2 --docker.auth --docker.buildoutput # Flags used for the gnosis/eels/consume-engine simulator From 9592ff5058c67ad9ea6e95339295bdde800bd000 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 00:22:55 +0530 Subject: [PATCH 175/186] chore: introduce free disk space --- .github/workflows/hive-generic.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 52bed93f041..f8c9a9fc272 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -147,6 +147,16 @@ jobs: }} simulator: ${{ fromJSON(inputs.simulator)}} steps: + - name: Free disk space + uses: jlumbroso/free-disk-space@main + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + swap-storage: true + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa with: From b4030d2bbf457e70b969debb3c7e1f54eb12a732 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 12:46:38 +0530 Subject: [PATCH 176/186] chore: remove gnosis engine simulator --- .github/workflows/hive-generic.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index f8c9a9fc272..6d14756b56c 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -19,8 +19,7 @@ on: default: >- [ "gnosis/eels/consume-engine", - "gnosis/eels/consume-rlp", - "gnosis/engine" + "gnosis/eels/consume-rlp" ] description: JSON array of simulators to test e.g. gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp hive_version: @@ -169,7 +168,6 @@ jobs: ${{ env.GLOBAL_EXTRA_FLAGS }} ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/engine' && env.ENGINE_FLAGS || '' }} ${{ inputs.extra_flags }} gcs_upload: true gcs_bucket: ${{ env.GCS_BUCKET }} From d8306f0ca2584bb8ccaed1efde81903a9c6140ac Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 13:05:13 +0530 Subject: [PATCH 177/186] chore: fix disk issue --- .github/workflows/hive-generic.yaml | 42 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 6d14756b56c..3f9513ee50c 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -85,7 +85,7 @@ env: # Flags used for all simulators GLOBAL_EXTRA_FLAGS: >- --client.checktimelimit=180s - --sim.parallelism=2 + --sim.parallelism=1 --docker.auth --docker.buildoutput # Flags used for the gnosis/eels/consume-engine simulator @@ -144,18 +144,36 @@ jobs: inputs.client_matrix == 'true' && fromJSON(inputs.client) || fromJSON(format('["{0}"]', join(fromJSON(inputs.client), '-'))) }} - simulator: ${{ fromJSON(inputs.simulator)}} + simulator: ${{ fromJSON(inputs.simulator) }} steps: - - name: Free disk space - uses: jlumbroso/free-disk-space@main - with: - tool-cache: false - android: true - dotnet: true - haskell: true - large-packages: true - swap-storage: true - + - name: Relocate Docker to /mnt & free root disk + run: | + echo "=== Disk before ===" + df -h + + # Free root partition + sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \ + /usr/local/share/boost /usr/lib/jvm \ + /usr/share/swift /usr/local/.ghcup + sudo apt-get clean -y + sudo apt-get autoremove -y + + echo "=== Disk after cleanup ===" + df -h + + # Stop Docker, move data root to /mnt (~70GB available) + sudo systemctl stop docker + sudo mkdir -p /mnt/docker + echo '{"data-root": "/mnt/docker"}' | sudo tee /etc/docker/daemon.json + sudo systemctl start docker + sudo systemctl is-active docker + + echo "=== Docker root dir ===" + docker info | grep "Docker Root Dir" + + echo "=== Disk after Docker relocation ===" + df -h + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa with: From 8f0fee212f68fc21ccd4049fcc9969f555c7f89f Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 13:48:06 +0530 Subject: [PATCH 178/186] chore: fix workflow --- .github/workflows/hive-generic.yaml | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 3f9513ee50c..29c4a7e84f8 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -138,6 +138,7 @@ jobs: ${{ github.head_ref || inputs.concurrency_group }}-${{ matrix.client }}-${{ matrix.simulator }} strategy: fail-fast: false + max-parallel: 2 matrix: client: >- ${{ @@ -146,33 +147,15 @@ jobs: }} simulator: ${{ fromJSON(inputs.simulator) }} steps: - - name: Relocate Docker to /mnt & free root disk + - name: Relocate Docker to /mnt run: | - echo "=== Disk before ===" - df -h - - # Free root partition - sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \ - /usr/local/share/boost /usr/lib/jvm \ - /usr/share/swift /usr/local/.ghcup - sudo apt-get clean -y - sudo apt-get autoremove -y - - echo "=== Disk after cleanup ===" - df -h - - # Stop Docker, move data root to /mnt (~70GB available) + echo "=== Disk before ===" && df -h sudo systemctl stop docker sudo mkdir -p /mnt/docker echo '{"data-root": "/mnt/docker"}' | sudo tee /etc/docker/daemon.json sudo systemctl start docker - sudo systemctl is-active docker - - echo "=== Docker root dir ===" - docker info | grep "Docker Root Dir" - - echo "=== Disk after Docker relocation ===" - df -h + echo "=== Docker Root ===" && docker info | grep "Docker Root Dir" + echo "=== Disk after ===" && df -h - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa From 9b9a2a8c22e5829090b5461f07231918d34634c1 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 15:40:12 +0530 Subject: [PATCH 179/186] chore: add trie file for amsterdam --- src/ethereum/forks/amsterdam/trie.py | 460 +++++++++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 src/ethereum/forks/amsterdam/trie.py diff --git a/src/ethereum/forks/amsterdam/trie.py b/src/ethereum/forks/amsterdam/trie.py new file mode 100644 index 00000000000..bf5ee0d6c43 --- /dev/null +++ b/src/ethereum/forks/amsterdam/trie.py @@ -0,0 +1,460 @@ +""" +State Trie. + +.. contents:: Table of Contents + :backlinks: none + :local: + +Introduction +------------ + +The state trie is the structure responsible for storing +`.fork_types.Account` objects. +""" + +import copy +from dataclasses import dataclass, field +from typing import ( + Callable, + Dict, + Generic, + List, + Mapping, + MutableMapping, + Optional, + Sequence, + Tuple, + TypeVar, + cast, +) + +from ethereum_rlp import Extended, rlp +from ethereum_types.bytes import Bytes +from ethereum_types.numeric import U256, Uint +from typing_extensions import assert_type + +from ethereum.crypto.hash import keccak256 +from ethereum.forks.bpo5 import trie as previous_trie +from ethereum.state import ( + Account, + Address, + BranchNode, + BranchSubnodes, + ExtensionNode, + InternalNode, + LeafNode, + Root, +) +from ethereum.utils.hexadecimal import hex_to_bytes + +from .blocks import Receipt, Withdrawal +from .fork_types import encode_account +from .transactions import LegacyTransaction + +# note: an empty trie (regardless of whether it is secured) has root: +# +# keccak256(RLP(b'')) +# == +# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 +# +# also: +# +# keccak256(RLP(())) +# == +# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 +# +# which is the sha3Uncles hash in block header with no uncles +EMPTY_TRIE_ROOT = Root( + hex_to_bytes( + "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + ) +) + +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal +K = TypeVar("K", bound=Bytes) +V = TypeVar( + "V", + Optional[Account], + Optional[Bytes], + Bytes, + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], + Optional[Withdrawal | Bytes], + Uint, + U256, +) + + +def encode_internal_node(node: Optional[InternalNode]) -> Extended: + """ + Encodes a Merkle Trie node into its RLP form. The RLP will then be + serialized into a `Bytes` object and hashed unless it is less than 32 bytes + when serialized. + + This function also accepts `None`, representing the absence of a node, + which is encoded to `b""`. + + Parameters + ---------- + node : Optional[InternalNode] + The node to encode. + + Returns + ------- + encoded : `Extended` + The node encoded as RLP. + + """ + unencoded: Extended + if node is None: + unencoded = b"" + elif isinstance(node, LeafNode): + unencoded = ( + nibble_list_to_compact(node.rest_of_key, True), + node.value, + ) + elif isinstance(node, ExtensionNode): + unencoded = ( + nibble_list_to_compact(node.key_segment, False), + node.subnode, + ) + elif isinstance(node, BranchNode): + unencoded = list(node.subnodes) + [node.value] + else: + raise AssertionError(f"Invalid internal node type {type(node)}!") + + encoded = rlp.encode(unencoded) + if len(encoded) < 32: + return unencoded + else: + return keccak256(encoded) + + +def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: + """ + Encode a Node for storage in the Merkle Trie. + """ + if isinstance(node, Account): + assert storage_root is not None + return encode_account(node, storage_root) + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): + return rlp.encode(node) + elif isinstance(node, Bytes): + return node + else: + return previous_trie.encode_node(node, storage_root) + + +@dataclass +class Trie(Generic[K, V]): + """ + The Merkle Trie. + """ + + secured: bool + default: V + _data: Dict[K, V] = field(default_factory=dict) + + +def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: + """ + Create a copy of `trie`. Since only frozen objects may be stored in tries, + the contents are reused. + + Parameters + ---------- + trie: `Trie` + Trie to copy. + + Returns + ------- + new_trie : `Trie[K, V]` + A copy of the trie. + + """ + return Trie(trie.secured, trie.default, copy.copy(trie._data)) + + +def trie_set(trie: Trie[K, V], key: K, value: V) -> None: + """ + Stores an item in a Merkle Trie. + + This method deletes the key if `value == trie.default`, because the Merkle + Trie represents the default value by omitting it from the trie. + + Parameters + ---------- + trie: `Trie` + Trie to store in. + key : `Bytes` + Key to lookup. + value : `V` + Node to insert at `key`. + + """ + if value == trie.default: + if key in trie._data: + del trie._data[key] + else: + trie._data[key] = value + + +def trie_get(trie: Trie[K, V], key: K) -> V: + """ + Gets an item from the Merkle Trie. + + This method returns `trie.default` if the key is missing. + + Parameters + ---------- + trie: + Trie to lookup in. + key : + Key to lookup. + + Returns + ------- + node : `V` + Node at `key` in the trie. + + """ + return trie._data.get(key, trie.default) + + +def common_prefix_length(a: Sequence, b: Sequence) -> int: + """ + Find the longest common prefix of two sequences. + """ + for i in range(len(a)): + if i >= len(b) or a[i] != b[i]: + return i + return len(a) + + +def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: + """ + Compresses nibble-list into a standard byte array with a flag. + + A nibble-list is a list of byte values no greater than `15`. The flag is + encoded in high nibble of the highest byte. The flag nibble can be broken + down into two two-bit flags. + + Highest nibble:: + + +---+---+----------+--------+ + | _ | _ | is_leaf | parity | + +---+---+----------+--------+ + 3 2 1 0 + + + The lowest bit of the nibble encodes the parity of the length of the + remaining nibbles -- `0` when even and `1` when odd. The second lowest bit + is used to distinguish leaf and extension nodes. The other two bits are not + used. + + Parameters + ---------- + x : + Array of nibbles. + is_leaf : + True if this is part of a leaf node, or false if it is an extension + node. + + Returns + ------- + compressed : `bytearray` + Compact byte array. + + """ + compact = bytearray() + + if len(x) % 2 == 0: # ie even length + compact.append(16 * (2 * is_leaf)) + for i in range(0, len(x), 2): + compact.append(16 * x[i] + x[i + 1]) + else: + compact.append(16 * ((2 * is_leaf) + 1) + x[0]) + for i in range(1, len(x), 2): + compact.append(16 * x[i] + x[i + 1]) + + return Bytes(compact) + + +def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: + """ + Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). + + Parameters + ---------- + bytes_: + The `Bytes` to convert. + + Returns + ------- + nibble_list : `Bytes` + The `Bytes` in nibble-list format. + + """ + nibble_list = bytearray(2 * len(bytes_)) + for byte_index, byte in enumerate(bytes_): + nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 + nibble_list[byte_index * 2 + 1] = byte & 0x0F + return Bytes(nibble_list) + + +def _prepare_trie( + trie: Trie[K, V], + get_storage_root: Optional[Callable[[Address], Root]] = None, +) -> Mapping[Bytes, Bytes]: + """ + Prepares the trie for root calculation. Removes values that are empty, + hashes the keys (if `secured == True`) and encodes all the nodes. + + Parameters + ---------- + trie : + The `Trie` to prepare. + get_storage_root : + Function to get the storage root of an account. Needed to encode + `Account` objects. + + Returns + ------- + out : `Mapping[ethereum.base_types.Bytes, Node]` + Object with keys mapped to nibble-byte form. + + """ + mapped: MutableMapping[Bytes, Bytes] = {} + + for preimage, value in trie._data.items(): + if isinstance(value, Account): + assert get_storage_root is not None + address = Address(preimage) + encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") + else: + encoded_value = encode_node(value) + if encoded_value == b"": + raise AssertionError + key: Bytes + if trie.secured: + # "secure" tries hash keys once before construction + key = keccak256(preimage) + else: + key = preimage + mapped[bytes_to_nibble_list(key)] = encoded_value + + return mapped + + +def root( + trie: Trie[K, V], + get_storage_root: Optional[Callable[[Address], Root]] = None, +) -> Root: + """ + Computes the root of a modified merkle patricia trie (MPT). + + Parameters + ---------- + trie : + `Trie` to get the root of. + get_storage_root : + Function to get the storage root of an account. Needed to encode + `Account` objects. + + + Returns + ------- + root : `.fork_types.Root` + MPT root of the underlying key-value pairs. + + """ + obj = _prepare_trie(trie, get_storage_root) + + root_node = encode_internal_node(patricialize(obj, Uint(0))) + if len(rlp.encode(root_node)) < 32: + return keccak256(rlp.encode(root_node)) + else: + assert isinstance(root_node, Bytes) + return Root(root_node) + + +def patricialize( + obj: Mapping[Bytes, Bytes], level: Uint +) -> Optional[InternalNode]: + """ + Structural composition function. + + Used to recursively patricialize and merkleize a dictionary. Includes + memoization of the tree structure and hashes. + + Parameters + ---------- + obj : + Underlying trie key-value pairs, with keys in nibble-list format. + level : + Current trie level. + + Returns + ------- + node : `ethereum.base_types.Bytes` + Root node of `obj`. + + """ + if len(obj) == 0: + return None + + arbitrary_key = next(iter(obj)) + + # if leaf node + if len(obj) == 1: + leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) + return leaf + + # prepare for extension node check by finding max j such that all keys in + # obj have the same key[i:j] + substring = arbitrary_key[level:] + prefix_length = len(substring) + for key in obj: + prefix_length = min( + prefix_length, common_prefix_length(substring, key[level:]) + ) + + # finished searching, found another key at the current level + if prefix_length == 0: + break + + # if extension node + if prefix_length > 0: + prefix = arbitrary_key[int(level) : int(level) + prefix_length] + return ExtensionNode( + prefix, + encode_internal_node( + patricialize(obj, level + Uint(prefix_length)) + ), + ) + + branches: List[MutableMapping[Bytes, Bytes]] = [] + for _ in range(16): + branches.append({}) + value = b"" + for key in obj: + if len(key) == level: + # shouldn't ever have an account or receipt in an internal node + if isinstance(obj[key], (Account, Receipt, Uint)): + raise AssertionError + value = obj[key] + else: + branches[key[level]][key] = obj[key] + + subnodes = tuple( + encode_internal_node(patricialize(branches[k], level + Uint(1))) + for k in range(16) + ) + return BranchNode( + cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), + value, + ) From 1cc02b6c03091f2ae9106e62e2a66e710eff9f27 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 18:17:55 +0530 Subject: [PATCH 180/186] chore: correct generic workflow --- .github/workflows/hive-generic.yaml | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml index 29c4a7e84f8..186ba7f7320 100644 --- a/.github/workflows/hive-generic.yaml +++ b/.github/workflows/hive-generic.yaml @@ -5,7 +5,7 @@ on: client: type: string default: '["go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"]' - description: JSON array of clients to test .e.g go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis + description: JSON array of clients to test e.g. go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis client_matrix: type: choice options: @@ -85,9 +85,11 @@ env: # Flags used for all simulators GLOBAL_EXTRA_FLAGS: >- --client.checktimelimit=180s - --sim.parallelism=1 - --docker.auth + --sim.parallelism=4 --docker.buildoutput + # Docker-specific flags (only used when client_source is 'docker') + DOCKER_AUTH_FLAGS: >- + --docker.auth # Flags used for the gnosis/eels/consume-engine simulator EELS_ENGINE_FLAGS: >- --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} @@ -117,6 +119,7 @@ jobs: hive_tag: ${{ steps.client_config.outputs.hive_tag }} # client_config contains the YAML client config for Hive client_config: ${{ steps.client_config.outputs.client_config }} + client_source: ${{ inputs.client_source || 'git' }} steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - uses: gnosischain/hive-github-action/helpers/client-config@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa @@ -138,7 +141,6 @@ jobs: ${{ github.head_ref || inputs.concurrency_group }}-${{ matrix.client }}-${{ matrix.simulator }} strategy: fail-fast: false - max-parallel: 2 matrix: client: >- ${{ @@ -147,16 +149,6 @@ jobs: }} simulator: ${{ fromJSON(inputs.simulator) }} steps: - - name: Relocate Docker to /mnt - run: | - echo "=== Disk before ===" && df -h - sudo systemctl stop docker - sudo mkdir -p /mnt/docker - echo '{"data-root": "/mnt/docker"}' | sudo tee /etc/docker/daemon.json - sudo systemctl start docker - echo "=== Docker Root ===" && docker info | grep "Docker Root Dir" - echo "=== Disk after ===" && df -h - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa with: @@ -167,6 +159,7 @@ jobs: client_config: ${{ needs.prepare.outputs.client_config }} extra_flags: >- ${{ env.GLOBAL_EXTRA_FLAGS }} + ${{ needs.prepare.outputs.client_source == 'docker' && env.DOCKER_AUTH_FLAGS || '' }} ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} ${{ inputs.extra_flags }} From cef409ab3ff7c9dafefbd0dce48d3adb69210188 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Fri, 24 Apr 2026 18:20:59 +0530 Subject: [PATCH 181/186] chore: correct bal hive workflow --- .github/workflows/hive-bal.yaml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml index 010207fa886..21a02482ad8 100644 --- a/.github/workflows/hive-bal.yaml +++ b/.github/workflows/hive-bal.yaml @@ -22,7 +22,7 @@ on: description: GitHub repository and tag for hive (repo@tag) client_source: type: choice - default: docker + default: git description: >- How client images should be sourced. 'git' will use the github repo and tag (See client_repos). @@ -30,19 +30,14 @@ on: options: - docker - git - common_client_tag: - type: string - description: >- - If provided, this tag will be used for all clients, overriding individual tags/branches in client_repos and client_images - default: "" client_repos: type: string default: | { - "geth": "gnosischain/go-ethereum@release-1.17.1-gc", + "geth": "gnosischain/go-ethereum@release-1.17.2-gc", "reth": "gnosischain/reth_gnosis@master", - "nethermind": "NethermindEth/nethermind@bal-devnet-3", - "erigon": "erigontech/erigon@bal-devnet-3" + "nethermind": "NethermindEth/nethermind@bal-devnet-4", + "erigon": "erigontech/erigon@bal-devnet-4" } description: 'JSON object containing client versions in format {"client": "repo@tag", ...}' client_images: @@ -51,8 +46,8 @@ on: { "geth": "ghcr.io/gnosischain/geth:latest", "reth": "ghcr.io/gnosischain/reth_gnosis:latest", - "nethermind": "nethermind/nethermind:bal-devnet-3", - "erigon": "erigontech/erigon:bal-devnet-3" + "nethermind": "nethermind/nethermind:latest", + "erigon": "erigontech/erigon:latest" } description: 'JSON object containing client docker images in format {"client": "registry:tag", ...}' @@ -181,4 +176,4 @@ jobs: rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} workflow_artifact_upload: true - website_upload: true \ No newline at end of file + website_upload: true From aedac108ec53291e08eb97446ce23566a12c196f Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 27 Apr 2026 14:20:27 +0530 Subject: [PATCH 182/186] Revert "chore: add trie file for amsterdam" This reverts commit 9fdadc80bba1f25013138cf3b3977fd8df474a6c. --- src/ethereum/forks/amsterdam/trie.py | 460 --------------------------- 1 file changed, 460 deletions(-) delete mode 100644 src/ethereum/forks/amsterdam/trie.py diff --git a/src/ethereum/forks/amsterdam/trie.py b/src/ethereum/forks/amsterdam/trie.py deleted file mode 100644 index bf5ee0d6c43..00000000000 --- a/src/ethereum/forks/amsterdam/trie.py +++ /dev/null @@ -1,460 +0,0 @@ -""" -State Trie. - -.. contents:: Table of Contents - :backlinks: none - :local: - -Introduction ------------- - -The state trie is the structure responsible for storing -`.fork_types.Account` objects. -""" - -import copy -from dataclasses import dataclass, field -from typing import ( - Callable, - Dict, - Generic, - List, - Mapping, - MutableMapping, - Optional, - Sequence, - Tuple, - TypeVar, - cast, -) - -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - -from ethereum.crypto.hash import keccak256 -from ethereum.forks.bpo5 import trie as previous_trie -from ethereum.state import ( - Account, - Address, - BranchNode, - BranchSubnodes, - ExtensionNode, - InternalNode, - LeafNode, - Root, -) -from ethereum.utils.hexadecimal import hex_to_bytes - -from .blocks import Receipt, Withdrawal -from .fork_types import encode_account -from .transactions import LegacyTransaction - -# note: an empty trie (regardless of whether it is secured) has root: -# -# keccak256(RLP(b'')) -# == -# 56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 # noqa: E501 -# -# also: -# -# keccak256(RLP(())) -# == -# 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 # noqa: E501 -# -# which is the sha3Uncles hash in block header with no uncles -EMPTY_TRIE_ROOT = Root( - hex_to_bytes( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - ) -) - -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal -K = TypeVar("K", bound=Bytes) -V = TypeVar( - "V", - Optional[Account], - Optional[Bytes], - Bytes, - Optional[LegacyTransaction | Bytes], - Optional[Receipt | Bytes], - Optional[Withdrawal | Bytes], - Uint, - U256, -) - - -def encode_internal_node(node: Optional[InternalNode]) -> Extended: - """ - Encodes a Merkle Trie node into its RLP form. The RLP will then be - serialized into a `Bytes` object and hashed unless it is less than 32 bytes - when serialized. - - This function also accepts `None`, representing the absence of a node, - which is encoded to `b""`. - - Parameters - ---------- - node : Optional[InternalNode] - The node to encode. - - Returns - ------- - encoded : `Extended` - The node encoded as RLP. - - """ - unencoded: Extended - if node is None: - unencoded = b"" - elif isinstance(node, LeafNode): - unencoded = ( - nibble_list_to_compact(node.rest_of_key, True), - node.value, - ) - elif isinstance(node, ExtensionNode): - unencoded = ( - nibble_list_to_compact(node.key_segment, False), - node.subnode, - ) - elif isinstance(node, BranchNode): - unencoded = list(node.subnodes) + [node.value] - else: - raise AssertionError(f"Invalid internal node type {type(node)}!") - - encoded = rlp.encode(unencoded) - if len(encoded) < 32: - return unencoded - else: - return keccak256(encoded) - - -def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: - """ - Encode a Node for storage in the Merkle Trie. - """ - if isinstance(node, Account): - assert storage_root is not None - return encode_account(node, storage_root) - elif isinstance( - node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) - ): - return rlp.encode(node) - elif isinstance(node, Bytes): - return node - else: - return previous_trie.encode_node(node, storage_root) - - -@dataclass -class Trie(Generic[K, V]): - """ - The Merkle Trie. - """ - - secured: bool - default: V - _data: Dict[K, V] = field(default_factory=dict) - - -def copy_trie(trie: Trie[K, V]) -> Trie[K, V]: - """ - Create a copy of `trie`. Since only frozen objects may be stored in tries, - the contents are reused. - - Parameters - ---------- - trie: `Trie` - Trie to copy. - - Returns - ------- - new_trie : `Trie[K, V]` - A copy of the trie. - - """ - return Trie(trie.secured, trie.default, copy.copy(trie._data)) - - -def trie_set(trie: Trie[K, V], key: K, value: V) -> None: - """ - Stores an item in a Merkle Trie. - - This method deletes the key if `value == trie.default`, because the Merkle - Trie represents the default value by omitting it from the trie. - - Parameters - ---------- - trie: `Trie` - Trie to store in. - key : `Bytes` - Key to lookup. - value : `V` - Node to insert at `key`. - - """ - if value == trie.default: - if key in trie._data: - del trie._data[key] - else: - trie._data[key] = value - - -def trie_get(trie: Trie[K, V], key: K) -> V: - """ - Gets an item from the Merkle Trie. - - This method returns `trie.default` if the key is missing. - - Parameters - ---------- - trie: - Trie to lookup in. - key : - Key to lookup. - - Returns - ------- - node : `V` - Node at `key` in the trie. - - """ - return trie._data.get(key, trie.default) - - -def common_prefix_length(a: Sequence, b: Sequence) -> int: - """ - Find the longest common prefix of two sequences. - """ - for i in range(len(a)): - if i >= len(b) or a[i] != b[i]: - return i - return len(a) - - -def nibble_list_to_compact(x: Bytes, is_leaf: bool) -> Bytes: - """ - Compresses nibble-list into a standard byte array with a flag. - - A nibble-list is a list of byte values no greater than `15`. The flag is - encoded in high nibble of the highest byte. The flag nibble can be broken - down into two two-bit flags. - - Highest nibble:: - - +---+---+----------+--------+ - | _ | _ | is_leaf | parity | - +---+---+----------+--------+ - 3 2 1 0 - - - The lowest bit of the nibble encodes the parity of the length of the - remaining nibbles -- `0` when even and `1` when odd. The second lowest bit - is used to distinguish leaf and extension nodes. The other two bits are not - used. - - Parameters - ---------- - x : - Array of nibbles. - is_leaf : - True if this is part of a leaf node, or false if it is an extension - node. - - Returns - ------- - compressed : `bytearray` - Compact byte array. - - """ - compact = bytearray() - - if len(x) % 2 == 0: # ie even length - compact.append(16 * (2 * is_leaf)) - for i in range(0, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - else: - compact.append(16 * ((2 * is_leaf) + 1) + x[0]) - for i in range(1, len(x), 2): - compact.append(16 * x[i] + x[i + 1]) - - return Bytes(compact) - - -def bytes_to_nibble_list(bytes_: Bytes) -> Bytes: - """ - Converts a `Bytes` into to a sequence of nibbles (bytes with value < 16). - - Parameters - ---------- - bytes_: - The `Bytes` to convert. - - Returns - ------- - nibble_list : `Bytes` - The `Bytes` in nibble-list format. - - """ - nibble_list = bytearray(2 * len(bytes_)) - for byte_index, byte in enumerate(bytes_): - nibble_list[byte_index * 2] = (byte & 0xF0) >> 4 - nibble_list[byte_index * 2 + 1] = byte & 0x0F - return Bytes(nibble_list) - - -def _prepare_trie( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Mapping[Bytes, Bytes]: - """ - Prepares the trie for root calculation. Removes values that are empty, - hashes the keys (if `secured == True`) and encodes all the nodes. - - Parameters - ---------- - trie : - The `Trie` to prepare. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - Returns - ------- - out : `Mapping[ethereum.base_types.Bytes, Node]` - Object with keys mapped to nibble-byte form. - - """ - mapped: MutableMapping[Bytes, Bytes] = {} - - for preimage, value in trie._data.items(): - if isinstance(value, Account): - assert get_storage_root is not None - address = Address(preimage) - encoded_value = encode_node(value, get_storage_root(address)) - elif value is None: - raise AssertionError("cannot encode `None`") - else: - encoded_value = encode_node(value) - if encoded_value == b"": - raise AssertionError - key: Bytes - if trie.secured: - # "secure" tries hash keys once before construction - key = keccak256(preimage) - else: - key = preimage - mapped[bytes_to_nibble_list(key)] = encoded_value - - return mapped - - -def root( - trie: Trie[K, V], - get_storage_root: Optional[Callable[[Address], Root]] = None, -) -> Root: - """ - Computes the root of a modified merkle patricia trie (MPT). - - Parameters - ---------- - trie : - `Trie` to get the root of. - get_storage_root : - Function to get the storage root of an account. Needed to encode - `Account` objects. - - - Returns - ------- - root : `.fork_types.Root` - MPT root of the underlying key-value pairs. - - """ - obj = _prepare_trie(trie, get_storage_root) - - root_node = encode_internal_node(patricialize(obj, Uint(0))) - if len(rlp.encode(root_node)) < 32: - return keccak256(rlp.encode(root_node)) - else: - assert isinstance(root_node, Bytes) - return Root(root_node) - - -def patricialize( - obj: Mapping[Bytes, Bytes], level: Uint -) -> Optional[InternalNode]: - """ - Structural composition function. - - Used to recursively patricialize and merkleize a dictionary. Includes - memoization of the tree structure and hashes. - - Parameters - ---------- - obj : - Underlying trie key-value pairs, with keys in nibble-list format. - level : - Current trie level. - - Returns - ------- - node : `ethereum.base_types.Bytes` - Root node of `obj`. - - """ - if len(obj) == 0: - return None - - arbitrary_key = next(iter(obj)) - - # if leaf node - if len(obj) == 1: - leaf = LeafNode(arbitrary_key[level:], obj[arbitrary_key]) - return leaf - - # prepare for extension node check by finding max j such that all keys in - # obj have the same key[i:j] - substring = arbitrary_key[level:] - prefix_length = len(substring) - for key in obj: - prefix_length = min( - prefix_length, common_prefix_length(substring, key[level:]) - ) - - # finished searching, found another key at the current level - if prefix_length == 0: - break - - # if extension node - if prefix_length > 0: - prefix = arbitrary_key[int(level) : int(level) + prefix_length] - return ExtensionNode( - prefix, - encode_internal_node( - patricialize(obj, level + Uint(prefix_length)) - ), - ) - - branches: List[MutableMapping[Bytes, Bytes]] = [] - for _ in range(16): - branches.append({}) - value = b"" - for key in obj: - if len(key) == level: - # shouldn't ever have an account or receipt in an internal node - if isinstance(obj[key], (Account, Receipt, Uint)): - raise AssertionError - value = obj[key] - else: - branches[key[level]][key] = obj[key] - - subnodes = tuple( - encode_internal_node(patricialize(branches[k], level + Uint(1))) - for k in range(16) - ) - return BranchNode( - cast(BranchSubnodes, assert_type(subnodes, Tuple[Extended, ...])), - value, - ) From 36a25698e78c35b0d68c11b29c58b25353cea1c3 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 27 Apr 2026 14:24:30 +0530 Subject: [PATCH 183/186] chore: fix lint issue --- .github/workflows/hive-bal.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml index 21a02482ad8..ee39b921419 100644 --- a/.github/workflows/hive-bal.yaml +++ b/.github/workflows/hive-bal.yaml @@ -116,7 +116,6 @@ jobs: with: client_repos: ${{ inputs.client_repos }} client_images: ${{ inputs.client_images }} - common_client_tag: ${{ inputs.common_client_tag }} client_source: ${{ inputs.client_source || 'git' }} hive_version: ${{ inputs.hive_version || 'gnosischain/hive@master' }} goproxy: ${{ env.GOPROXY }} From 51e01a1bfcd1829839263c8ae4e344cd4b83f6f3 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 23:02:35 +0530 Subject: [PATCH 184/186] chore: fix t8n tool changes for amsterdam --- src/ethereum/forks/amsterdam/fork.py | 78 ++++++++++++++++++++++++---- src/ethereum/forks/cancun/fork.py | 3 -- src/ethereum/forks/osaka/fork.py | 3 -- src/ethereum/forks/paris/fork.py | 3 -- src/ethereum/forks/prague/fork.py | 3 -- src/ethereum/forks/shanghai/fork.py | 3 -- 6 files changed, 67 insertions(+), 26 deletions(-) diff --git a/src/ethereum/forks/amsterdam/fork.py b/src/ethereum/forks/amsterdam/fork.py index ce45f5bd6d2..01996e1a0bd 100644 --- a/src/ethereum/forks/amsterdam/fork.py +++ b/src/ethereum/forks/amsterdam/fork.py @@ -40,6 +40,7 @@ from ethereum.forks.bpo5.blocks import Header as PreviousHeader from ethereum.merkle_patricia_trie import root, trie_set from ethereum.state import ( + EMPTY_ACCOUNT, EMPTY_CODE_HASH, Address, BlockDiff, @@ -80,14 +81,15 @@ from .state_tracker import ( BlockState, TransactionState, + account_exists, account_exists_and_is_empty, - create_ether, destroy_account, extract_block_diff, get_account, get_code, incorporate_tx_into_block, increment_nonce, + set_account, set_account_balance, ) from .transactions import ( @@ -120,6 +122,16 @@ ELASTICITY_MULTIPLIER = Uint(2) EMPTY_OMMER_HASH = keccak256(rlp.encode([])) SYSTEM_ADDRESS = hex_to_address("0xfffffffffffffffffffffffffffffffffffffffe") +DEPOSIT_CONTRACT_ADDRESS = hex_to_address( + "0xbabe2bed00000000000000000000000000000003" +) +BLOCK_REWARDS_CONTRACT_ADDRESS = hex_to_address( + "0x2000000000000000000000000000000000000001" +) +FEE_COLLECTOR_ADDRESS = hex_to_address( + "0x1559000000000000000000000000000000000000" +) +MAX_FAILED_WITHDRAWALS_TO_PROCESS = 4 BEACON_ROOTS_ADDRESS = hex_to_address( "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" ) @@ -1091,6 +1103,29 @@ def process_transaction( tx_state, block_env.coinbase, coinbase_balance_after_mining_fee ) + # transfer base fee to fee collector address + base_fee = U256(tx_gas_used * block_env.base_fee_per_gas) + if base_fee != 0: + fee_collector_balance = get_account( + tx_state, FEE_COLLECTOR_ADDRESS + ).balance + set_account_balance( + tx_state, + FEE_COLLECTOR_ADDRESS, + fee_collector_balance + base_fee, + ) + + # transfer blob fee to fee collector address + if blob_gas_fee != 0: + blob_fee_collector_balance = get_account( + tx_state, BLOB_FEE_COLLECTOR + ).balance + set_account_balance( + tx_state, + BLOB_FEE_COLLECTOR, + blob_fee_collector_balance + U256(blob_gas_fee), + ) + # EIP-7708: Emit burn logs for balances held by accounts marked for # deletion AFTER miner fee transfer. finalization_logs: List[Log] = [] @@ -1153,6 +1188,14 @@ def process_withdrawals( Spec: https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md """ + wd_state = TransactionState(parent=block_env.state) + deposit_contract = get_account(wd_state, DEPOSIT_CONTRACT_ADDRESS) + if deposit_contract.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(wd_state, SYSTEM_ADDRESS): + set_account(wd_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + amounts = [] addresses = [] for w in withdrawals: @@ -1172,6 +1215,10 @@ def process_withdrawals( if out.error: raise InvalidBlock(f"Withdrawal system call failed: {out.error}") + incorporate_tx_into_block( + wd_state, block_env.block_access_list_builder + ) + def process_block_rewards( block_env: vm.BlockEnvironment, @@ -1182,15 +1229,26 @@ def process_block_rewards( Spec: https://github.com/gnosischain/specs/blob/master/execution/posdao-post-merge.md Contract: https://github.com/gnosischain/posdao-contracts/blob/0315e8ee854cb02d03f4c18965584a74f30796f7/contracts/base/BlockRewardAuRaBase.sol#L234C14-L234C20 """ - # reward(address[],uint16[]) with empty lists - data = bytes.fromhex( - "f91c2898" - "0000000000000000000000000000000000000000000000000000000000000040" - "0000000000000000000000000000000000000000000000000000000000000060" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" + # reward(address[],uint16[]) with benefactors=[coinbase], kind=[0] + coinbase_padded = b"\x00" * 12 + bytes(block_env.coinbase) + data = ( + bytes.fromhex("f91c2898") + + (64).to_bytes(32, "big") # offset of address[] arg + + (128).to_bytes(32, "big") # offset of uint16[] arg + + (1).to_bytes(32, "big") # length of address[] = 1 + + coinbase_padded # address[0] = coinbase + + (1).to_bytes(32, "big") # length of uint16[] = 1 + + (0).to_bytes(32, "big") # kind[0] = 0 (RewardAuthor) ) + reward_state = TransactionState(parent=block_env.state) + account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) + if account.code_hash == EMPTY_CODE_HASH: + return + + if not account_exists(reward_state, SYSTEM_ADDRESS): + set_account(reward_state, SYSTEM_ADDRESS, EMPTY_ACCOUNT) + out = process_unchecked_system_transaction( block_env=block_env, target_address=BLOCK_REWARDS_CONTRACT_ADDRESS, @@ -1199,9 +1257,7 @@ def process_block_rewards( if out.error: raise InvalidBlock(f"Block rewards system call failed: {out.error}") - reward_state = TransactionState(parent=block_env.state) - account = get_account(reward_state, BLOCK_REWARDS_CONTRACT_ADDRESS) - if account.code_hash == EMPTY_CODE_HASH: + if len(out.return_data) == 0: return addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) diff --git a/src/ethereum/forks/cancun/fork.py b/src/ethereum/forks/cancun/fork.py index 2fe2a96fb77..564bedd7054 100644 --- a/src/ethereum/forks/cancun/fork.py +++ b/src/ethereum/forks/cancun/fork.py @@ -925,9 +925,6 @@ def process_block_rewards( if len(out.return_data) == 0: return - if len(out.return_data) == 0: - return - addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/osaka/fork.py b/src/ethereum/forks/osaka/fork.py index 12066bf17c0..df0e02bc19f 100644 --- a/src/ethereum/forks/osaka/fork.py +++ b/src/ethereum/forks/osaka/fork.py @@ -1124,9 +1124,6 @@ def process_block_rewards( if len(out.return_data) == 0: return - if len(out.return_data) == 0: - return - addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/paris/fork.py b/src/ethereum/forks/paris/fork.py index 484dec3ab0d..4800677666a 100644 --- a/src/ethereum/forks/paris/fork.py +++ b/src/ethereum/forks/paris/fork.py @@ -777,9 +777,6 @@ def process_block_rewards( if len(out.return_data) == 0: return - if len(out.return_data) == 0: - return - addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/prague/fork.py b/src/ethereum/forks/prague/fork.py index f30f3e8deb2..1638f030721 100644 --- a/src/ethereum/forks/prague/fork.py +++ b/src/ethereum/forks/prague/fork.py @@ -1107,9 +1107,6 @@ def process_block_rewards( if len(out.return_data) == 0: return - if len(out.return_data) == 0: - return - addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) diff --git a/src/ethereum/forks/shanghai/fork.py b/src/ethereum/forks/shanghai/fork.py index 88d1f5120cc..895f56cff02 100644 --- a/src/ethereum/forks/shanghai/fork.py +++ b/src/ethereum/forks/shanghai/fork.py @@ -834,9 +834,6 @@ def process_block_rewards( if len(out.return_data) == 0: return - if len(out.return_data) == 0: - return - addresses, amounts = decode(["address[]", "uint256[]"], out.return_data) for addr, amount in zip(addresses, amounts, strict=True): address = hex_to_address(addr) From 1a8983a7dba111c835e87ca23c568733389cc003 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 23:02:44 +0530 Subject: [PATCH 185/186] chore: fix workflows --- .github/workflows/hive-bal.yaml | 178 ---------------------------- .github/workflows/hive-generic.yaml | 174 --------------------------- 2 files changed, 352 deletions(-) delete mode 100644 .github/workflows/hive-bal.yaml delete mode 100644 .github/workflows/hive-generic.yaml diff --git a/.github/workflows/hive-bal.yaml b/.github/workflows/hive-bal.yaml deleted file mode 100644 index ee39b921419..00000000000 --- a/.github/workflows/hive-bal.yaml +++ /dev/null @@ -1,178 +0,0 @@ -name: Hive - BAL -on: - schedule: - - cron: '0 0 * * *' # Run every day at 00:00 UTC - workflow_dispatch: - inputs: - client: - type: string - default: '"go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"' - description: Comma-separated list of clients to test e.g. go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis - simulator: - type: string - default: >- - "gnosis/eels/consume-engine", - "gnosis/eels/consume-rlp" - description: >- - Comma-separated list of simulators to test - e.g. gnosis/eels/consume-engine, gnosis/eels/consume-rlp - hive_version: - type: string - default: gnosischain/hive@master - description: GitHub repository and tag for hive (repo@tag) - client_source: - type: choice - default: git - description: >- - How client images should be sourced. - 'git' will use the github repo and tag (See client_repos). - 'docker' will use the docker registry and tag (See client_images). - options: - - docker - - git - client_repos: - type: string - default: | - { - "geth": "gnosischain/go-ethereum@release-1.17.2-gc", - "reth": "gnosischain/reth_gnosis@master", - "nethermind": "NethermindEth/nethermind@bal-devnet-4", - "erigon": "erigontech/erigon@bal-devnet-4" - } - description: 'JSON object containing client versions in format {"client": "repo@tag", ...}' - client_images: - type: string - default: | - { - "geth": "ghcr.io/gnosischain/geth:latest", - "reth": "ghcr.io/gnosischain/reth_gnosis:latest", - "nethermind": "nethermind/nethermind:latest", - "erigon": "erigontech/erigon:latest" - } - description: 'JSON object containing client docker images in format {"client": "registry:tag", ...}' - -env: - # Proxy - GOPROXY: "${{ vars.GOPROXY }}" - # Hive action environment variables - GCS_BUCKET: gnosis-hive-ui-staging - GCS_PATH: bal - GCS_PUBLIC_URL: https://storage.googleapis.com/gnosis-hive-ui-staging/bal - INSTALL_RCLONE_VERSION: v1.68.2 - # Flags used for all simulators - GLOBAL_EXTRA_FLAGS: >- - --client.checktimelimit=300s - --docker.buildoutput - # Docker-specific flags (only used when client_source is 'docker') - DOCKER_AUTH_FLAGS: >- - --docker.auth - # Flags used for the gnosis/eels/consume-engine simulator - EELS_ENGINE_FLAGS: >- - --sim.parallelism=6 - --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} - --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} - --sim.limit='.*(8024|7708|7778|7843|7928|7954|8037).*' - --sim.limit.exact=false - --sim.loglevel=3 - # Flags used for the gnosis/eels/consume-rlp simulator - EELS_RLP_FLAGS: >- - --sim.parallelism=6 - --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} - --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} - --sim.limit='.*(8024|7708|7778|7843|7928|7954|8037).*' - --sim.limit.exact=false - --sim.loglevel=3 - -jobs: - prepare: - runs-on: ubuntu-latest - outputs: - hive_repo: ${{ steps.client_config.outputs.hive_repo }} - hive_tag: ${{ steps.client_config.outputs.hive_tag }} - client_config: ${{ steps.client_config.outputs.client_config }} - client_source: ${{ inputs.client_source || 'git' }} - fixtures_url: ${{ steps.latest.outputs.fixtures_url }} - eels_branch: ${{ steps.latest.outputs.eels_branch }} - steps: - - name: Get latest bal fixtures and branch - id: latest - env: - GH_TOKEN: ${{ github.token }} - run: | - # Get latest bal fixtures release from EEST - TAG=$(gh release list --repo gnosischain/execution-spec-tests --json tagName --limit 100 | jq -r '[.[] | select(.tagName | startswith("bal"))][0].tagName') - FIXTURES_URL="https://github.com/gnosischain/execution-spec-tests/releases/download/${TAG}/fixtures_bal.tar.gz" - echo "fixtures_url=$FIXTURES_URL" >> "$GITHUB_OUTPUT" - echo "Using fixtures from: $FIXTURES_URL" - - # Get devnets/bal from EELS - BRANCH="devnets/bal" - echo "eels_branch=$BRANCH" >> "$GITHUB_OUTPUT" - echo "Using EELS branch: $BRANCH" - - - uses: gnosischain/hive-github-action/helpers/client-config@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa - name: "Client config" - id: client_config - with: - client_repos: ${{ inputs.client_repos }} - client_images: ${{ inputs.client_images }} - client_source: ${{ inputs.client_source || 'git' }} - hive_version: ${{ inputs.hive_version || 'gnosischain/hive@master' }} - goproxy: ${{ env.GOPROXY }} - - test: - timeout-minutes: 2160 - needs: prepare - env: - # BAL-specific environment variables - HIVE_PARALLEL_TX_PROCESSING_DISABLED: "true" - HIVE_AMSTERDAM_TIMESTAMP: "1759250952" - # Dynamic EELS build args from prepare job - EELS_BUILD_ARG_FIXTURES: ${{ needs.prepare.outputs.fixtures_url }} - EELS_BUILD_ARG_BRANCH: ${{ needs.prepare.outputs.eels_branch }} - runs-on: >- - ${{ - matrix.simulator == 'gnosis/rpc-compat' && 'ubuntu-latest' || - contains(matrix.simulator, 'gnosis/eels/') && 'self-hosted-ghr-size-ccx33-x64' || - 'ubuntu-latest' - }} - concurrency: - group: >- - ${{ github.head_ref || inputs }}-${{ matrix.client }}-${{ matrix.simulator }}-quick - strategy: - fail-fast: false - matrix: - client: >- - ${{ fromJSON(format('[{0}]', inputs.client || ' - "go-ethereum-gnosis", - "reth-gnosis", - "nethermind-gnosis", - "erigon-gnosis" - '))}} - simulator: >- - ${{ fromJSON(format('[{0}]', inputs.simulator || ' - "gnosis/eels/consume-engine", - "gnosis/eels/consume-rlp" - '))}} - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa - with: - hive_repository: ${{ needs.prepare.outputs.hive_repo }} - hive_version: ${{ needs.prepare.outputs.hive_tag }} - client: ${{ matrix.client }} - simulator: ${{ matrix.simulator }} - client_config: ${{ needs.prepare.outputs.client_config }} - extra_flags: >- - ${{ env.GLOBAL_EXTRA_FLAGS }} - ${{ needs.prepare.outputs.client_source == 'docker' && env.DOCKER_AUTH_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} - gcs_upload: true - gcs_bucket: ${{ env.GCS_BUCKET }} - gcs_path: ${{ env.GCS_PATH }} - gcs_public_url: ${{ env.GCS_PUBLIC_URL }} - rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} - rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} - workflow_artifact_upload: true - website_upload: true diff --git a/.github/workflows/hive-generic.yaml b/.github/workflows/hive-generic.yaml deleted file mode 100644 index 186ba7f7320..00000000000 --- a/.github/workflows/hive-generic.yaml +++ /dev/null @@ -1,174 +0,0 @@ -name: Hive - Generic -on: - workflow_dispatch: - inputs: - client: - type: string - default: '["go-ethereum-gnosis","reth-gnosis","nethermind-gnosis","erigon-gnosis"]' - description: JSON array of clients to test e.g. go-ethereum-gnosis, reth-gnosis, nethermind-gnosis, erigon-gnosis - client_matrix: - type: choice - options: - - "true" - - "false" - default: "true" - description: If "true", run each client in a separate matrix job. If "false", run all clients together in a single job. - simulator: - type: string - # Disabled for now: devp2p, gnosis/consensus, gnosis/graphql, gnosis/rpc-compat - default: >- - [ - "gnosis/eels/consume-engine", - "gnosis/eels/consume-rlp" - ] - description: JSON array of simulators to test e.g. gnosis/rpc-compat, gnosis/eels/consume-engine, gnosis/eels/consume-rlp - hive_version: - type: string - default: gnosischain/hive@master - description: GitHub repository and tag for hive (repo@tag) - client_source: - type: choice - description: >- - How client images should be sourced. - 'git' will use the github repo and tag (See client_config repos). - 'docker' will use the docker registry and tag (See client_config images). - options: - - docker - - git - default: git - client_config: - type: string - default: | - { - "repos": { - "geth": "gnosischain/go-ethereum@release-1.17.2-gc", - "reth": "gnosischain/reth_gnosis@master", - "nethermind": "NethermindEth/nethermind@master", - "erigon": "erigontech/erigon@main" - }, - "images": { - "geth": "ghcr.io/gnosischain/geth:latest", - "reth": "ghcr.io/gnosischain/reth_gnosis:latest", - "nethermind": "nethermind/nethermind:latest", - "erigon": "erigontech/erigon:latest" - } - } - description: 'JSON object containing client configuration with "repos" and "images" objects for git and docker sources respectively' - extra_flags: - type: string - default: "" - description: Additional flags to append to the hive command - concurrency_group: - type: string - default: "default" - description: Concurrency group for the workflow - workflow_artifact_upload: - description: "Upload test results as an workflow artifact" - required: false - default: "false" - timeout_minutes: - type: string - default: "2880" - description: "Timeout in minutes for the test job (default: 2880 = 2 days)" - - -env: - # Proxy - GOPROXY: "${{ vars.GOPROXY }}" - # Hive action environment variables - GCS_BUCKET: gnosis-hive-ui-staging - GCS_PATH: generic - GCS_PUBLIC_URL: https://storage.googleapis.com/gnosis-hive-ui-staging/generic - INSTALL_RCLONE_VERSION: v1.68.2 - EELS_BUILD_ARG_FIXTURES: https://github.com/gnosischain/execution-spec-tests/releases/download/mainnet@v0.1.0/fixtures_mainnet.tar.gz - EELS_BUILD_ARG_BRANCH: forks/amsterdam - # Flags used for all simulators - GLOBAL_EXTRA_FLAGS: >- - --client.checktimelimit=180s - --sim.parallelism=4 - --docker.buildoutput - # Docker-specific flags (only used when client_source is 'docker') - DOCKER_AUTH_FLAGS: >- - --docker.auth - # Flags used for the gnosis/eels/consume-engine simulator - EELS_ENGINE_FLAGS: >- - --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} - --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} - --sim.loglevel=3 - # Flags used for the gnosis/eels/consume-rlp simulator - EELS_RLP_FLAGS: >- - --sim.buildarg fixtures=${EELS_BUILD_ARG_FIXTURES} - --sim.buildarg branch=${EELS_BUILD_ARG_BRANCH} - --sim.loglevel=3 - # # Flags used for the gnosis/rpc-compat simulator - # RPC_COMPAT_FLAGS: >- - # --sim.loglevel=3 - # # Flags used for the gnosis/consensus simulator - # CONSENSUS_FLAGS: >- - # --sim.loglevel=3 - # # Flags used for the gnosis/graphql simulator - # GRAPHQL_FLAGS: >- - # --sim.loglevel=3 - -jobs: - prepare: - runs-on: ubuntu-latest - outputs: - # Hive version - hive_repo: ${{ steps.client_config.outputs.hive_repo }} - hive_tag: ${{ steps.client_config.outputs.hive_tag }} - # client_config contains the YAML client config for Hive - client_config: ${{ steps.client_config.outputs.client_config }} - client_source: ${{ inputs.client_source || 'git' }} - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - - uses: gnosischain/hive-github-action/helpers/client-config@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa - name: "Client config" - id: client_config - with: - client_repos: ${{ toJSON(fromJSON(inputs.client_config).repos) }} - client_images: ${{ toJSON(fromJSON(inputs.client_config).images) }} - client_source: ${{ inputs.client_source }} - hive_version: ${{ inputs.hive_version }} - goproxy: ${{ env.GOPROXY }} - - test: - timeout-minutes: ${{ fromJSON(inputs.timeout_minutes) }} - needs: prepare - runs-on: ubuntu-latest - concurrency: - group: >- - ${{ github.head_ref || inputs.concurrency_group }}-${{ matrix.client }}-${{ matrix.simulator }} - strategy: - fail-fast: false - matrix: - client: >- - ${{ - inputs.client_matrix == 'true' && fromJSON(inputs.client) || - fromJSON(format('["{0}"]', join(fromJSON(inputs.client), '-'))) - }} - simulator: ${{ fromJSON(inputs.simulator) }} - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v5.0.0 - - uses: gnosischain/hive-github-action@315b005b3f9d6582796d5917ddbf0bee3dc6fbfa - with: - hive_repository: ${{ needs.prepare.outputs.hive_repo }} - hive_version: ${{ needs.prepare.outputs.hive_tag }} - client: ${{ inputs.client_matrix == 'true' && matrix.client || join(fromJSON(inputs.client), ',') }} - simulator: ${{ matrix.simulator }} - client_config: ${{ needs.prepare.outputs.client_config }} - extra_flags: >- - ${{ env.GLOBAL_EXTRA_FLAGS }} - ${{ needs.prepare.outputs.client_source == 'docker' && env.DOCKER_AUTH_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/eels/consume-engine' && env.EELS_ENGINE_FLAGS || '' }} - ${{ matrix.simulator == 'gnosis/eels/consume-rlp' && env.EELS_RLP_FLAGS || '' }} - ${{ inputs.extra_flags }} - gcs_upload: true - gcs_bucket: ${{ env.GCS_BUCKET }} - gcs_path: ${{ env.GCS_PATH }} - gcs_public_url: ${{ env.GCS_PUBLIC_URL }} - rclone_config: ${{ secrets.HIVE_RCLONE_CONFIG }} - rclone_version: ${{ env.INSTALL_RCLONE_VERSION }} - workflow_artifact_upload: ${{ inputs.workflow_artifact_upload }} - website_upload: true - website_index_generation: true From 6714f22d4a664977f521796005f1f57944c6e066 Mon Sep 17 00:00:00 2001 From: Chetna Miittal Date: Mon, 25 May 2026 23:08:35 +0530 Subject: [PATCH 186/186] chore: cleanup client names --- .github/configs/hive/latest.yaml | 8 ++++---- .github/workflows/eest_hive_gnosis.yaml | 4 ++-- .github/workflows/eest_hive_gnosis_multi_client.yaml | 8 ++++---- .../workflows/eest_hive_gnosis_multi_client_until.yaml | 8 ++++---- .github/workflows/eest_hive_matrix.yaml | 4 ++-- .github/workflows/hive-consume.yaml | 10 +++++----- .github/workflows/hive-execute.yaml | 2 +- CLAUDE.md | 4 ++-- plan.md | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/configs/hive/latest.yaml b/.github/configs/hive/latest.yaml index 0ad950ce6dd..6dcfd75e351 100644 --- a/.github/configs/hive/latest.yaml +++ b/.github/configs/hive/latest.yaml @@ -2,7 +2,7 @@ # Geth (Go-Ethereum) # GHCR: https://ghcr.io/chetna-mittal/geth -- client: go-ethereum-gnosis +- client: go-ethereum nametag: "" build_args: baseimage: ghcr.io/chetna-mittal/geth @@ -10,7 +10,7 @@ # Nethermind # Docker Hub: https://hub.docker.com/r/nethermind/nethermind -- client: nethermind-gnosis +- client: nethermind nametag: "" build_args: baseimage: docker.io/nethermind/nethermind @@ -18,7 +18,7 @@ # Reth (Gnosis) # GHCR: https://ghcr.io/gnosischain/reth_gnosis -- client: reth-gnosis +- client: reth nametag: "" build_args: baseimage: ghcr.io/gnosischain/reth_gnosis @@ -26,7 +26,7 @@ # Erigon # Docker Hub: https://hub.docker.com/r/erigontech/erigon -- client: erigon-gnosis +- client: erigon nametag: "" build_args: baseimage: docker.io/erigontech/erigon diff --git a/.github/workflows/eest_hive_gnosis.yaml b/.github/workflows/eest_hive_gnosis.yaml index fcdfe909907..f18ccb91e47 100644 --- a/.github/workflows/eest_hive_gnosis.yaml +++ b/.github/workflows/eest_hive_gnosis.yaml @@ -10,7 +10,7 @@ on: client: description: "Client passed to --client" required: true - default: "nethermind-gnosis" + default: "nethermind" test_dir: description: "Optional test directory under tests/ (e.g. osaka). Leave empty to fill all tests." required: false @@ -49,7 +49,7 @@ jobs: --sim.loglevel=5 \ --docker.output \ --docker.pull > hive.log 2>&1 & - + - name: Install wait-on utility run: npm install -g wait-on diff --git a/.github/workflows/eest_hive_gnosis_multi_client.yaml b/.github/workflows/eest_hive_gnosis_multi_client.yaml index 13942d8f335..e01fe0f179e 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client.yaml @@ -52,10 +52,10 @@ jobs: fail-fast: false matrix: client: - - reth-gnosis - - go-ethereum-gnosis - - nethermind-gnosis - - erigon-gnosis + - reth + - go-ethereum + - nethermind + - erigon steps: - name: Checkout the repository diff --git a/.github/workflows/eest_hive_gnosis_multi_client_until.yaml b/.github/workflows/eest_hive_gnosis_multi_client_until.yaml index a6b1afadc36..fea312e5e69 100644 --- a/.github/workflows/eest_hive_gnosis_multi_client_until.yaml +++ b/.github/workflows/eest_hive_gnosis_multi_client_until.yaml @@ -52,10 +52,10 @@ jobs: fail-fast: false matrix: client: - - reth-gnosis - - go-ethereum-gnosis - - nethermind-gnosis - - erigon-gnosis + - reth + - go-ethereum + - nethermind + - erigon steps: - name: Checkout the repository diff --git a/.github/workflows/eest_hive_matrix.yaml b/.github/workflows/eest_hive_matrix.yaml index cc2d21a77a3..c9a4f48475a 100644 --- a/.github/workflows/eest_hive_matrix.yaml +++ b/.github/workflows/eest_hive_matrix.yaml @@ -10,12 +10,12 @@ on: client: description: "Client passed to --client" required: true - default: "nethermind-gnosis" + default: "nethermind" test_dirs: description: "Comma-separated list of EIP numbers or directory names" required: true default: "amsterdam" - + jobs: # Prepare matrix from input prepare: diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index 4f85eccdcc6..47e39fd79f1 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -33,9 +33,9 @@ on: required: false default: "ghcr.io/chetna-mittal/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., go-ethereum-gnosis, reth-gnosis)" + description: "Hive client to test (e.g., go-ethereum, reth)" required: false - default: "go-ethereum-gnosis" + default: "go-ethereum" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -48,10 +48,10 @@ on: type: string default: "ghcr.io/chetna-mittal/geth:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" client: - description: "Hive client to test (e.g., go-ethereum-gnosis, reth-gnosis)" + description: "Hive client to test (e.g., go-ethereum, reth)" required: false type: string - default: "go-ethereum-gnosis" + default: "go-ethereum" client_file: description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" required: false @@ -84,7 +84,7 @@ jobs: needs: cache-docker-images runs-on: ubuntu-latest env: - CLIENT: ${{ inputs.client || 'go-ethereum-gnosis' }} + CLIENT: ${{ inputs.client || 'go-ethereum' }} CLIENT_FILE: ${{ inputs.client_file || 'latest.yaml' }} strategy: fail-fast: true diff --git a/.github/workflows/hive-execute.yaml b/.github/workflows/hive-execute.yaml index bc170d73b76..2abbb0c3a37 100644 --- a/.github/workflows/hive-execute.yaml +++ b/.github/workflows/hive-execute.yaml @@ -86,7 +86,7 @@ jobs: id: start-hive uses: ./execution-specs/.github/actions/start-hive-dev with: - clients: go-ethereum-gnosis + clients: go-ethereum client-file: execution-specs/.github/configs/hive/latest.yaml hive-path: hive timeout: "180" diff --git a/CLAUDE.md b/CLAUDE.md index fafc2ddc12f..08bda7eddca 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -71,7 +71,7 @@ There are two phases in the test pipeline: **fill** (generate fixtures from the **Core test pipeline** (`test.yaml`): Runs on PRs. Fill only — no consume. Jobs: `static`, `py3` (fill Paris->Osaka), `pypy3`, `tests_pytest_py3`, `tests_pytest_pypy3`. Setup action (`.github/actions/setup-env/`) installs Rust, build-essential, tox, and downloads geth. -**Hive integration** (`hive-consume.yaml`): Runs on PRs touching hive paths or `forks/**` pushes. Intended to consume fixtures against `go-ethereum-gnosis` via Hive (4 modes: Engine, RLP, Sync, Dev Mode). Uses `gnosischain/hive` repo (branch `master`) and `latest.yaml` client config. +**Hive integration** (`hive-consume.yaml`): Runs on PRs touching hive paths or `forks/**` pushes. Intended to consume fixtures against `go-ethereum` via Hive (4 modes: Engine, RLP, Sync, Dev Mode). Uses `gnosischain/hive` repo (branch `master`) and `latest.yaml` client config. **Manual hive workflows** (workflow_dispatch only, not automated on PRs): @@ -84,7 +84,7 @@ There are two phases in the test pipeline: **fill** (generate fixtures from the |------------------------------------|-----------------------------------|-------------------------------------------------------------------------------------| | test.yaml | PR, push to master | Core pipeline: static checks, py3 fill, pypy3 fill, framework unit tests | | test-docs.yaml | PR, push | mkdocs build, markdownlint, changelog validation | -| hive-consume.yaml | PR (hive paths), push to forks/** | Hive integration: Engine/RLP/Sync simulators + Dev Mode against go-ethereum-gnosis | +| hive-consume.yaml | PR (hive paths), push to forks/** | Hive integration: Engine/RLP/Sync simulators + Dev Mode against go-ethereum | | benchmark.yaml | push to forks/** | Gas benchmarks, fixed opcode benchmarks | | eest_hive_gnosis.yaml | manual | Fill + consume against a single Gnosis client | | eest_hive_gnosis_multi_client.yaml | manual | Fill once, then consume against 4 Gnosis clients (reth/geth/nethermind/erigon) | diff --git a/plan.md b/plan.md index 3b77996c33b..82d5ee18d85 100644 --- a/plan.md +++ b/plan.md @@ -8,7 +8,7 @@ Gnosis fork of Ethereum EELS. Branch structure: `forks/osaka` (shipped), `forks/ ### 1. Extend Hive consume to multi-client -**Status**: Single-client consume (nethermind-gnosis) implemented in PR [#12](https://github.com/gnosischain/execution-specs/pull/12). Next step is extending to all 4 Gnosis clients (reth, geth, nethermind, erigon) — either as a matrix in `hive-consume.yaml` or keeping the multi-client variant as a separate manual workflow. +**Status**: Single-client consume (nethermind) implemented in PR [#12](https://github.com/gnosischain/execution-specs/pull/12). Next step is extending to all 4 Gnosis clients (reth, geth, nethermind, erigon) — either as a matrix in `hive-consume.yaml` or keeping the multi-client variant as a separate manual workflow. ### 2. Optimize fill scope for PR vs release @@ -58,4 +58,4 @@ The `gnosis-osaka` branch is based on upstream `forks/osaka`. As upstream evolve - [x] CI workflow adaptation to Gnosis infrastructure (hive repo, client configs, Docker images) - [x] CLAUDE.md created with full project documentation - [x] Branch structure: `forks/osaka`, `forks/amsterdam`, `mainnet` (upstream merge strategy) -- [x] Hive consume fix: fill+consume with nethermind-gnosis — PR [#12](https://github.com/gnosischain/execution-specs/pull/12) +- [x] Hive consume fix: fill+consume with nethermind — PR [#12](https://github.com/gnosischain/execution-specs/pull/12)